单片机课程设计之多功能秒表Word文档下载推荐.docx
《单片机课程设计之多功能秒表Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《单片机课程设计之多功能秒表Word文档下载推荐.docx(40页珍藏版)》请在冰豆网上搜索。
Pin9、10:
(P1.4、P1.5)两路AD输入,可做差分输入,需要设置ADC的寄存器。
Pin11、12:
(P1.6、P1.7)各200uA激励电流源,可配合RTD等
做应用。
Pin13:
两路AD输入做普通输入时的电压参考端,AD输入电压不能低于此引脚电压。
Pin14:
片内DAC输出。
Pin15:
复位引脚。
Pin16、17:
单片机RS232接口的RXD(P3.0)TXD(P3.1)。
Pin18:
(P3.2)外部中断0,用于红外接收和PS/2接口。
Pin19:
(P3.3)LCD1602,LCD12864A的EN引脚,控制第一位数码管。
Pin20、21:
DVDD、DGND数字电源输入。
Pin22:
(P3.4)PS/2接口的data信号。
Pin23:
(P3.5)LCD1602和LCD12864A的RW。
Pin24:
(P3.6)LCD1602和LCD12864A的RS。
Pin25:
LCD12864A的CS1。
Pin26:
IIC接口时钟信号。
Pin27:
IIC接口data信号。
Pin28:
(P2.0)SPI接口时钟信号。
Pin29:
(P2.1)SPI接口MOSI信号、控制第6位数码管的位码。
Pin30:
(P2.2)SPI接口MISO信号、控制第7位数码管的位码。
Pin31:
(P2.3)SPI接口SS信号、控制第8位数码管的位码;
P2.0~3也作为4X4矩阵式键盘的扫描输出信号、步进电机的控制信号、数码管第数码管第6、7、8位位码。
但是SPI、4X4矩阵式键盘、步进电机、数码管第6、7、8位功能不能同时实现。
Pin32、Pin33:
接外部32.768KHz晶振。
Pin34、Pin35:
DVDD、DGND。
Pin36:
(P2.4)LCD12864A的CS2。
Pin37:
(P2.5)内部PWM模块输出,控制红外LED。
Pin38:
(P2.6)内部PWM模块输出,控制蜂鸣器。
Pin39:
(P2.7)内部PWM模块的外部时钟输入(也可以用内部时钟)。
Pin40:
EA,低电平有效,正常使用时拉低。
Pin41:
PSEN,在此引脚电平为低时按复位键进入debug模式,可以下载和调试程序。
Pin42:
ALE。
Pin47、Pin48:
DGND、DVDD。
Pin43、44、45、46、49、50、51、52:
P0口、LCD1602和LCD12864的数据总线,数码管的段码。
2.电源模块
电源模块原理图如图
本学习板共有如下3种供电方式:
(1)5V电源适配器供电(开关往上拨、插针1下面两脚接跳线帽)。
将开关sw4第2、3脚接通(开关往上拨),电源网络DVDD连接到插针1第2脚的输出,将插针1的第1、2脚(插针1下面两脚)接跳线帽,DVDD直接连接到电源适配器输入端,即为5V电源适配器供电模式。
(2)7~12V电源适配器供电(开关往上拨、插针1上面两脚接跳线帽)
将开关sw4第2、3脚接通(开关往上拨),电源网络DVDD连接到插针1第2脚的输出,将插针1的第2、3脚(插针1上面两脚)接跳线帽,DVDD连接到稳压芯片7805的输出,而7805的输入端连接到电源适配器输入端,即为7~12V的电源适配器经7805给学习板供电的模式。
(3)USB供电(开关往下拨)。
将开关sw4第1、2脚接通(开关往下拨),电源网络DVDD连接到USB电源输入端。
3.数码管
该模块原理如图
(1)DS0~7:
数码管段码。
(2)BIT0~7:
数码管位码。
(3)MOTORA~D:
步进电机驱动信号。
(4)DISCTRL0~4:
显示控制信号,控制数码管低5位。
(5)D0~8:
单片机P0口。
本设计采用共阴极数码管,段码由PNP三极管驱动,位码由NPN型三极管驱动。
引脚复用:
数码管低5位(板上为右边5位)的位码由DISCTRL0~4控制,可单独使用,高3位的位码控制信号与SPI信号,电机驱动信号,4X4矩阵式键盘复用,使用数码管高3位时参与复用的其他功能则不能使用。
插针配置:
(1)若要使用数码管第4~0位(板上为右边5位),可以接通插针8。
(2)若要使用数码管第7~5位(板上为左边3位),可以分别接通插针5~7和9。
4.RS232串口
该模块中采用maxin公司的max232作电平转换,为方便调试硬件,对RXD,TXD信号设测试点和LED。
5.8路LED
8个LED接P0口,低电平时LED亮,这样不会影响P0口逻辑电平。
LED限流电阻取4.7K,通过LED电流约为0.8mA,在P0口驱动能力范围之内。
使用该模块,可以接通插针2,
6.蜂鸣器
该模块原理图如图1.10所示。
本设计中采用无源电磁式蜂鸣器,蜂鸣器由PWM1(P2.6)控制。
PWM1和PWM0均为片内PWM模块的输出。
蜂鸣器采用普通NPN三极管。
使用蜂鸣器,可以接通插针3。
7.按键模块
由于P1口(用于行扫描)内部无上拉电阻,为使无键按下时行信号为高电平,故将行信号接上拉电阻,电阻大小10K即可。
P2.0~P2.3为4X4矩阵式键盘列扫描信号,又复用作步进电机控制信号,SPI信号、P2.1~P2.3还复用为数码管第5、6、7位位码控制信号。
参与复用的一项功能使用时,其他参与复用的功能则不能使用。
(1)插针10上面两脚接跳线帽,4X4矩阵式键盘输入,行扫描信号为P1.0~P1.3,列扫描信号为P2.0~2.3。
(2)插针10下面两脚接跳线帽,独立按键输入,该模式有4个独立按键可用,按键扫描所用端口为P1.0~P1.3。
这4个按键为4X4矩阵键盘的左边4个按键。
8.复位与下载
复位与下载电路如图
进入下载或调试模式的步骤为:
(1)按住BTN1(downordebug按键)不要放开;
(2)按下BTN2(reset按键),然后放开BTN2(reset按键);
(3)放开BTN1(downordebug按键)。
这样单片机就进入了调试模式,可以下载或调试程序。
四、流程图
1、主程序:
主程序流程图
2、秒表正计时子程序
3、倒计时子程序
五、主程序
miao_biao:
#include<
aduc848.h>
#include"
keypp.h"
iic.h"
#defineucharunsignedchar
#defineuintunsignedint
unsignedcharb[7]={50,59,10,3,22,6,11},clock[2]={2,11};
//日期和时间初值
codeunsignedchartab[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x19,0x00};
//共阴数码管0-9
unsignedchartime[7];
codeunsignedchartab2[]={0x39,0xff};
//闹钟显示
voiddelay(unsignedintcnt);
unsignedchargetkey1();
//读键盘
voidtim(void);
//中断
voidKeyDelay(unsignedintKeyJsTime);
//键盘扫描延时
voiddisplay(ucharbit7,ucharbit6,ucharbit5,ucharbit4,
ucharbit3,ucharbit2,ucharbit1,ucharbit0);
//显示子程序
voidReadTime(unsignedcharTIME[7]);
//DS1307读时间
voidSetTime(unsignedcharTIME[7]);
//设置时间初值
voidSwitchRTC(unsignedcharSWITCH);
//秒最高位设置
uchardis_num_h;
//显示记录数据的组别十位
uchardis_num_l;
//显示记录数据的组别个位
uchardis_min_h;
//要显示的分的十位;
uchardis_min_l;
//要显示的分的个位;
uchardis_sec_h;
//要显示的秒的十位;
uchardis_sec_l;
//要显示的秒的个位;
uchardis_dsec;
//要显示的0.1秒;
ucharmin=0x00;
ucharsec=0x00;
uchardsec=0x00;
ucharen,i,clocken=0;
main()
{
unsignedcharquzhi,xianzhi,symbol=0x55,set,set1=0x55,ce;
unsignedcharc[30];
unsignedcharnum,num1,j,k,stop=1;
PLLCON&
=0xf8;
//设置频率为12.58MHz
TMOD=0x01;
//定时器工作模式设置
TH0=0x3c;
//初值
TL0=0x00;
IE=0x82;
//中断控制,10000010,EA=1开总中断,ET0=1:
定时器0中断允许
I2CCON=0xE8;
//开启iic通信;
SetTime(b);
//设定初始时间;
SwitchRTC
(1);
while
(1)
{
ReadTime(time);
if(((clock[0]==time[1])&
&
(clock[1]==time[2])&
(clocken==0)&
stop))
{
PWM0H=205;
PWM1L=500;
PWMCON=0x21;
//蜂鸣器响
KeyDelay(333);
//延时
PWM1H=0;
PWM1L=0;
PWMCON=0x00;
if(getkey1()!
=0x55)
{
stop=0;
}
}
if(time[1]==clock[0]+1)stop=1;
//闹钟响一分钟
if((time[0]==0)&
(time[1]==0))//整点报时
{
i=1;
while(i)
{
PWM0H=50;
PWM1L=100;
i++;
if(i==20)
{
i=0;
}
}
}
en=getkey1();
if((en==0x80)||(en==0x55))//无效键或无键
en=symbol;
}
if(xianzhi==8)
display(dis_num_h,dis_num_l,dis_min_h,dis_min_l,
dis_sec_h,dis_sec_l,0xff,dis_dsec);
//显示已记录的值
///////////////////////////////////////////////////////////////////////////////////
if(en==1)//显示北京时间,年月日星期
symbol=1;
display(tab[time[6]/10],tab[time[6]%10],tab[time[5]/10],tab[time[5]%10],
tab[time[4]/10],tab[time[4]%10],0xff,tab[time[3]%10]);
////////////////////////////////////////////////////////////////////////////////////
if(en==2)//显示北京时间,闹钟开关标志和时分秒
symbol=2;
display(tab2[clocken],0xff,tab[time[2]/10],tab[time[2]%10],tab[time[1]/10],
tab[time[1]%10],tab[time[0]/10],tab[time[0]%10]);
elseif(en==3)//秒表正常工作:
正计时
min=0;
sec=0;
dsec=0;
symbol=3;
while
(1)
quzhi=getkey1();
if(num<
11)
display(dis_min_h,dis_min_l,0xff,0xff,dis_sec_h,dis_sec_l,0xff,dis_dsec);
else
display(0x71,0x83,0xe3,0xe3,0xff,0xff,0xff,0xff);
//显示full
if(quzhi==5)
quzhi=0x55;
num=1;
if(TR0==1)TR0=0;
elseTR0=1;
}elseif(quzhi==6)//秒表读值,按键6
c[3*(num-1)+2]=dsec;
//读出的值放在c[]中
c[3*(num-1)+1]=sec;
//每四位为一段,依次时取值的顺序、分、秒、0.1秒
c[3*(num-1)+0]=min;
num++;
}elseif(quzhi!
=0x55)//任意键按下,表示计时结束
TR0=0;
num1=1;
symbol=0x55;
min=0;
sec=0;
dsec=0;
break;
}
}
if(getkey1()==8)
//////////////////////////////////////////////////////////////////////////////////////
elseif(en==4)//秒表倒计时
symbol=4;
j=0;
for(i=0;
i<
=30;
i++)c[i]=0;
display(dis_min_h,dis_min_l,0xff,0xff,dis_sec_h,dis_sec_l,0xff,dis_dsec);
set=getkey1();
while(j<
5)
{
ce=getkey1();
display(tab[c[0]],tab[c[1]],0xff,0xff,tab[c[2]],tab[c[3]],0xff,tab[c[4]]);
if((ce!
=0x55)&
(ce!
=0x80))
{
if(ce>
9)ce=0;
c[j]=ce;
j++;
}
min=c[0]*10+c[1];
sec=c[2]*10+c[3];
dsec=c[4];
}
dis_min_h=tab[min/10];
//分、秒及0.1秒显示值的处理
dis_min_l=tab[min%10];
dis_sec_h=tab[sec/10];
dis_sec_l=tab[sec%10];
dis_dsec=tab[dsec];
if(set==5)//倒计时开始
set=0x55;
TR0=1;
TF0=1;
if((min==0)&
(sec==0)&
(dsec==0))//倒计时结束
while(i)
PWM0H=50;
KeyDelay(333);
PWM1H=0;
i++;
if(i==200)
{
i=0;
break;
}
if(set!
=0x55)
for(i=0;
30;
ce=0x55;
elseif(en==8)
symbol=0x55;
xianzhi=8;
dis_num_h=tab[num1/10];
dis_num_l=tab[num1%10];
dis_min_h=tab[c[(num1-1)*3+0]/10];
dis_min_l=tab[c[(num1-1)*3+0]%10];
dis_sec_h=tab[c[(num1-1)*3+1]/10];
dis_sec_l=tab[c[(num1-1)*3+1]%10];
dis_dsec=tab[c[(num1-1)*3+2]];
num1++;
if(num1>
num)
xianzhi=0x55;
elseif(en==9)//进入北京时间设置
=6;
i++)b[i]=0;
{
=13)
if(j<
=5)
display(tab[b[2]/10],tab[b[2]%10],0xff,tab[b[1]/10],
tab[b[1]%10],0xff,tab[b[0]/10],tab[b[0]%10]);
elseif(j<
display(tab[b[6]/10],tab[b[6]%10],tab[b[5]/10],
tab[b[5]%10],tab[b[4]/10],tab[b[4]%10],0xff,tab[b[3]%10]);
if(ce==10)break;
//中途退出设置
elseif((ce!
{if(ce>
9)ce=0;
b[2]=c[0]*10+c[1];
b[1]=c[2]*10+c[3];
b[0]=c[4]*10+c[5];
b[6]=c[6]*10+c[7];
b[5]=c[8]*10+c[9];
b[4]=c[10]*10+c[11];
b[3]=c[12];
ReadTime(time);
c[13]=time[2]/10;
c[14]=time[2]%10;
c[15]=time[1]/10;
c[16]=time[1]%10;
c[17]=time[0]/10;
c[18]=time[0]%10;
c[19]=time[6]/10;
c[20]=time[6]%10;
c[21]=time[5]/10;
c[22]=time[5]