12.2 秒表(定时器扫描按键数码管)
#include REGX52.H#include I2C.h#define AT24C02_ADDRESS 0xA0/*** brief AT24C02写入一个字节* param WordAddress 要写入字节的地址* param Data 要写入的数据* retval 无*/void AT24C02_WriteByte(unsigned char WordAddress,Data){I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_SendByte(Data);I2C_ReceiveAck();I2C_Stop();}/*** brief AT24C02读取一个字节* param WordAddress 要读出字节的地址* retval 读出的数据*/unsigned char AT24C02_ReadByte(unsigned char WordAddress){unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(AT24C02_ADDRESS|0x01);I2C_ReceiveAck();DataI2C_ReceiveByte();I2C_SendAck(1);I2C_Stop();return Data;}#include REGX52.Hsbit I2C_SCLP2^1;sbit I2C_SDAP2^0;/*** brief I2C开始* param 无* retval 无*/void I2C_Start(void){I2C_SDA1;I2C_SCL1;I2C_SDA0;I2C_SCL0;}/*** brief I2C停止* param 无* retval 无*/void I2C_Stop(void){I2C_SDA0;I2C_SCL1;I2C_SDA1;}/*** brief I2C发送一个字节* param Byte 要发送的字节* retval 无*/void I2C_SendByte(unsigned char Byte){unsigned char i;for(i0;i8;i){I2C_SDAByte(0x80i);I2C_SCL1;I2C_SCL0;}}/*** brief I2C接收一个字节* param 无* retval 接收到的一个字节数据*/unsigned char I2C_ReceiveByte(void){unsigned char i,Byte0x00;I2C_SDA1;for(i0;i8;i){I2C_SCL1;if(I2C_SDA){Byte|(0x80i);}I2C_SCL0;}return Byte;}/*** brief I2C发送应答* param AckBit 应答位0为应答1为非应答* retval 无*/void I2C_SendAck(unsigned char AckBit){I2C_SDAAckBit;I2C_SCL1;I2C_SCL0;}/*** brief I2C接收应答位* param 无* retval 接收到的应答位0为应答1为非应答*/unsigned char I2C_ReceiveAck(void){unsigned char AckBit;I2C_SDA1;I2C_SCL1;AckBitI2C_SDA;I2C_SCL0;return AckBit;}#include REGX52.H#include Timer0.h#include Key.h#include Nixie.h#include Delay.h#include AT24C02.hunsigned char KeyNum;unsigned char Min,Sec,MiniSec;unsigned char RunFlag;void main(){Timer0_Init();while(1){KeyNumKey();if(KeyNum1) //K1按键按下{RunFlag!RunFlag; //启动标志位翻转}if(KeyNum2) //K2按键按下{Min0; //分秒清0Sec0;MiniSec0;}if(KeyNum3) //K3按键按下{AT24C02_WriteByte(0,Min); //将分秒写入AT24C02Delay(5);AT24C02_WriteByte(1,Sec);Delay(5);AT24C02_WriteByte(2,MiniSec);Delay(5);}if(KeyNum4) //K4按键按下{MinAT24C02_ReadByte(0); //读出AT24C02数据SecAT24C02_ReadByte(1);MiniSecAT24C02_ReadByte(2);}Nixie_SetBuf(1,Min/10); //设置显示缓存显示数据Nixie_SetBuf(2,Min%10);Nixie_SetBuf(3,11);Nixie_SetBuf(4,Sec/10);Nixie_SetBuf(5,Sec%10);Nixie_SetBuf(6,11);Nixie_SetBuf(7,MiniSec/10);Nixie_SetBuf(8,MiniSec%10);}}/*** brief 秒表驱动函数在中断中调用* param 无* retval 无*/void Sec_Loop(void){if(RunFlag){MiniSec;if(MiniSec100){MiniSec0;Sec;if(Sec60){Sec0;Min;if(Min60){Min0;}}}}}void Timer0_Routine() interrupt 1{static unsigned int T0Count1,T0Count2,T0Count3;TL0 0x18; //设置定时初值TH0 0xFC; //设置定时初值T0Count1;if(T0Count120){T0Count10;Key_Loop(); //20ms调用一次按键驱动函数}T0Count2;if(T0Count22){T0Count20;Nixie_Loop();//2ms调用一次数码管驱动函数}T0Count3;if(T0Count310){T0Count30;Sec_Loop(); //10ms调用一次数秒表驱动函数}}Delay Key Nixie Timer0