首页 第四十六节源代码讲解

第四十六节源代码讲解

举报
开通vip

第四十六节源代码讲解#include"REG52.H"#defineconst_voice_short40//蜂鸣器短叫的持续时间#defineconst_key_time120//按键去抖动延时的时间#defineconst_key_time220//按键去抖动延时的时间#defineconst_key_time320//按键去抖动延时的时间voidinitial_myself(void);voidinitial_peripheral(void);voiddelay_short(unsignedintuiDelayShort);vo...

#include"REG52.H"#defineconst_voice_short40//蜂鸣器短叫的持续时间#defineconst_key_time120//按键去抖动延时的时间#defineconst_key_time220//按键去抖动延时的时间#defineconst_key_time320//按键去抖动延时的时间voidinitial_myself(void);voidinitial_peripheral(void);voiddelay_short(unsignedintuiDelayShort);voiddelay_long(unsignedintuiDelaylong);//驱动数码管的74HC595voiddig_hc595_drive(unsignedcharucDigStatusTemp16_09,unsignedcharucDigStatusTemp08_01);voiddisplay_drive(void);//显示数码管字模的驱动函数voiddisplay_service(void);//显示的窗口菜单服务程序//驱动LED的74HC595voidhc595_drive(unsignedcharucLedStatusTemp16_09,unsignedcharucLedStatusTemp08_01);voidstart24(void);//开始位voidack24(void);//确认位voidstop24(void);//停止位unsignedcharread24(void);//读取一个字节的时序voidwrite24(unsignedchardd);//发送一个字节的时序unsignedcharread_eeprom(unsignedintaddress);//从一个地址读取出一个字节数据voidwrite_eeprom(unsignedintaddress,unsignedchardd);//往一个地址存入一个字节数据unsignedintread_eeprom_int(unsignedintaddress);//从一个地址读取出一个int类型的数据voidwrite_eeprom_int(unsignedintaddress,unsignedintuiWriteData);//往一个地址存入一个int类型的数据voidT0_time(void);//定时中断函数voidkey_service(void);//按键服务的应用程序voidkey_scan(void);//按键扫描函数放在定时中断里sbitkey_sr1=P0^0;//对应朱兆祺学习板的S1键sbitkey_sr2=P0^1;//对应朱兆祺学习板的S5键sbitkey_sr3=P0^2;//对应朱兆祺学习板的S9键sbitkey_gnd_dr=P0^4;//模拟独立按键的地GND,因此必须一直输出低电平sbitbeep_dr=P2^7;//蜂鸣器的驱动IO口sbiteeprom_scl_dr=P3^7;//时钟线sbiteeprom_sda_dr_sr=P3^6;//数据的输出线和输入线sbitdig_hc595_sh_dr=P2^0;//数码管的74HC595程序sbitdig_hc595_st_dr=P2^1;sbitdig_hc595_ds_dr=P2^2;sbithc595_sh_dr=P2^3;//LED灯的74HC595程序sbithc595_st_dr=P2^4;sbithc595_ds_dr=P2^5;unsignedcharucKeySec=0;//被触发的按键编号unsignedintuiKeyTimeCnt1=0;//按键去抖动延时计数器unsignedcharucKeyLock1=0;//按键触发后自锁的变量标志unsignedintuiKeyTimeCnt2=0;//按键去抖动延时计数器unsignedcharucKeyLock2=0;//按键触发后自锁的变量标志unsignedintuiKeyTimeCnt3=0;//按键去抖动延时计数器unsignedcharucKeyLock3=0;//按键触发后自锁的变量标志unsignedintuiVoiceCnt=0;//蜂鸣器鸣叫的持续时间计数器unsignedcharucVoiceLock=0;//蜂鸣器鸣叫的原子锁unsignedcharucDigShow8;//第8位数码管要显示的内容unsignedcharucDigShow7;//第7位数码管要显示的内容unsignedcharucDigShow6;//第6位数码管要显示的内容unsignedcharucDigShow5;//第5位数码管要显示的内容unsignedcharucDigShow4;//第4位数码管要显示的内容unsignedcharucDigShow3;//第3位数码管要显示的内容unsignedcharucDigShow2;//第2位数码管要显示的内容unsignedcharucDigShow1;//第1位数码管要显示的内容unsignedcharucDigDot8;//数码管8的小数点是否显示的标志unsignedcharucDigDot7;//数码管7的小数点是否显示的标志unsignedcharucDigDot6;//数码管6的小数点是否显示的标志unsignedcharucDigDot5;//数码管5的小数点是否显示的标志unsignedcharucDigDot4;//数码管4的小数点是否显示的标志unsignedcharucDigDot3;//数码管3的小数点是否显示的标志unsignedcharucDigDot2;//数码管2的小数点是否显示的标志unsignedcharucDigDot1;//数码管1的小数点是否显示的标志unsignedcharucDigShowTemp=0;//临时中间变量unsignedcharucDisplayDriveStep=1;//动态扫描数码管的步骤变量unsignedcharucWd1Update=1;//窗口1更新显示标志unsignedcharucWd2Update=0;//窗口2更新显示标志unsignedcharucWd3Update=0;//窗口3更新显示标志unsignedcharucWd4Update=0;//窗口4更新显示标志unsignedcharucWd=1;//本程序的核心变量,窗口显示变量。类似于一级菜单的变量。代表显示不同的窗口。unsignedintuiSetData1=0;//本程序中需要被设置的参数1unsignedintuiSetData2=0;//本程序中需要被设置的参数2unsignedintuiSetData3=0;//本程序中需要被设置的参数3unsignedintuiSetData4=0;//本程序中需要被设置的参数4unsignedcharucTemp1=0;//中间过渡变量unsignedcharucTemp2=0;//中间过渡变量unsignedcharucTemp3=0;//中间过渡变量unsignedcharucTemp4=0;//中间过渡变量//根据原理图得出的共阴数码管字模表codeunsignedchardig_table[]={0x3f,//0序号00x06,//1序号10x5b,//2序号20x4f,//3序号30x66,//4序号40x6d,//5序号50x7d,//6序号60x07,//7序号70x7f,//8序号80x6f,//9序号90x00,//无序号100x40,//-序号110x73,//P序号12};voidmain(){initial_myself();delay_long(100);initial_peripheral();while(1){key_service();//按键服务的应用程序display_service();//显示的窗口菜单服务程序}}//AT24C02驱动程序voidstart24(void)//开始位{eeprom_sda_dr_sr=1;eeprom_scl_dr=1;delay_short(15);eeprom_sda_dr_sr=0;delay_short(15);eeprom_scl_dr=0;}voidack24(void)//确认位时序{eeprom_sda_dr_sr=1;//51单片机在读取数据之前要先置一,表示数据输入eeprom_scl_dr=1;delay_short(15);eeprom_scl_dr=0;delay_short(15);//在本驱动程序中,我没有对ACK信号进行出错判断,因为我这么多年一直都是这样用也没出现过什么问题。//有兴趣的朋友可以自己增加出错判断,不一定非要按我的方式去做。}voidstop24(void)//停止位{eeprom_sda_dr_sr=0;eeprom_scl_dr=1;delay_short(15);eeprom_sda_dr_sr=1;}unsignedcharread24(void)//读取一个字节的时序{unsignedcharoutdata,tempdata;outdata=0;eeprom_sda_dr_sr=1;//51单片机的IO口在读取数据之前要先置一,表示数据输入delay_short(2);for(tempdata=0;tempdata<8;tempdata++){eeprom_scl_dr=0;delay_short(2);eeprom_scl_dr=1;delay_short(2);outdata<<=1;if(eeprom_sda_dr_sr==1)outdata++;eeprom_sda_dr_sr=1;//51单片机的IO口在读取数据之前要先置一,表示数据输入delay_short(2);}return(outdata);}voidwrite24(unsignedchardd)//发送一个字节的时序{unsignedchartempdata;for(tempdata=0;tempdata<8;tempdata++){if(dd>=0x80)eeprom_sda_dr_sr=1;elseeeprom_sda_dr_sr=0;dd<<=1;delay_short(2);eeprom_scl_dr=1;delay_short(4);eeprom_scl_dr=0;}}unsignedcharread_eeprom(unsignedintaddress)//从一个地址读取出一个字节数据{unsignedchardd,cAddress;cAddress=address;//把低字节地址传递给一个字节变量。/*注释一:*IIC通讯过程是一个要求一气呵成的通讯过程,中间不能被其它中断影响时序出错,因此*在整个通讯过程中应该先关闭总中断,完成之后再开中断。但是,这样就会引起另外一个新*问题,如果关闭总中断的时间太长,会导致动态数码管不能及时均匀的扫描,在操作EEPROM时,*数码管就会出现闪烁的现象,解决这个问题最好的 办法 鲁班奖评选办法下载鲁班奖评选办法下载鲁班奖评选办法下载企业年金办法下载企业年金办法下载 就是在做项目中尽量不要用动态扫描数码管*的 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,应该用静态显示的方案。那么程序上还有没有改善的方法?有的,下一节我会讲这个问题*的改善方法。*/EA=0;//禁止中断start24();//IIC通讯开始write24(0xA0);//此字节包含读写指令和芯片地址两方面的内容。//指令为写指令。地址为"000"的信息,此信息由A0,A1,A2的引脚决定ack24();//发送应答信号write24(cAddress);//发送读取的存储地址(范围是0至255)ack24();//发送应答信号start24();//开始write24(0xA1);//此字节包含读写指令和芯片地址两方面的内容。//指令为读指令。地址为"000"的信息,此信息由A0,A1,A2的引脚决定ack24();//发送应答信号dd=read24();//读取一个字节ack24();//发送应答信号stop24();//停止/*注释二:*在写入或者读取完一个字节之后,一定要加上一段延时时间。在11.0592M晶振的系统中,*写入数据时 经验 班主任工作经验交流宣传工作经验交流材料优秀班主任经验交流小学课改经验典型材料房地产总经理管理经验 值用delay_short(2000),读取数据时经验值用delay_short(800)。*否则在连续写入或者读取一串数据时容易丢失数据。如果一旦发现丢失数据,*应该适当继续把这个时间延长,尤其是在写入数据时。*/delay_short(800);//此处最关键,此处的延时时间一定要,而且要足够长,此处也是导致动态数码管闪烁的根本原因EA=1;//允许中断return(dd);}voidwrite_eeprom(unsignedintaddress,unsignedchardd)//往一个地址存入一个字节数据{unsignedcharcAddress;cAddress=address;//把低字节地址传递给一个字节变量。EA=0;//禁止中断start24();//IIC通讯开始write24(0xA0);//此字节包含读写指令和芯片地址两方面的内容。//指令为写指令。地址为"000"的信息,此信息由A0,A1,A2的引脚决定ack24();//发送应答信号write24(cAddress);//发送写入的存储地址(范围是0至255)ack24();//发送应答信号write24(dd);//写入存储的数据ack24();//发送应答信号stop24();//停止delay_short(2000);//此处最关键,此处的延时时间一定要,而且要足够长,此处也是导致动态数码管闪烁的根本原因EA=1;//允许中断}unsignedintread_eeprom_int(unsignedintaddress)//从一个地址读取出一个int类型的数据{unsignedcharucReadDataH;unsignedcharucReadDataL;unsignedintuiReadDate;ucReadDataH=read_eeprom(address);//读取高字节ucReadDataL=read_eeprom(address+1);//读取低字节uiReadDate=ucReadDataH;//把两个字节合并成一个int类型数据uiReadDate=uiReadDate<<8;uiReadDate=uiReadDate+ucReadDataL;returnuiReadDate;}voidwrite_eeprom_int(unsignedintaddress,unsignedintuiWriteData)//往一个地址存入一个int类型的数据{unsignedcharucWriteDataH;unsignedcharucWriteDataL;ucWriteDataH=uiWriteData>>8;ucWriteDataL=uiWriteData;write_eeprom(address,ucWriteDataH);//存入高字节write_eeprom(address+1,ucWriteDataL);//存入低字节}voiddisplay_service(void)//显示的窗口菜单服务程序{switch(ucWd)//本程序的核心变量,窗口显示变量。类似于一级菜单的变量。代表显示不同的窗口。{case1://显示P--1窗口的数据if(ucWd1Update==1)//窗口1要全部更新显示{ucWd1Update=0;//及时清零标志,避免一直进来扫描ucDigShow8=12;//第8位数码管显示PucDigShow7=11;//第7位数码管显示-ucDigShow6=1;//第6位数码管显示1ucDigShow5=10;//第5位数码管显示无//先分解数据ucTemp4=uiSetData1/1000;ucTemp3=uiSetData1%1000/100;ucTemp2=uiSetData1%100/10;ucTemp1=uiSetData1%10;//再过渡需要显示的数据到缓冲变量里,让过渡的时间越短越好if(uiSetData1<1000){ucDigShow4=10;//如果小于1000,千位显示无}else{ucDigShow4=ucTemp4;//第4位数码管要显示的内容}if(uiSetData1<100){ucDigShow3=10;//如果小于100,百位显示无}else{ucDigShow3=ucTemp3;//第3位数码管要显示的内容}if(uiSetData1<10){ucDigShow2=10;//如果小于10,十位显示无}else{ucDigShow2=ucTemp2;//第2位数码管要显示的内容}ucDigShow1=ucTemp1;//第1位数码管要显示的内容}break;case2://显示P--2窗口的数据if(ucWd2Update==1)//窗口2要全部更新显示{ucWd2Update=0;//及时清零标志,避免一直进来扫描ucDigShow8=12;//第8位数码管显示PucDigShow7=11;//第7位数码管显示-ucDigShow6=2;//第6位数码管显示2ucDigShow5=10;//第5位数码管显示无ucTemp4=uiSetData2/1000;//分解数据ucTemp3=uiSetData2%1000/100;ucTemp2=uiSetData2%100/10;ucTemp1=uiSetData2%10;if(uiSetData2<1000){ucDigShow4=10;//如果小于1000,千位显示无}else{ucDigShow4=ucTemp4;//第4位数码管要显示的内容}if(uiSetData2<100){ucDigShow3=10;//如果小于100,百位显示无}else{ucDigShow3=ucTemp3;//第3位数码管要显示的内容}if(uiSetData2<10){ucDigShow2=10;//如果小于10,十位显示无}else{ucDigShow2=ucTemp2;//第2位数码管要显示的内容}ucDigShow1=ucTemp1;//第1位数码管要显示的内容}break;case3://显示P--3窗口的数据if(ucWd3Update==1)//窗口3要全部更新显示{ucWd3Update=0;//及时清零标志,避免一直进来扫描ucDigShow8=12;//第8位数码管显示PucDigShow7=11;//第7位数码管显示-ucDigShow6=3;//第6位数码管显示3ucDigShow5=10;//第5位数码管显示无ucTemp4=uiSetData3/1000;//分解数据ucTemp3=uiSetData3%1000/100;ucTemp2=uiSetData3%100/10;ucTemp1=uiSetData3%10;if(uiSetData3<1000){ucDigShow4=10;//如果小于1000,千位显示无}else{ucDigShow4=ucTemp4;//第4位数码管要显示的内容}if(uiSetData3<100){ucDigShow3=10;//如果小于100,百位显示无}else{ucDigShow3=ucTemp3;//第3位数码管要显示的内容}if(uiSetData3<10){ucDigShow2=10;//如果小于10,十位显示无}else{ucDigShow2=ucTemp2;//第2位数码管要显示的内容}ucDigShow1=ucTemp1;//第1位数码管要显示的内容}break;case4://显示P--4窗口的数据if(ucWd4Update==1)//窗口4要全部更新显示{ucWd4Update=0;//及时清零标志,避免一直进来扫描ucDigShow8=12;//第8位数码管显示PucDigShow7=11;//第7位数码管显示-ucDigShow6=4;//第6位数码管显示4ucDigShow5=10;//第5位数码管显示无ucTemp4=uiSetData4/1000;//分解数据ucTemp3=uiSetData4%1000/100;ucTemp2=uiSetData4%100/10;ucTemp1=uiSetData4%10;if(uiSetData4<1000){ucDigShow4=10;//如果小于1000,千位显示无}else{ucDigShow4=ucTemp4;//第4位数码管要显示的内容}if(uiSetData4<100){ucDigShow3=10;//如果小于100,百位显示无}else{ucDigShow3=ucTemp3;//第3位数码管要显示的内容}if(uiSetData4<10){ucDigShow2=10;//如果小于10,十位显示无}else{ucDigShow2=ucTemp2;//第2位数码管要显示的内容}ucDigShow1=ucTemp1;//第1位数码管要显示的内容}break;}}voidkey_scan(void)//按键扫描函数放在定时中断里{if(key_sr1==1)//IO是高电平, 说明 关于失联党员情况说明岗位说明总经理岗位说明书会计岗位说明书行政主管岗位说明书 按键没有被按下,这时要及时清零一些标志位{ucKeyLock1=0;//按键自锁标志清零uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。}elseif(ucKeyLock1==0)//有按键按下,且是第一次被按下{uiKeyTimeCnt1++;//累加定时中断次数if(uiKeyTimeCnt1>const_key_time1){uiKeyTimeCnt1=0;ucKeyLock1=1;//自锁按键置位,避免一直触发ucKeySec=1;//触发1号键}}if(key_sr2==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位{ucKeyLock2=0;//按键自锁标志清零uiKeyTimeCnt2=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。}elseif(ucKeyLock2==0)//有按键按下,且是第一次被按下{uiKeyTimeCnt2++;//累加定时中断次数if(uiKeyTimeCnt2>const_key_time2){uiKeyTimeCnt2=0;ucKeyLock2=1;//自锁按键置位,避免一直触发ucKeySec=2;//触发2号键}}if(key_sr3==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位{ucKeyLock3=0;//按键自锁标志清零uiKeyTimeCnt3=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。}elseif(ucKeyLock3==0)//有按键按下,且是第一次被按下{uiKeyTimeCnt3++;//累加定时中断次数if(uiKeyTimeCnt3>const_key_time3){uiKeyTimeCnt3=0;ucKeyLock3=1;//自锁按键置位,避免一直触发ucKeySec=3;//触发3号键}}}voidkey_service(void)//按键服务的应用程序{switch(ucKeySec)//按键服务状态切换{case1://加按键对应朱兆祺学习板的S1键switch(ucWd)//在不同的窗口下,设置不同的参数{case1:uiSetData1++;if(uiSetData1>9999)//最大值是9999{uiSetData1=9999;}write_eeprom_int(0,uiSetData1);//存入EEPROM由于内部有延时函数,所以此处会引起数码管闪烁ucWd1Update=1;//窗口1更新显示break;case2:uiSetData2++;if(uiSetData2>9999)//最大值是9999{uiSetData2=9999;}write_eeprom_int(2,uiSetData2);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd2Update=1;//窗口2更新显示break;case3:uiSetData3++;if(uiSetData3>9999)//最大值是9999{uiSetData3=9999;}write_eeprom_int(4,uiSetData3);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd3Update=1;//窗口3更新显示break;case4:uiSetData4++;if(uiSetData4>9999)//最大值是9999{uiSetData4=9999;}write_eeprom_int(6,uiSetData4);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd4Update=1;//窗口4更新显示break;}ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCntuiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。ucVoiceLock=0;//原子锁解锁,保护主函数与中断函数的共享变量uiVoiceCntucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发break;case2://减按键对应朱兆祺学习板的S5键switch(ucWd)//在不同的窗口下,设置不同的参数{case1:uiSetData1--;if(uiSetData1>9999){uiSetData1=0;//最小值是0}write_eeprom_int(0,uiSetData1);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd1Update=1;//窗口1更新显示break;case2:uiSetData2--;if(uiSetData2>9999){uiSetData2=0;//最小值是0}write_eeprom_int(2,uiSetData2);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd2Update=1;//窗口2更新显示break;case3:uiSetData3--;if(uiSetData3>9999){uiSetData3=0;//最小值是0}write_eeprom_int(4,uiSetData3);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd3Update=1;//窗口3更新显示break;case4:uiSetData4--;if(uiSetData4>9999){uiSetData4=0;//最小值是0}write_eeprom_int(6,uiSetData4);//存入EEPROM,由于内部有延时函数,所以此处会引起数码管闪烁ucWd4Update=1;//窗口4更新显示break;}ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCntuiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。ucVoiceLock=0;//原子锁解锁,保护主函数与中断函数的共享变量uiVoiceCntucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发break;case3://切换窗口按键对应朱兆祺学习板的S9键ucWd++;//切换窗口if(ucWd>4){ucWd=1;}switch(ucWd)//在不同的窗口下,在不同的窗口下,更新显示不同的窗口{case1:ucWd1Update=1;//窗口1更新显示break;case2:ucWd2Update=1;//窗口2更新显示break;case3:ucWd3Update=1;//窗口3更新显示break;case4:ucWd4Update=1;//窗口4更新显示break;}ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCntuiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。ucVoiceLock=0;//原子锁解锁,保护主函数与中断函数的共享变量uiVoiceCntucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发break;}}voiddisplay_drive(void){//以下程序,如果加一些数组和移位的元素,还可以压缩容量。但是鸿哥追求的不是容量,而是清晰的讲解思路switch(ucDisplayDriveStep){case1://显示第1位ucDigShowTemp=dig_table[ucDigShow1];if(ucDigDot1==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xfe);break;case2://显示第2位ucDigShowTemp=dig_table[ucDigShow2];if(ucDigDot2==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xfd);break;case3://显示第3位ucDigShowTemp=dig_table[ucDigShow3];if(ucDigDot3==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xfb);break;case4://显示第4位ucDigShowTemp=dig_table[ucDigShow4];if(ucDigDot4==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xf7);break;case5://显示第5位ucDigShowTemp=dig_table[ucDigShow5];if(ucDigDot5==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xef);break;case6://显示第6位ucDigShowTemp=dig_table[ucDigShow6];if(ucDigDot6==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xdf);break;case7://显示第7位ucDigShowTemp=dig_table[ucDigShow7];if(ucDigDot7==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0xbf);break;case8://显示第8位ucDigShowTemp=dig_table[ucDigShow8];if(ucDigDot8==1){ucDigShowTemp=ucDigShowTemp|0x80;//显示小数点}dig_hc595_drive(ucDigShowTemp,0x7f);break;}ucDisplayDriveStep++;if(ucDisplayDriveStep>8)//扫描完8个数码管后,重新从第一个开始扫描{ucDisplayDriveStep=1;}}//数码管的74HC595驱动函数voiddig_hc595_drive(unsignedcharucDigStatusTemp16_09,unsignedcharucDigStatusTemp08_01){unsignedchari;unsignedcharucTempData;dig_hc595_sh_dr=0;dig_hc595_st_dr=0;ucTempData=ucDigStatusTemp16_09;//先送高8位for(i=0;i<8;i++){if(ucTempData>=0x80)dig_hc595_ds_dr=1;elsedig_hc595_ds_dr=0;dig_hc595_sh_dr=0;//SH引脚的上升沿把数据送入寄存器delay_short(1);dig_hc595_sh_dr=1;delay_short(1);ucTempData=ucTempData<<1;}ucTempData=ucDigStatusTemp08_01;//再先送低8位for(i=0;i<8;i++){if(ucTempData>=0x80)dig_hc595_ds_dr=1;elsedig_hc595_ds_dr=0;dig_hc595_sh_dr=0;//SH引脚的上升沿把数据送入寄存器delay_short(1);dig_hc595_sh_dr=1;delay_short(1);ucTempData=ucTempData<<1;}dig_hc595_st_dr=0;//ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来delay_short(1);dig_hc595_st_dr=1;delay_short(1);dig_hc595_sh_dr=0;//拉低,抗干扰就增强dig_hc595_st_dr=0;dig_hc595_ds_dr=0;}//LED灯的74HC595驱动函数voidhc595_drive(unsignedcharucLedStatusTemp16_09,unsignedcharucLedStatusTemp08_01){unsignedchari;unsignedcharucTempData;hc595_sh_dr=0;hc595_st_dr=0;ucTempData=ucLedStatusTemp16_09;//先送高8位for(i=0;i<8;i++){if(ucTempData>=0x80)hc595_ds_dr=1;elsehc595_ds_dr=0;hc595_sh_dr=0;//SH引脚的上升沿把数据送入寄存器delay_short(1);hc595_sh_dr=1;delay_short(1);ucTempData=ucTempData<<1;}ucTempData=ucLedStatusTemp08_01;//再先送低8位for(i=0;i<8;i++){if(ucTempData>=0x80)hc595_ds_dr=1;elsehc595_ds_dr=0;hc595_sh_dr=0;//SH引脚的上升沿把数据送入寄存器delay_short(1);hc595_sh_dr=1;delay_short(1);ucTempData=ucTempData<<1;}hc595_st_dr=0;//ST引脚把两个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来delay_short(1);hc595_st_dr=1;delay_short(1);hc595_sh_dr=0;//拉低,抗干扰就增强hc595_st_dr=0;hc595_ds_dr=0;}voidT0_time(void)interrupt1//定时中断{TF0=0;//清除中断标志TR0=0;//关中断/*注释三:*此处多增加一个原子锁,作为中断与主函数共享数据的保护,实际上是借鉴了"红金龙吸味"关于原子锁的建议.*/if(ucVoiceLock==0)//原子锁判断{if(uiVoiceCnt!=0){uiVoiceCnt--;//每次进入定时中断都自减1,直到等于零为止。才停止鸣叫beep_dr=0;//蜂鸣器是PNP三极管控制,低电平就开始鸣叫。}else{;//此处多加一个空指令,想维持跟if括号语句的数量对称,都是两条指令。不加也可以。beep_dr=1;//蜂鸣器是PNP三极管控制,高电平就停止鸣叫。}}key_scan();//按键扫描函数display_drive();//数码管字模的驱动函数TH0=0xfe;//重装初始值(65535-500)=65035=0xfe0bTL0=0x0b;TR0=1;//开中断}voiddelay_short(unsignedintuiDelayShort){unsignedinti;for(i=0;i9999)//不在范围内{uiSetData1=0;//填入一个初始化数据write_eeprom_int(0,uiSetData1);//存入uiSetData1,内部占用2个字节地址}uiSetData2=read_eeprom_int(2);//读取uiSetData2,内部占用2个字节地址if(uiSetData2>9999)//不在范围内{uiSetData2=0;//填入一个初始化数据write_eeprom_int(2,uiSetData2);//存入uiSetData2,内部占用2个字节地址}uiSetData3=read_eeprom_int(4);//读取uiSetData3,内部占用2个字节地址if(uiSetData3>9999)//不在范围内{uiSetData3=0;//填入一个初始化数据write_eeprom_int(4,uiSetData3);//存入uiSetData3,内部占用2个字节地址}uiSetData4=read_eeprom_int(6);//读取uiSetData4,内部占用2个字节地址if(uiSetData4>9999)//不在范围内{uiSetData4=0;//填入一个初始化数据write_eeprom_int(6,uiSetData4);//存入uiSetData4,内部占用2个字节地址}}
本文档为【第四十六节源代码讲解】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: ¥30.0 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
三年五年
从事土建工程多年,精通各类土建图纸。
格式:txt
大小:31KB
软件:记事本
页数:0
分类:成人教育
上传时间:2022-03-11
浏览量:0