📄 f_12_12_adc_ser2.c
字号:
// For MCC18, this file uses the -Oi flag, which
// turns on integer promotions so that (ADRESH << 8) works.
#include "config.h"#include "delay.h"#include "serial.c"#include "serio.c"#include "jwb.h"/* * program to read ADC with ADC IRQs */void init(void);void char2hex(unsigned char c, unsigned char *s);void int2hex(int c, unsigned char *s);void Adc2Hex(int c, unsigned char *s);void SelectAdcChannel(unsigned char c);unsigned char ReadPot(void);int ReadTemp(void);int ReadAdcChannel(unsigned char c);void StartAdcCycle(unsigned char c);extern void serial_init (char brg, char hi_speed);const unsigned char MESSAGE1[] = "turn pot";unsigned char str1[9];unsigned char str2[9];#define ADC_AN0 0#define ADC_AN1 1#define ADC_IDLE 255volatile unsigned char AdcState;volatile int adc0;volatile int adc1;#if defined(HI_TECH_C)void interrupt pic_isr(void)#endif#if defined(__18CXX)#pragma interrupt pic_isrvoid pic_isr(void)#endif{ unsigned char temp; if (ADIF) { ADIF = 0; switch (AdcState) { case ADC_AN0: if ( ADFM ) adc0 = ((ADRESH << 8) | ADRESL); else adc0 = ((ADRESH << 2) | (ADRESL>>6)); temp = ADCON0 & 0xC1; // clear bits except ADCS1:ASCS0 and ADON //ADCON0 = temp | 0x20; // select the RA5/AN4 (pot) ADCON0 = temp | 0x08; // select the AN1 AdcState = ADC_IDLE; break; case ADC_AN1: if ( ADFM ) adc1 = ((ADRESH << 8) | ADRESL); else adc1 = ((ADRESH << 2) | (ADRESL>>6)); temp = ADCON0 & 0xC1; // clear bits except ADCS1:ASCS0 and ADON ADCON0 = temp; // select the RA0/AN0 AdcState = ADC_IDLE; break; case ADC_IDLE: // shouldn't ever get here! break; } }}void StartAdcCycle(unsigned char c) { AdcState = c; GODONE = 1;}void main(void){ unsigned char c; double va0, va1; init(); AdcState = ADC_IDLE; IPEN = 0; ADIE = 1; PEIE = 1; GIE = 1; printf("Hit any key to read ADCs..."); pcrlf(); while(1) { c = getch(); StartAdcCycle(ADC_AN0); printf("AN0="); while (AdcState != ADC_IDLE); va0 = 5.0 * adc0/1024; // convert LM34 value to temperature StartAdcCycle(ADC_AN1); printf("%4d (%1.3fV) AN1=", adc0, va0 ); while (AdcState != ADC_IDLE); va1 = 5.0 * adc1/1024; // convert pot value to voltage (Vdd=5V) printf("%4d (%1.3fV)", adc1, va1); pcrlf(); }}// initialize the PIC and peripheralsvoid init(void){ PORTA = 0x00; ADCON0 = BIT7|BIT6|BIT0; // internal ADC oscillator + ADON ADCON1 = BIT6|0x4; // L.just, AN0+AN1+AN3, no ext REFs SET_AS_INPUT(TRISA, BIT0 | BIT1); // inputs for Two ADC channels PORTB = 0x00; SET_AS_OUTPUT(TRISB, BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 ); // set RB0-RB5 to output // recall that RB6 and RB7 are reserved for the HW programmer/debugger PORTC = 0x00; SET_AS_OUTPUT(TRISC, BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5); // RC0,RC3,RC5 drive DAC // RC6 and RC7 are used in serial UART, so leave them alone // initialize the serial port serial_init(95, 1); // setup 19200 baud serial IO}int ReadAdcChannel(unsigned char c){ unsigned char temp; temp = ADCON0 & (BIT7|BIT6|BIT0); // clear bits except ADCS1:ASCS0 and ADON ADCON0 = temp | ((c & 0x7)<<3); // select the desired ADC channel and write to ADCON0 DelayUs(20); // wait 20us for ADC to get ready GODONE = 1; // start ADC conversion while(GODONE); // then wait for ADC to finish if ( ADFM ) return ((ADRESH << 8) | ADRESL); else return ((ADRESH << 2) | (ADRESL>>6) );}void SelectAdcChannel(unsigned char c){ unsigned char temp; temp = ADCON0 & (BIT7|BIT6|BIT0); // clear bits except ADCS1:ASCS0 and ADON ADCON0 = temp | ((c & 0x7)<<3); // select the desired ADC channel and write to ADCON0}//for MCC18, place the interrupt vector goto#if defined(__18CXX)#if defined(HIGH_INTERRUPT)#pragma code HighVector=HIGH_INTERRUPT#else#pragma code HighVector=0x0008 #endifvoid HighVector (void){ _asm goto pic_isr _endasm}#pragma code#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -