1 基于51单片机用LCD1602实现时-分的显示
2. 按键控制时-分的调整
3. 能实现整时报时的功能(蜂鸣器响)
4. 闹钟模式
5.按键切换模式(模式一:时-分显示,模式二:60秒倒计时) 一、设计思路:
主体:
通过外部中断0来控制mod值;mod=0,1.2,3分别对应时钟模式,调整模式,闹钟设置模式,一分钟倒计时模式。
细节:
mod0
通过定时计数器,每一秒增加变量秒(s),每60秒,增加1分(min)并且s置0,每60min,增加1小时h,当h>23,h=0;进行一天循环
mod1
按键控制增加min,h和s制0
mod2
另外设置变量min1,h1,当min=min1,h=h1时蜂鸣器响
mod3
设置变量daojishi=60, 通过定时计数器,每一秒daojishi减1,当daojishi<0时,蜂鸣器响
另外:
1.设置外部中断2,关闭蜂鸣器
2.时间发送一次只能发送一个位 程序:
#include
//K1后K3加分钟,K4加时间,K2加秒,K1进入闹钟设置,K2退出
//K2关闭闹钟
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
#define data8b P1 sbit K1=P3^2; //外部中断0
sbit K2=P3^3; //外部中断1
sbit K3=P3^0;
sbit K4=P3^1;
sbit BUZ=P2^4; //蜂鸣器,0响
sbit RW=P2^5; //4脚,数据(1)or命令(0)
sbit RS=P2^6; //5脚,读(1)写(0)
sbit E=P2^7; //6脚,使能信号
u8 code dat1[]={0X30,0X31,0X32,0X33, 0X34,0X35,0X36,0X37, 0X38,0X39};
void delay(u16 i) //延时函数
{ while(i--); }
void open012() //打开中断0,1,定时器中断0
{ TMOD|=0X01; //选择为定时器0模式,工作方式1
ET0=1; //打开定时器0中断允许
EA=1; //打开总中断
TR0=1; //打开定时器
EX0=1; //打开外部中断0
IT0=1; //边沿触发方式
EX1=1; //打开外部中断1
IT1=1; //边沿触发
}
void wrm(u8 dat) //写入命令
{ delay(1000);
RS=0;
RW=0;
E=0;
data8b=dat;
E=1;
delay(1000);
E=0; }
void wrd(u8 dat) //写入数据
{
delay(1000);
RS=1;
RW=0;
E=0;
data8b=dat;
E=1;
delay(1000);
E=0;
}
void zero()
{
wrm(0X38); //八位数据,两行显示,5*7
wrm(0X0c); //无光标,打开显示
wrm(0X06); //光标右移,屏幕不移动
wrm(0X01); //清屏
wrm(0X80); //设置数据指针起点
}
u8 fg=0,sg=0,bfg=0,bsg=0;
u16 i=0;
u8 s=0;
u8 mod=0;
char dingshi;
bit bell=0;
bit zanting=1;
void fangsong()
{
wrd(dat1[sg/10]); //时十位
wrd(dat1[sg%10]); //时个位
wrd(0x3A); //:
wrd(dat1[fg/10]); //分十位
wrd(dat1[fg%10]); //分个位
wrd(0x3A); //:
wrd(dat1[(s/10)]); //秒十
wrd(dat1[(s%10)]); //秒个
}
void fangsong1()
{
wrm(0X80);
wrd(dat1[sg/10]); //时十位
wrd(dat1[sg%10]); //时个位
wrd(0x3A); //:
wrd(dat1[fg/10]); //分十位
wrd(dat1[fg%10]); //分个位
wrd(0x3A); //:
wrd(dat1[(s/10)]); //秒十
wrd(dat1[(s%10)]); //秒个
}
void chuli()
{
if(fg==60)
{
sg++;
fg=0;
}
if(sg==24)
{
sg=0;
}
}
void main()
{
u8 shijian;
open012();
zero();
chuli();
fangsong();
shijian=100;
while(1)
{
while(mod==0)
{
EX1=1; //打开外部中断1
if(s==60)
{
fg++; //60秒转化为1分钟
s=0;
}
chuli();
if((fg==0)&&(shijian!=sg))
{
BUZ=0;
shijian=sg;
}
fangsong1();
if((BUZ==0)&&(bell==0))
{
delay(1000);
BUZ=1;
}
if((fg==bfg)&&(sg==bsg)&&(bell==1))
BUZ=0;
else BUZ=1;
}
while(mod==1)
{ EX1=0; //关闭外部中断1
zero();
fangsong();
if(K3==0)
{ delay(1000);
if(K3==0)
fg++;
}
if(K4==0)
{ delay(1000);
if(K4==0)
sg++;
}
if(K2==0)
{ delay(1000);
if(K2==0) s=0; }
if(fg>59)
{ fg=0; }
if(sg>23)
{ sg=0; }
if(s>=59)
{ s=0; }
}
while(mod==2) //设置闹钟
{
if(bfg==60)
{ bsg++;
bsg=0;
}
if(bsg==24)
{ bsg=0; }
zero();
wrd(0x20);
wrd(0x20);
wrd(0x20);
wrd(dat1[(bsg/10)]); //时十位
wrd(dat1[(bsg%10)]); //时个位
wrd(0x3A); //:
wrd(dat1[(bfg/10)]); //分十位
wrd(dat1[(bfg%10)]); //分个位
if(K3==0)
{ delay(1000);
if(K3==0) bfg++;
}
if(K4==0)
{ delay(1000);
if(K4==0) bsg++;
} bell=1;
zero();
}
while(mod==3)
{ while(zanting)
{ dingshi=60;
EX1=1; //打开外部中断1
wrm(0X80);
wrd(dat1[(dingshi/10)]); //时十位
wrd(dat1[(dingshi%10)]); //时个位 }
wrm(0X80);
wrd(dat1[(dingshi/10)]); //时十位
wrd(dat1[(dingshi%10)]); //时个位
while(dingshi<0)
{ wrm(0X80);
wrd(dat1[0]); //时十位
wrd(dat1[0]); //时个位 BUZ=0;
}
}
}
}
void time0() interrupt 1
{ TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
i++;
if(i==1000) //ms转化为s
{
i=0;
s++;
dingshi--; }
}
void key1() interrupt 0 //外部中断0,调整时间
{ delay(1000);
if(K1==0)
{ mod++;
while(!K1);
}
if(mod>3)
{
mod=0;
}
zero();
}
void naozhong() interrupt 2 //开关闹钟
{ if(K2==0) { delay(1000); //消抖
if(K2==0)
{
bell=0;
BUZ=1;
zanting=~zanting; } //关闭蜂鸣器
while(!K2); //确认按键松开 } }
二、收获
1.更熟练掌握了定时器中断和外部中断的使用
可以通过打开和关闭外部中断使同一个按键实现不同的功能 2.了解到了一点寄存器操作
3.中断配置小结
外部中断
定时器中断
串口通信
4.更熟练使用proteus
制作了一个小型软件开发版
5.学会了如何学习一个新元器件(LCD1602)
1.看说明书,重点是看时序图,真值表等
2.按照时序图写程序
3.一二都不成立时,查找相关资料
6.下载原理
单片机的烧写原理:
单片机烧写,又称为单片机程序下载、烧录等,本质上是单片机和PC机按照芯片厂家规定的编程协议,通过芯片厂家规定的接口,把已编译好的程序传输到单片机,单片机把数据存储到自身存储器中。
理解这个原理需要知道几个知识点:
单片机内部是有程序的,是出厂时固化在硬件中,用户无法修改的(这也会被认为它内部没有程序),这些程序可以调用各种通信接口、内部存储器等;
可以下载的通信接口:JTAG,SPI,UART,usb等;(还有很多可以扩展485、以太网等)
编程协议:一般大厂都会公开的,在芯片的专用技术手册中会有;
存储器:有很多种,掩膜,EPROM,EEROM,flash等寿命不一样,掩膜只能一次,而且要工厂做,flash擦写次数10000+;
可以这样比喻性的理解:单片机就是电脑的主板,我们写的程序就是操作系统,主板里面装入引导操作系统的基本程序,下载程序就是给电脑装系统! 7.其他
1.理解了现在电子表的操作原理
2.学会了借助现成品(电子表)作参考,写程序
3.懂得了与人交流的重要性(受王同学的启发,完善了原有程序)
三.后期计划
1、继续32的学习
2、练习焊功
3、继续51其他外设的学习
4、按兴趣学习电路、模电、数电、DXP等相关知识