• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

dsPIC30F6014a ADC

frahman3

Member
Hi,

I'm new in this tread. This is my first programming in ADC using dspic30F6014a. Currently I'm trying to read voltage values from sensors using ADC from dspic30F6014a with 20MHz osc. These values are transmitted via UART1 and displayed on the hyper terminal. I compiled the program using CCS C ver 5.010 with no errors or warning. The problem is the voltage values are not displayed on the hyper terminal screen. The port settings in hyper terminal are as follows:

Bits per second:9600
Data bits:8
Parity: none
Stop bits: 1
Flow control: Hardware

I am expecting the 13 voltages will be displayed in 1 column and ended with C character. Can anyone assist me, what did i miss/mistakes here?

Regards
FR



CSS:
#include <30F6014A.h>
#use delay(clock=20000000)
#use rs232(baud=9600,UART1)

void InitUSART1(void);
void InitADC12 (void);
void SendADC (void);

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_8);

   const int8 channel_1[]=1,2,3,4,5,6,7,8,9,10,11,12,13;     
   int16 ADC_value[sizeof(channel_1)];
   int16 voltage[sizeof(channel_1)];
  
   int16 value;

   //I/O ports configurations(1:input, 0:output)
  
   set_tris_b(0xFFFF);     //set port_b as analog input/ADC
 
 

   while(TRUE)
   {
      
      for (value=0;value <sizeof(channel_1);value++)
      
      {
        set_adc_channel(channel_1[value]);
        ADC_value[value]=read_adc();
        voltage[value]=ADC_value[value]*(5000/255);
        
      }
        
      {
         printf("%4.3w\r\n", voltage[value]);
      }
         printf("c\r\n");
    }
}
 

frahman3

Member
Hi,

Thanks Mike for the reply. I changed as suggested but still same. Previously, I tried to display the values with ADC from pic18F4580 and its ok.

Regads
FR
 

rjenkinsgb

Well-Known Member
Most Helpful Member
C:
while(TRUE)
   {
   
      for (value=0;value <sizeof(channel_1);value++)
   
      {
        set_adc_channel(channel_1[value]);
        ADC_value[value]=read_adc();
        voltage[value]=ADC_value[value]*(5000/255);
     
      }
     
      {
         printf("%4.3w\r\n", voltage[value]);
      }
         printf("c\r\n");
    }
You have the line to print the values outside of the "for" loop?

Try

C:
while(TRUE)
   {
    
      for (value=0;value <sizeof(channel_1);value++)
    
      {
        set_adc_channel(channel_1[value]);
        ADC_value[value]=read_adc();
        voltage[value]=ADC_value[value]*(5000/255);
      
        printf("%4.3w\r\n", voltage[value]);
      }
         printf("c\r\n");
    }
Or add another loop to print the stored values.
 

frahman3

Member
HI,

Changes that has been made:
a) Hyper terminal flow control changed from "hardware" to "none."
b) Move printf into for loop

I changed the code as advice. Result still same.

CSS:
#Include <30F6014A.h>
#use delay(clock=20000000)
#use rs232(baud=9600,UART1)

void InitUSART1(void);
void InitADC12 (void);
void SendADC (void);

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_8);

   const int8 channel_1[]=1,2,3,4,5,6,7,8,9,10,11,12,13;     
   int16 ADC_value[sizeof(channel_1)];
   int16 voltage[sizeof(channel_1)];
  
   int16 value;

   //I/O ports configurations(1:input, 0:output)
  
   set_tris_b(0xFFFF);     //set port_b as analog input/ADC
 
 

   while(TRUE)
   {
      
      for (value=0;value <sizeof(channel_1);value++)
      
      {
        set_adc_channel(channel_1[value]);
        ADC_value[value]=read_adc();
        voltage[value]=ADC_value[value]*(5000/255);
        printf("%4.3w\r\n", voltage[value]);
      }
        
      //{
         //printf("%4.3w\r\n", voltage[value]);
      //}
         printf("c\r\n");
    }
}
 

rjenkinsgb

Well-Known Member
Most Helpful Member
What electrical interface are you using between the MCU and the PC?

Are you getting any signal at all from the MCU TX pin? It should show as some low level of AC on a multimeter if data is being transmitted.

