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
// 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;
}
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;
}
((unsigned int)ADRESH<<8)
It´s hard to compare an instantaneous ADC value with a rather low pass filtered DVM reading.I checked voltage at AN4 using DMM, its a stable
Yes, this exactly is the problem.I did not type casted ADRESH, since its a 1 byte register.
Volts (in mV) | Expected ADC count | Actual ADC count |
0 | 0 | 0 |
50 | 51 | 46 |
100 | 102 | 97 |
150 | 154 | 148 |
200 | 205 | 199 |
250 | 256 | 248 |
300 | 307 | 299 |
350 | 358 | 350 |
400 | 410 | 400 |
450 | 461 | 451 |
500 | 512 | 502 |
550 | 563 | 552 |
600 | 614 | 602 |
650 | 666 | 654 |
700 | 717 | 705 |
750 | 768 | 754 |
800 | 819 | 805 |
850 | 870 | 856 |
900 | 922 | 907 |
950 | 973 | 957 |
1000 | 1024 | 1007 |
Volts (in mV) | V at AN4 (in Volts- post amplification) | Expected ADC count | Actual ADC count |
0 | 0 | 0 | 0 |
50 | 0.13 | 51 | 46 |
100 | 0.26 | 102 | 97 |
150 | 0.39 | 154 | 148 |
200 | 0.52 | 205 | 199 |
250 | 0.65 | 256 | 248 |
300 | 0.78 | 307 | 299 |
350 | 0.91 | 358 | 350 |
400 | 1.04 | 410 | 400 |
450 | 1.17 | 461 | 451 |
500 | 1.3 | 512 | 502 |
550 | 1.43 | 563 | 552 |
600 | 1.56 | 614 | 602 |
650 | 1.69 | 666 | 654 |
700 | 1.82 | 717 | 705 |
750 | 1.95 | 768 | 754 |
800 | 2.08 | 819 | 805 |
850 | 2.21 | 870 | 856 |
900 | 2.34 | 922 | 907 |
950 | 2.47 | 973 | 957 |
1000 | 2.88 | 1024 | 1007 |
2944 ;adc.c: 31: adc_data = ((ADRESH<<8) + ADRESL);
2945 072C 081E movf 30,w ;volatile
2946 072D 00AA movwf ADC_Read@adc_data+1
2947 072E 1683 bsf 3,5 ;RP0=1, select bank1
2948 072F 1303 bcf 3,6 ;RP1=0, select bank1
2949 0730 081E movf 30,w ;volatile
2950 0731 1283 bcf 3,5 ;RP0=0, select bank0
2951 0732 1303 bcf 3,6 ;RP1=0, select bank0
2952 0733 00A9 movwf ADC_Read@adc_data
"rock steady" means precision, but not accuracy.Also, I checked the refrence voltage for entire range of input voltage i.e. 0-1Volts, its rock steady.
Ok. I didn't check it on oscilloscope for noise or fluctuations (as I don't have it in my home setup) but when checked on DVM, it constantly shows 2.88V."rock steady" means precision, but not accuracy.
If we talk about noise or fluctuation we talk about precision.
If we talk about gain error, then we talk about accuracy. It means it should be 2.88V but actally it is 2.92V, for example.
Klaus
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?