51单片机基础难点知识理解后,直接通过下面3个小项目可以更好理解51单片机。中断 定时器 串口甚至是基础的IO输入输出都有结合,再加上一些外设模块的学习(如1602显示屏,L298N电机驱动等) 项目一:秒表设计 项目二:LCD1602显示器显示 项目三:循迹+蓝牙小车
题目要求
设计一个秒表,具有清理 暂停/启动功能 1.显示格式 分 - 秒 - 毫秒(精确到50ms) 例如:08 - 26 - 18 表示 8分26秒900毫秒 2.按键要求 s1 启动/暂停 s2 清零
原理分析
知识点
①数码管显示数字:51单片机基本IO的输入与输出 ②秒表功能的实现: 51单片机定时器功能 ③按键要求 : 51单片机的按键访问或者外部中断的应用 ④动态数码管显示: 74HC138芯片的应用+视觉暂留效应
硬件原理图:
采用普中A2开发板 如图所示,开发板的数码管模块由74HC138芯片驱动,通过控制138芯片的ABC三个输入端来控制对应数码管(3-8段译码器)
独立按键模块 简单来看,就是开发板上四个按键一端接GND 一端接上51单片机的四个IO口,默认情况为高电平
代码实现
代码的封装 1.解决数码管显示: 定义好相关变量已经存放数码管段码的数组 2.解决定时器部分:定时器初始化 定时器中断服务函数 3.解决数码管动态显示 : 74HC138的动态显示 4.按键功能 5.主函数不断的调用各部分函数
#include "reg52.h"
sbit s1 = P3^1;
sbit s2 = P3^0;
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
sbit led1 = P2^0;
typedef unsigned int u16;
u16 hour=0;
u16 minute=0;
u16 second=0;
u16 msecond = 0;
u16 stat;
int code smg_duan [] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int xsq[8] = {0};
void Delay(u16 time)
{
while(time--);
}
void Init_All()
{
TMOD &= 0xf0;
TMOD |= 0x01;
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void timer0_ser () interrupt 1
{
TH0 = (65536-50000)/256;
TL0 = (65536-50000)%256;
msecond++;
if(msecond==20)
{
msecond=0;
led1 = ~led1;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==60)
hour=0;
}
}
}
}
void PrintShuMa ()
{
u16 i;
for(i=0;i<8;i++){
switch(i)
{
case (0):
LSA=0,LSB=0,LSC=0;
break;
case (1):
LSA=1,LSB=0,LSC=0;
break;
case (2):
LSA=0,LSB=1,LSC=0;
break;
case (3):
LSA=1,LSB=1,LSC=0;
break;
case (4):
LSA=0,LSB=0,LSC=1;
break;
case (5):
LSA=1,LSB=0,LSC=1;
break;
case (6):
LSA=0,LSB=1,LSC=1;
break;
case (7):
LSA=1,LSB=1,LSC=1;
break;
}
P0 = xsq [i];
Delay(200);
P0=0x00;
}
}
void key()
{
if(s1 == 0)
{
Delay(200);
if(s1 == 0)
{
TR0 = ~TR0;
}
while(!s1);
}
if(s2 == 0)
{
Delay(200);
if(s2 == 0)
{
led1 = ~led1;
hour = 0;
minute = 0;
second = 0;
msecond = 0;
}
while(!s2);
}
}
void display()
{
xsq[7]=smg_duan[hour/10];
xsq[6]=smg_duan[hour%10];
xsq[5]=0x40;
xsq[4]=smg_duan[minute/10];
xsq[3]=smg_duan[minute%10];
xsq[2]=0x40;
xsq[1]=smg_duan[second/10];
xsq[0]=smg_duan[second%10];
}
int main()
{
Init_All();
while(1)
{
PrintShuMa();
key();
display();
}
}
还可以往以下方面拓展: 1.把按键访问改成用外部中断的模式,如果外部中断IO口(就两个)不够,还可以外加芯片来拓展中断IO口 2.可以加上按键按其它的实现加减功能,拓展成矩阵按键实现更多功能,如设定指定时间报警等 3.51单片机的定时器还可以实现测频率的功能(但不是很准)
总结
这个小实验不是很难而且还可以帮助很好的理解定时器,定时器中断的概念以及使用数码管的显示原理,74HC138芯片的应用 结合原理图独立把代码敲出来,换个定时器,改变定时器参数,定时器还可以往不同方向拓展,基本上从IO到定时器都没问题了
|