Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void ADC_Init(void){
- //Configure Inputs
- TRISA |= 0x01;
- ANSEL |= 0x01;
- ADCON0 = (1<<0) | (0<<2); //Enable ADC and select channel 0
- ADCON1 = (0<<4) | (0<<5); //Set both references to PIC supply
- ADCON2 = (0<<0) | (7<<3) | (0<<7); //Use 20 acquisition cycles and FOsc/2, left justified
- }
- void ADC_StartConv(void){
- ADCON0 |= (1<<1);
- }
- unsigned int ADC_CheckConv(void){
- if(ADCON0 & 2) return 1;
- else return 0;
- }
- void ADC_WaitForConv(void){
- while(ADC_CheckConv());
- }
- unsigned char ADC_GetConv(void){
- return ADRESH;
- }
- volatile unsigned int ISample = 0, AmntSamples = 0;
- volatile int LPF = 0, HSample = 0;
- volatile int SZCrossP = 0;
- volatile unsigned char IZC = 0;
- //Long is 32bit?
- volatile unsigned long Frequency = 0;
- void InterruptServiceLow(void) {
- //This interrupt takes 25 instructions (approx 25 cycles = 1.6us @ 64MHz=16MIPS)
- //Happens every 16us (1/(16MHz/256)), uses about 1.6us/16us = 10% of CPU time
- //Interrupt frequency: 62.5kHz
- if (INTCON & 0b00000100) { //TIMER0 Interrupt
- INTCON &= 0b11111011; //CLEAR Timer0 interrupt flag
- tick++;
- timer0intflag = 1;
- ISample = ADC_GetConv(); //Get previously converted value
- ADC_StartConv(); //Start conversion in the background
- //High pass the sample to get rid of DC offset, cutoff determined through Matlab
- //as 40Hz
- LPF += (ISample - LPF)>>7;
- AmntSamples++;
- //Set the last sample
- LSample = HSample;
- HSample = ISample - LPF;
- //Detect zero crossing point
- //If current sample is positive and last sample was negative
- //Therefore, this finds the rising edge of a signal
- if(HSample>0 && LSample <=0){
- if(!IZC){
- AmntSamples = 0;
- IZC = 1;
- }
- //Second rising edge
- else{
- IZC = 0;
- SZCrossP = AmntSamples;
- //The whole period took 'SZCrossP' samples. Knowing one tick is 16us
- //The frequency will be equal to 1/(SZCrossP*16us) e.g. if there were 100
- //samples for the whole period, the frequency would be 625Hz (1/(100*16e-6).
- //The equation could also be 1e6/(SZCrossP*16).
- //Multiplication by 16 is the same as upshifting by 4.
- Frequency = 1000000ul/((unsigned long)SZCrossP<<4);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment