STM32实时时钟RTC按键修改时间.docx
- 文档编号:5422064
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:22
- 大小:23.69KB
STM32实时时钟RTC按键修改时间.docx
《STM32实时时钟RTC按键修改时间.docx》由会员分享,可在线阅读,更多相关《STM32实时时钟RTC按键修改时间.docx(22页珍藏版)》请在冰豆网上搜索。
STM32实时时钟RTC按键修改时间
User文件夹下main.c
#include"sys.h"
#include"usart.h"
#include"delay.h"
#include"led.h"
#include"key.h"
#include"exti.h"
#include"wdg.h"
#include"timerx.h"
#include"adc.h"
#include"rtc.h"
#include"12864.h"
#include"ov7670.h"
#include"usmart.h"
#include"enc28j60.h"
#include"uip.h"
#include"uip_arp.h"
#include"tapdev.h"
#include"timer.h"
#include"math.h"
#include"string.h"
#include"syn.h"
//MiniSTM32开发板扩展实验21
//ENC28J60网络模块实验
//正点原子@ALIENTEK
//技术论坛:
//广州市星翼电子科技有限公司
voiduip_polling(void);
voidDisplay_Time(void);
voidreceived_date(u8*str);
u16Process_date(u8q,u8b,u8s,u8g);
#defineBUF((structuip_eth_hdr*)&uip_buf[0])
u8t,Addres_1=10,Addres_2=1,Addres_3=168,Addres_4=192;
intmain(void)
{
Stm32_Clock_Init(9);//系统时钟设置
//usart_init(72,9600);//串口初始化为9600
USART3_Init(36,9600);
USART2_Init(36,9600);
delay_init(72);//延时初始化
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))
{
LCD_ShowString(3,0,"接收数据:
");
disp_IP();
}
else
{LCD_ShowString(3,0,"已断开!
");
disp_IP();
}
if(tcp_client_sta&(1<<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秒的定时器
timer_set(&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>0
//需要发送的数据在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_periodic(i);//处理TCP通信事件 //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf,长度是uip_len(这是2个全局变量) if(uip_len>0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } } #ifUIP_UDP//UIP_UDP //轮流处理每个UDP连接,UIP_UDP_CONNS缺省是10个 for(i=0;i { uip_udp_periodic(i);//处理UDP通信事件 //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf,长度是uip_len(这是2个全局变量) if(uip_len>0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } } #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); LCD12684_Wdat(0x2d); LCD_Shownum1(timer.w_date); switch(timer.week) { case0: LCD_ShowString(1,7,"日");break; case1: LCD_ShowString(1,7,"一");break; case2: LCD_ShowString(1,7,"二");break; case3: LCD_ShowString(1,7,"三");break; case4: LCD_ShowString(1,7,"四");break; case5: LCD_ShowString(1,7,"五");break; case6: LCD_ShowString(1,7,"六");break; } LCD_Shownum(1,0,timer.hour); LCD12684_Wdat(0x3a); LCD_Shownum1(timer.min); LCD12684_Wdat(0x3a); 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);//设置本地设置IP地址 uip_sethostaddr(ipaddr); tcp_client_reconnect(); disp_IP();break; case19: RTC->CRH&=~(0X01); while(! (RTC->CRL&(1<<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; while(! (RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 break; case6: case7: case8: case9: case10: case11: LCD_ShowString(3,5,str); Speech(str);break; default: break; } } u16Process_date(u8q,u8b,u8s,u8g) { u16temp; temp=q*1000+b*100+(s-0x30)*10+(g-0x30); returntemp; } HARDWARE文件夹下rtc。 C文件 #include"sys.h" #include"rtc.h" #include"delay.h" #include"usart.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //MiniSTM32开发板 //RTC实时时钟驱动代码 //正点原子@ALIENTEK //技术论坛: //修改日期: 2010/12/30 //版本: V1.1 //版权所有,XX。 //Copyright(C)正点原子2009-2019 //Allrightsreserved //******************************************************************************** //V1.1修改说明 //修改了RTC_Init函数分频设置无效的bug //修改了RTC_Get函数的一个bug ////////////////////////////////////////////////////////////////////////////////// //MiniSTM32开发板 //RTC实时时钟驱动代码 //正点原子@ALIENTEK //2010/6/6 tmtimer;//时钟结构体 //实时时钟配置 //初始化RTC时钟,同时检测时钟是否工作正常 //BKP->DR1用于保存是否第一次配置的设置 //返回0: 正常 //其他: 错误代码 u8RTC_Init(void) { //检查是不是第一次配置时钟 u8temp=0; if(BKP->DR1! =0X5050)//第一次配置 { RCC->APB1ENR|=1<<28;//使能电源时钟 RCC->APB1ENR|=1<<27;//使能备份时钟 PWR->CR|=1<<8;//取消备份区写保护 RCC->BDCR|=1<<16;//备份区域软复位 RCC->BDCR&=~(1<<16);//备份区域软复位结束 RCC->BDCR|=1<<0;//开启外部低速振荡器 while((! (RCC->BDCR&0X02))&&temp<250)//等待外部时钟就绪 { temp++; delay_ms(10); }; if(temp>=250)return1;//初始化时钟失败,晶振有问题 RCC->BDCR|=1<<8;//LSI作为RTC时钟 RCC->BDCR|=1<<15;//RTC时钟使能 while(! (RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 while(! (RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH|=0X01;//允许秒中断 while(! (RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 RTC->CRL|=1<<4;//允许配置 RTC->PRLH=0X0000; RTC->PRLL=32767;//时钟周期设置(有待观察,看是否跑慢了? )理论值: 32767 Auto_Time_Set(); //RTC_Set(2009,12,2,10,0,55);//设置时间 RTC->CRL&=~(1<<4);//配置更新 while(! (RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 BKP->DR1=0X5050; //BKP_Write(1,0X5050);;//在寄存器1标记已经开启了 //printf("FIRSTTIME\n"); }else//系统继续计时 { while(! (RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH|=0x01;//允许秒中断 while(! (RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 //printf("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->CRL&0x0001)//秒钟中断 { RTC_Get();//更新时间 //printf("CRL: %d\n",RTC->CRL); } if(RTC->CRL&0x0002)//闹钟中断 { //printf("Alarm! \n"); RTC->CRL&=~(0x0002);//清闹钟中断 //闹钟处理 } RTC->CRL&=0X0FFA;//清除溢出,秒钟中断标志 while(! (RTC->CRL&(1<<5)));//等待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 { if(Is_Leap_Year(t))seccount+=31622400;//闰年的秒钟数 elseseccount+=31536000;//平年的秒钟数 } smon-=1; for(t=0;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;//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32 实时 时钟 RTC 按键 修改 时间
![提示](https://static.bdocx.com/images/bang_tan.gif)