|
创意旋转时钟,自己添加ESP8266网络自动校时功能
[复制链接]
前段时间t 宝买了个创意旋转时钟
用了一段时间感觉走时不准, 打算加个自动校时功能就自己重写了单片机程序并配了个ESP8266的模块
现在终于不用再手工校对时间了,而且还有18650电池,可以充电
正面
背面
单片机程序
-
#include <global.h>
#include <stdio.h>
#include "DS1302.h"
#include "DS18B20.h"
//-----------------------------------------------
/* define constants */
#define FOSC 12000000
#define BAUD 19200 //UART baudrate
bit UpdateDisp,UpdateTime,ShowTemp,CapTemp,TempChange,UpdateMsg,ShowFlag;
static uint8 ss=0;
static uint16 ms=0;
#define CommBufSize 0x3F
struct tcomm_buf{
uint8 sendBuf[CommBufSize],receBuf[CommBufSize];
uint8 receTimeOut;
uint8 sendCount; //发送字节个数
uint8 receCount; //接收到的字节个数
uint8 sendPosi; //发送位置
};
struct tcomm_buf xdata comm1_data;
/*
void Delay1ms() //@12.000MHz
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
void Delayms(uint16 c) //@12.000MHz
{
while(c--)
Delay1ms();
}
*/
void Uart_Check(void);
void UpdateLed(void){
P3= P3|0xF0; //高四位数码管 P3.1 P3.2 串口 P3.2 MODE P3.3 Plus
P2=0xFF;
P0=~(1<<(sec%8)); //Led/数码管公用IO
P2=~(1<<(sec/8)); //led
}
const uint8 NixieMap[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x9C,0xFF};
void UpdateNixie(uint8 l){
int8 tmpVal;
P2=0xFF; //led
P3=(P3|0xF0);
P0= 0xFF;
if(ShowTemp){
switch(l){
case 0:
tmpVal = Temp1/10;
break;
case 1:
tmpVal = Temp1%10;
break;
case 2:
tmpVal = 16;
break;
case 3:
tmpVal = 0x0C;
break;
}
P0= NixieMap[tmpVal]; //Led/数码管公用IO
}
else
{
switch(l){
case 0:
tmpVal = hour/10;
//P0= 0xC0;
//P3=0xE0|(P3&0x0F);
break;
case 1:
tmpVal = hour%10;
//P0= 0xF9;
//P3=0xD0|(P3&0x0F);
break;
case 2:
tmpVal = min/10;
//P0= 0xA4;
//P3=0xB0|(P3&0x0F);
break;
case 3:
tmpVal = min%10;
//P0= 0xB0;
//P3=0x70|(P3&0x0F);
break;
}
if(l==1&&ShowFlag)
P0= NixieMap[tmpVal] & 0x7F; //Led/数码管公用IO
else
P0= NixieMap[tmpVal]; //Led/数码管公用IO
}
P3=(~(1<<(l+4)))|(P3 & 0x0F); //高四位数码管 P3.0 P3.1 串口 P3.2 MODE P3.3 Plus
}
//void UartInit(void) //115200bps@22.1184MHz
//{
// PCON |= 0x80; //使能波特率倍速位SMOD
// SCON = 0x50; //8位数据,可变波特率
// AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
// AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
// TMOD &= 0x0F; //清除定时器1模式位
// TMOD |= 0x20; //设定定时器1为8位自动重装方式
// TL1 = 0xFF; //设定定时初值
// TH1 = 0xFF; //设定定时器重装值
// ET1 = 0; //禁止定时器1中断
// TR1 = 1; //启动定时器1
// ES=1;
//}
//void UartInit(void) //19200bps@22.1184MHz
//{
// PCON &= 0x7F; //波特率不倍速
// SCON = 0x50; //8位数据,可变波特率
// AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
// AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
// TMOD &= 0x0F; //清除定时器1模式位
// TMOD |= 0x20; //设定定时器1为8位自动重装方式
// TL1 = 0xFD; //设定定时初值
// TH1 = 0xFD; //设定定时器重装值
// ET1 = 0; //禁止定时器1中断
// TR1 = 1; //启动定时器1
// ES=1;
//}
void UartInit(void) //9600bps@22.1184MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1;
}
//void Timer0Init(void) //1毫秒@22.1184MHz
//{
// AUXR &= 0x7F; //定时器时钟12T模式
// TMOD &= 0xF0; //设置定时器模式
// TL0 = 0x00; //设置定时初值
// TH0 = 0xB8; //设置定时初值
// TF0 = 0; //清除TF0标志
// TR0 = 1; //定时器0开始计时
// ET0 = 1; //enable timer0 interrupt
//}
void Timer0Init(void) //25毫秒@22.1184MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x4C; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //enable timer0 interrupt
}
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{
UpdateDisp=1;
ShowFlag = ms<122;
if(ms++>222){
ms=0;
sec++;
switch(sec%4){
case 1:
TempChange=1;
break;
case 2:
CapTemp=1;
break;
case 3:
//ShowTemp=1;
break;
}
if(sec>=60){
sec=0;
UpdateTime=1;
}
if((sec%5)>=3){
ShowTemp=1;
}
else
ShowTemp=0;
}
}
void WaitMs(void){
while(UpdateDisp==0);
}
void main()
{
P0=0xFF; //Led/数码管公用IO
P1=0xFF; // 蜂鸣器 P1.0 18B20 P1.1 P1.2 P1.3 DS1302
P2=0xFF; //led
P3=0xFF; //高四位数码管 P3.0 P3.1 串口 P3.2 MODE P3.3 Plus
ShowFlag = 0;
ShowTemp = 0;
comm1_data.sendCount=0;
comm1_data.sendPosi=0;
UartInit();
Timer0Init();
EA = 1; //Open master interrupt switch
printf("STC89-90xx\r\nUart Test !\r\n");
DS1302_readtime();
// year=18;
// month=11;
// day=2;
// hour=14;
// min=32;
// sec=0;
//
// DS1302_Write();
//P0=0x1;
//uint8 c=1;
while(1){
Uart_Check();
UpdateNixie(0);
WaitMs();
UpdateNixie(1);
WaitMs();
UpdateNixie(2);
WaitMs();
UpdateNixie(3);
WaitMs();
UpdateLed();
if(UpdateTime){
UpdateTime=0;
DS1302_readtime();//sec,min,hour,day,month,week,year
printf("Update Time %02d-%02d-%02d %02d:%02d:%02d\r\n",year,month,day,hour,min,sec);
}
if(TempChange){
TempChange=0;
Start_Change();
}
if(CapTemp){
CapTemp=0;
Read_Temperature();
}
// if(ShowTemp){
// ShowTemp=0;
// printf("Temperature: %.1f\r\n",Temp);
// }
WaitMs();
}
}
/*----------------------------
UART interrupt service routine
----------------------------*/
void Uart_Isr() interrupt 4 using 1
{
if(TI)
{
TI = 0;
if(comm1_data.sendPosi < comm1_data.sendCount)
{
SBUF = comm1_data.sendBuf[comm1_data.sendPosi++];
}
else
{
comm1_data.sendPosi = 0;
comm1_data.sendCount = 0;
comm1_data.receCount = 0; //清接收地址偏移寄存器
}
}
else if(RI)
{
RI = 0;
comm1_data.receTimeOut = 5; //通讯超时值
……………………
|
|