STM32实时时钟RTC按键修改时间.docx

上传人:b****8 文档编号:28468894 上传时间:2023-07-14 格式:DOCX 页数:23 大小:23.28KB
下载 相关 举报
STM32实时时钟RTC按键修改时间.docx_第1页
第1页 / 共23页
STM32实时时钟RTC按键修改时间.docx_第2页
第2页 / 共23页
STM32实时时钟RTC按键修改时间.docx_第3页
第3页 / 共23页
STM32实时时钟RTC按键修改时间.docx_第4页
第4页 / 共23页
STM32实时时钟RTC按键修改时间.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

STM32实时时钟RTC按键修改时间.docx

《STM32实时时钟RTC按键修改时间.docx》由会员分享,可在线阅读,更多相关《STM32实时时钟RTC按键修改时间.docx(23页珍藏版)》请在冰豆网上搜索。

STM32实时时钟RTC按键修改时间.docx

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)

{

//系统时钟设置

//串口初始化为9600

//延时初始化

//初始化与LED连接的硬件接口

//初始化LCD

Stm32_Clock_Init(9);//usart_init(72,9600);

USART3_Init(36,9600);

USART2_Init(36,9600);delay_init(72);

LED_Init();

LCD12864_InitPort();

LCD12864_Init();

//KEY_Init();

RTC_Init();

//usmart_dev.init(72);

EXTIX_Init();

while(tapdev_init())

{

//初始化按键

//初始化RTC

//初始化USMART

//初始化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));uip_listen(HTONS(80));

tcp_client_reconnect();

while

(1)

{Display_Time();

//监听1200端口,用于TCPServer

//监听80端口,用于WebServer

II尝试连接到TCPServer端,用于TCPClient

uip_polling();//处理uip事件,必须插入到用户程序的循环体中

IIkey=KEY_Scan();

if(tcp_client_tsta!

=tcp_client_sta)IITCPClient状态改变

{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))〃收到新数据

{

IILCD12864_Clr();II清除之前显示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>O)tapdev_send();〃需要发送数据,则通过tapdev_send发送

}

}elseif(timer_expired(&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/6tmtimer;//时钟结构体//实时时钟配置//初始化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->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寄存器操作完成//允许配置

//时钟周期设置(有待观察,看是否跑慢了?

)理论

//设置时间//配置更新

//等待RTC寄存器操作完成

BKP->DR1=0X5050;

//BKP_Write(1,0X5050);;//在寄存器1标记已经开启了

//printf("FIRSTTIME\n");

}else//系统继续计时

{

等待RTC寄存器同步

//允许秒中断

等待RTC寄存器操作完成

while(!

(RTC->CRL&(1<<3)));//RTC->CRH|=0x01;

while(!

(RTC->CRL&(1<<5)));////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;//小时秒钟数seccount+=(u32)min*60;//分钟秒钟数

seccount+=sec;〃最后的秒钟加上去

//设置时钟

RCC->APB1ENR|=1<<28;//使能电源时钟

RCC->APB1ENR|=1<<27;//使能备份时钟

PWR->CR|=1<<8;//取消备份区写保护//上面三步是必须的!

RTC->CRL|=1<<4;//允许配置

RTC->CNTL=seccount&0xffff;

RTC->CNTH=seccount>>16;

RTC->CRL&=~(1<<4);//配置更新while(!

(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成return0;

}//得到当前的时间//返回值:

0,成功;其他:

错误代码.u8RTC_Get(void)

{

staticu16daycnt=0;

u32timecount=0;

u32temp=0;

u16temp1=0;

timecount=RTC->CNTH;//得到计数器中的值(秒钟数)

timecount<<=16;

timecount+=RTC->CNTL;

temp=timecount/86400;//得到天数(秒钟数对应的)

if(daycnt!

=temp)//超过一天了

{

daycnt=temp;

temp1=1970;//从1970年开始

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 职业教育 > 职高对口

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1