|
楼主 |
发表于 2024-11-24 22:23:24
|
显示全部楼层
本帖最后由 海上生明月丶 于 2024-11-24 22:24 编辑
- #include <REG51.H>
- #include <INTRINS.H>
- sfr WDT_CONTR = 0xC1;
- sfr ISP_DATA = 0xC2;
- sfr ISP_ADDRH = 0xC3;
- sfr ISP_ADDRL = 0xC4;
- sfr ISP_CMD = 0xC5;
- sfr ISP_TRIG = 0xC6;
- sfr ISP_CONTR = 0xC7;
-
- sbit TM1650_SDA = 0xB5;
- sbit TM1650_SCL = 0xB4;
- sbit KEY2 = 0xB3;
- sbit KEY1 = 0xB2;
- sbit SCL = 0xB1;
- sbit SDA = 0xB0;
- unsigned char Sec,Min,Hour,BMin,BHour,Mode,H1,L1,H2,L2;
- /******************************************海上生明月******************************************/
- //延时xms
- void Delay(unsigned int Xms) //1ms延时函数 @11.0592MHz
- {
- unsigned char data i, j;
- while(Xms--)
- {
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- void Delay5us(void) //@11.0592MHz
- {
- unsigned char data i;
- _nop_();
- i = 11;
- while (--i);
- }
- /******************************************海上生明月******************************************/
- //TM1650_I2C
- void TM1650_I2C_S()//I2C开始
- {
- TM1650_SDA=1;
- TM1650_SCL=1;
- Delay5us();
- TM1650_SDA=0;
- TM1650_SCL=0;
- Delay5us();
- }
- void TM1650_I2C_P()//I2C结束
- {
- TM1650_SDA=0;
- TM1650_SCL=1;
- Delay5us();
- TM1650_SDA=1;
- }
- void TM1650_I2C_W(unsigned char Data)//I2C发送数据
- {
- char i;
- for(i=0;i<8;i++)
- {
- TM1650_SDA=Data&(0x80>>i);
- TM1650_SCL=1;
- Delay5us();
- TM1650_SCL=0;
- Delay5us();
- }
- }
- void TM1650_I2C_ACK(void)//I2C接收ACK
- {
- TM1650_SDA=1;
- TM1650_SCL=1;
- Delay5us();
- TM1650_SCL=0;
- Delay5us();
- }
- /******************************************海上生明月******************************************/
- //TM1650数码管显示
- //数码管段码
- unsigned char NixieTable[24]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x80,0x76,0x38};
- unsigned char Location[4]={0x6E,0x6C,0x6A,0x68};//位选
- unsigned char Luminance[9]={0x00,0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01};//数码管亮度
- //TM1650初始化
- //Data数码管亮度 范围0~8 8最亮 0关闭显示
- void TM1650_Init(unsigned char Data)
- {
- TM1650_I2C_S();
- TM1650_I2C_W(0x48);
- TM1650_I2C_ACK();
- TM1650_I2C_W(Luminance[Data]);
- TM1650_I2C_ACK();
- TM1650_I2C_P();
- }
- //数码管显示
- //Digit 要显示的位置,范围1~4
- //Number 要显示的数字,范围0~10 10是关闭显示
- void TM1650_Nixie(unsigned char Digit,unsigned char Number)
- {
- TM1650_I2C_S();
- TM1650_I2C_W(Location[Digit-1]);
- TM1650_I2C_ACK();
- TM1650_I2C_W(NixieTable[Number]);
- TM1650_I2C_ACK();
- TM1650_I2C_P();
- }
- /******************************************海上生明月******************************************/
- //RX8025T_I2C
- void I2C_S()
- {
- SDA=1;
- SCL=1;
- Delay5us();
- SDA=0;
- SCL=0;
- Delay5us();
- }
- void I2C_P()
- {
- SDA=0;
- SCL=1;
- Delay5us();
- SDA=1;
- }
- void I2C_W(unsigned char Data)
- {
- char i;
- for(i=0;i<8;i++)
- {
- SDA=Data&(0x80>>i);
- SCL=1;
- Delay5us();
- SCL=0;
- Delay5us();
- }
- }
- unsigned char I2C_R(void)
- {
- unsigned char i,Data=0x00;
- SDA=1;
- for(i=0;i<8;i++)
- {
- SCL=1;
- Delay5us();
- if(SDA)
- Data|=(0x80>>i);
- SCL=0;
- Delay5us();
- }
- return Data;
- }
- void I2C_ACK(void)
- {
- SDA=1;
- SCL=1;
- Delay5us();
- SCL=0;
- Delay5us();
- }
- void I2C_WACK(bit Data)
- {
- SDA=Data;
- SCL=1;
- Delay5us();
- SCL=0;
- Delay5us();
- }
- /******************************************海上生明月******************************************/
- //RX8025T
- void R8025_Init(void)//R8025初始化
- {
- I2C_S();
- I2C_W(0x64);
- I2C_ACK();
- I2C_W(0x0D);
- I2C_ACK();
- I2C_W(0x00);
- I2C_ACK();
- I2C_W(0x00);
- I2C_ACK();
- I2C_W(0x40);
- I2C_ACK();
- I2C_P();
- }
- void R8025_R(void)//RX8025T读取分钟、小时
- {
- I2C_S();
- I2C_W(0x64);
- I2C_ACK();
- I2C_W(0x00);
- I2C_ACK();
- I2C_S();
- I2C_W(0x65);
- I2C_ACK();
- Sec=I2C_R();
- I2C_WACK(0);
- BMin=I2C_R();
- I2C_WACK(0);
- BHour=I2C_R();
- I2C_WACK(0);
- I2C_P();
- }
- void R8025_W(void)//R8025写入时、分、秒(00)
- {
- I2C_S();
- I2C_W(0x64);
- I2C_ACK();
- I2C_W(0x00);
- I2C_ACK();
- I2C_W(0x00);
- I2C_ACK();
- I2C_W(BMin);
- I2C_ACK();
- I2C_W(BHour);
- I2C_ACK();
- I2C_P();
- }
- /******************************************海上生明月******************************************/
- void BCD_Num(void)//BCD码转10进制
- {
- Min=(BMin/16)*10+BMin%16;
- Hour=(BHour/16)*10+BHour%16;
- }
- void Num_BCD(void)//10进制转BCD码
- {
- BMin=(Min/10)*16+Min%10;
- BHour=(Hour/10)*16+Hour%10;
- }
- /******************************************海上生明月******************************************/
- //Eeprom初始化
- //STC15W104 Eeprom地址0x0000~0x03FF共2个扇区
- void Eeprom_Init()
- {
- ISP_CONTR=0x82;
- }
- //Eeprom写入一个字节
- //ADDRH写入地址高8位,ADDRL写入地址低8位,Data要写入的字节
- void Eeprom_W(unsigned char ADDRH,unsigned char ADDRL,unsigned char Data)
- {
- ISP_ADDRH=ADDRH;
- ISP_ADDRL=ADDRL;
- ISP_DATA=Data;
- ISP_CMD=0x02;
- ISP_TRIG=0x5A;
- ISP_TRIG=0xA5;
- Delay(5);
- }
- //Eeprom读取一个字节
- //ADDRH读取地址高8位,ADDRL读取地址低8位
- unsigned char Eeprom_R(unsigned char ADDRH,unsigned char ADDRL)
- {
- unsigned char Data;
- ISP_ADDRH=ADDRH;
- ISP_ADDRL=ADDRL;
- ISP_CMD=0x01;
- ISP_TRIG=0x5A;
- ISP_TRIG=0xA5;
- Data=ISP_DATA;
- Delay(2);
- return Data;
- }
- //Eeprom擦除一个扇区
- //ADDRH擦除地址高8位,ADDRL擦除地址低8位(擦除扇区的任何一个地址)
- void Eeprom_Del(unsigned char ADDRH,unsigned char ADDRL)
- {
- ISP_ADDRH=ADDRH;
- ISP_ADDRL=ADDRL;
- ISP_CMD=0x03;
- ISP_TRIG=0x5A;
- ISP_TRIG=0xA5;
- Delay(30);
- }
- /******************************************海上生明月******************************************/
- void TimeShow(void)//时间显示
- {
-
- R8025_R(); //读取时间
- BCD_Num(); //把读取的时间BCD码转为10进制
- if(Hour/10==0) //小时显示,小时十位为0,不显示
- TM1650_Nixie(4,10);
- if(Hour/10)
- TM1650_Nixie(4,Hour/10);
- TM1650_Nixie(3,Hour%10);
- TM1650_Nixie(2,Min/10); //分钟显示
- TM1650_Nixie(1,Min%10);
- Delay(500); //延时半秒
-
- if(Hour/10==0)
- TM1650_Nixie(4,10+11); //显示“:”让“:”循环闪烁
- if(Hour/10)
- TM1650_Nixie(4,(Hour/10)+11);
- Delay(500);
- if(Hour==H1 && Min==00 && Sec<=1)//定时判断,只判断整点的0秒和1秒避免一直初始化TM1650
- TM1650_Init(L1); //设置时间到,初始化为指定亮度
- if(Hour==H2 && Min==00 && Sec<=1)
- TM1650_Init(L2);
-
- WDT_CONTR|=0x10;//喂狗
- }
- /******************************************海上生明月******************************************/
- void HourSet(void)//小时设置
- {
- TM1650_Nixie(1,10);
- TM1650_Nixie(2,10);
- if(KEY2==0)
- {
- Delay(20);
- while(KEY2==0);
- Delay(20);
- Hour++;
- Hour%=24;
- }
- if(Hour/10==0)
- TM1650_Nixie(4,10);
- if(Hour/10)
- TM1650_Nixie(4,Hour/10);
- TM1650_Nixie(3,Hour%10);
- WDT_CONTR|=0x10;
- }
- void MinSet(void)//分钟设置
- {
- TM1650_Nixie(3,10);
- TM1650_Nixie(4,10);
- if(KEY2==0)
- {
- Delay(20);
- while(KEY2==0);
- Delay(20);
- Min++;
- Min%=60;
- }
- TM1650_Nixie(2,Min/10);
- TM1650_Nixie(1,Min%10);
- Num_BCD();
- WDT_CONTR|=0x10;
- }
- /******************************************海上生明月******************************************/
- void H1Set(void)//第一时间点设置
- {
- TM1650_Nixie(4,22);//数码管第四位显示 H
- TM1650_Nixie(3,1); //数码管第三位显示 1
-
- TM1650_Nixie(2,H1/10);
- TM1650_Nixie(1,H1%10);
- if(KEY2==0)
- {
- Delay(20);
- while(KEY2==0);
- Delay(20);
- H1++;
- H1%=24;
- }
- WDT_CONTR|=0x10;
- }
- void L1Set(void)//第一时间点亮度设置
- {
- TM1650_Nixie(4,23);//数码管第四位显示 L
- TM1650_Nixie(3,1);
-
- TM1650_Nixie(2,L1/10);
- TM1650_Nixie(1,L1%10);
- if(KEY2==0)
- {
- Delay(20);
- while(KEY2==0);
- Delay(20);
- L1++;
- if(L1>=9)
- L1=1;
- }
- WDT_CONTR|=0x10;
- }
- void H2Set(void)//第二个时间点设置
- {
- TM1650_Nixie(4,22);
- TM1650_Nixie(3,2);
-
- TM1650_Nixie(2,H2/10);
- TM1650_Nixie(1,H2%10);
- if(KEY2==0)
- {
- Delay(20);
- while(KEY2==0);
- Delay(20);
- H2++;
- H2%=24;
- }
- WDT_CONTR|=0x10;
- }
- void L2Set(void)//第二时间点亮度设置
- {
- TM1650_Nixie(4,23);
- TM1650_Nixie(3,2);
-
- TM1650_Nixie(2,L2/10);
- TM1650_Nixie(1,L2%10);
- if(KEY2==0)
- {
- Delay(20);
- while(KEY2==0);
- Delay(20);
- L2++;
- L2%=9;
- }
- WDT_CONTR|=0x10;
- }
- /******************************************海上生明月******************************************/
- void Int_Init(void)//INT0中断初始化
- {
-
- IT0=1;
- IE0=0;
- EX0=1;
- EA =1;
- }
- void Int0_Routine(void) interrupt 0//INT0中断函数
- {
- EA =0; //关闭中断
- Delay(30); //按键消抖
- if(KEY1==0) //二次判断
- {
- if(Mode==0)
- {
- if(L1<=8) //检测Eeprom内是否存储上次设置
- TM1650_Init(L1);
- else
- TM1650_Init(1);
- Delay(10);
- Mode=1;
-
- }
- else if(Mode==1)
- {
- Delay(10);
- Mode=2;
- }
- else if(Mode==2)
- {
- R8025_W(); //设置的时间写入8025,秒位写入00
- Eeprom_Del(0x00,0x00);//擦除Eeprom
- Delay(10);
- Mode=3;
- }
- else if(Mode==3)
- {
- Eeprom_W(0x00,0x00,H1);//向Eeprom写入H1
- Delay(10);
- Mode=4;
- }
- else if(Mode==4)
- {
- Eeprom_W(0x00,0x01,L1);//向Eeprom写入L1
- Delay(10);
- Mode=5;
- }
- else if(Mode==5)
- {
- Eeprom_W(0x00,0x02,H2);//向Eeprom写入H2
- Delay(10);
- Mode=6;;
- }
- else if(Mode==6)
- {
- Eeprom_W(0x00,0x03,L2);//向Eeprom写入L2
- TM1650_Init(L1); //进入时间显示后,亮度按L1设置
- Delay(10);
- Mode=0;
- }
- }
- EA =1; //打开中断,等待下次按键
- }
- /******************************************海上生明月******************************************/
- void main()
- {
- Eeprom_Init(); //Eeprom初始化
- R8025_Init(); //RX8025T初始化
- WDT_CONTR=0x3F; //看门狗初始化
-
- H1=Eeprom_R(0x00,0x00);//读取上次设置
- L1=Eeprom_R(0x00,0x01);//读取上次设置
- H2=Eeprom_R(0x00,0x02);//读取上次设置
- L2=Eeprom_R(0x00,0x03);//读取上次设置
-
- Delay(100);
- if(L1<=8)//检测Eeprom内是否存储上次设置
- {
- TM1650_Init(L1);//如果存储上次设置,TM1650初始化按上次L1设置
- }
- else
- {
- TM1650_Init(1);//如果未存储上次设置,TM1650初始化亮度1
- }
- Int_Init();//按键中断初始化
-
- while(1)
- {
- switch(Mode)
- {
- case 0: TimeShow(); break;//时间显示
- case 1: HourSet(); break;//小时设置
- case 2: MinSet(); break;//分钟设置
- case 3: H1Set(); break;//H1设置,设置第1个时间点
- case 4: L1Set(); break;//L1设置,第1个时间点,变化亮度值,L1也是默认亮度值(不能设置为0)
- case 5: H2Set(); break;//H2设置,设置第2个时间点
- case 6: L2Set(); break;//L2设置,第2个时间点,变化亮度值(0,关闭显示)
- }
- }
- }
- /******************************************海上生明月******************************************/
复制代码 |
打赏
-
查看全部打赏
|