CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

UART -dspic30F6014a
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
arelone



Joined: 06 Dec 2015
Posts: 42

View user's profile Send private message

UART -dspic30F6014a
PostPosted: Fri May 24, 2019 3:04 am     Reply with quote

Hi,

I am wondering when I try to read 4.788V from multichannel ADCs. Only channel AN0 seems working, for others it displays -16.000. Why is this happening? Does the dspic require delay to read from other ADCs? or I missed to declare/ insert include files in the code? I tried to insert delay (50us) in reading from ADCs but the problem remains. Any ideas?

Regards
Arelone

Here is the output in the hyper terminal:
4752.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
-16.000
9.999

Code:

#include <30F6014A.h>
#include <float.h>
#include <string.h>
#fuses HS, NOWDT, NOPROTECT, PUT64, BORV27
//correct - Power On Reset Timer value 64ms, Brownout reset at 2.7V
#use delay(clock=20000000)  //20 MHz crystal

//#use rs232(baud=9600,UART2)
#define LED PIN_B10
//#define VSS_VDD
#define WDT_OFF=0
#use rs232(baud=9600,UART2)

void main()
{

   setup_adc_ports(sAN0 | sAN1 | sAN2 | sAN3 | sAN4 | sAN5 | sAN6 | sAN7 | sAN8 | sAN9 | sAN10 | sAN11 | sAN12 | sAN13 | sAN14 | sAN15, VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_2);
   
   setup_adc_ports(ALL_ANALOG); 
   // Built-in A/D setup function
   setup_adc(ADC_CLOCK_INTERNAL); 
   // Built-in A/D setup function
   
   const int8 channel_1[]=1,2,3,4,5,6,7,8,9,10,11,12,13;
   int16 ADC_value1[sizeof(channel_1)];
   
   int32 value;
   float voltage[sizeof(channel_1)];
   //int32 voltage[sizeof(channel_1)];

   //I/O ports configurations(1:input, 0:output)
   set_tris_a(0x0000);     //set port_a as output
   set_tris_b(0xFFFF);     //set port_b as analog input/ADC
   set_tris_c(0x0000);     //set port_c as output
   set_tris_d(0x0000);     //set port_d as output
   set_tris_f(0x0000);     //set port_f as output
   set_tris_g(0x0000);     //set port_g as output
   
   
   output_a(0x0000);       //clear port_a to all 0s
   output_c(0x0000);       //clear port_c to all 0s
   output_d(0xFFFF);       //clear port_d to all 1s-portD dafault at HIGH state
   output_f(0x0000);       //clear port_f to all 0s
   output_g(0x0000);       //clear port_g o all 0s

   while(TRUE)
   {
      //read from chnnel 0, 0++ (1,2,3...7)
      for (value=0;value<sizeof(channel_1);value++)
      {
       
        set_adc_channel(channel_1[value]);
        delay_us(50);
        ADC_value1[value]=read_adc();
        delay_us(50);
        voltage[value] = (ADC_value1[value]);
      }
      //display value from channels 0...7
      for (value=0;value<sizeof(channel_1);value++)
       {
       //printf("%4.3f",voltage[value]);
       printf("%4.3f\r\n",voltage[value]);
       
       }
       //printf("9.999");
       printf("9.999\r\n");
  }
}
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri May 24, 2019 5:59 pm     Reply with quote

OK I don't use that PIC but some comments
1) The PIC ADC returns bits NOT a floating voltage so this line
printf("%4.3f\r\n",voltage[value]);
doesn't make any sense to me.
2) -16.00 could be the float equal to the ADC being >VDD. Again the ADC is monopolar and should NEVER give a -ve value.
3) Your code seems really, really complicated.
IE.. for (value=0;value<sizeof(channel_1);value++)
Simply select an ADC pin, read it, display it, delay then select another pin..........
4) If you've got say 8 ADC pins make for(value=0;value<9;value++) is a LOT easier to read and understand, at least to this fossil.
5) ALWAYS add 'ERRORS' to the #USE RS232( ...options...)
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Fri May 24, 2019 10:38 pm     Reply with quote

