功能说明:
本次设计的是基于ATMEGA16单片机的数字电压表,主要实现了通过单片机的内部模数转换器来实现对外部电压的检测,将电压值显示在数码管上,同是还具备声光报警的功能,当外部电压超过设定的阈值时(程序里设定的是4V),就会启动声光报警。
原理图如下:
效果图
源程序:
/*
* ATMEGA16.c
*
* Created: 2022/7/6 19:47:36
* Author: 阳子
*/
#include <mega16.h>
#define uchar unsigned char//宏定义
#define uint unsigned int
uchar temp,V_SegData = 4;//变量定义
uint V_LEDCounter;
#define BEEP_ON PORTD &= ~0x01//宏定义
#define BEEP_ON_OFF PORTD ^= 0x01
#define BEEP_OFF PORTD |= 0x01
unsigned char table[10]=//数码管0-9
{
0x3f,
0x06,
0x5b,
0x4f,
0x66,
0x6d,
0x7d,
0x07,
0x7f,
0x6f
};
void F_Delayxms(uint q)//延时函数
{
uint i,j;//定义变量
for(i=0;i<q;i++)//利用FOR循环计数延时
for(j=0;j<120;j++);
}
/*-----------------------------------------------------------------
函数名称: void AdcInit(void)
函数功能: ADC初始化
参 数:
返 回 值: 无
-----------------------------------------------------------------*/
void AdcInit(void)
{
ADCSR = 0x00; //ADC关闭
ADMUX = 0x62; //外部参考源AVCC,左对齐,选择ADC2通道
ACSR = 0x80; //模拟比较器控制和状态寄存器ACSR的ACD置1,使模拟比较器禁用
ADCSRA = 0xE3; //开启ADC,8分频,
SFIOR = 0x00;
}
void F_SystemInit()//IO初始化
{
DDRA=0x00;
PORTA=0xFF;
DDRB=0xff;
PORTB=0xFF;
DDRC=0xff;
PORTC=0xFF;
DDRD=0xfD;
PORTD=0xDF;
AdcInit();//AD初始化
}
void F_Display(uchar i)//显示函数
{
PORTB = 0xfe;//确定位
PORTC = table[i/51]|0x80;//显示个整数位
F_Delayxms(1);//延时
PORTC = 0x00;//消隐
PORTB = 0xfD;//确定位
PORTC = table[(i%51)*10/51];//显示十分位
F_Delayxms(1);//延时
PORTC = 0x00;//消隐
PORTB = 0xfb;//确定位
PORTC = table[((i%51)*10%51)*10/51];//显示百分位
F_Delayxms(1);//延时
PORTC = 0x00;//消隐
if(i > (51*V_SegData))//判断是否超过阈值
{
V_LEDCounter++;
if(V_LEDCounter >= 2000)
{
V_LEDCounter = 0;
BEEP_ON;//报警
}
}
else
{
BEEP_OFF;//取消报警
}
}
void main(void)
{
F_SystemInit();
while (1)
{
if(ADIF)
{
temp= ADCH;//取AD数据
ADCSRA = 0xE3;//使能AD
}
F_Display(temp);//调用显示部分
}
}