今天先写一个不能调时间的电子闹钟~
使用模块:数码管、独立按键、两个四位LED,串口
要求如下:
1.数码管显示:
时间显示当前时间hh-mm-ss,闹钟设置界面hh-mm-ss
2.独立按键:
1 号键,模式循环切换。在闹钟设置界面下:2号键短按hh,mm,ss切换,2号键长按(超过1s),存储闹钟时间并开启闹钟。3号键,当前选中数据累加1,有界限回滚。4键,数据递减1,有界限回滚。
3. LED
开启闹钟后LED1以0.5s闪烁。
闹钟时间到,LED1以0.2s间隔闪烁,按下任意键关闭闪烁。设置hh时,LED6以0.5s闪烁,设置mm时,LED7以0.5s闪烁,设置ss时,LED8以0.5s闪烁。
4.串口:
闹钟时间到,单片机通过串口以1s间隔,向上位机发送时间到提示,格式为“TIME IS UP!rn”,按下任意键(2,3,4)停止发送
5.系统上电:
时钟时间为:11-59-50,闹钟默认关LED全灭。
6. 总体要求:
按键灵敏,做好消抖处理,数码管显示正常 无残影,LED亮灭正常,
无干扰,在任意界面,时钟走时准确,无暂停
引用上一节用过的动态数码管代码
#include#include "Delay.h" //调用延时函数 //数码管x显示 char NixieTable[15] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x40}; //number 0 1 2 3 4 5 6 7 8 9 - void Nixie(int location, number) { //(位置,数字) switch (location) { //选中LED位置 case 0:P2_4 = 1;P2_3 = 1;P2_2 = 1;break; case 1:P2_4 = 1;P2_3 = 1;P2_2 = 0;break; case 2:P2_4 = 1;P2_3 = 0;P2_2 = 1;break; case 3:P2_4 = 1;P2_3 = 0;P2_2 = 0;break; case 4:P2_4 = 0;P2_3 = 1;P2_2 = 1;break; case 5:P2_4 = 0;P2_3 = 1;P2_2 = 0;break; case 6:P2_4 = 0;P2_3 = 0;P2_2 = 1;break; case 7:P2_4 = 0;P2_3 = 0;P2_2 = 0;break; } P0 = NixieTable[number]; //数字 Delay(1); P0 = 0x00; //消影清零 }
时钟显示思路:
创建三个变量,分别表示时分秒,然后再创建一个数组,把时分秒数位分离,存放到这个数组里,方便显示两位的时分秒。
unsigned char Sec=55,Min=59,Hour=11;//定义时间变量及初始化(时分秒)
unsigned char Time_Show[10];
void NixieShow(void)//计算与显示时间
{
//计算时间
Time_Show[0]=Hour/10;
Time_Show[1]=Hour%10;
Time_Show[3]=Min /10;
Time_Show[4]=Min %10;
Time_Show[6]=Sec /10;
Time_Show[7]=Sec %10;
if(Sec >= 60) //越界判断
{
Sec = 0;Min++;
if(Min >= 60)
{
Min = 0;Hour++;
if(Hour >= 24)
{Hour = 0;}
}
}
Nixie(0,Time_Show[0]);
Nixie(1,Time_Show[1]);
Nixie(2,10);//显示-
Nixie(3,Time_Show[3]);
Nixie(4,Time_Show[4]);
Nixie(5,10);//显示-
Nixie(6,Time_Show[6]);
Nixie(7,Time_Show[7]);
}
然后在定时器里设置变量Sec每秒自加1,这样就写完了一个简单的不可调时钟。
现在写一下模式切换和设置闹钟
unsigned char Key_Value;//按键
unsigned char Sec=55,Min=59,Hour=11;//定义时间变量及初始化(时分秒)
char C_Sec=5,C_Min,C_Hour=12;//定义闹钟变量(时分秒)//char类型便于越界判断
unsigned char Time_Show[10],Clock_SetShow[10];
unsigned char SET_Mode = 0;//按键1的模式切换
unsigned char TimeSetSelect = 0;
unsigned char flash_Location;//LED闪烁的位置,调整时间设置
unsigned int LED1,LED6,LED7,LED8;//int类型,之前越界了
unsigned char T_equal=0;
unsigned char C_SetFinish;//闹钟设定好的标志位
下面代码是闹钟的数位分离及其显示
void ClockShowNUM(void)
{
//闹钟设置时间显示
Clock_SetShow[0]=C_Hour/10;
Clock_SetShow[1]=C_Hour%10;
Clock_SetShow[3]=C_Min /10;
Clock_SetShow[4]=C_Min %10;
Clock_SetShow[6]=C_Sec /10;
Clock_SetShow[7]=C_Sec %10;
Nixie(0,Clock_SetShow[0]);
Nixie(1,Clock_SetShow[1]);
Nixie(2,10);//显示-
Nixie(3,Clock_SetShow[3]);
Nixie(4,Clock_SetShow[4]);
Nixie(5,10);//显示-
Nixie(6,Clock_SetShow[6]);
Nixie(7,Clock_SetShow[7]);
}
串口部分
void SendString(unsigned char *p)
{ //发送一个字符串
while(*p != ' '){UART_SendByte(*p++);}
}
配置一下闹钟,操作LED,及其模式转换,越界判断
void Clock_Set(void)
{
if(Key_Value == 1) {SET_Mode=1;}//设置
if(Key_Value == 22)//长按,闹钟设置成功
{
SET_Mode=0;
P2_5=1;//控制后边三个灯不亮
P2_6=1;
P2_7=1;
C_SetFinish=1;//闹钟设定好的标志位
}
if(SET_Mode == 0)
{
NixieShow();//正常时钟显示
if((Sec==C_Sec) && (Min==C_Min) && (Hour==C_Hour))//闹钟时间到
{
T_equal=1;
}
//串口发送数据
if(T_equal==1)
{
SendString("TIME IS UP!rn");
Delay(1000);
if(LED1>=200){
P2_0=~P2_0;
LED1=0;
}
if(Key_Value==1 || Key_Value==2 || Key_Value==3 || Key_Value==4)
//按任意键取消
{
T_equal=0;
P2_0=1;
// RI=0;
}
}
}
if(SET_Mode == 1) //进入设置界面
{
FLASH_Select(); //设置闹钟 闪烁提示灯
ClockShowNUM();
if(Key_Value == 2)//时分秒设置切换
{
TimeSetSelect++;
if(TimeSetSelect>2){
TimeSetSelect = 0;
}
}
if(TimeSetSelect == 0)//调小时 Hour
{
flash_Location=6;
P2_6=1;P2_7=1;//另外两个灯灭
if(Key_Value == 3){C_Hour += 1;}
if(Key_Value == 4){C_Hour -= 1;}
if(C_Hour >= 24){C_Hour = 0;}
if(C_Hour < 0) {C_Hour = 23;}
}
if(TimeSetSelect == 1)//调分钟 Min
{
flash_Location=7;
P2_5=1;P2_7=1;//另外两个灯灭
if(Key_Value == 3){C_Min += 1;}
if(Key_Value == 4){C_Min -= 1;}
if(C_Min >= 60)
{
C_Min = 0;C_Hour++;
if(C_Hour >= 24)
{C_Hour = 0;}
}
if(C_Min < 0)
{
C_Min = 59;C_Hour--;
if(C_Hour < 0)
{C_Hour = 23;}
}
}
if(TimeSetSelect == 2)//调秒钟 Sec
{
flash_Location=8;
P2_5=1;P2_6=1;//另外两个灯灭
if(Key_Value == 3){C_Sec += 1;}
if(Key_Value == 4){C_Sec -= 1;}
if(C_Sec >= 60)
{
C_Sec = 0;C_Min++;
if(C_Min >= 60)
{
C_Min = 0;C_Hour++;
if(C_Hour >= 24)
{C_Hour = 0;}
}
}
if(C_Sec < 0)
{
C_Sec = 59;C_Min--;
if(C_Min < 0)
{
C_Min = 59;C_Hour--;
if(C_Hour < 0)
{C_Hour = 23;}
}
}
}
ClockShowNUM();//刷新显示
}
}
LED闪烁选择代码
void FLASH_Select(void)
{
if(LED1>=500){
P2_0=~P2_0;
LED1=0;
}
if(flash_Location==6){if(LED6>=500){P2_5=~P2_5;LED6=0;}}
if(flash_Location==7){if(LED7>=500){P2_6=~P2_6;LED7=0;}}
if(flash_Location==8){if(LED8>=500){P2_7=~P2_7;LED8=0;}}
}
定时器0
void Timer0_Routine() interrupt 1 //定时器0的中断函数
{ //1ms
static unsigned int T0Count,anjian;
TL0 = 0x66;
TH0 = 0xFC;
T0Count++;anjian++;
if(anjian>=10){KeyScan();anjian = 0;}//按键检测
if(T0Count>=1000){Sec++;T0Count=0;} //秒钟计数加一
if(SET_Mode==0 && C_SetFinish==1){//时间未到
LED1++;// 闹钟时间到0.2s间隔闪烁
if(LED1>=500)
{
P2_0=~P2_0;
LED1=0;
}
}
else if(SET_Mode==0 && T_equal==1){//时间到时候
LED1++;// 闹钟时间到0.2s间隔闪烁
if(LED1>=200)
{
P2_0=~P2_0;
LED1=0;
}
}
if(flash_Location==6){ LED6++;}
if(flash_Location==7){ LED7++;}
if(flash_Location==8){ LED8++;}
}
最后写一下主函数
void main()
{
Timer0_Init();
Timer1_Init();
UART_Init();//串口初始化
P2=0xFF; //上电全灭
while(1)
{
Key_Value = GetKey_Num(); //获取键码值
Clock_Set(); //闹钟设置
}
}
最初的头文件部分
#include#include #include "Timer0.h" #include "Timer1.h" #include "Delay.h" #include "Nixie.h" #include "KeyTimer0.h" #include "UART.h"
整个工程上传到资源里了,大家可以自行下载~
欢迎大佬指正!



