//程序实现A/D转换功能,A/D采用中断方式。该程序通过pic单片机p18f458的RA2模拟通道送入一直流电压, //当送入的直流电压大于2.5V时,与PORTD口相连的8个发光二极管闪动,当直流电压恢复到 //http://www.51hei.com单片机网提供此ad转换程序,有问题请联系本站。 //2.5V以下时,发光二极管停止闪动,且只有低四个发光。
#include "p18f458.h"
union adres { int y1; unsigned char adre[2]; }adresult; //定义一个共用体,用于存放A/D转换的结果
unsigned char i; unsigned int j;
void InterruptHandlerHigh(void);
//系统各I/O口初始化子程序 void initial() { TRISD=0X00; //D口为输出 i=0x00; }
//A/D转化初始化子程序 void adinitial() { INTCON=0X00; //禁止总中断和外围中断 ADCON0=0x51; //选择A/D通道为RA2,打开A/D转换器 //在工作状态,且使A/D转换时钟为8tosc ADCON1=0X80; //转换结果右移,及ADRESH寄存器的高6位为"0" //且把RA2口设置为模拟量输入方式 PIR1bits.ADIF=0; //清除A/D转换标志 PIE1bits.ADIE=1; //A/D转换中断允许 INTCONbits.PEIE=1; //外围中断允许 IPR1bits.ADIP=1; //B口变位中断高优先级 RCONbits.IPEN=1; //使能中断优先级 PORTAbits.RA2=1; //设置RA2为输入方式 }
//延时子程序 void delay() { for(j=5535;--j;) continue; }
//报警子程序 void alarm() { i=i^0xFF; //通过异或方式每次把i的各位值取反 PORTD=i; //D口输出i的值 }
//高优先级中断向量, #pragma code InterruptVectorHigh=0x08 void InterruptVectorHigh (void) { _asm goto InterruptHandlerHigh //跳到中断程 _endasm }
//高优先级中断服务程序 #pragma code #pragma interrupt InterruptHandlerHigh void InterruptHandlerHigh () { PIR1bits.ADIF=0; //清除中断标志 adresult.adre[0]=ADRESL; adresult.adre[1]=ADRESH; //读取并存储A/D转换结果,A/D转换的结果通过共 //用体的形式放入了变量y1中 if(adresult.y1>0x200) { alarm(); //如果输入的模拟量大于2.5V(对应数字量 //0X200h),则调用报警子程序 delay(); //调用延时子程序,使电压检测不要过于频繁 } else PORTD=0XF0 ; //如果输入的模拟量小于2.5V,则与D口相连的 //8个发光二极管的低4个发亮,表示系统正常 ADCON0bits.GO=1; //启动下一次A/D转换 }
//主程序 main() { adinitial(); //A/D转换初始化 initial(); //系统各I/O口初始化 INTCONbits.GIE=1; //总中断允许 ADCON0bits.GO=1; //启动A/D转换 while(1) { ; } //等待中断,在中断中循环检测外部电压 }
|