and, you have not got a line specifying the ADC value size to be returned.

#device ADC=12

Without this, the default is normally for the ADC value to be returned
left lustified, so when put into a signed int16, any value above half range
will give a -ve return.
arelone



Joined: 06 Dec 2015
Posts: 42

View user's profile Send private message

PostPosted: Wed Jun 26, 2019 1:15 am     Reply with quote

Hi,

I compiled the code with CCS C ver. 5.010 with a new dspic30F6014a chip using UART1 or UART2 and it works accordingly.

Below I attached code for getting delay of 1us using internal clock (7.37MHz x16) and read analog samples from multi-channel ADC. I verified with an oscilloscope and the pulses created are approximately 1us. However during the operation, the chip becomes warm. Is this normal? or is there any better examples to create the 1us delay?.

Can someone explain to me the relationship between ADC frequency & TAD particularly in my case which using internal clock. How to calculate the acquisition time and no. of samples for the 12 bits ADC for each channel? Is it possible to setting the ADC to read 1 sample per channel? Any examples that I can make as reference?

Regards

Code:

#include <30F6014A.h>
#device ADC=12
#include <float.h>
#include <string.h>
#fuses FRC_PLL16, NOWDT, NOPROTECT, PUT64, BORV27 //7.37MHz x16

#use delay(clock=117920000,internal)
#use rs232(baud=9600,UART1,ERRORS)


