|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Mon Mar 20, 2017 1:17 am |
|
|
As posted, the CS line is possibly being glitched.
The #USE SPI controls the CS. I set it high _once_ at the start of the code, to ensure it is high 'ASAP' at boot, but from that moment it should not be touched again. The #USE SPI controls it.
Temtronic removes this, but then forgets that SPI will still be sending, when you leave the spi_xfer.
If you want to control the CS yourself, then it needs to be removed from the #USE statement, but also then the spi_xfer, needs to do a dummy read. Remember spi_xfer, without a read, will exit, while a byte is still to be sent (it exits as soon as the last byte to transfer is loaded into the shift register). While if told to 'read', it waits till both bytes are transferred.
So to control it manually:
Code: |
#include "18F2520.h"
#fuses INTRC_IO, NOWDT,BROWNOUT,PUT
#use delay(clock=1000000)
#define CS_PIN PIN_C1 //where this is the pin you want
#use spi(SPI1, BITS=16, MODE=0,stream=DAC_STREAM)
void main()
{
int16 value, dummy;
output_high(CS_PIN); //ensure this starts high
value = 5000;
delay_ms(1000); //gives chip time to power up
while(1)
{
output_low(CS_PIN);
delay_cycles(1); //added some hold time
dummy=spi_xfer(DAC_STREAM,value,16);
//this ensures the spi_xfer waits for the transaction to finish
delay_cycles(1); //added some hold time
output_high(CS_PIN);
delay_ms(250);
}
}
|
If this still glitches, you need to be looking at whether there is crosstalk between the digital lines and the analog output. That is 'why' the analog pins are separated on the other side of the chip, but some careful testing may reveal a whisker... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9081 Location: Greensville,Ontario
|
|
Posted: Mon Mar 20, 2017 5:09 am |
|
|
Gee Mr. T it wasn't me , well this time anyway
The 'cyclic' problem does sound like a possible hardware issue(floating pins,bypass cap on wrong pin)s but now I'm curious if the 1Hz LED program would run 100%. It could even be the power supply,depending on what it is.
Maybe dump the listing and confirem the WDT fuse is disabled? see it there's some 'odd' code.
Have to admit without seeing it on the bench it's hard to nail exactly what's causing the problem. It'll be nice to hear 'up and running' and WHAT fixes this one !
jay aka temtronic |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Mon Mar 20, 2017 7:55 am |
|
|
Apologies. It was Jeremiah's.
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Mon Mar 20, 2017 7:57 am |
|
|
I see that PCM_Programmer said that in other threads he refers to using 4.114. Must admit that is so old, it could easily be a compiler problem.
One obvious question. What ciruit is on the MCLR pin?. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1314
|
|
Posted: Mon Mar 20, 2017 12:03 pm |
|
|
Ttelmah wrote: | Apologies. It was Jeremiah's.
|
Sorry, I am used to PCD where the spi_xfer() function does wait for the transmission to finish before leaving.
Code: |
.................... #use spi(SPI2,FORCE_HW,master,mode=0)
*
0200: MOV W5,[W15++]
0202: MOV W0,W4
0204: MOV W1,W5
0206: MOV #18,W3
0208: CPSGT W2,W3
020A: BRA 210
020C: MOV #B,W3
020E: BRA 222
0210: MOV #10,W3
0212: CPSGT W2,W3
0214: BRA 21A
0216: MOV #A,W3
0218: BRA 222
021A: MOV #8,W3
021C: CPSGT W2,W3
021E: BRA 222
0220: MOV #9,W3
0222: MOV.B [W3+#0],W0L
0224: MOV.B W0L,268 //write value to TXRX reg
0226: BTSS.B 260.0 //wait for rx received bit to be set
0228: BRA 226
022A: MOV.B 268,W0L //save the result
022C: MOV.B W0L,[W3--]
022E: BCLR.B 260.6
0230: SUB.B #8,W2L
0232: BRA GTU,222
0234: MOV W4,W0
0236: MOV W5,W1
0238: MOV [--W15],W5
023A: RETURN
|
The call in question had no dummy variable
Code: |
.................... spi_xfer(0x00);
02A2: MOV #8,W2
02A4: MOV #0,W0
02A6: MOV #0,W1
02A8: CALL 200
|
Note the lack of dummy variable. I wonder why PCD does things so differently? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19195
|
|
Posted: Mon Mar 20, 2017 12:45 pm |
|
|
It also does the loops for multiple transfers even if you only specify to transfer one. The PIC16/18 version seems much better written...
It is strange. This has been noted in another thread. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 20, 2017 1:40 pm |
|
|
Hemnath has not told us the Silicon Revision of his 18F2520 PIC.
There is an errata on Rev. A1 that states:
Quote: |
40. Module: MSSP
When the MSSP is configured for SPI mode, the
Buffer Full bit, BF (SSPSTAT<0>), should not be
polled in software to determine when the transfer
is complete.
Work around:
Copy the SSPSTAT register into a variable and
perform the bit test on the variable. In Example 5,
SSPSTAT is copied into the working register
where the bit test is performed.
EXAMPLE 5:
loop_MSB:
MOVF SSPSTAT, W // Copy SSPSTAT into W register
BTFSS WREG, BF // Then poll BF in the W reg.
BRA loop_MSB
A second option is to poll the Master Synchronous
Serial Port Interrupt Flag bit, SSPIF (PIR1<3>).
This bit can be polled and will set when the transfer
is complete.
|
Hemnath's vs. 4.114 is polling the bit. It does it twice in the
code below, because it's setup for a 16-bit transaction (two bytes).
If he has Silicon Revision A1, this could be causing a problem:
Quote: | .................... #use spi(SPI1, BITS=16, ENABLE=CS_PIN, MODE=0)
001C: BCF F94.1
001E: BCF F8B.1
0020: MOVF FC9,W
0022: MOVFF 08,FC9
0026: BTFSS FC7.0 // Poll the BF flag in the SSPSTAT reg
0028: BRA 0026
002A: MOVFF FC9,02
002E: MOVF FC9,W
0030: MOVFF 07,FC9
0034: BTFSS FC7.0
0036: BRA 0034
0038: MOVFF FC9,01
003C: BCF F94.1
003E: BSF F8B.1
0040: GOTO 00A0 (RETURN)
|
In vs. 5.070, CCS handles it according to the errata. CCS does it their
own way, by rotating it into the W register, but they're taking into
account the errata.
Quote: | .................... #use spi(SPI1, BITS=16, ENABLE=CS_PIN, MODE=0)
0020: BCF F94.1
0022: BCF F8B.1
0024: MOVF FC9,W
0026: MOVFF 08,FC9
002A: RRCF FC7,W // Rotate BF bit into the W register
002C: BNC 002A
002E: MOVFF FC9,01
0032: MOVF FC9,W
0034: MOVFF 07,FC9
0038: RRCF FC7,W
003A: BNC 0038
003C: MOVFF FC9,00
0040: BCF F94.1
0042: BSF F8B.1
0044: GOTO 00A0 (RETURN)
|
So, the question is, what silicon revision does Hemnath have ?
Is it the A1 version of the PIC ? His debugger/programmer will report
this information when it connects to the PIC. |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 227 Location: chennai
|
|
Posted: Mon Mar 20, 2017 9:38 pm |
|
|
Connected the PIC with my programmer and checked the revision on MPLAB.
PIC18F2520 found (Rev 0x7) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 20, 2017 11:58 pm |
|
|
That is the B4 silicon revision, and the BF polling issue is not mentioned
in the B4 errata sheet. So presumably it doesn't apply. |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 227 Location: chennai
|
|
Posted: Tue Mar 21, 2017 4:36 am |
|
|
Hi,
I have tried to solve the problem by rewriting the program and it works.
Code: | void main()
{
TRISB=0; // PORTB is configured as an output port
TRISC=0; // PORTC is configured as an output port
PORTC=0;
PORTB=0;
delay_ms(1000);
SSPSTAT=0x80; //Status Register SSPSTAT=10000000
SSPCON1=0x20; //Enables serial port pins & set the SPI clock as clock = FOSC/4
output_high(CS);
delay_ms(1000);
while(1)
{
output_low(CS);
SSPBUF=5; // sending the upper 8 bits serially
while(!BF); // wait until the upper 8 bits are sent
SSPBUF=220; // sending the lower 8 bits serially
while(!BF); // wait until the lower 8 bits are sent
output_high(CS);
delay_ms(50);
}
} |
Now the output is stable. Some changes in uV (thats acceptable). Here I have done the SSPSTAT register as 'Transmit occurs on transition from active to Idle clock state', since it specifies in the datasheet Quote: | In LTC1655 datasheet, DIN (Pin 2): The TTL Level Input for the Serial Interface
Data. Data on the DIN pin is latched into the shift register
on the rising edge of the serial clock and is loaded MSB
first. The LTC1655/LTC1655L requires a 16-bit word. | .
Also i tried these changes by setting up the #use spi line by including,
Code: | #use spi(SPI1, BITS=16, ENABLE=CS_PIN, MODE=0, SAMPLE_RISE) | , but it didn't help me to solve. I don't know what is the code inside the #use spi line, but someone have to check it.
You guys are really helpful. Thanks all. |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 227 Location: chennai
|
|
Posted: Tue Mar 21, 2017 5:56 am |
|
|
I am facing another problem.
When I simply put some constant value on SSPBUF = 10, the output voltage is constant.
When i initialize a variable 'high_value = 10' and SSPBUF = high_value, the output voltage value on dac is changing.
delay_ms(500) also applied in the program. What could be the issue? Any collision on WCOL? |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 227 Location: chennai
|
|
Posted: Thu Mar 23, 2017 2:13 am |
|
|
any help?
high_value is initialized as unsigned int8 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 23, 2017 10:50 am |
|
|
1. Don't run it at 1 MHz. Run at 4 MHz or higher. I'm just telling you
how I would do it.
2. Try a different family of PIC.
3. Tell us where you got the DAC. Was it Ebay ? How much did you pay ?
There is a possibility that the DAC is a counterfeit chip.
4. Post a high-resolution, in-focus photo of your board or bread-board.
How to post an image on the CCS forum:
Go to this website: http://postimage.org/
Upload your image. Select family safe. Then click the first button for
"Hotlink to Forum" to get a link to the image.
Then go to the CCS forum and type Ctrl-V to paste the link into a post.
If postimage.org doesn't work in your country, then use Google to find
another free image hosting site for forums.
5. Post your circuit schematic.
The last two are most important. I want to see if you have simple things
like 100 nF bypass capacitors on all Vdd pins of all chips on the board.
I want to see how the board is constructed. |
|
|
hemnath
Joined: 03 Oct 2012 Posts: 227 Location: chennai
|
|
Posted: Fri Mar 24, 2017 1:04 am |
|
|
I have managed to solve the problem by reading the datasheet again and again. As @temtronic already asked me to look at DAC is updating too fast. Yes certainly this is the problem.
I have reconfigured the register SSPCON1 = 0b00100001; // SPI Master mode, clock = FOSC/16 => 4MHz/16 => 250KHz which satisfies (because LTC1655 has max update rate of 750KHz). Now the code the working.
I have written a small logic to convert 16 bit number to two 8 bits. Below is the logic . Pls check LTC1655 datasheet page 13(breadboard circuit built) and I am using Ra = 200Ohms. So max current of 4.096V/200Ohms => 20.48mA.
When I send 65535, output measured current is 20.4042 (thats OK which is quite near). When I send 32768, output measured current is 6.8023 mA. I assumed to get 10.20mA, right?
Code: | #include "18F2520.h"
#include "f2420_regs.h"
#fuses INTRC_IO, NOWDT,BROWNOUT,PUT
#use delay(clock=4000000)
#define RS PIN_A2
#define EN PIN_A1
#define CS PIN_C0
void dac(unsigned int16 data);
unsigned int16 value;
unsigned int8 high_value = 0;
unsigned int8 low_value = 0;
void main()
{
TRISB=0; // PORTB is configured as an output port
TRISC=0; // PORTC is configured as an output port
PORTC=0;
PORTB=0;
delay_ms(1000);
SSPSTAT=0x80; //Status Register SSPSTAT=10000000
// SSPSTAT=0xC0; //Status Register SSPSTAT=11000000
// SSPCON1=0x20; //Enables serial port pins & set the SPI clock as clock = FOSC/4
SSPCON1 = 0b00100001;
output_high(CS);
delay_ms(1000);
value = 0;
while(1)
{
value = 32768;
dac(value);
delay_ms(300);
}
}
void dac(unsigned int16 data)
{
high_value = ((data >> 8) & (0xFF));
low_value = ((data >> 0) & (0xFF));
output_low(CS);
SSPBUF=high_value; // sending the upper 8 bits serially
while(!BF); // wait until the upper 8 bits are sent
SSPBUF=low_value; // sending the lower 8 bits serially
while(!BF); // wait until the lower 8 bits are sent
output_high(CS);
}
|
Anything wrong in the code? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 24, 2017 8:44 pm |
|
|
You didn't answer any of my questions or post any information.
I don't believe you have it working, because each time you said it was
working in the past, you very soon came back and said, not really.
My best guess is either there's something wrong with your board,
(eg., no bypass capacitors), or it's a counterfeit chip.
I have no doubt I could it make it work, except that Digikey wants $16.96
USD for 1 piece of p/n LTC1655CN8#PBF-ND. That's too much. If it
was $5, I would do it. So I can't help you anymore. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|