单片机综合课程设计.docx
《单片机综合课程设计.docx》由会员分享,可在线阅读,更多相关《单片机综合课程设计.docx(23页珍藏版)》请在冰豆网上搜索。
单片机综合课程设计
单片机课程设计报告
题目
简易数字电压表
学院
电子信息学院
专业
班级
学号
学生姓名
指导教师
课程设计目的和要求
本课程设计基于ATmega16单片机来实现简易数字电压表。
通过课程的设计进一步加深学生对单片机控制的理解和掌握,增强学生的实际动手操作能力。
此次设计要求基于ATmega16单片机自带的AD模块进行数据采集,通过按键控制选择不同通道,在四位LED数码管上进行电压输出显示。
设计原理
系统组成
图1简易数字电压表的系统构成
由上图的简易数字电压表的系统划分图可以将此次的设计划分为四部分,ATmega16单片机主控电路、按键控制选择通道电路、数码管显示电路、外部电压信号输入电路。
由于ATmega16有一个10位的逐次逼近型ADC,此ADC与一个8通道的模拟多路复用器连接,可以对来自端口PA的8路单端输入电压进行采样。
因此,在设计中就直接采用Atmega16自带的ADC进行电压信号的采样分析。
当然根据设计对采样精度的要求的不同也可以采用其他ADC电路进行电压的采样分析。
单片机主控电路
图2ATmega16主控电路
如上图所示,ATmega16单片机采用16M晶振构成的外部时钟电路,通过按键控制PB4、PB5、PB6.、PB7的高低电平来选择通道输入,PA4—PA7用于控制四位数码管的使能端,PC0—PC7用来控制数码管的显示,外部待测电压可由PA0—PA3输入。
按键电路和复位电路
图3按键电路
设计中采用低电平有效。
图4复位电路
复位是单片机的初始化操作,只要给RESET引脚加上2个机器周期以上的高或低电平信号,即可使单片机复位。
除了进入系统的正常初始化之外,当程序运行出错或是操作错误使系统处于死锁状态时,为了摆脱死锁状态,也需要按复位键重新复位。
如图4在本次设计中采用按键复位低电平有效。
数码管显示电路
本设计中采用4位8段共阳极数码管进行电压等输出显示。
利用PNP三极管构成开关电路来对各位数码管的使能端进行控制。
图5数码管显示
程序设计流程
图6程序设计流程图
附件:
程序及相关说明
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
voidset_low(void);
voidset_channel(void);
voidset_time(void);
voidnormal();
voidbeep();
ucharcode=0;
ucharnum_tab1[]={0x28,0xee,0x32,0xa2,0xe4,0xa1,0x21,0xea,0x20,0xa0,0x39};
ucharnum_tab2[]={0x08,0xce,0x12,0x82,0xc4,0x81,0x01,0xca,0x00,0x80};
ucharcout=0;
ucharsecond=0;
ucharv[];
uintvol_tage;
uintmax=30000;
uintmin=0;
signedcharchan=1;
inttime=3;
uchart1,t2;
uintaddata;
ucharnum_chan;
//主程序
voidmain()
{
io_init();
ad_init();
while
(1)
{
vol_tage=adc_convert();
process(vol_tage);
disp_number();
while
(1)
{
if(!
(PINB&(1<<7)))
{
delay_ms(150);
if(!
(PINB&(1<<7)))
{
while(!
(PINB&(1<<7)))
{
process(max);
disp_high();
}
code++;
}
}
if((code%4)==1)
{
set_high();//设置上限
if(!
(PINB&(1<<7)))
{
delay_ms(150);
if(!
(PINB&(1<<7)))
{
while(!
(PINB&(1<<7)))
{
process(min);
disp_low();
}
code++;
}
}
}
if((code%4)==2)
{
set_low();
if(!
(PINB&(1<<7)))
{
delay_ms(150);
if(!
(PINB&(1<<7)))
{
while(!
(PINB&(1<<7)))
{
disp_channel();
}
code++;
}
}
}
if((code%4)==3)
{
set_channel();
if(!
(PINB&(1<<7)))
{
delay_ms(150);
if(!
(PINB&(1<<7)))
{
while(!
(PINB&(1<<7)))
{
disp_time(time);
}
code++;
}
}
}
if((code%4)==0)
{
set_time();
if(!
(PINB&(1<<7)))
{
delay_ms(150);
if(!
(PINB&(1<<7)))
{
while(!
(PINB&(1<<7)))
{
process(max);
disp_high();
}
code++;
}
}
}
beep();
switch(chan)
{
case1:
num_chan=0xc0;break;
case2:
num_chan=0xc1;break;
case3:
num_chan=0xc2;break;
default:
num_chan=0xc3;break;
}
}
}
}
//--------------------------------------
//ms延时子函数
//-----------------------------------------
voiddelay_ms(uintj1)
{
uinti2;
while(j1--)
{
for(i2=0;i2<1000;i2++)
{;}
}
}
//--------------------------------------
//端口初始化子函数
//-----------------------------------------
voidio_init()
{
DDRA|=0xf0;//数码管位输出
DDRB&=0x0f;//键盘输入
DDRB|=0x04;
DDRC|=0xff;//数码管段输出
PORTA|=0xf0;
PORTC|=0xff;
PORTB|=0xf4;
}
//--------------------------------------
//AD初始化子函数
//-----------------------------------------
voidad_init()
{
ADMUX=0xc0;//参考电压:
AREF,转换结果右对齐,ADC0输入
ADCSRA=0x07;//单次转换模式,分频因子设置为128,禁止AD中断
}
//--------------------------------------
//AD数据读取子函数
//-----------------------------------------
uintadc_convert()
{
ucharadh,adl;
ADMUX=num_chan;//选择内部参考电压2.56v,选择ADC0,数据右对齐
ADCSRA|=(1<<7);//ADC使能
ADCSRA|=(1<<6);//启动AD转换
while(!
(ADCSRA&(1<<4)));//等待转换结束
adl=ADCL;
adh=ADCH;//读取转换结果
addata=adl+adh*256;
addata=addata*25;
returnaddata;
}
//--------------------------------------
//数码管显示子函数
//-----------------------------------------
voidprocess(uintnum)
{
v[0]=num/10000;
v[1]=num/1000%10;
v[2]=num/100%10;
v[3]=num/10%10;
}
voiddisp()
{
PORTC=0xff;
PORTA=0xbf;
PORTC=num_tab2[v[0]];
__delay_cycles(10000);
PORTC=0xff;
PORTA=0xdf;
PORTC=num_tab1[v[1]];
__delay_cycles(10000);
PORTC=0xff;
PORTA=0xef;
PORTC=num_tab1[v[2]];
__delay_cycles(10000);
}
voiddisp_number()
{
PORTC=0xff;
PORTA=0x7f;
PORTC=num_tab1[chan];
__delay_cycles(10000);
disp();
}
voiddisp_high()
{
PORTC=0xff;
PORTA=0x7f;
PORTC=0x64;
__delay_cycles(10000);
disp();
}
voiddisp_low()
{
PORTC=0xff;
PORTA=0x7f;
PORTC=0x3d;
__delay_cycles(10000);
disp();
}
voiddisp_channel()
{
PORTC=0xff;
PORTA=0x7f;
PORTC=num_tab1[10];
delay_ms(20);
PORTC=0xff;
PORTA=0xbf;
PORTC=0x64;
delay_ms(20);
PORTC=0xff;
PORTA=0xef;
PORTC=num_tab1[chan];
delay_ms(20);
}
voiddisp_time(charcn)
{
uchartime_1,time_2;
time_1=cn/10;
time_2=cn%10;
PORTC=0xff;
PORTA=0x7f;
PORTC=0xa1;
__delay_cycles(10000);
PORTC=0xff;
PORTA=0xdf;
PORTC=num_tab1[time_1];
__delay_cycles(10000);
PORTC=0xff;
PORTA=0xef;
PORTC=num_tab1[time_2];
__delay_cycles(10000);
}
voidset_high(void)
{
process(max);
disp_high();
switch(PINB&0xf0)
{
case0xe0:
delay_ms
(2);if(!
(PINB&(1<<4)))max+=5000;while(!
(PINB&(1<<4))){process(max);disp_high();}break;
case0xd0:
delay_ms
(2);if(!
(PINB&(1<<5)))max-=5000;while(!
(PINB&(1<<5))){process(max);disp_high();}break;
default:
break;
}
if(max>49000)max=50000;
if(max<10)max=0;
normal();
}
voidset_low(void)
{
process(min);
disp_low();
switch(PINB&0xf0)
{
case0xe0:
__delay_cycles(160000);if(!
(PINB&(1<<4)))min+=5000;while(!
(PINB&(1<<4))){process(min);disp_low();}break;
case0xd0:
__delay_cycles(160000);if(!
(PINB&(1<<5)))min-=5000;while(!
(PINB&(1<<5))){process(min);disp_low();}break;
default:
break;
}
if(min<10)min=0;
if(min>49000)min=50000;
normal();
}
voidset_channel(void)
{
disp_channel();
switch(PINB&0xf0)
{
case0xe0:
__delay_cycles(160000);if(!
(PINB&(1<<4)))chan++;while(!
(PINB&(1<<4)))
{
disp_channel();
}
break;
case0xd0:
__delay_cycles(160000);if(!
(PINB&(1<<5)))chan--;while(!
(PINB&(1<<5)))
{
disp_channel();
}
break;
default:
break;
}
if(chan>4)chan=1;
if(chan<1)chan=4;
normal();
}
#pragmavector=TIMER0_OVF_vect
__interruptvoidTOver0_isr(void)
{
cout++;
if(cout==250)
{
second++;
}
if(second==time)
{
second=0;
chan++;
if(chan>4)
chan=1;
if(chan<1)
chan=4;
}
}
voidauto_time(void)
{
TCCR0|=(1<<2);//T/C0工作于定时方式,系统时钟256分频
TCNT0=0x06;//计数初值
TIMSK|=(1<<0);//使能T0溢出中断
SREG|=(1<<7);//使能全局中断
while
(1)
{
vol_tage=adc_convert();
process(vol_tage);
disp_number();
switch(chan)
{
case1:
num_chan=0xc0;break;
case2:
num_chan=0xc1;break;
case3:
num_chan=0xc2;break;
default:
num_chan=0xc3;break;
}
if(!
(PINB&(1<<6)))
{
__delay_cycles(160000);
if(!
(PINB&(1<<6)))
{
while(!
(PINB&(1<<6)))
{
vol_tage=adc_convert();
process(vol_tage);
disp_number();
}
SREG^=(1<<7);
}
}
}
}
voidset_time(void)
{
disp_time(time);
switch(PINB&0xf0)
{
case0xe0:
__delay_cycles(160000);if(!
(PINB&(1<<4)))time++;while(!
(PINB&(1<<4)))disp_time(time);break;//K3make'```'++
case0xd0:
__delay_cycles(160000);if(!
(PINB&(1<<5)))time--;while(!
(PINB&(1<<5)))disp_time(time);break;//K4make'````'--
default:
break;
}
if(time<0)
time=60;
if(time>60)
time=0;
if(!
(PINB&(1<<6)))
{
__delay_cycles(160000);
if(!
(PINB&(1<<6)))
{
while(!
(PINB&(1<<6)))
{
;
}
auto_time();
}
}
}
voidnormal()
{
beep();
if(!
(PINB&(1<<6)))
{
delay_ms(10);
if(!
(PINB&(1<<6)))
{
while
(1)
{
vol_tage=adc_convert();
process(vol_tage);
disp_number();
while(!
(PINB&(1<<6)))
{
vol_tage=adc_convert();
process(vol_tage);
disp_number();
}
if(!
(PINB&(1<<7)))
break;
}
}
}
}