void main()
{
   set_TRIS_C(0x0000);
   set_TRIS_D(0x0000);
   
   SETUP_ADC(adc_OFF);
   setup_adc_ports(ALL_ANALOG); 
   setup_adc_ports(sAN0 |sAN1|sAN2|sAN3|sAN4|sAN5|sAN6|sAN7|sAN8|sAN9|sAN10|sAN11|sAN12|sAN13|sAN14|sAN15, VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_2);
   setup_adc(ADC_CLOCK_INTERNAL); 
   // Built-in A/D setup function
   
   output_high(PIN_C2);
   output_high(PIN_C3);
   output_high(PIN_C4);
   output_high(PIN_G6);
   output_high(PIN_G7);
   output_high(PIN_D8);
   output_high(PIN_D9);
   output_high(PIN_D10);
   output_high(PIN_D11);
   output_high(PIN_G15);
   //setup_adc_ports(ALL_ANALOG); 
   // Build-in A/D setup function
   
   signed int32 ert_adc_value_5;
   signed int32 ert_adc_value_6;
   signed int32 ert_adc_value_7;
   signed int32 ert_adc_value_8;
   signed int32 ert_adc_value_9;
   signed int32 ert_adc_value_10;
   signed int32 ert_adc_value_11;
   signed int32 ert_adc_value_12;
   signed int32 ert_adc_value_13;
 
   
   
   signed int32 ert_voltages_5;
   signed int32 ert_voltages_6;
   signed int32 ert_voltages_7;
   signed int32 ert_voltages_8;
   signed int32 ert_voltages_9;
   signed int32 ert_voltages_10;
   signed int32 ert_voltages_11;
   signed int32 ert_voltages_12;
   signed int32 ert_voltages_13;
   
   while(TRUE)
     {       
     //TR1 as transmitter
      output_high(PIN_C1);  //excitation signal 328kHz at TR1
      delay_us(2);           
      output_low(PIN_C1);
      delay_us(1); 
      output_high(PIN_C1);
      delay_us(2); 
      output_low(PIN_C1); 
      delay_us(49);        // delay 54.4us
      output_low(PIN_C2);  // ch 5
      output_low(PIN_D8);  // ch 13
      delay_us(8);         // delay 62.4us
      output_low(PIN_C3);  // ch 6
      output_low(PIN_D9);  // ch 12
      delay_us(6);         // delay 68.8us
      output_low(PIN_C4);  // ch 7
      output_low(PIN_D10);  // ch 11
      delay_us(3);         // delay 72.0us
      output_low(PIN_G6);  // ch 8
      output_low(PIN_D11);  // ch 10
      delay_us(1);         // delay 72.8us
      output_low(PIN_G7);  // ch 9
     
      //sample at TR5
      output_low(PIN_G15);
      set_adc_channel(4);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_5=read_adc();    //starts conversion & store it in value
      ert_voltages_5=(ert_adc_value_5)*5000/4096;// last result of last conversion
      printf("Ch05=%u\r\n",ert_voltages_5);   
     
      //sample at TR6
      set_adc_channel(5);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_6=read_adc();    //starts conversion & store it in value
      ert_voltages_6=(ert_adc_value_6)*5000/4096;// last result of last conversion
      printf("Ch06=%u\r\n",ert_voltages_6);
     
      //sample at TR7
      set_adc_channel(6);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_7=read_adc();    //starts conversion & store it in value
      ert_voltages_7=(ert_adc_value_7)*5000/4096;// last result of last conversion
      printf("Ch07=%u\r\n",ert_voltages_7);
     
      //sample at TR8
      set_adc_channel(7);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_8=read_adc();    //starts conversion & store it in value
      ert_voltages_8=(ert_adc_value_8)*5000/4096;// last result of last conversion
      printf("Ch08=%u\r\n",ert_voltages_8);
     
      //sample at TR9
      set_adc_channel(8);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_9=read_adc();    //starts conversion & store it in value
      ert_voltages_9=(ert_adc_value_9)*5000/4096;// last result of last conversion
      printf("Ch09=%u\r\n",ert_voltages_9);
     
      //sample at TR10
      set_adc_channel(9);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_10=read_adc();    //starts conversion & store it in value
      ert_voltages_10=(ert_adc_value_10)*5000/4096;// last result of last conversion
      printf("Ch10=%u\r\n",ert_voltages_10);
     
      //sample at TR11
      set_adc_channel(10);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_11=read_adc();    //starts conversion & store it in value
      ert_voltages_11=(ert_adc_value_11)*5000/4096;// last result of last conversion
      printf("Ch11=%u\r\n",ert_voltages_11);
     
      //sample at TR12
      set_adc_channel(11);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_12=read_adc();    //starts conversion & store it in value
      ert_voltages_12=(ert_adc_value_12)*5000/4096;// last result of last conversion
      printf("Ch12=%u\r\n",ert_voltages_12);
     
      //sample at TR13
      set_adc_channel(12);     //read from channel 0
      delay_us(10);           //delay is required after setting channel and bef.read
      ert_adc_value_13=read_adc();    //starts conversion & store it in value
      ert_voltages_13=(ert_adc_value_13)*5000/4096;// last result of last conversion
      printf("Ch13=%u\r\n",ert_voltages_13);
     
      output_high(PIN_G15);
      output_high(PIN_C2);
      output_high(PIN_C3);
      output_high(PIN_C4);
      output_high(PIN_G6);
      output_high(PIN_G7);
      output_high(PIN_D8);
      output_high(PIN_D9);
      output_high(PIN_D10);
      output_high(PIN_D11);
   
      }

   
}//end main
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jun 26, 2019 4:55 am     Reply with quote

While I don't use that PIC, I offer some comments..
1) Yes, the PIC will get warm. If YOU did 117 million pushups in a second, you'd be warm too ! CMOS devices are very low poer 'at rest', it's during 'transitions' (0>1>0, 0>1,1>0) that they consume power. Power = heat.

2) I was curious about your program and I think you're trying to read several ultrasonic sensors with analog outputs ? IF so, post the make/model info.

3) You should have two tasks. 1 acquire the ADC readings, 2 - display them. You could be getting sensor glitches but without knowing what sensors you're using, it's hard to help.

4) analog can be tricky to get 'right', especially over 8 bits AND fast. You need proper PCB design (layout, caps, traces, filtering, etc.) as well as shielding from sensors to PCB. A STABLE PSU is required as well as a precision Vref. That way 1.2345 volts is ALWAYS 1.2345 and not 1.2346 or 1.2344.

5) You need to read the ADC section of the datasheet to understand the ADC. As well, check Microchip's website for 'apnotes'. They have dozens. read them all, especially the older ones so you can 'see' how it works.

