pravin b
Member level 5
- Joined
- May 20, 2012
- Messages
- 85
- Helped
- 2
- Reputation
- 4
- Reaction score
- 1
- Trophy points
- 1,288
- Location
- Mumbai, India
- Activity points
- 2,083
Hello all, I am using PIC16F886 to read the input voltage 0-1 Volt (amplified to 0-2.88V) at channel AN4. I have set +Vref=2.88 (external) and -Vref=Vss. I am displaying the measured voltage on 3 digit 7 segment display. The problem I am facing is- I get the displayed voltage lesser than the actual. SO, initially I had doubt on hardware, but the other program which is in assembly language (with which I am not comfortable) is showing perfect reading. Which indicates that my software (written in C) has some issue, which I am not able to identify. I am attching here both assembly and C program, it woud be helpful if someone here can guide me to some direction. Thanks.
I am using MPLABX IDE, XC8 compiler.
MC- pic16f886, internal oscillator.
Main file C Code:
ADC code:
Attaching working code in assembly language.
Thanks.
I am using MPLABX IDE, XC8 compiler.
MC- pic16f886, internal oscillator.
Main file C Code:
C:
// PIC16F886 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
void systemInitialization(void)
{
//select internal frequncy to 8Mhz
OSCCON = 0x71; //IRCF=111, SCS=1
while(!(OSCCON & (OSTS && HTS))); //wait till OSC gets stable
portInitialization();
timer0_init();
ADCInitialization();
// UART_Init(9600); //for debugging only
}
void main(void)
{
unsigned int adcReading=0, avgAdcReading=0, adc_arr[ADC_AVG_COUNT]= {0}, speed = 0, Vspeed = 0;
systemInitialization();
while(1)
{
//take moving average of 10 readings
char i=0;
//array shifting
for(i=0; i<ADC_AVG_COUNT-1; i++)
{
adc_arr[i]=adc_arr[i+1];
}
//update current reading in arrac
adc_arr[ADC_AVG_COUNT-1]=ADC_Read(SPEED_INPUT_CH);
//take avarage of readings in array
for(i=0;i<ADC_AVG_COUNT;i++)
{
avgAdcReading += adc_arr[i];
}
adcReading = avgAdcReading/ADC_AVG_COUNT; //moving average value
avgAdcReading = 0;
disNum = ((float)1000/1023)*adcReading; //this shows 0->0 & 1023->100
// char dstr[6];
// sprintf(dstr, "%d\n", adcReading);
// UART_TxString(dstr);
}
return;
}
ADC code:
C:
void ADCInitialization(void)
{
ADCON0 = 0x90;//0x91; //fosc/32, ch4 selected
ADCON1 = 0x90; //Vref from RA3/AN3, right justified
ADCON0 = ADCON0|0x01; //turn on ADC module
}
unsigned int ADC_Read(unsigned char channel)
{
int aadc, bbdc, ccdc;
unsigned int adc_data=0;
// if(channel > 7) //Channel range is 0 ~ 7
// return 0;
//
// ADCON0 &= 0xC5; //Clearing channel selection bits
// ADCON0 |= channel<<3; //Setting channel selection bits
__delay_ms(2); //Acquisition time to charge hold capacitor
GO_nDONE = 1; //Initializes A/D conversion
while(GO_nDONE); //Waiting for conversion to complete
adc_data = ((ADRESH<<8) + ADRESL);
return adc_data;
}
Attaching working code in assembly language.
Thanks.