You could also try "Realterm" - I find that infinitely preferable to hyperterm for working with serial data.
 

Pommie

Well-Known Member
Most Helpful Member
I'm not familiar with the ds pics but wondered about a few things.

How do you know your inputs are analogue? Edit, ignore this question.
Assuming you want voltage in mV then shouldn't
voltage[value]=ADC_value[value]*(5000/255);
be
voltage[value]=ADC_value[value]*5000/4096;
However, this can overflow due to the ADC being 12 bit.
Placing the 5000/255 in brackets will reduce accuracy as it's equivalent to * 19 when it should be *19.6.

Mike.
Edit, what does printf("%4.3w\r\n", voltage[value]); do? I'm not familiar with %4.3 - is this correct?
Also, is the serial port the default output for printf?
 
Last edited:

rjenkinsgb

Well-Known Member
Most Helpful Member
Looks like the stdout on the Ds pics is UART2 - see link.
That's for the Microchip compiler, frahman3 is using the CCS compiler (the same as we use).

According to the info for that:
printf() defaults to STDOUT (the last USE RS232).


Edit - that's made me think though, I wonder if the watchdog is enabled by default & causing continual resets?

Adding this may avoid that?
C:
setup_wdt(WDT_OFF);
 
Last edited:

Nigel Goodwin

Super Moderator
Most Helpful Member
He seems to be doing very little setting up?, and the more powerful the PIC the more setting up is involved the enhanced 14 bit range have a bewildering arrange of options, and the PIC32's are much worse.

Unless of course the CCS compiler does all that for you?.
 

rjenkinsgb

Well-Known Member
Most Helpful Member
Unless of course the CCS compiler does all that for you?.
It does indeed.

You need the header include for the specific device, the frequency definition and then a #use and/or setup line or two for each peripheral.

There are a lot more options available but the defaults generally "just work" :)
 

Pommie

Well-Known Member
Most Helpful Member
How would the CCS compiler know to use UART1 as stdout? Surely it expects some kinda screen.

Mike.
 

Nigel Goodwin

Super Moderator
Most Helpful Member
How would the CCS compiler know to use UART1 as stdout? Surely it expects some kinda screen.

Mike.
It wouldn't 'know', but if the compiler is designed to use UART1 as the default stdout then that is what it uses - it's purely down to the writer of the compiler - assuming there's a default stdout at all?. As far as I'm aware the XC compilers require you to specifically set where you want stdout to go (not that I use it very much, as it takes far too much code space).

The kind of 'screen' is simply a serial terminal connected via the UART.
 

frahman3

Member
Hi,

Thank to all of you for the advice. This morning I checked the output from pins associated with UART1 and UART2, and found that both ports did not produce any signals compared with the good UART from the pic 18F4580. I shocked because it was a new unit. I will update after I replaced it.

Regards
FR
 

Nigel Goodwin

Super Moderator
Most Helpful Member
As you're using an unusual compiler I've no idea if the UART's are supposed to work or not, but they don't work unless you specifically tell them to under XC compilers - if you configure the serial ports using MCC one of the options (a check box) is to generate code to send STDOUT to the serial port.

I presume CCS requires something similar?, as why add the code if you're not using it?.

This sounds FAR more likely that a duff PIC, they are very sturdy devices and take some damaging.
 

rjenkinsgb

Well-Known Member
Most Helpful Member
I've no idea if the UART's are supposed to work or not, but they don't work unless you specifically tell them to under XC compilers
This is the only line it is supposed to require:
#use rs232(baud=9600,UART1)

You can use a similar line anywhere in the code and the STDOUT, STDI etc. then use the parameters specified until another #use rs232.


There are other options that allow ports to be named and then selected by name in the program, if you need multiple simultaneous ports - but that should work as it's set up.

It may be worth repeating the #use rs232 line in the body, just before loop.


This morning I checked the output from pins associated with UART1 and UART2, and found that both ports did not produce any signals compared with the good UART from the pic 18F4580

Did you try it after adding the line
setup_wdt(WDT_OFF);
??


And are you sure the MCU oscillator is properly configured and running - what are you using for that??
 

Latest threads

EE World Online Articles

Loading

 
Top