电子闹钟

功能要求:

1、  实时时钟(由数码管显示时:分,中间的“:”一亮一灭表示1秒,可用小数点表示,也可以用一个LED表示);

2、  时钟的时、分可调节;

3、  闹钟时间可以设置,闹钟初值为8:00,(并保存在EEPROM中,掉电不丢失);

4、  闹钟时间到,蜂鸣器响10秒;

5、  按键使用数量不宜超过5个;

6、  整点时间,通过串行口上传一次时钟信息;

7、  自行补充新功能(选做项);

单片机型号:atmega16

流程图

proteus模拟电路图:

代码(适用于atmega16实物,如需用以上电路图模拟还需修改IO口配置)

#include <iom16v.h>
#include <macros.h>unsigned char led_buf[] = { 0x3F, 0x06, 0x5B, 0x4F,0x66, 0x6D, 0x7D, 0x07,0x7F, 0x6F };  //共阴极数码管编码表,分别表示0~f;
unsigned char position[6] = { 0xfe, 0xfd, 0xef, 0xdf, 0xbf, 0x7f }; // 位选码
unsigned char show[] = "NOW IS : ";
unsigned char transmit_time[10] = "0123456789";
unsigned char maohao = ':', temp[6];
unsigned char time[3], time_set[3], YuSheTime[3] = { 0, 0, 8 }; //时、分、秒计数和设置单元及定时时间8:00,确保掉电不清除
unsigned char dis_buf[10]; //显示缓冲区,存放要显示的10个字符的段码值
unsigned char  timecounterofkeys, timecounter;
unsigned char clock_state = 2, set_state, return_time;
int time_add, point, set_on, time_1second, key_stime_ok;#define key_input PINB //按键输入口
#define key_mask 0B00001111 //按键输入屏蔽码
#define key_no 0
#define key_s1 1 //s1按键
#define key_s2 2 //s2按键
#define key_s3 3 //s3按键
#define key_s4 4 //s4按键
#define key_state_0 0 //按键状态0 1 2
#define key_state_1 1
#define key_state_2 2void io_init(void);//I/O口初始化函数//
void T0_init(void);//T/C0初始化函数///
void usart_init(unsigned int baud);//usart初始化//
void usart_transmit_byte(unsigned char data);//发送一个字符//
void usart_transmit_string(unsigned char* buf);//发送一个字符串//
unsigned char usart_recieve_byte(void);//接收一个字符//
void time_to_disbuffer(unsigned char* time);//时钟时间送显示缓冲区函数//
void display(void);//时钟时间送显示缓冲区函数//
void timer0_comp_isr(void);//显示输出函数///
unsigned char read_key(void);//读取按键函数//
void time_dealer(void);//时间处理函数//
void zhengdianhanshu(void);//整点时间函数//
void main(void);//主函数//I/O口初始化函数//
void io_init(void)
{DDRC = 0xFF; //LED段码输出DDRD = 0xfe;  //LED位控输出(1111 1110)PORTD = 0xFF; //输出高电平DDRB = 0xe0; //按钮输入口(1110 0000)PORTB = 0xFF;DDRA = 0xff;  //输出口PORTA = 0xff; //输出高电平
}///T/C0初始化函数///
void T0_init(void)
{OCR0 = 0xF9;  //OCR0 = 0xF9(249),(249+1)/125=2msTCCR0 = 0x0B; //内部时钟,CTC模式,64分频,8M/64=125KHz
}usart初始化//
void usart_init(unsigned int baud)
{UBRRH = (unsigned char)(baud >> 8);UBRRL = (unsigned char)baud;         // 波特率:4800,时钟频率:8MHz (0110 0111)UCSRA = 0x20;UCSRB = (1 << TXEN) | (1 << RXEN);   //发送使能|接收时能(0001 1000)UCSRC = (1 << URSEL) | (3 << UCSZ0); //异步模式,帧格式:1个起始位,8个数据位,无校验,1个停止位;
}
发送一个字符//
void usart_transmit_byte(unsigned char data)
{while (!(UCSRA & (1 << UDRE))){;}UDR = data;
}
计时器Timer0:比较匹配中断服务,定时:2ms
#pragma interrupt_handler timer0_comp_isr: iv_TIMER0_COMP //计时器Timer0:比较匹配输出
void timer0_comp_isr(void)
{display();if (++timecounterofkeys >= 5){timecounterofkeys = 0;key_stime_ok = 1;  //10ms时,给key_stime_ok赋值为1if (!(++timecounter % 25)){set_on = !set_on;}if (timecounter >= 100) //判断是否达到一秒{timecounter = 0;time_1second = 1;}}
}
发送一个字符串//
void usart_transmit_string(unsigned char* databuf)
{while (*databuf != '\0'){usart_transmit_byte(*databuf++);}
}接收一个字符//
unsigned char usart_recieve_byte(void)
{// 等待接收数据while (!(UCSRA & (1 << RXC)));// 从缓冲器中获取并返回数据return UDR;
}时钟时间送显示缓冲区函数//
void time_to_disbuffer(unsigned char* time)
{unsigned char i, j = 0;for (i = 0; i <= 2; i++){dis_buf[j++] = time[i] % 10;dis_buf[j++] = time[i] / 10;}
}///显示输出函数///
void display(void)
{static unsigned char posit = 2; //从分钟开始显示PORTD = 0xFF; //!输出高电平PORTC = led_buf[dis_buf[posit]]; //缓存段码if (set_on && (posit == clock_state)) //被调位闪烁{PORTC = 0x00;}if (point && posit == 4) //控制第四位小数点闪烁{PORTC |= 0x80;}PORTD = position[posit]; //控制输出的位if (++posit >= 6){posit = 2;          //从分钟开始显示}
}读取按键函数//
unsigned char read_key(void)
{static unsigned char key_state = 0, key_press;unsigned char key_return = key_no; //相当于key_return =0;key_press = key_input & key_mask; //读取按键I/O电平switch (key_state){case key_state_0: //按键初始态if (key_press != key_mask){key_state = key_state_1;}break; //键被按下,状态转换到键确认态case key_state_1: //按键确认态if (key_press == (key_input & key_mask)){if (key_press == 0b00001110){key_return = key_s1;}else if (key_press == 0b00001101){key_return = key_s2;}else if (key_press == 0b00001011){key_return = key_s3;}else if (key_press == 0b00000111){key_return = key_s4;}key_state = key_state_2; // 状态转换到键释放态}else{key_state = key_state_0; // 按键已抬起,转换到按键初始态}break;case key_state_2:if (key_press == key_mask){key_state = key_state_0;}break; //按键已释放,转换到按键初始态}return key_return;
}
//时间处理函数//
void time_dealer(void)
{while (1){if (++time[0] >= 60)      // 秒加1{time[0] = 0;          //秒超过60,秒数清0if (++time[1] >= 60){time[1] = 0;         //分数超过60,分清0if (++time[2] >= 24){time[2] = 0;     //时超过24,时清0}}}}
} //整点时间函数//
void zhengdianhanshu(void)//整点时间,通过串行口上传一次时钟信息/
{if ((time[1] == 0) && (time[0] == 0)) //分秒同时为零,表示整点,向串口上传一次时间{temp[5] = time[2] % 10;temp[4] = (unsigned char)time[2] / 10;temp[3] = time[1] % 10;temp[2] = (unsigned char)time[1] / 10;temp[1] = time[0] % 10;temp[0] = (unsigned char)time[0] / 10;usart_transmit_string(show);usart_transmit_byte(transmit_time[temp[4]]);usart_transmit_byte(transmit_time[temp[5]]);usart_transmit_byte(maohao);usart_transmit_byte(transmit_time[temp[2]]);usart_transmit_byte(transmit_time[temp[3]]);usart_transmit_byte(maohao);usart_transmit_byte(transmit_time[temp[0]]);usart_transmit_byte(transmit_time[temp[1]]);usart_transmit_string("\r\n");}
}
主函数//
void main(void)
{unsigned char key_temp, i;//初始化T0_init(); //T/C0初始化io_init(); //I/O口初始化usart_init(103); //usart初始化,波特率设置为4800;//设时间初值07:59:00time[2] = 7;time[1] = 59;time[0] = 0;TIMSK = 0x12; //允许T/C1比较匹配A中断,允许T/C0比较匹配中断,开放全局中断SEI();while (1){if (time_1second) //1秒到{time_1second = 0;point = ~point; //闪烁标志,一秒亮,一秒灭//     time_dealer();if (++time[0] >= 60) //! 秒加1,{time[0] = 0;         //!秒数超过60,秒数清0if (++time[1] >= 60) //!分加1{time[1] = 0;         //!分数超过60,分数清0if (++time[2] >= 24) //!时加1{time[2] = 0; //!时数超过24,时数清0}}}//最初十秒不操作就进入初始设置时间if ((++return_time >= 10) && (clock_state != 6)){clock_state = 6;}if (clock_state == 6){time_to_disbuffer(time);}zhengdianhanshu();/*整点时间,通过串行口上传一次时钟信息*/
/*            if ((time[1] == 0) && (time[0] == 0)) //!分钟,秒钟为零,表示整点,就上传一次时间{temp[5] = time[2] % 10;temp[4] = (unsigned char)time[2] / 10;temp[3] = time[1] % 10;temp[2] = (unsigned char)time[1] / 10;temp[1] = time[0] % 10;temp[0] = (unsigned char)time[0] / 10;usart_transmit_string(show);usart_transmit_byte(transmit_time[temp[4]]);usart_transmit_byte(transmit_time[temp[5]]);usart_transmit_byte(maohao);usart_transmit_byte(transmit_time[temp[2]]);usart_transmit_byte(transmit_time[temp[3]]);usart_transmit_byte(maohao);usart_transmit_byte(transmit_time[temp[0]]);usart_transmit_byte(transmit_time[temp[1]]);usart_transmit_string("\r\n");}
*//*设定闹钟时间到,蜂鸣器响10秒*/if ((time[2] == YuSheTime[2]) && (time[1] == YuSheTime[1]) && (time[0] == YuSheTime[0])){PORTA = 0x7f; //(0111 1111),低电平蜂鸣器响}if ((time[2] == YuSheTime[2]) && (time[1] == YuSheTime[1]) && (time[0] == YuSheTime[0] + 10)){PORTA = 0xff; //(1111 1111),高电平蜂鸣器关}}if (key_stime_ok) //10ms到,键处理{key_stime_ok = 0;key_temp = read_key(); //调用按键接口程序if (key_temp) //确认有按键按下{return_time = 0;        //置零时间,直至等待十秒不操作if (key_temp == key_s1) // s1键按下,设定时钟时间功能{if (++clock_state >= 7){clock_state = 2;}if (clock_state == 2){for (i = 0; i <= 2; i++){time_set[i] = 0;}time_to_disbuffer(time_set);}if (clock_state == 6){for (i = 0; i <= 2; i++){time[i] = time_set[i];}time_to_disbuffer(time);}}if (key_temp == key_s2)   //s2键按下,设定闹钟时间功能{if (++clock_state >= 7){clock_state = 2;}if (clock_state == 2)   //不按按钮,设定闹钟初始值为08:00{time_to_disbuffer(YuSheTime);}if (clock_state == 6){for (i = 0; i <= 2; i++){YuSheTime[i] = time_set[i];}time_to_disbuffer(YuSheTime);}}if ((clock_state != 6) && (key_temp == key_s3))  //每按一下s3,被调试位数值加一{if (clock_state % 2){time_set[clock_state / 2] += 10;}else{if ((time_set[clock_state / 2] % 10) == 9){time_set[clock_state / 2] -= 9;}else{time_set[clock_state / 2] += 1;}}if (time_set[0] >= 60){time_set[0] -= 60;}if (time_set[1] >= 60){time_set[1] -= 60;}if (time_set[2] >= 24){time_set[2] -= 10;}time_to_disbuffer(time_set);  //设置时间送入显示缓存}if (key_temp == key_s4)   //s4按下,向串口传输当前时间{temp[5] = time[2] % 10;temp[4] = (unsigned char)time[2] / 10;temp[3] = time[1] % 10;temp[2] = (unsigned char)time[1] / 10;temp[1] = time[0] % 10;temp[0] = (unsigned char)time[0] / 10;usart_transmit_string(show);usart_transmit_byte(transmit_time[temp[4]]);usart_transmit_byte(transmit_time[temp[5]]);usart_transmit_byte(maohao);usart_transmit_byte(transmit_time[temp[2]]);usart_transmit_byte(transmit_time[temp[3]]);usart_transmit_byte(maohao);usart_transmit_byte(transmit_time[temp[0]]);usart_transmit_byte(transmit_time[temp[1]]);usart_transmit_string("\r\n");}}}}
}

电子闹钟(atmega16)相关推荐

  1. 用单片机用c语言做闹钟,基于单片机与ds1302时钟芯片的电子闹钟C程序

    原标题:基于单片机与ds1302时钟芯片的电子闹钟C程序 #include #define w_second 0x80 //秒写入地址 #define w_minute 0x82 //分写入地址 #d ...

  2. 36、基于STM32的电子闹钟(DS1302)

    编号:36 基于STM32的电子闹钟(DS1302) 功能描述: 本设计由STM32单片机+液晶1602+按键+DS1302时钟模块+声光报警模组成. 1.采用STM32F103最小系统. 2.利用D ...

  3. 基于51单片机、DS1302时钟模块的电子闹钟设计

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.设计原理 1.DS1302介绍 2.闹钟音乐播放原理 二.程序设计 1.DS1302.h 2.ds1302.c 3.mu ...

  4. 用51单片机和LCD显示模块自制电子闹钟

    本文主要简单讲解利用51单片机.LCD显示模块等硬件搭建一个可以计时.显示日期的小的电子DIY作品. 硬件资源: 51单片机1个.LCD显示1个.按键2个.蜂鸣器1个.8050三极管2个等. 一.硬件 ...

  5. 基于AT89C51单片机的电子闹钟设计与仿真

    点击链接获取Keil源码与Project Backups仿真图: https://download.csdn.net/download/qq_64505944/87761718?spm=1001.20 ...

  6. 9.3 Qt实现电子闹钟

    电子闹钟 显示当前系统时间,设置定时闹钟,闹钟响进行语音播报自定义信息 代码示例 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget&g ...

  7. android闹钟设计的开题报告,电子闹钟设计开题报告.doc

    电子闹钟设计开题报告.doc 宁波职业技术学院电子信息工程系 本科生毕业论文(设计)开题报告设计题目音乐电子闹钟的设计学生姓名王娟专业计算机应用指导教师孟德新选题目的.价值和意义20世纪末,电子技术获 ...

  8. 汇编语言实现电子闹钟

    2.1 设计思路 首先使用8255.8254.8259 三个芯片实现电子时钟的功能,让闹钟可以正常走时:其次,在时钟的基础上添加闹铃功能.整点报时功能.设置当前时间功能:完成设计. 2.2 设计方案 ...

  9. C语言电子闹钟(显示时间、计时器、闹钟、倒计时、世界时钟)C语言大作业

    #include <stdio.h> #include <time.h> //时间函数 #include <conio.h> //字符模式函数 #include & ...

最新文章

  1. 一句话说清聚集索引和非聚集索引以及MySQL的InnoDB和MyISAM
  2. org.apache.commons.lang.StringUtils的jar包是什么
  3. SEE Conf 2021 如期而至,体验科技极致美
  4. Mozilla宣布年底前放弃支持Persona登录服务
  5. 【Java基础】字符串与数组
  6. 25个国外优秀电子商务网站设计案例
  7. Intel Realsense深度摄像头的自校准功能(self-calibration-for-depth-cameras)
  8. winform下 PictureBox 显示网络图片
  9. python控制台执行代码字符串_编写Python脚本以使用控制台命令执行
  10. 第37课 thinkphp5添加商品基本信息及通过前置钩子上传商品主图 模型事件(勾子函数)...
  11. 【2017年第1期】智慧城市多源异构大数据处理框架
  12. 什么是std :: move(),什么时候应该使用?
  13. Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle
  14. mysql数据库导入导出sql文件
  15. java整人代码大全_整人代码vbs大全分享
  16. layui表头样式_Layui表格好看样式
  17. 我的2016——我和嵌入式的那些事
  18. Java 简单论文查重程序(SimHash+海明距离算法)
  19. Python基础知识:切片
  20. 来吧 兄弟萌 我们一起学做粥

热门文章

  1. 对比ubuntu与centos系统 ​​​​
  2. xhprof php,PHP性能分析(xhprof)
  3. 我们花了八年时间,证明不内卷也可以活得更好 | 厂长来了
  4. An error occurred while loading navigation: Invalid UTF-8 string in BSON document的问题解决
  5. NLP文本预处理:步骤、示例 | 附github源码
  6. Weego工作室简介
  7. 巴基斯坦银行联手支付宝推出区块链汇款服务
  8. python3思维导图.xmind_《Python3:字典(或者Json)数据转成思维导图xmind文件》
  9. Verilog 数字时钟
  10. 计算机二级c语言报名照片怎么调,报考计算机二级时对于照片的要求有哪些