STM32实时时钟RTC按键修改时间文档格式.docx
《STM32实时时钟RTC按键修改时间文档格式.docx》由会员分享,可在线阅读,更多相关《STM32实时时钟RTC按键修改时间文档格式.docx(22页珍藏版)》请在冰豆网上搜索。
//延时初始化
LED_Init();
//初始化与LED连接的硬件接口
LCD12864_InitPort();
//初始化LCD
LCD12864_Init();
//KEY_Init();
//初始化按键
RTC_Init();
//初始化RTC
//usmart_dev.init(72);
//初始化USMART
EXTIX_Init();
while(tapdev_init())//初始化ENC28J60错误
{
LCD_ShowString(3,0,"
28J60InitError!
"
);
delay_ms(200);
LCD12864_Clr();
//清除之前显示
};
uip_init();
//uIP初始化
uip_ipaddr(ipaddr,192,168,1,10);
//设置本地设置IP地址
uip_sethostaddr(ipaddr);
uip_ipaddr(ipaddr,192,168,1,1);
//设置网关IP地址(其实就是你路由器的IP地址)
uip_setdraddr(ipaddr);
uip_ipaddr(ipaddr,255,255,254,0);
//设置网络掩码
uip_setnetmask(ipaddr);
uip_listen(HTONS(1200));
//监听1200端口,用于TCPServer
uip_listen(HTONS(80));
//监听80端口,用于WebServer
tcp_client_reconnect();
//尝试连接到TCPServer端,用于TCPClient
while
(1)
{Display_Time();
uip_polling();
//处理uip事件,必须插入到用户程序的循环体中
//key=KEY_Scan();
if(tcp_client_tsta!
=tcp_client_sta)//TCPClient状态改变
{
if(tcp_client_sta&
(1<
<
7))
{
接收数据:
disp_IP();
}
else
{LCD_ShowString(3,0,"
已断开!
"
disp_IP();
if(tcp_client_sta&
6))//收到新数据
{
//LCD12864_Clr();
//清除之前显示
received_date(tcp_client_databuf);
tcp_client_sta&
=~(1<
6);
}
tcp_client_tsta=tcp_client_sta;
delay_ms
(1);
usart3_Receive_Process();
}
}
//uip事件处理函数
//必须将该函数插入用户主循环,循环调用.
voiduip_polling(void)
{
u8i;
staticstructtimerperiodic_timer,arp_timer;
staticu8timer_ok=0;
if(timer_ok==0)//仅初始化一次
timer_ok=1;
timer_set(&
periodic_timer,CLOCK_SECOND/2);
//创建1个0.5秒的定时器
arp_timer,CLOCK_SECOND*10);
//创建1个10秒的定时器
}
uip_len=tapdev_read();
//从网络设备读取一个IP包,得到数据长度.uip_len在uip.c中定义
if(uip_len>
0)//有数据
{
//处理IP数据包(只有校验通过的IP包才会被接收)
if(BUF->
type==htons(UIP_ETHTYPE_IP))//是否是IP包?
{
uip_arp_ipin();
//去除以太网头结构,更新ARP表
uip_input();
//IP包处理
//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>
0
//需要发送的数据在uip_buf,长度是uip_len(这是2个全局变量)
if(uip_len>
0)//需要回应数据
{
uip_arp_out();
//加以太网头结构,在主动连接时可能要构造ARP请求
tapdev_send();
//发送数据到以太网
}
}elseif(BUF->
type==htons(UIP_ETHTYPE_ARP))//处理arp报文,是否是ARP请求包?
uip_arp_arpin();
//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>
//需要发送的数据在uip_buf,长度是uip_len(这是2个全局变量)
if(uip_len>
0)tapdev_send();
//需要发送数据,则通过tapdev_send发送
}elseif(timer_expired(&
periodic_timer))//0.5秒定时器超时
timer_reset(&
periodic_timer);
//复位0.5秒定时器
//轮流处理每个TCP连接,UIP_CONNS缺省是40个
for(i=0;
i<
UIP_CONNS;
i++)
uip_periodic(i);
//处理TCP通信事件
//当上面的函数执行后,如果需要发送数据,则全局变量uip_len>
//需要发送的数据在uip_buf,长度是uip_len(这是2个全局变量)
0)
#ifUIP_UDP//UIP_UDP
//轮流处理每个UDP连接,UIP_UDP_CONNS缺省是10个
UIP_UDP_CONNS;
uip_udp_periodic(i);
//处理UDP通信事件
if(uip_len>
0)
#endif
//每隔10秒调用1次ARP定时器函数用于定期ARP处理,ARP表10秒更新一次,旧的条目会被抛弃
if(timer_expired(&
arp_timer))
timer_reset(&
arp_timer);
uip_arp_timer();
}
voidDisplay_Time(void)
{if(t!
=timer.sec)
{t=timer.sec;
LCD_ShowString(1,5,"
星期"
LCD_ShowString(0,3,"
20"
LCD_Shownum(0,4,(timer.w_year%100));
LCD12684_Wdat(0x2d);
LCD_Shownum1(timer.w_month);
LCD_Shownum1(timer.w_date);
switch(timer.week)
case0:
LCD_ShowString(1,7,"
日"
break;
case1:
一"
case2:
二"
case3:
三"
case4:
四"
case5:
五"
case6:
六"
LCD_Shownum(1,0,timer.hour);
LCD12684_Wdat(0x3a);
LCD_Shownum1(timer.min);
LCD_Shownum1(timer.sec);
voidreceived_date(u8*str)
{u8len;
len=(u8)strlen(str);
switch(len)
case13:
Addres_4=(u8)Process_date(0,(str[0]-0x30),str[1],str[2]);
Addres_3=(u8)Process_date(0,(str[4]-0x30),str[5],str[6]);
Addres_2=(u8)Process_date(0,0,str[8],str[9]);
Addres_1=(u8)Process_date(0,0,str[11],str[12]);
uip_ipaddr(ipaddr,Addres_4,Addres_3,Addres_2,Addres_1);
uip_sethostaddr(ipaddr);
disp_IP();
break;
case19:
RTC->
CRH&
=~(0X01);
while(!
(RTC->
CRL&
5)));
//等待RTC寄存器操作完成
timer.w_year=(s16)Process_date(str[0]-0x30,str[1]-0x30,str[2],str[3]);
timer.w_month=(s8)Process_date(0,0,str[5],str[6]);
timer.w_date=(s8)Process_date(0,0,str[8],str[9]);
timer.hour=(s8)Process_date(0,0,str[11],str[12]);
timer.min=(s8)Process_date(0,0,str[14],str[15]);
timer.sec=(s8)Process_date(0,0,str[17],str[18]);
RTC_Set(timer.w_year,timer.w_month,timer.w_date,timer.hour,timer.min,timer.sec);
//设置时间
RTC->
CRH|=0X01;
//等待RTC寄存器操作完成
case6:
case7:
case8:
case9:
case10:
case11:
LCD_ShowString(3,5,str);
Speech(str);
default:
u16Process_date(u8q,u8b,u8s,u8g)
u16temp;
temp=q*1000+b*100+(s-0x30)*10+(g-0x30);
returntemp;
HARDWARE文件夹下rtc。
C文件
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//MiniSTM32开发板
//RTC实时时钟驱动代码
//修改日期:
2010/12/30
//版本:
V1.1
//版权所有,XX。
//Copyright(C)正点原子2009-2019
//Allrightsreserved
//********************************************************************************
//V1.1修改说明
//修改了RTC_Init函数分频设置无效的bug
//修改了RTC_Get函数的一个bug
//RTC实时时钟驱动代码
//2010/6/6
tmtimer;
//时钟结构体
//实时时钟配置
//初始化RTC时钟,同时检测时钟是否工作正常
//BKP->
DR1用于保存是否第一次配置的设置
//返回0:
正常
//其他:
错误代码
u8RTC_Init(void)
//检查是不是第一次配置时钟
u8temp=0;
if(BKP->
DR1!
=0X5050)//第一次配置
RCC->
APB1ENR|=1<
28;
//使能电源时钟
27;
//使能备份时钟
PWR->
CR|=1<
8;
//取消备份区写保护
BDCR|=1<
16;
//备份区域软复位
BDCR&
16);
//备份区域软复位结束
RCC->
0;
//开启外部低速振荡器
while((!
(RCC->
0X02))&
&
temp<
250)//等待外部时钟就绪
temp++;
delay_ms(10);
};
if(temp>
=250)return1;
//初始化时钟失败,晶振有问题
//LSI作为RTC时钟
15;
//RTC时钟使能
while(!
//等待RTC寄存器操作完成
3)));
//等待RTC寄存器同步
RTC->
//允许秒中断
CRL|=1<
4;
//允许配置
PRLH=0X0000;
PRLL=32767;
//时钟周期设置(有待观察,看是否跑慢了?
)理论值:
32767
Auto_Time_Set();
//RTC_Set(2009,12,2,10,0,55);
//设置时间
4);
//配置更新
//等待RTC寄存器操作完成
BKP->
DR1=0X5050;
//BKP_Write(1,0X5050);
;
//在寄存器1标记已经开启了
//printf("
FIRSTTIME\n"
}else//系统继续计时
CRH|=0x01;
//等待RTC寄存器操作完成
OK\n"
}
MY_NVIC_Init(0,0,RTC_IRQChannel,2);
//RTC,G2,P2,S2.优先级最低
RTC_Get();
//更新时间
return0;
//ok
//RTC中断服务函数
//constu8*Week[2][7]=
//{
//{"
Sunday"
"
Monday"
Tuesday"
Wednesday"
Thursday"
Friday"
Saturday"
},
//};
//RTC时钟中断
//每秒触发一次
voidRTC_IRQHandler(void)
{
if(RTC->
0x0001)//秒钟中断
{
RTC_Get();
//更新时间
CRL:
%d\n"
RTC->
CRL);
0x0002)//闹钟中断
Alarm!
\n"
=~(0x0002);
//清闹钟中断
//闹钟处理
}
=0X0FFA;
//清除溢出,秒钟中断标志
//等待RTC寄存器操作完成
//判断是否是闰年函数
//月份123456789101112
//闰年312931303130313130313031
//非闰年312831303130313130313031
//输入:
年份
//输出:
该年份是不是闰年.1,是.0,不是
u8Is_Leap_Year(u16year)
{
if(year%4==0)//必须能被4整除
if(year%100==0)
{
if(year%400==0)return1;
//如果以00结尾,还要能被400整除
elsereturn0;
}elsereturn1;
}elsereturn0;
}
//设置时钟
//把输入的时钟转换为秒钟
//以1970年1月1日为基准
//1970~2099年为合法年份
//返回值:
0,成功;
其他:
错误代码.
//月份数据表
u8consttable_week[12]={0,3,3,6,1,4,6,2,5,0,3,5};
//月修正数据表
//平年的月份日期表
constu8mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
u8RTC_Set(u16syear,u8smon,u8sday,u8hour,u8min,u8sec)
u16t;
u32seccount=0;
if(syear<
1970||syear>
2099)return1;
for(t=1970;
t<
syear;
t++)//把所有年份的秒钟相加
if(Is_Leap_Year(t))seccount+=31622400;
//闰年的秒钟数
elseseccount+=31536000;
//平年的秒钟数
smon-=1;
for(t=0;
smon;
t++)//把前面月份的秒钟数相加
seccount+=(u32)mon_table[t]*86400;
//月份秒钟数相加
if(Is_Leap_Year(syear)&
t==1)seccount+=86400;
//闰年2月份增加一天的秒钟数
seccount+=(u32)(sday-1)*86400;
//把前面日期的秒钟数相加
seccount+=(u32)hour*3600;
//