编写程序,使用数码管显示ADC测量得到的电压值。电压值由1位整数和1位小数构成。例如若当前AN0通道上的电压为6V,则数码管应显示3.6。
#include
#include
#define uint8 unsigned char
#define uint16 unsigned int
__CONFIG(FOSC_HS &WDTE_OFF &BOREN_OFF &PWRTE_OFF &LVP_OFF); //设置配置位
//WDTE_OFF:disable watchdog timer 看门狗禁止
//LVP_OFF:low voltage programming disabled 低电压编程禁止
//FOSC_HS:high speed crystal/resonator 4M以上晶振选择HS高速
//PWRTDIS:disable power up timer
//BOREN_OFF:disable brown out reset
/***************************定义全局变量***************************************/
uint8 disp[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //共阳数码管段码表
uint16 AD_Result; //ADC转换结果变量
uint16 count;
long AD_Result_temp;
/***************************声明函数*******************************************/
void ADC_Init(void);
void Time2_Init(void);
void DelayUS(uint8 delay);
void LED_Display(uint8 chosebit, uint8 wdata);
/*******************************************************************************
* 函 数 名: DelayUS(uint8 delay)
* 函数功能: 微秒延时 for 20MHZ
* 入口参数: delay
* 返 回: 无
*******************************************************************************/
void DelayUS(uint8 delay)
{
while(--delay);
}
/******************************************************************************
* 函 数 名: ADC_Init(void)
* 函数功能: ADC初始化
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void ADC_Init(void)
{
TRISA0 = 1; //模拟通道0设置为输入
ADCON1 = 0x8E; //10001110 Vref+ = VDD Vref- = VSS
ADCON0 = 0x01; //选择通道0,使能AD
ADIF = 0; //中断标志清零
ADIE = 1; //ADC中断使能
}
/*******************************************************************************
* 函 数 名: Time2_Init(void)
* 函数功能: 定时器2初始化
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void Time2_Init(void)
{
T2CON = 0x01; //postscale 1:1 prescale 1:4
PR2 = 250; //匹配寄存器 1*4*250*200ns = 200us
TMR2IF = 0; //定时器2中断标志位清零
GIE = 1; //开总中断
PEIE = 1; //开外设中断
TMR2IE = 1; //开定时器中断
}
/*******************************************************************************
* 函 数 名: LED_Display(uint8 chosebit,uint8 wdata)
* 函数功能: 单个数码管显示
* 入口参数: chosebit选择字位,wdata字型
* 返 回: 无
*******************************************************************************/
void LED_Display(uint8 chosebit, uint8 wdata)
{
if((chosebit < 0) || (chosebit > 4))
return;
ADCON1 = 0x8E; //10001110 RA0位模拟输入
TRISA &= 0x01;
TRISE &= 0xEF; //配置PORTD为普通IO口,对PORTD的操作务必加上这句
TRISD = 0x00; //数据线配置为输出
PORTA = (PORTA & 0xE3) | ((chosebit + 3) << 2); //RA2:RA3:RA4:011 选通第一位 100选通第二位 101选通第三位 110选通第四位
PORTD = wdata; //送显示数字的断码
DelayUS(100); //延时
PORTD = 0xFF; //关闭显示
}
/******************************************************************************
* 函 数 名: mian(void)
* 函数功能: 对模拟通道0进行采样,并显示,再采样,再显示
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void main(void)
{
long temp;
ADC_Init(); //ADC初始化
Time2_Init(); //定时器2初始化
GIE = 1; //总中断使能
PEIE = 1; //外设中断设能
GO = 1; //启动ADC转换
TMR2ON = 1; //启动定时器2计时
while(1)
{
temp = AD_Result_temp;
temp /= 10;
LED_Display(2, disp[temp % 10]); //显示十分位
temp /= 10;
LED_Display(1, disp[temp % 10] & 0x7F); //显示个位
}
}
/******************************************************************************
* 函 数 名: interrupt PIC_Init(void)
* 函数功能: 中断函数
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void interrupt PIC_Init(void)
{
if(ADIF == 1)
{
ADIE = 0; //关AD中断
ADIF = 0; //AD中断标志清零
AD_Result = ADRESL & 0x00FF; //读取ADC采样结果
AD_Result |= ADRESH << 8 ;
AD_Result_temp = AD_Result * 50; //5V为VDD电压,根据不同的电压作修改
AD_Result_temp = AD_Result_temp * 10 / 1023; //再放大10倍,方便计算显示
ADIE = 1; //开启AD中断
}
if(TMR2IF == 1)
{
TMR2IE = 0; //关定时器0中断
TMR2IF = 0; //清标志位
count++; //计数值加1
if(count >= 500) //200us*500 = 100ms,即0.1s启动采样一次
{
count = 0;
GO = 1; //启动ADC转换
}
TMR2 = 0x00;
TMR2IE = 1; //开中断
}
}