|
|
View previous topic :: View next topic |
Author |
Message |
AlPicCss73
Joined: 20 May 2015 Posts: 18
|
General Fault When using ADC in dsPIC |
Posted: Fri Jun 05, 2015 4:05 am |
|
|
Hi All
As I'm new to the CCS 5, I've a little (big!) problem using the ADC. The problems are:
1. The help of ccs told me that by using #DEVICE ADC=x, I can change the resolution, but this code makes error during the compilation. I learnt that in the ccs 5 I've to change the resolution in the header file. A big progress for me but! if I want to change the resolution in the code whenever I want, what I've to do?
2. look at this code please:
Code: |
#include <main.h>
int16 value;
void main()
{
setup_adc_ports(sAN8, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_0);
while(TRUE)
{
//TODO: User Code
value = read_adc();
printf("Pin AN8 A/C value = %LX\n\r", value);
delay_ms(100);
}
}
|
This is a modified code of ccs's help. What I understand and want from this code is to read just from the pin AN8 and bring the value back for me. But what happens in the real world is all the ANx pins are active and can read a value from external the voltage and no need to say, the results are unstable and unacceptable at all.
I'm really confused and I appreciate if anyone can help me. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri Jun 05, 2015 5:32 am |
|
|
1) WHY do you want to change the resolution of the ADC when the program is running?
Normally you set it once, done. If set for say 10 bit and you only need 8, then simply shift right twice (10 bits ->> 8 bits). Now you can directly set the ADC register bits, just consult the datasheet's ADC section, then the PIC 'header' file to get the appropriate names of the registers/bits. Though really I've never needed to do that in 20 years...
2) the BIG problem I see is you using the adc_clock_internal ! Again, read the datasheet buy 99.99999% of all ADC use never uses the internal option. I suspect this is cauisng the bad readings.
3) be very careful with the PCB traces and wiring. getting reliable, accurate, repeatable ADC operation means you MUST use proper analog design and layout. If you have poor layout, a 12 bit ADC project might only have 8 bits of 'good' data !
Jay |
|
|
drh
Joined: 12 Jul 2004 Posts: 192 Location: Hemet, California USA
|
|
Posted: Fri Jun 05, 2015 7:53 am |
|
|
You need to select the ADC channel also. i.e. set_adc_channel(n); _________________ David |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Fri Jun 05, 2015 12:50 pm |
|
|
The ADC=x operand, is a _pre-processor directive_, not a program instruction. It changes the actual code generated and registers accessed.
Easiest way to change the value at run time, is to use ADC=16 (giving a left justified 16bit value), and then taking the high byte of the result gives an 8bit value, while /64 will give a 10 bit result. |
|
|
AlPicCss73
Joined: 20 May 2015 Posts: 18
|
|
Posted: Sat Jun 06, 2015 12:48 am |
|
|
temtronic wrote: | 1) WHY do you want to change the resolution of the ADC when the program is running?
Normally you set it once, done. If set for say 10 bit and you only need 8, then simply shift right twice (10 bits ->> 8 bits). Now you can directly set the ADC register bits, just consult the datasheet's ADC section, then the PIC 'header' file to get the appropriate names of the registers/bits. Though really I've never needed to do that in 20 years...
2) the BIG problem I see is you using the adc_clock_internal ! Again, read the datasheet buy 99.99999% of all ADC use never uses the internal option. I suspect this is cauisng the bad readings.
3) be very careful with the PCB traces and wiring. getting reliable, accurate, repeatable ADC operation means you MUST use proper analog design and layout. If you have poor layout, a 12 bit ADC project might only have 8 bits of 'good' data !
Jay |
Nope! The problems are neither the clock nor the board. My board completly works. With another code generated by mikroc pro, everythings are fine. But with ccs it's all a mess. With or without adc_channel() nothing changed.
So, what will remain? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sat Jun 06, 2015 1:32 am |
|
|
Key thing (of course), is that he hasn't told us the actual PIC, or the compiler version.
Now ADC_CLOCK_INTERNAL, should not be used above 1Mhz unless you put the chip to sleep, on 90% of PIC's, but he says 'dsPIC', and most of these do allow the internal clock. So he may be the exception here.
So:
1) Post the compiler version.
2) Post the actual PIC.
3) Post the program.
Currently, he has posted 75% of the program, without all the fuses, chip data, clock settings etc.. These are all vital parts of the program. Without these we cannot compile the code, and see what is wrong. |
|
|
AlPicCss73
Joined: 20 May 2015 Posts: 18
|
|
Posted: Sat Jun 06, 2015 2:58 am |
|
|
Ttelmah wrote: | Key thing (of course), is that he hasn't told us the actual PIC, or the compiler version.
Now ADC_CLOCK_INTERNAL, should not be used above 1Mhz unless you put the chip to sleep, on 90% of PIC's, but he says 'dsPIC', and most of these do allow the internal clock. So he may be the exception here.
So:
1) Post the compiler version.
2) Post the actual PIC.
3) Post the program.
Currently, he has posted 75% of the program, without all the fuses, chip data, clock settings etc.. These are all vital parts of the program. Without these we cannot compile the code, and see what is wrong. |
The code is all represented above. I use the dspic33fj256gp710 and the compiler is ccs 5.045. The clock is set at 20 MHz. Once again, I've correct responses using Mikroc pro with those settings.
Code: |
#include <33FJ128GP710.h>
#device ADC=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG //JTAG disabled
#device ICSP=1
#use delay(crystal=20000000)
#use rs232(UART2, baud=19200, stream=UART_PORT1)
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sat Jun 06, 2015 4:32 am |
|
|
OK. Now you have given us the rest of the program.
Comments like 'it works in MicroC', are pointless. CCS, is _not_ MicroC, and both require their own setups. While the core 'language' is the same, every I/O operation and setting is compiler specific. What you post would _not_ work in MicroC, without their settings, and different instructions. It's a bit like saying 'diesel works in my other car'. When the car you are now driving is petrol, that is not exactly a sensible comment....
The read_adc function in MicroC (adc_read), also selects the channel. Downside of this is that it means you have to wait for Tacq, every time you use this function. This is why CCS keep the two operations separate. MicroC also defaults to the RC clock, which is not recommended by the manufacturer for 90+% of PIC's.
So the CCS code should be:
Code: |
#include <33FJ128GP710.h>
#device ADC=12
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG //JTAG disabled
#device ICSP=1
#use delay(crystal=20000000)
#use rs232(UART2, baud=19200, stream=UART_PORT1, ERRORS)
void main()
{
int16 value; //general practice keep variables local unless they must be global
setup_adc_ports(sAN8, VSS_VDD); //enable AN8 to multplexer & select reference
setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_0); //select clock & Tacq
set_adc_channel(8); //select the channel
while(TRUE)
{
delay_ms(100); //since you have set Tacq==0, you must delay _before_ reading
value = read_adc();
printf("Pin AN8 A/C value = %X\n\r", value);
}
}
|
Assuming you have got a 20MHz crystal attached. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1355
|
|
Posted: Sat Jun 06, 2015 7:10 am |
|
|
As a general note on dsPICs and PIC24's:
It's also good to set to the two oscillator fuses explicitly. The compiler can sometimes figure them out based on your code, but it isn't always able to.
If your clock really is a 20MHz external crystal, then it will probably figure out the correct ones.
That said, on some older revisions I have found bugs with that decision making process.
For a 20MHz external crystal, you should add:
#fuses PR //selects the external oscillator as the source for the mux
#fuses HS //selects the high frequency circuit for the external osc |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sat Jun 06, 2015 9:49 am |
|
|
Agreed.
I did actually check that his compiler version is selecting those fuses correctly, since it is commonly a problem. |
|
|
AlPicCss73
Joined: 20 May 2015 Posts: 18
|
|
Posted: Sun Jun 07, 2015 3:38 am |
|
|
Now it works! Ttelmah was right. The problem was I thought that the channel() selects one of four built in channels in the chip but it selects the pin channels. My bad comprehension and maybe bad explanation of ccs's help.
Thanks guys. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sun Jun 07, 2015 7:25 am |
|
|
It's actually how the chip itself works.
On the PIC you have a setting that configures 'which' ADC channels are actually connected to the multiplexer. Then you have a setting to select which multiplexer channel to connect to the ADC.
These are separate, since every channel connected to the multiplexer, potentially introduces more noise to the ADC.
CCS show how to do it in their examples, but as a common 'thing' do assume that people actually read the chip data sheets. This is a problem, for people not used to working this way.
The general 'flow chart', for every chip with CCS, is:
Read the CCS manual.
Read the chip data sheet.
Read the .h file for the processor.
Then you'll find every CCS option (and fuse) actually corresponds directly to settings in the data sheet. So on chips that only allow particular combinations of channels to the ADC, these exact options are the defines in the .h file.
Suddenly the options start to make sense.
CCS try to give you 'wrappers' for operations like UART I/O etc., but also try to give you direct access to the hardware. It's very salutary when you code something in assembler, and then try the same operation in CCS, and find that the compiler manages to be within a couple of instructions over dozens of lines of code, of doing it DIY!... This is the 'delight' of CCS, but does bring with it the need to think closer to the chip itself than with some other compilers. |
|
|
|
|
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
|