Jay
arelone



Joined: 06 Dec 2015
Posts: 42

View user's profile Send private message

UART -dspic30F6014a
PostPosted: Fri Oct 18, 2019 6:41 pm     Reply with quote

Hi,

I need some help here. I'm trying to use the PLL clock multiplier settings for the attached program. I'm using 20MHz oscillator. Before this I was using #fuses HS,...#use delay (clock=20000000) statement and the ADC works as expected however I am not getting 1us pulse, the best I can get is 1.42us. I decided to tried the PLL options with #FUSES HS2_PLL4,...(20MHz/2 * 4=40MHz) #use delay (clock=20000000). Now i can get approximately 1.088us but the measurement data received from UART are unreadable characters. Please help.

Arelone

Code:

#include <30F6014A.h>
#device ADC=12
#include <float.h>
#include <string.h>
#fuses HS2_PLL4,NOWDT, NOPROTECT, PUT64, BORV27,
#use delay(clock=20000000)  //20MHz MHz crystal used
#use rs232(baud=9600,UART1,ERRORS)


void main()
{
   set_TRIS_C(0x0000);
   set_TRIS_D(0x0000);
   
   SETUP_ADC(adc_OFF);
   setup_adc_ports(ALL_ANALOG); 
   setup_adc_ports(sAN0 |sAN1|sAN2|sAN3|sAN4|sAN5|sAN6|sAN7|sAN8|sAN9|sAN10|sAN11|sAN12|sAN13|sAN14|sAN15, VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64 | ADC_TAD_MUL_2);
   setup_adc(ADC_CLOCK_INTERNAL); 
   // Built-in A/D setup function
   
     
   //setup_adc_ports(ALL_ANALOG); 
   // Build-in A/D setup function
   
   signed int32 ert_adc_value_5;
   signed int32 ert_adc_value_6;
   signed int32 ert_adc_value_7;
   signed int32 ert_adc_value_8;
   signed int32 ert_adc_value_9;
   signed int32 ert_adc_value_10;
   signed int32 ert_adc_value_11;
   signed int32 ert_adc_value_12;
   signed int32 ert_adc_value_13;
   
   
 
   signed int32 ert_voltages_5;
   signed int32 ert_voltages_6;
   signed int32 ert_voltages_7;
   signed int32 ert_voltages_8;
   signed int32 ert_voltages_9;
   signed int32 ert_voltages_10;
   signed int32 ert_voltages_11;
   signed int32 ert_voltages_12;
   signed int32 ert_voltages_13;
   
   
 
   while(TRUE)
     {       
     
     
      output_high(PIN_D4); 
      delay_us(1);           
      output_low(PIN_D4);
      delay_us(2); 
      output_high(PIN_D4);
      delay_us(1); 
      output_low(PIN_D4); 
      delay_us(2);         
     
     
      //sample at TR5
      set_adc_channel(4);     //read from channel 4
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_5=read_adc();    //starts conversion & store it in value
      ert_voltages_5=(ert_adc_value_5)*5000/4096;// last result of last conversion
      printf("Ch05=%u\n\r",ert_voltages_5);
      output_high(PIN_C2);
     
      //sample at TR6
      set_adc_channel(5);     //read from channel 5
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_6=read_adc();    //starts conversion & store it in value
      ert_voltages_6=(ert_adc_value_6)*5000/4096;// last result of last conversion
      printf("Ch06=%u\r\n",ert_voltages_6);
      output_high(PIN_C3);
     
      //sample at TR7
      set_adc_channel(6);     //read from channel 6
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_7=read_adc();    //starts conversion & store it in value
      ert_voltages_7=(ert_adc_value_7)*5000/4096;// last result of last conversion
      printf("Ch07=%u\r\n",ert_voltages_7);
     
      //sample at TR8
      set_adc_channel(7);     //read from channel 7
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_8=read_adc();    //starts conversion & store it in value
      ert_voltages_8=(ert_adc_value_8)*5000/4096;// last result of last conversion
      printf("Ch08=%u\r\n",ert_voltages_8);
     
      //sample at TR9
      set_adc_channel(8);     //read from channel 8
      delay_ms(10);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_AND_READ);
      ert_adc_value_9=read_adc();    //starts conversion & store it in value
      ert_voltages_9=(ert_adc_value_9)*5000/4096;// last result of last conversion
      printf("Ch09=%u\r\n",ert_voltages_9);
     
      //sample at TR10
      set_adc_channel(9);     //read from channel 9
      delay_ms(10);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_10=read_adc();    //starts conversion & store it in value
      ert_voltages_10=(ert_adc_value_10)*5000/4096;// last result of last conversion
      printf("Ch10=%u\r\n",ert_voltages_10);
     
      //sample at TR11
      set_adc_channel(10);     //read from channel 10
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_11=read_adc();    //starts conversion & store it in value
      ert_voltages_11=(ert_adc_value_11)*5000/4096;// last result of last conversion
      printf("Ch11=%u\r\n",ert_voltages_11);
     
      //sample at TR12
      set_adc_channel(11);     //read from channel 11
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_12=read_adc();    //starts conversion & store it in value
      ert_voltages_12=(ert_adc_value_12)*5000/4096;// last result of last conversion
      printf("Ch12=%u\r\n",ert_voltages_12);
     
      //sample at TR13
      set_adc_channel(12);     //read from channel 12
      delay_us(20);           //delay is required after setting channel and bef.read
      //read_adc(ADC_START_ONLY);
      ert_adc_value_13=read_adc();    //starts conversion & store it in value
      ert_voltages_13=(ert_adc_value_13)*5000/4096;// last result of last conversion
      printf("Ch13=%u\r\n",ert_voltages_13);
       printf("Ch99=9888\r\n");
     
     
      }

    //}
   //}
}//end main
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Sat Oct 19, 2019 12:33 am     Reply with quote

