1、按键未按下时,IO口为高电平,按键按下后IO口被拉低。1.2.3蜂鸣器驱动电路发音部分是通过三极管放大驱动蜂鸣器工作,当IO口输出低电平时,三极管导通,蜂鸣器响。1.2.4 数码管驱动电路由于点亮数码管所需电流较大,对单片机IO口连接上拉电阻,提高IO口的电流输出能力。1.2.5 电源电路由于系统需要在712V的供电下正常工作,故采用了78M05三段稳压芯片。78M05能将735V的直流电源转换成5V直流电压。1.3软件部分的设计1.3.1主程序部分的设计程序部分主要采用了程序结构的模块化设计,避免了一些函数的不必要的重复书写,使程序变得单间易懂。程序在执行时,主程序要须通过调用子函数就可完成
2、相应的功能 。1.3.2中断计时器及时间进位数字电子钟设计中主要使用定时器T0中断ET0,利用ET0中断进行计时时间的自增,从而实现计时功能。STC89C51RC有两个通用定时/计数器。两者均可配置为定时器或事件计数器。另外增加了定时器T0/T1,溢出时T0/T1脚自动翻转的功能选项。 用作“定时器”功能时,每经过一个机器周期,寄存器值加1。 用作“计数器”功能时,寄存器在对应的外部输入管脚T0/T1上每发生一次1到0的跳变时加1。使用该功能时,外部输入每个机器周期被采样一次。设计中采用了中断方式1作为定时中断,其定时计数初值的设置可由以下公式计算得到。1.3.3 闹钟子函数闹钟时间的判别主要
3、是通过设定时间与实时时间对逐位对比确定是否进行闹铃。1.3.4 按键扫描这些函数主要是判断是否有按键按下,并根据相应按键按下的情况调用相关函数执行。1.3.5 时钟闹钟设置此部分主要是通过判断flag_sw、flag_set在不同值时通过调用加1、减1子函数对时间和闹钟进行设置。1.3.6 显示数字函数函数通过判断需要显示的数字及显示的位置进行相应显示。1.3.7 显示界面函数函数通过判断标志位flag_sw判断需要显示的界面。1.3.8 闹钟记录及读取STC89C51RC单片机内部集成了的EEPROM是与程序空间是分开的,利用ISP/IAP技术可将内部Data Flash当EEPROM,擦写
4、次数在10万次以上。EEPROM可分为若干个扇区,每个扇区包含512字节。使用时,建议同一次修改的数据放在同一个扇区,不是同一次修改的数据放在不同的扇区,不一定要用满。数据存储器的擦除操作是按扇区进行的。EEPROM可用于保存一些需要在应用过程中修改并且掉电不丢失的参数数据。在用户程序中,可以对EEPROM进行字节读/字节编程/扇区擦除操作。IAP及EEPROM新增特殊功能寄存器介绍符号描述地址位地址及符号MSB LSB复位值ISP_DATAISP/IAP Flash Data RegisterE2H11111111BISP_ADDRHISP/IAP Flash Address HighE3H
5、0000 0000BISP_ADDRLISP/IAP Flash Address LowE4HISP_CMDISP/IAP Flash Command RegisterE5H- - - - - - MS1MS0xxxx xx00BISP_TRIGISP/IAP Flash Command TriggerE6Hxxxx xxxxBISP_CONTRISP/IAP Control RegisterE7HISPEN SWBS SWRST - - WT2 WT1WT0000x x000B1. ISP/IAP数据寄存器ISP_DATA ISP_DATA : ISP/IAP操作时的数据寄存器。ISP/IA
6、P 从Flash读出的数据放在此处,向Flash写的数据也需放在此处2. ISP/IAP地址寄存器ISP_ADDRH和ISP_ADDRL ISP_ADDRH : ISP/IAP 操作时的地址寄存器高八位。该寄存器地址为E3H,复位后值为00H. ISP_ADDRL : ISP/IAP 操作时的地址寄存器低八位。该寄存器地址为E4H,复位后值为00H. 3. ISP/IAP命令寄存器ISP_CMD ISP/IAP命令寄存器IAP_CMD格式如下:SFR nameAddressbitB7B6B5B4B3B2B1B0name-MS1MS0MS2命令 / 操作 模式选择Standby 待机模式,无IS
7、P操作1从用户的应用程序区对Data Flash/EEPROM区进行字节读进行字节编程进行扇区擦除程序在系统ISP程序区时可以对用户应用程序区/数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除;程序在用户应用程序区时,仅可以对数据Flash 区(EEPROM)进行字节读/字节编程/扇区擦除。已经固化有ISP引导码,并设置为上电复位进入ISP 4. ISP/IA命令触发寄存器ISP_TRIG ISP_TRIG: ISP/IAP 操作时的命令触发寄存器。在ISPEN(ISP_CONTR.7) = 1时,对ISP_TRIG先写入46h,再写入B9h,ISP/IAP 命令才会生效。ISP
8、/IAP操作完成后,ISP地址高八位寄存器ISP_ADDRH、ISP地址低八位寄存器ISP_ADDRL 和ISP命令寄存器ISP_CMD的内容不变。如果接下来要对下一个地址的数据进行ISP/IAP操作, 需手动将该地址的高8位和低8位分别写入ISP_ADDRH和ISP_ADDRL寄存器。每次ISP操作时,都要对ISP_TRIG先写入46H,再写入B9H,ISP/IAP命令才会生效。5. ISP/IAP命令寄存器ISP_CONTR ISP/IAP控制寄存器IAP_CONTR格式如下:SFR name Address bit B7 B6 B5 B4 B3 B2 B0 IAP_CONTR E7H n
9、ame ISPEN SWBS SWRST - WT2 WT0 ISPEN: ISP/IAP功能允许位。0:禁止IAP/ISP读/写/擦除Data Flash/EEPROM 1: 允许IAP/ISP读/写/擦除Data Flash/EEPROM SWBS: 软件选择从用户应用程序区启动(送0),还是从系统ISP监控程序区启动(送1)。要与SWRST直接配合才可以实现SWRST: 0: 不操作; 1: 产生软件系统复位,硬件自动复位。设置等待时间 CPU等待时间(机器周期),(1个机器周期=12个CPU工作时钟 ) WT1 Read/读Program/编程(=72uS) Sector Erase
10、扇区擦除(=13.1304ms) Recommended System Clock 跟等待参数对应的推荐系统时钟 0 1 6个机器周期30个机器周期5471个机器周期 5MHz 11个机器周期60个机器周期10942个机器周期10MHz 22个机器周期120个机器周期21885个机器周期20MHz 43个机器周期240个机器周期43769个机器周期40MHz STC89C51RC/RD+系列单片机EEPROM空间大小及地址STC89C51RC/RD+系列单片机内部可用EEPROM的地址与程序空间是分开的:程序在用户应用程序区时,可以对EEPROM 行IAP/ISP操作。具体某个型号单片机内部E
11、EPROM大小及详细地址请参阅:1. STC89C51RC/RD+系列单片机内部EEPROM详细地址表2. STC89C51RC/RD+系列单片机内部EEPROM空间大小选型一览表STC89C51RC系列单片机内部EEPROM详细地址表具体某型号有多少扇区的EEPROM,参照前面的EEPROM空间大小选型一览表, 每个扇区0.5 K字节第一扇区第二扇区第三扇区第四扇区起始地址结束地址2000h21FFh2200h23FFh2400h25FFh2600h27FFh第五扇区第六扇区第七扇区第八扇区2800h29FFh2A00h2BFFh2C00h2DFFh2E00h2FFFh每个扇区512字节,建
12、议同一次修改的数据放在同一扇区, 不是同一次修改的数据放在不同的扇区,不必用满, 当然可全用。2.硬件调试PCB制作完成后,为检测其能否正常工作,我编写了将数码管全部点亮,蜂鸣器控制口置低电平的程序。发现如下问题:1.某一数码管右侧的所有数码管的相同段不亮;2.数码管的小数点全部不亮;3.蜂鸣器负极直接单片机IO口,蜂鸣器声音微小。经检查后发现原因如下:1.数码管板底层走线较细,钻孔时被打断,由于两块PCB已焊接到一起,拆解修补困难,故在数码管板顶层直接飞线;2.PCB布局失误,使得固定螺丝与排孔引脚接错,而螺丝接地,使得该线路与GND短路;3.单片机灌电流过小,使得电流无法驱动蜂鸣器,再加上
13、三极管扩流后,问题得到了解决。附录A:电路原理图附录B:电路PCB图附录C:源程序#includeintrins.h#define dp 10char sec, min, h, date = 1, mon = 1, year = 12;char h_ala = 0, min_ala = 1, sw_ala=1;char flag_set, flag_sw;char count;sbit num1 = P00;sbit num2 = P04;sbit num3 = P27;sbit num4 = P23;sbit num5 = P20;sbit num6 = P21;sbit bell = P2
14、2;sbit key_set = P30;sbit key_sw = P31;sbit key_l = P32;sbit key_down = P33;sbit key_ok = P34;sbit key_up = P35;sbit key_r = P36;void Delay(unsigned int z); void display_num(char num, char po);void display_sec(void);void display_min(void);void display_h(void);void display_year(void);void display_mon
15、(void);void display_date(void);void display_time(void);void display_dates(void);void display_h_ala(void);void display_min_ala(void);void display_sw_ala(void);void display_alarm(void);void display(void);void carry(void);void key_swscan(void);void key_setscan(void);void set(void);void alarm(void);void
16、 InitTimer0(void);#define RdCommand 0x01 /定义ISP的操作命令#define PrgCommand 0x02#define EraseCommand 0x03#define Error 1#define Ok 0#define WaitTime 0x01 /定义CPU等待时间sfr ISP_DATA = 0xe2;sfr ISP_ADDRH = 0xe3;sfr ISP_ADDRL = 0xe4;sfr ISP_CMD = 0xe5;sfr ISP_TRIG = 0xe6;sfr ISP_CONTR = 0xe7;void ISP_IAP_enable
17、(void);void ISP_IAP_disable(void);void ISPgoon(void);unsigned char byte_read(unsigned int byte_addr);void SectorErase(unsigned int sector_addr);void byte_write(unsigned int byte_addr, unsigned char original_data);void read_ala(void);void record_ala(void);void main(void) read_ala(); / 读取闹铃 InitTimer0
18、(); / 定时器0初始化 while(1) carry(); / 进位 display(); / 显示 alarm(); / 闹钟 key_swscan(); / 切换界面按键扫描 key_setscan(); / 设置按键(改变设置标志位)扫描 if (flag_set != 0) / 设置标志位不为0,开始设置 set(); /= 延时函数 =void Delay(unsigned int z) unsigned int x, y; for(x=z; x0 ;x-) for(y=120; y0; y-);/= 显示数字 =void display_num(char num, char p
19、o) unsigned char code Tab = 0x77,0x14,0xB3,0xB6,0xD4,0xE6,0xE7,0x34,0xF7,0xF6,0x08; if (!(num = 0 & (po = 1 | po = 3 | po = 5) | (flag_sw = 1 & po = 1) switch (po) case 1: P1 = Tabnum; num1 = 0; Delay(1); num1 = 1; break; case 2: num2 = 0; num2 = 1; case 3: num3 = 0; num3 = 1; case 4: num4 = 0; num4
20、 = 1; case 5: num5 = 0; num5 = 1; default: num6 = 0; num6 = 1;/= 显示秒 =void display_sec(void) if (flag_set = 3 & count 10 | flag_set != 3) display_num(sec / 10, 5); display_num(sec % 10, 6);/= 显示分 =void display_min(void) if (flag_set = 2 &= 2) display_num(min / 10, 3); display_num(min % 10, 4); displ
21、ay_num(dp, 4);/= 显示时 =void display_h(void) if (flag_set = 1 &= 1) display_num(h / 10, 1); display_num(h % 10, 2); display_num(dp, 2);/= 显示日 =void display_date(void) display_num(date / 10, 5); display_num(date % 10, 6);/= 显示月 =void display_mon(void) display_num(mon / 10, 3); display_num(mon % 10, 4);
22、/= 显示年 =void display_year(void) display_num(year / 10, 1); display_num(year % 10, 2);/= 显示时间 =void display_time(void) display_sec(); display_min(); display_h();/= 显示日期 =void display_dates(void) display_date(); display_mon(); display_year();/= 显示闹钟时 =void display_h_ala(void) display_num(h_ala / 10, 1); display_num(h_ala % 10, 2); displ
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1