【51单片机】童年回忆,咬手鲨鱼改装闹钟
2017-02-28 14:13
260 查看
1.概要:
还记得小时候玩的咬手鲨鱼吗?数十颗牙齿随机按下,鲨鱼嘴巴就会咬下。现在来试着把它改成闹钟吧!
2.最后成品图:
使用方法:闹钟响起,必须按下那颗会使嘴巴闭合的牙齿才能关闭闹钟(每次随机)。也就是说,早上起床会被鲨鱼咬到痛醒,或者你也能闪躲不被咬到,如果足够清醒的话。
3.教程:
(1)材料:咬手鲨鱼+51单片机+DS3231+ TM1637驱动数码管
(2)程序:(看程序注释应该知道怎么接线)
4.STC89C52RC程序:
5.塞进去,大功告成:
PS:最后做好后送人了,听反馈似乎代码还有点小问题,所以你可以再自己改改。
还记得小时候玩的咬手鲨鱼吗?数十颗牙齿随机按下,鲨鱼嘴巴就会咬下。现在来试着把它改成闹钟吧!
2.最后成品图:
使用方法:闹钟响起,必须按下那颗会使嘴巴闭合的牙齿才能关闭闹钟(每次随机)。也就是说,早上起床会被鲨鱼咬到痛醒,或者你也能闪躲不被咬到,如果足够清醒的话。
3.教程:
(1)材料:咬手鲨鱼+51单片机+DS3231+ TM1637驱动数码管
(2)程序:(看程序注释应该知道怎么接线)
4.STC89C52RC程序:
#include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int #define DS3231_WriteAddress 0xD0 #define DS3231_ReadAddress 0xD1 #define DS3231_SECOND 0x00 #define DS3231_MINUTE 0x01 #define DS3231_HOUR 0x02 #define DS3231_WEEK 0x03 #define DS3231_DAY 0x04 #define DS3231_MONTH 0x05 #define DS3231_YEAR 0x06 unsigned char dpFlag = 0; //dp标志位 unsigned char code SEGData[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//1-9,不带数点 unsigned char code SEGDataDp[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //1-9,带数点 unsigned int countTime = 0; unsigned char time, sec; uchar alarmHour = 24, alarmMin = 60, alarmHour2 = 24, alarmMin2 = 60; sbit CLK = P0^0; //数码管时钟 sbit DIO = P0^1; //数码管数据 sbit SDA = P0^2; //模拟I2C数据传送位SDA sbit SCL = P0^3; //模拟I2C时钟控制位SCL sbit we1 = P1^0; //时,十位 sbit we2 = P1^1; //时,个位 sbit we3 = P1^2; //分,十位 sbit we4 = P1^3; //分,个位 sbit we5 = P1^4; //秒,十位 sbit we6 = P1^5; //秒,个位 sbit closeBeep = P2^6; //?? sbit beep = P2^7; //蜂鸣器 bit ack; //应答标志位 struct { char shi; char ge; } Hour; struct { char shi; char ge; } Minute; uchar flag = 0; uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar Recive_table[3]; static uchar i = 0; uchar num = 0; void TM1637_start(); void TM1637_stop(); void TM1637_write1Bit(unsigned char mBit); void TM1637_write1Byte(unsigned char mByte); void TM1637_writeCammand(unsigned char mData); void TM1637_writeData(unsigned char addr, unsigned char mData); void time_set(char hour, char min); void time_display(); void timer0_init(); void delay_140us(); void delayus(uint us); uchar BCD2HEX(uchar val) //BCD码转换为Byte { uchar temp; temp=val&0x0f; val>>=4; val&=0x0f; val*=10; temp+=val; return temp; } uchar HEX2BCD(uchar val) //B码转换为BCD码 { return (((val%100)/10)<<4)|(val%10); } void delayus(uint us) { while (us--); } void Start_I2C() { SDA=1; //??????????? delayus(1); SCL=1; delayus(5); //??????????4.7us,?? SDA=0; //?????? delayus(5); // ??????????4祍 SCL=0; //??I2C??,????????? delayus(2); } void Stop_I2C() { SDA=0; //??????????? delayus(1); //??????????? SCL=1; //??????????4us delayus(5); SDA=1; //??I2C?????? delayus(4); } void SendByte(uchar c) { uchar BitCnt; for(BitCnt=0;BitCnt<8;BitCnt++) //?????????8? { if((c<<BitCnt)&0x80) SDA=1; //????? else SDA=0; delayus(1); SCL=1; //??????,???????????? delayus(5); //???????????4祍 SCL=0; } delayus(2); SDA=1; //8??????????,??????? delayus(2); SCL=1; delayus(3); if(SDA==1) ack=0; else ack=1; //??????????? SCL=0; delayus(2); } uchar RcvByte() { uchar retc; uchar BitCnt; retc = 0; SDA = 1; //????????? for(BitCnt = 0;BitCnt < 8;BitCnt++) { delayus(1); SCL = 0; //??????,??????? delayus(5); //?????????4.7祍 SCL = 1; //??????????????? delayus(3); retc = retc << 1; if(SDA == 1) retc = retc + 1; //????,????????retc? delayus(2); } SCL = 0; delayus(2); return(retc); } void Ack_I2C(bit a) { if(a == 0) SDA = 0; //???????????? else SDA = 1; delayus(3); SCL = 1; delayus(5); //?????????4祍 SCL = 0; //????,??I2C???????? ffd3 delayus(2); } uchar write_byte(uchar addr, uchar write_data) { Start_I2C(); SendByte(DS3231_WriteAddress); if (ack == 0) return 0; SendByte(addr); if (ack == 0) return 0; SendByte(write_data); if (ack == 0) return 0; Stop_I2C(); delayus(10); return 1; } uchar read_current() { uchar read_data; Start_I2C(); SendByte(DS3231_ReadAddress); if(ack == 0) return(0); read_data = RcvByte(); Ack_I2C(1); Stop_I2C(); return read_data; } uchar read_random(uchar random_addr) { Start_I2C(); SendByte(DS3231_WriteAddress); if(ack == 0) return(0); SendByte(random_addr); if(ack == 0) return(0); return(read_current()); } /******************************************************************** * 名称 : void init() * 功能 : 程序初始化 * 输入 : void * 输出 : 无 **************************************************************/ void init() { TMOD = 0X21; //用定时器设置串口波特率 9600 TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; TR0 = 1; ET0 = 1; EA = 1; //for bluetooth TH1 = 0xfd; TL1 = 0xfd; TR1 = 1; REN = 1; //串口初始化 SM0 = 0; SM1 = 1; EA = 1; //开启总中断 ES = 1; } /******************************************************************** * 名称 : void time_display() * 功能 : 显示时间 * 输入 : void * 输出 : 无 **************************************************************/ void TimeDisplay(uchar Dhour,uchar Dmin) { Hour.shi = Dhour / 10; //时,十位 Hour.ge = Dhour % 10; //时,个位 Minute.shi = Dmin / 10; //分,十位 Minute.ge = Dmin % 10; //分,个位 TM1637_writeCammand(0x44); TM1637_writeData(0xc0, SEGData[Hour.shi]); if(dpFlag) TM1637_writeData(0xc1, SEGDataDp[Hour.ge]); //带数点 else TM1637_writeData(0xc1, SEGData[Hour.ge]); //不带数点 TM1637_writeData(0xc2, SEGData[Minute.shi]); TM1637_writeData(0xc3, SEGData[Minute.ge]); TM1637_writeCammand(0x8a); } /******************************************************************** * 名称 : void computer_and_display_time() * 功能 : 显示时间 * 输入 : void * 输出 : 无 **************************************************************/ void compute_and_display_time() { //计算时间 uchar Htemp1, Htemp2, Mtemp1, Mtemp2;// Stemp1, Stemp2; Htemp1 = read_random(DS3231_HOUR); //获取时 Htemp1&=0x3f; Htemp2 = BCD2HEX(Htemp1); Mtemp1 = read_random(DS3231_MINUTE); //获取分 Mtemp2 = BCD2HEX(Mtemp1); if(alarmHour == Htemp2 && alarmMin == Mtemp2) { if(closeBeep == 0) { if(beep == 1) beep = 0; else beep = 1; } else { beep = 0; } } else closeBeep = 0; //显示时间 TimeDisplay(Htemp2, Mtemp2); } /******************************************************************** * 名称 : void TM1637_start() * 功能 : start信号 * 输入 : void * 输出 : 无 **************************************************************/ void TM1637_start() { CLK = 1; DIO = 1; delay_140us(); DIO = 0; delay_140us(); CLK = 0; delay_140us(); } /******************************************************************** * 名称 : void TM1637_stop() * 功能 : stop信号 * 输入 : void * 输出 : 无 **************************************************************/ void TM1637_stop() { CLK = 0; delay_140us(); DIO = 0; delay_140us(); CLK = 1; delay_140us(); DIO = 1; delay_140us(); } /******************************************************************** * 名称 : void TM1637_write1Bit(unsigned char mBit) * 功能 : 写入1bit * 输入 : unsigned char mBit * 输出 : 无 **************************************************************/ void TM1637_write1Bit(unsigned char mBit) { CLK = 0; delay_140us(); if(mBit) DIO = 1; else DIO = 0; delay_140us(); CLK = 1; delay_140us(); } /******************************************************************** * 名称 : void TM1637_write1Byte(unsigned char mByte) * 功能 : 写入1bit数据 * 输入 : unsigned char mByte * 输出 : 无 **************************************************************/ void TM1637_write1Byte(unsigned char mByte) { char loop = 0; for(loop = 0; loop < 8; loop++) { TM1637_write1Bit((mByte>>loop)&0x01); //取得最低位 } CLK = 0; delay_140us(); DIO = 1; delay_140us(); CLK = 1; delay_140us(); while(DIO == 1); //获得应答位 } /******************************************************************** * 名称 : void TM1637_writeCammand(unsigned char mData) * 功能 : 写入1byte指令 * 输入 : unsigned char mData * 输出 : 无 **************************************************************/ void TM1637_writeCammand(unsigned char mData) { TM1637_start(); TM1637_write1Byte(mData); //指令数据 TM1637_stop(); } /******************************************************************** * 名称 : void TM1637_writeData(unsigned char addr, unsigned char mData) * 功能 : 固定地址写入1byte数据 * 输入 : unsigned char addr, unsigned char mData * 输出 : 无 **************************************************************/ void TM1637_writeData(unsigned char addr, unsigned char mData) { TM1637_start(); TM1637_write1Byte(addr); //地址 TM1637_write1Byte(mData); //数据 TM1637_stop(); } /******************************************************************** * 名称 : void timer0_isr() * 功能 : 定时50ms(实际运行时由于指令运行的延时,会大于50ms) * 输入 : void * 输出 : 无 **************************************************************/ void timer0_isr() interrupt 1 { TH0 = (65536 - 50000) / 256; //5 ???? TL0 = (65536 - 50000) % 256; countTime ++; } /******************************************************************** * 名称 : delay_140us() * 功能 : 延时 * 输入 : void * 输出 : 无 **************************************************************/ void delay_140us() { int i; for(i = 0; i < 20; i++) _nop_(); } /******************************************************************** * 名称 : void ModifyTime(uchar hou,uchar min,uchar sec) * 功能 : 修改时间(全) * 输入 : void * 输出 : 无 **************************************************************/ void ModifyTime(uchar hou, uchar min,uchar sec) { uchar temp = 0; temp = HEX2BCD(hou); write_byte(DS3231_HOUR, temp); //设置时 temp = HEX2BCD(min); write_byte(DS3231_MINUTE, temp); //设置分 temp = HEX2BCD(sec); write_byte(DS3231_SECOND, temp); //设置秒 } /******************************************************************** * 名称 : void ModifyTime(uchar hou,uchar min,uchar sec) * 功能 : 修改时间(时) * 输入 : void * 输出 : 无 **************************************************************/ void ModifyHour(hour) { uchar temp = HEX2BCD(hour); write_byte(DS3231_HOUR, temp); //设置时 } /******************************************************************** * 名称 : void Modifymin(minute) * 功能 : 修改时间(分) * 输入 : void * 输出 : 无 **************************************************************/ void ModifyMinute(minute) { uchar temp = HEX2BCD(minute); write_byte(DS3231_MINUTE, temp); //设置分 } /******************************************************************** * 名称 : void ModifyTime(uchar hou,uchar min,uchar sec) * 功能 : 修改时间(秒) * 输入 : void * 输出 : 无 **************************************************************/ void ModifySecond(second) { uchar temp = HEX2BCD(second); write_byte(DS3231_SECOND, temp); //设置秒 } /******************************************************************** * 名称 : void receiveData() interrupt 4 * 功能 : 接收蓝牙数据 * 输入 : void * 输出 : 无 **************************************************************/ void receiveData() interrupt 4 { if(RI == 1) { RI = 0; Recive_table = SBUF; if(Recive_table == '\n') { if(i == 4)//调整时间 { num = (Recive_table[1] - '0') * 10 + (Recive_table[2] - '0'); if(Recive_table[0] == 'h') ModifyHour(num); else if(Recive_table[0] == 'm') ModifyMinute(num); } else if(i == 2)//获取时钟时间并发给手机 flag = 1; else if(i == 5) { alarmHour = (Recive_table[0] - '0') * 10 + (Recive_table[1] - '0'); alarmMin = (Recive_table[2] - '0') * 10 + (Recive_table[3] - '0'); flag = 2; } i = 0; } else i++; } else TI = 0; } /*********************************************************** ***** ***** 主函数 ***** ***********************************************************/ void main() { init(); // bluetoothVcc = 1; // bluetoothGnd = 0; beep = 0; closeBeep = 0; while(1) { //计算+显示时间 compute_and_display_time(); if(countTime <= 10) //第一微秒:不带数点 { dpFlag = 0; } else if(countTime <= 20) //第二微秒:带数点 { dpFlag = 1; } else //重置计数器 { countTime = 0; } //蓝牙操作 if(flag == 1) //反馈回当前时间 { uchar Htemp1, Htemp2, Mtemp1, Mtemp2; Htemp1 = read_random(DS3231_HOUR); //获取时 Htemp1&=0x3f; Htemp2 = BCD2HEX(Htemp1); Mtemp1 = read_random(DS3231_MINUTE); //获取分 Mtemp2 = BCD2HEX(Mtemp1); //发送时 ES = 0; SBUF = Htemp2; while(!TI); TI = 0; ES = 1; //发送分 ES = 0; SBUF = Mtemp2; while(!TI); TI = 0; ES = 1; flag = 0; } else if(flag == 2)//设置闹钟 { dpFlag = 1; TimeDisplay(alarmHour, alarmMin); ES = 0; SBUF = 1; //单片机的数据发送到计算机,表示闹钟设置成功 while(!TI); TI = 0; ES = 1; flag = 0; delayus(100000); } } }
5.塞进去,大功告成:
PS:最后做好后送人了,听反馈似乎代码还有点小问题,所以你可以再自己改改。
相关文章推荐
- 回忆童年春节吃食
- HTML5 canvas制作童年的回忆大风车
- 来一场3D的童年回忆:走向三维的《大力水手》
- 有才人制作的童年回忆,送给70末出生的同胞们
- 回忆快乐的童年 —— 写在六一儿童节时
- 终于可以弹完“童年的回忆”了!
- 童年的回忆:我与蚕宝宝的故事
- 80后程序员童年回忆之:恐龙快打无限子弹 2014-7-9最新版本下载
- 对过去的回忆---之童年记事
- 童年的回忆
- POJ 3348 Cows | 凸包——童年的回忆(误)
- 童年回忆(3)
- 1975-1989出生的各位。这些回忆你能忘却么?我们的童年
- 儿时回忆—— 淘气的童年
- 【井字游戏】做一款回忆童年的游戏
- 运用51单片机来实现时间跟闹钟的作用
- 【童年回忆】【FC模拟器 + ROM大合集下载】
- 儿时回忆—— 童年的美食
- 童年回忆
- 农村80后的童年回忆--转发微博