You have two set_adc_ports, and setup_adc instructions. Only the last
will actually be respected. A second instruction overrides the first.
The first actually shows an important feature. The use of TAD_MUL.
This allows you to program the ADC to automatically perform the delay
before reading.
Now in fact on a DSPIC like this it is possible to scan a set of analog
inputs automatically, with programmed timings between
samples. However you are trying to exceed the capabilities of the PIC. The
maximum sample rate on this chip is 200K samples/second (5uSec), and
this only if you have the 'best' clock selected (to give Tad=334nSec). Using
the default internal clock will be just 666KHz typically, and with this a single
conversion will take 21uSec. Using your 20MHz Fosc, the fastest conversion
possible is 133KHz, so 7.5uSec per conversion.
arelone



Joined: 06 Dec 2015
Posts: 42

View user's profile Send private message

UART -dspic30F6014a
PostPosted: Sat Oct 19, 2019 10:50 am     Reply with quote

Hi,

Thank you for the explanation. But I still confusing on this matter and correct me if my understanding are wrong.
In my case if I want to use 40MHz obtained from (HS/2)*4 what is the minimum TAD here? is it 334nSec?
Another thing is, I could not correlate if I obtained the FOSC, TCY,actual TAD, and sampling time = 1TAD + 14 TAD, how to relate these values in setup_ADC options (CLK_DIV_? & TAD_MUL_?). Sorry again for lack of knowledge in programming.

Arelone.
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Sat Oct 19, 2019 1:43 pm     Reply with quote

No, You'd need to use a clock that is a multiple of 6MHz to get the fastest
conversion. The best you can get from 40MHz, is using a divisor of 7,
which will give a Tad of 350nSec and a conversion time of 5.25uSec.
190476 conversions per second.
arelone



Joined: 06 Dec 2015
Posts: 42

View user's profile Send private message

UART -dspic30F6014a
PostPosted: Wed Oct 23, 2019 8:46 am     Reply with quote

Hi,

Thanks for the knowledge Ttelmah. Now I can run the code smoothly. Here is the corrected hardware code.
Code:

#fuses NOWDT, NOPROTECT, PUT64, BORV27
#use delay (clock=58982400, xtal=7372800)

Arelone
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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