用20引脚的小单片机,驱动1302时钟芯片,和小屏12864显示时间和计数信息。
由于只有2K ROM空间,所以程序比较简单,没有调时间,按键采用外部中断和定时器控制防连续计数
按一下外部中断1,单次数值 +1,按一下外部中断2,单次清0,积++,
制作出来的实物图如下:
单片机源程序如下:
代码:
- /****************************************************************
- 通用头文件
- ****************************************************************/
- #include <STC12C2052.H>
- #include <intrins.h>
- #include <DS1302.H>
- #include<time0.H>
- #include<STC12C2052EEPROM.H>
- #include <LCDMINI12864.H>
- //uchar x;
- //#include<KEY.H>
- /****************************************************************
- 硬件接口定义
- ****************************************************************/
- /*DS1302IO接口 请用3P杜邦线与对应的P1口链接*/
- //sbit TSCLK = P1^0; //DS1302时钟引脚
- //sbit TIO = P1^1; //DS1302数据引脚
- //sbit TRST = P1^2; //DS1302使能引脚
- /*4位独立按键引脚*/
- //sbit KEY_S2 = P3^0; //S2独立按键
- //sbit KEY_S3 = P3^1; //S3独立按键
- //sbit KEY_S4 = P3^2; //S4独立按键
- //sbit KEY_S5 = P3^3; //S5独立按键
- /*数码管*/
- //sbit WE = P2^7; //数码管位选
- //sbit DU = P2^6; //数码管段选
- /*DS18B20温度传感器引脚*/
- //sbit DS18B20_IO = P2^2; //DS18B20通信引脚
- /*5V有源蜂鸣器引脚*/
- //sbit BUZZER = P2^3; //蜂鸣器引脚
- sbit BEEP = P3^4 ; //蜂鸣器
- void LCDMINI12864_EEPROM_DIS()
- {
-
- // 计数值 单
- strEEPROM_Z1[0] = (EEPROM_Z1/100) + '!'; //十位转为ASCII码
- strEEPROM_Z1[1] = ' '; //十位转为ASCII码
- strEEPROM_Z1[2] = (EEPROM_Z1% 100/10) + '!'; //十位转为ASCII码
- strEEPROM_Z1[3] = ' '; //十位转为ASCII码
- strEEPROM_Z1[4] = (EEPROM_Z1% 10) + '!'; //十位转为ASCII码
- strEEPROM_Z1[5] = '\0'; //字符串结束符
- Disp_String_8x16( 7, 59, strEEPROM_Z1);//显示温度
- // 计数值 总
- strEEPROM_Z2[0] = (EEPROM_Z2/100) + '!'; //十位转为ASCII码
- strEEPROM_Z2[1] = (EEPROM_Z2% 100/10) + '!'; //十位转为ASCII码
- strEEPROM_Z2[2] = (EEPROM_Z2% 10) + '!'; //十位转为ASCII码
- strEEPROM_Z2[3] = '\0'; //字符串结束符
- Disp_String_8x16( 5, 28, strEEPROM_Z2);//显示温度
-
-
- }
- void main()
- {
-
- InitLcd();//mini12864初始化
- LcdCls( 1, 1, 128, 64); //清屏指定区域
- LCDMINI12864_GUDING(); //液晶显示固定不变的信息
- // inital_1302(); // 时钟初始化
- P1M0=0; P1M1=0XE0; // DS1302推挽输出,因为没接上拉电阻 ,信号不稳定
- time0init(); //定时器0 初始化
- EEPROM_Z1= dcx(0x2000); // 开机读取EEPROM区 总值
- EEPROM_Z2= dcx(0x2001); // 开机读取EEPROM区 总值
- // EEPROM_Z1=EEPROM_Z1A*256+EEPROM_Z1B ; //拆分的值 再乘回去,显示
- EA=1;
- EX0=1; //外部中断0开
- IT0=1; //电平触发
- EX1=1; //外部中断0开
- IT1=1; //电平触发
-
- while(1)
- {
-
-
- if(t0z3>=15) // 上电定时器++,1.5秒后
- {
- x4_flag=1; //标志位置1,让t0z3不再加值 ,
- LCDMINI12864_TIME_DIS2(); // 上电1。5后先刷新一次 时值 ,然后1000个50毫秒后再刷新
- LCDMINI12864_TIME_DIS3(); //刷新一次 周 年 月 日 ,然后都不刷新了。
- }
- if(x1_flag==1){LCDMINI12864_TIME_DIS1();x1_flag=0;t0z1=0; } //单独读秒,分 并刷新 秒 分
- if(x2_flag==1){LCDMINI12864_EEPROM_DIS();x2_flag=0;t0z0=3; } //显示计数值
- if(x3_flag==1){LCDMINI12864_TIME_DIS2();x3_flag=0;t0z2=0; } //读时 并刷新 时
-
-
- }
- }
- void exint0() interrupt 0
- {
- if(t0z0>=19) // 计时器0过了19个50毫秒,后
- {
- EEPROM_Z1++; //计数值 ++
- BEEP=0; // FMQ响
-
- t0z0=0; // 让计数器0归0
- if(EEPROM_Z1>=200)delay(900); // 如果计数值 到了200,长响,
- else delay(300); //让FMQ响一会
- BEEP=1; // 关闭FMQ
- cc(0x2000); // 擦除第1个扇区(2000h~21FFh)
- xcx(0x2000,EEPROM_Z1); // 对EEPROM区2002h写入2
- xcx(0x2001,EEPROM_Z2); // 对EEPROM区2002h写入2
- EA=1; //使用EEPROM后,要再开
-
- }
-
- }
- void exint1() interrupt 2 //清零键
- {
- delay(300); //延时一会
- EEPROM_Z1=0; // 计数值 清零
- EEPROM_Z2++; // 累计值 +1
- cc(0x2000); // 擦除第1个扇区(2000h~21FFh)
- xcx(0x2000,EEPROM_Z1); // 对EEPROM区2002h写入2
- xcx(0x2001,EEPROM_Z2); // 对EEPROM区2002h写入2
- EA=1; //使用EEPROM后,要再开
- t0z0=0; // 计时器0归0,让计数值 刷新 显示
- }
Keil代码有待改进: