Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] dspic30f programming for adc module with 2 analog input

Status
Not open for further replies.

amitroy1984

Newbie level 1
Joined
Feb 16, 2016
Messages
1
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
19
hello,
i am trying to write a program for dspic30f4012.
I have a requirement to call a adcvalue() function
within an interrupt routine of timer1. This adcvalue()
function needs to switch on the ADC. Load the digital
values of analog signals at AN0 and AN1 to variables
defined as data1, data2. And then again turn down
the ADC. This cycle repeats each time within the timer1 ISR.

Can anyone tell me how to do it.(need to know adc setting and adcvalue function)
I wrote the following code but it doesnt work.
Code:
 //ADC initialisation
void AD_set()  // ***** A to D (A/D) Settings
{
  ADPCFG = 0x0038; // Configure pins AN(3-5)/RB(3-5) into Digital 
                   // I/O mode AN(0-2) pins are in Analog mode
//  ADCON1bits.ADSIDL= 0;
//  ADCON1bits.FORM= 0;
//  ADCON1bits.SSRC= 7;
//  ADCON1bits.SAMP= 1;
ADCON1= 0x00E0;
  ADCHS = 0x0000;  // 
  ADCSSL = 0x0003;
//  ADCON3bits.SAMC= 8;
//  ADCON3bits.ADRC= 0;
//  ADCON3bits.ADCS= 1;
 ADCON3= 0x0F00;
//  ADCON2bits.VCFG= 0;
//  ADCON2bits.CSCNA= 1;
//  ADCON2bits.SMPI= 1;
//  ADCON2bits.BUFM= 0;
//  ADCON2bits.ALTS= 0;
ADCON2= 0x0404;
  //ADCON2 = 0x0004; // Interrupt after every 2 samples
}

My main prog is as follows
Code:
// main-prog.c
#include<p30f4012.h>
#include "settings-prog.h"
_FOSC(CSW_FSCM_OFF & XT); // To use the external crystal
_FWDT(WDT_OFF);	// To disable the watchdog timer
void send_data(int);	
int AD_value();		// Declare the AD value reading function
int AD_value1();
float R, P;
void main()
{		
  uart_set();    // Initialise UART settings
  AD_set();      // Initialise ADC settings
  timer1_set(T); // Initialise Timer-1 settings & start timer
  TRISEbits.TRISE8 = 0; // RE8 is configured as output
 
  // Continue until stop the power
  for(;;);
}// End of main()
		
// Interrupt service routine (ISR) for interrupt from Timer1

void __attribute__((interrupt, no_auto_psv)) _T1Interrupt (void)
{
  IFS0bits.T1IF = 0; // Clear timer 1 interrupt flag  
  uart_tx(9);
  P= AD_value1();
  send_data(P); 
  uart_tx(9);       // Space between 2 pieces of data.
  R= AD_value(); 
  send_data(R);
} // End of ISR of Timer 1

int AD_value()
{
int ADCValue;
ADCON1bits.ASAM= 1;
//IEC0bits.ADIE= 0;
IFS0bits.ADIF= 0;
ADCON1bits.ADON= 1;
while (!IFS0bits.ADIF);
ADCON1bits.ASAM=0;
ADCValue= ADCBUF0;
return(ADCValue);
}// End of AD_value()

int AD_value1()
{
int ADCValue1;
ADCON1bits.ASAM= 1;
//IEC0bits.ADIE= 0;
IFS0bits.ADIF= 0;
ADCON1bits.ADON= 1;
while (!IFS0bits.ADIF);
ADCON1bits.ASAM=0;
ADCValue1= ADCBUF1;
return(ADCValue1);
}// End of AD_value()
void send_data(int s_data)
{
  int s;
  if(s_data < 0)
  { 
    // Send the negative sign (ASCII is 45)
    uart_tx(45);
    s_data = -1*s_data;
  }
 
  // Digit with the position value of 100
  s = s_data/100;
  uart_tx(s+48);
  
  // Digit with the position value of 10
  s_data = s_data - (s *100);
  s = s_data/10;
  uart_tx(s+48);
  
  // Digit with the position value of 1
  s_data = s_data - (s *10);
  uart_tx(s_data+4);
}// End of send_data()
 

Hi,

I'm not familiar with dspic, so I can't help you with the code..

I see two problems:
* Why do you reconfigure the port pins every ISR? In my eyes this should be done once at start up. Configured as logic pins they may oscillate, draw increased VCC current and may have different input current. Therefore I expect the analog voltage may need some time to settle before you should perform the ADC conversion.
* an ISR should be short in time. I don't know how much time your adc function and your uart function need, nor do I know how often the ISR is executed.

To lower the time within the ISR: maybe you could just start the conversion and then leave the ISR..and wait for the ADC_finished interrupt. Maybe its possible to start a conversion automatically without a Start_isr. Read datasheet.
The same is with the UART functions. Many uart functions use busy_waits until the transmit register is free fir new data. But try to avoid thos busy_waits within an ISR.

But as said before..I'm not that familiar with your microcontroller. Mybe it's all correct how you do it.

Klaus
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top