View previous topic :: View next topic |
Author |
Message |
jeanp
Joined: 07 Jul 2022 Posts: 4
|
dsPic33ev256gm006 adc channel an32-an63 |
Posted: Fri Jul 08, 2022 2:06 am |
|
|
Compiler version 5.081.
I have been fighting for two days against the adc of the dsPic33ev256gm006. In my old projects I have never had any problems with other pic's adc. The problem is the following:
There are a lot of voltages to read in this project. Precisely I have to read the pins an4, an9, an11, an16, an17, an18, an30, an31, an49, an51, an53, an54, and an55. For pins up to an31 the reading is correct, while for the pins from an49 upwards the reading is wrong. On the data sheet it says that the pins from an32 to an63 are multiplexed but I have not found any reference to how they should be managed. To perform some tests, I wrote a simple code to read only the an18 and an55 pins and send the values on the serial.
Code: |
#include <33ev256gm006.h>
#device ADC=10
#fuses HS,BROWNOUT,NOWDT,NOPROTECT,NOWRT
#use delay(internal=7370000)
#pin_select U1TX=PIN_D5
#pin_select U1RX=PIN_F0
#use rs232(UART1,baud=9600,xmit=PIN_D5,rcv=PIN_F0,enable=PIN_D6,errors,stream=RS485)
#define GREENLED PIN_C7
void main(void)
{
unsigned int16 an18, an55;
unsigned int8 i;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN18 | sAN55);
delay_ms(10);
fprintf(RS485, "\r\nADC TEST\r\n");
for(i=0; i<3; i++)
{
output_high(GREENLED);
delay_ms(400);
output_low(GREENLED);
delay_ms(400);
}
for(;;)
{
set_adc_channel(55);
delay_ms(100);
an55 = read_adc();
set_adc_channel(18);
delay_ms(100);
an18 = read_adc();
delay_ms(1000);
fprintf(RS485,"an18=%lu an55=%lu\r\n", an18, an55);
}
}
|
The reading of an18 is correct, that of an55 is wrong. Thanks to those who will give me some suggestions. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1349
|
|
Posted: Fri Jul 08, 2022 8:17 am |
|
|
I haven't read the data sheet on that pic, but on a dsPIC I used about a decade ago, analog pins 32-63 were on ADC 2. Does this pic have 2 ADC modules per chance? If so, you might have to use the ADC2 functions instead of ADC1. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Fri Jul 08, 2022 1:02 pm |
|
|
These channels are all on the primary ADC,
The multiplexing doesn't affect single channel operation. What it affects
is if you are programming scanning of multiple channels. You can't
have more than one of these selected.
It may be a compiler version problem. Would need to look at the assembler
generated. Out for the next couple of days, so can't do this now.
He should remove the HS fuse. Currently though running on the
internal oscillator he is running the crystal oscillator as well.
Won't cause this problem though.
The multiplexed ADC channels are connectable to the internal op-amps
and comparators. Might be worth explicitly turning these off.
Are you sure that a sensible signal is actually going to A7?.
What are you seeing from this channel?. |
|
|
jeanp
Joined: 07 Jul 2022 Posts: 4
|
|
Posted: Mon Jul 11, 2022 12:31 am |
|
|
Yes, you are right, HS fuse is a remnant of an old design with external quartz.
The test to disable the comparators I had already done without success, adding the instructions
Code: |
setup_comparator(1,NC_NC);
setup_comparator(2,NC_NC);
setup_comparator(3,NC_NC);
setup_comparator(4,NC_NC);
setup_comparator(5,NC_NC);
|
The assembler generated by the instructions looks correct
Code: |
.................... for(;;)
.................... {
.................... set_adc_channel(55);
00402: MOV #37,W4
00404: MOV W4,328
.................... delay_ms(100);
00406: MOV #64,W0
00408: CALL 250
.................... an55 = read_adc();
0040C: BCLR.B 320.0
0040E: BSET.B 320.1
00410: BTSS.B 320.0
00412: BRA 410
00414: PUSH 300
00416: POP 1006
....................
.................... set_adc_channel(18);
00418: MOV #12,W4
0041A: MOV W4,328
.................... delay_ms(100);
0041C: MOV #64,W0
0041E: CALL 250
.................... an18 = read_adc();
00422: BCLR.B 320.0
00424: BSET.B 320.1
00426: BTSS.B 320.0
00428: BRA 426
0042A: PUSH 300
0042C: POP 1004
|
In this test I used pin a7 (therefore an55) because on that pin I read a voltage derived from a potentiometer connected between vdd and vss. So I can directly measure the voltage arriving on the pin with the tester.
An additional element that I have noticed continuing with the tests is that if I try to read any analog input from an32 up, the value read is always the same.
However, there is one thing that keeps spinning in my head. Looking at Figure 24-1 on the data sheet, there appears to be another multiplexing stage for the an32-an63 analog pins. What comes to my mind is that there is another register to set to use those channels. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jul 11, 2022 1:53 am |
|
|
I agree the diagram is 'strange'. However if you look, the numbers being
shown are just continuations of the values used for the lower channels.
The extra is just the sixth bit in the multiplexer value that selects this
other part.
The compiler does write the correct channel number to the multiplexer.
Try the experiment of reading channel 61. This should be the bandgap
reference. If this reads correctly, then it says everything else is working
and it is something to do with the selection of the pin.
I really suggest you talk to CCS about this. |
|
|
jeanp
Joined: 07 Jul 2022 Posts: 4
|
|
Posted: Mon Jul 11, 2022 2:43 am |
|
|
The reading of the band gap voltage is correct. I read a value of 245 which means about 1.2V. Also the reading of CTMU temp diode 'could' be correct (I read a value of 103). While the reading of channel an63 (unconnected) is the same as that of channel an55, and it is the same of all the other channels from an32 to an60. It seems that all these channels are not internally connected to the adc, although the value assigned to the Ad0chs0 register is correct.
If you have any other suggestions, I welcome them. In the meantime I will try to contact CCS and Microchip as well. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jul 11, 2022 3:41 am |
|
|
I'm suspicious of the ANSEL bits.
Looking with your compiler, at the generated code, the selection:
setup_adc_ports(sAN18 | sAN55);
Is only turning on one bit.
Now to select both these channels, two bits need to be turned on.
ANSELA.7 and ANSELG.7
It is only turning on G.7 (0xEB6.7), not 0xE0E.7. In fact it clears
the A.7 bit.
With 5.109, it merrily sets both bits.
So you need to update the compiler.
Searching the changes list has:
5.087 setup_adc_ports() now sets analog pins above AN50 correctly on dsPIC33EVxxxGMxxx devices.
It is fixed after this. |
|
|
jeanp
Joined: 07 Jul 2022 Posts: 4
|
|
Posted: Mon Jul 11, 2022 6:16 am |
|
|
Thank you very much. Now setting ansel bit manually works. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jul 11, 2022 6:38 am |
|
|
Well done.
Interesting that setting this works. I Didn't suggest this, since the data sheet
says that the ADC has to be off when you change these bits. I suspect it
actually means that you must not be reading when doing this. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Mon Jul 11, 2022 9:14 am |
|
|
Quote: |
Interesting that setting this works.
|
Mr. Ttelmah, out of curiosity. Why wouldn't it work? If the bits are set manually instead of
Code: |
setup_adc_ports(sAN18 | sAN55);
| , isn't it the same thing?
Samo |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Jul 11, 2022 9:52 am |
|
|
As I said, because the data sheet says the ADC has to be off when you
change these. If he sets both bits manually before waking the ADC
then it should be OK.
However if he just sets the extra one, the setup_adc_ports turns the
portA bit off so will override this.
If he does it after using the CCS functions the ADC will then be on. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Mon Jul 11, 2022 9:58 am |
|
|
That is why I was wondering where the problem might be. I'd just delete or comment out CCS's setup part and do it manually at the same spot. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Jul 12, 2022 5:34 am |
|
|
The point is you have to completely remove the CCS function for this,
and make sure you are doing this before you enable the ADC. Not
necessarily 'instantly obvious'. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Tue Jul 12, 2022 11:05 am |
|
|
Quote: |
Not necessarily 'instantly obvious'.
|
Very true :-) |
|
|
|