8051写一个考研/雅思用的小计时器
想法来由:
做题时缺个定时器
用手机定时?不想在做题时用手机。
某宝上买个定时器?
如图
9.9包邮?还是算了,没小钱钱
正好有块好久不用的8051,别积灰了,利用起来
显示屏是LCD1602,想利用oled的同学们可以自行更改代码
(啥?为啥不用32?为什么不用oled,串口屏?因为那些我还得频繁使用…这个51正好当桌上计时器)
上代码:
main函数
void main()
{
Init_Timer0(); //初始化timer
InitLcd1602(); //初始化lcd1602
boot_Screen(); //初始化开机显示
while(1){
KeyDriver(); //按键检测
if(staSystem == E_Timing)
{
Show_Countdown();
//定时时间到
if(display[4] == flag_over||(display[4]== flag_over%16 && display[5]== flag_over/16) )
{
Timing_end();
beep();
}
}
delay1(50);
}
}
display.c
#include "display.h"
#include "config.h"
#include "LCD1602.h"
extern uchar display[];
extern uchar display2[];
void boot_Screen() //初始化开机界面
{
unsigned char *p = "Uncompromising"; //毫不妥协
unsigned char *o = " by Leon";
InitLcd1602(); //1602初始化
LcdShowStr(0,0,p);
LcdShowStr(0,1,o);
}
/*
function: 名称为显示倒计时,由于倒计时有较大延时,所以函数内仍然是正计时
*/
void Show_Countdown()
{
uchar i;
for(i=0;i<6;i++)
{
display2[i]=display[i]+0x30;
}
//此处减一只是为了使右边3位空出来,当然觉得不美观可以用清屏函数解决
LCD1602_Dis_OneChar(13-1,1,display2[0]);
LCD1602_Dis_OneChar(12-1,1,display2[1]);
LCD1602_Dis_OneChar(11-1,1,':');
LCD1602_Dis_OneChar(10-1,1,display2[2]);
LCD1602_Dis_OneChar(9-1,1, display2[3]);
LCD1602_Dis_OneChar(8-1,1,':');
LCD1602_Dis_OneChar(7-1,1,display2[4]);
LCD1602_Dis_OneChar(6-1,1,display2[5]);
LCD1602_Dis_OneChar(5-1,1,':');
DisplayOneStr(3-1,1,display[6]);
}
/*
function: 显示选择时间界面
*/
void Show_interface(uint x)
{
uchar code cdis1[ ] = {" 3min "};
uchar code cdis2[ ] = {" 7min "};
uchar code cdis3[ ] = {" 10min "};
uchar code cdis4[ ] = {" 15min "};
uchar code cdis5[ ] = {" 20min "};
uchar code cdis6[ ] = {" 40min "};
uchar code cdis7[ ] = {"Yes"}; //指示
/*接下来该写页面滚动展示7min,10min等等 想办法与按键结合上 */
LcdShowStr(13,0,cdis7);
switch (x){
case 1: LcdShowStr(0,0,cdis1);LcdShowStr(0,1,cdis2);break;
case 2: LcdShowStr(0,0,cdis2);LcdShowStr(0,1,cdis3);break;
case 3: LcdShowStr(0,0,cdis3);LcdShowStr(0,1,cdis4);break;
case 4: LcdShowStr(0,0,cdis4);LcdShowStr(0,1,cdis5);break;
case 5: LcdShowStr(0,0,cdis5);LcdShowStr(0,1,cdis6);break;
case 6: LcdShowStr(0,0,cdis6);LcdShowStr(0,1,cdis1);break;
}
}
/*
function: 计时中止显示END
*/
void Timing_end()
{
uchar code t [ ] = {"*******END*******"};
LcdShowStr(0,0,t);
}
app.c 这个文件是设置按键功能的文件
#include "config.h"
#include "Lcd1602.h"
#include "Key.h"
#include "main.h"
#include "app.h"
#include "display.h"
extern uchar display[]; //为了能在启动计时时将定时器从零开始计时
static uint cnt=0; //如果只有roll_up可以定义在函数内,但是roll_down需要共用此变量
void begin_end()
{ uint z;
static uint k=0; //为了能中止计时,若无此静态变量,则无法开始(begin)计时
if (staSystem == E_SET_TIME || staSystem == E_T_END) // 状态变量,此时为begin
{
Init_Timer0(); //开始计时
for(z=0;z<7;z++) display[z]=0; //全部回零开始计数 ,在测试时这里别忘了注释掉,测试成功
staSystem = E_Timing; //改变变量为计时状态
}
if(staSystem == E_Timing && k%2==1) //如果为计时状态,需要计时中止
{
staSystem = E_T_END; //换状态,配合main函数可以使显示卡在按按钮时的时间
}
k++ ;
KEY_S2_ON=1;
}
/*
function:屏幕上滚函数
将Show_interface(cnt)函数和Set_Time(uint t)嵌入,其根本目的是分离显示函数的定义位置
以及简化每个函数的代码行数,这样简洁易读,便于维护
*/
void Roll_up()
{
if (staSystem == E_SET_TIME)
{
Show_interface(1); //初始化
cnt++; //cnt++的位置需要注意
if(cnt==7) cnt=0;
switch (cnt){
case 1: Show_interface(cnt); Set_Time(0x03);break;
case 2: Show_interface(cnt); Set_Time(0x07);break;
case 3: Show_interface(cnt); Set_Time(0x10);break;
case 4: Show_interface(cnt); Set_Time(0x15);break;
case 5: Show_interface(cnt); Set_Time(0x20);break;
case 6: Show_interface(cnt); Set_Time(0x40);break;
}
}
KEY_S3_ON=1;
}
/*
function:屏幕下滚函数
*/
void Roll_down()
{
if (staSystem == E_SET_TIME)
{
cnt--;
if(cnt==0) cnt=5;
switch (cnt){
case 1: Show_interface(cnt); Set_Time(0x03);break;
case 2: Show_interface(cnt); Set_Time(0x07);break;
case 3: Show_interface(cnt); Set_Time(0x10);break;
case 4: Show_interface(cnt); Set_Time(0x15);break;
case 5: Show_interface(cnt); Set_Time(0x20);break;
case 6: Show_interface(cnt); Set_Time(0x40);break;
}
}
KEY_S4_ON=1;
}
/*
function:返回函数
注意:只有当计时中止(即s2被再次按下后)此按键才能生效
*/
void Back()
{
if (staSystem == E_T_END)
staSystem = E_SET_TIME;
Roll_up(); //为了回到显示界面
KEY_S5_ON=1;
}
/************按键系统**************/
void KeyDriver(){
if(KEY_S2_ON==0){ //确定/计时开始/中止
begin_end();
}
else if(KEY_S3_ON==0){ //上滚
Roll_up();
}
else if(KEY_S4_ON==0){ //下滚
Roll_down();
}
else if(KEY_S5_ON==0){ // back
Back();
}
}
我感觉大家也不喜欢看一片一片的代码,我把代码上传到GitHub上了,大家直接下载即可。
https://github.com/integratedcircuit/8051-
附效果图
后记:去年2月份疫情在家做了带设置闹钟和测量环境温度的万年历(51和32版本都有,32采用的是oled),以后有时间再写博客吧。没想到这么快一年过去了,感觉都没做什么哈哈。
时不我待,加油