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

更新时间:2023-03-11 22:00:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

User文件夹下main.c #include \#include \ #include \ #include \ #include \#include \#include \#include \#include \#include \

#include \ #include \#include \ #include \#include \#include \#include \#include \ #include \ #include \ #include \

//Mini STM32开发板扩展实验21 //ENC28J60网络模块 实验 //正点原子@ALIENTEK

//技术论坛:www.openedv.com //广州市星翼电子科技有限公司 void uip_polling(void); void Display_Time(void); void received_date(u8 *str);

u16 Process_date(u8 q,u8 b,u8 s,u8 g);

#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) u8 t,Addres_1=10,Addres_2=1,Addres_3=168,Addres_4=192; int main(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,\ 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端口,用于TCP Server uip_listen(HTONS(80)); //监听80端口,用于Web Server tcp_client_reconnect(); //尝试连接到TCP Server端,用于TCP Client while (1) { Display_Time(); uip_polling(); //处理uip事件,必须插入到用户程序的循环体中 // key=KEY_Scan(); if(tcp_client_tsta!=tcp_client_sta)//TCP Client状态改变 { 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事件处理函数

//必须将该函数插入用户主循环,循环调用. void uip_polling(void) { u8 i; static struct timer periodic_timer, arp_timer; static u8 timer_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();//发送数据到以太网 } }else if (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发送 } }else if(timer_expired(&periodic_timer)) //0.5秒定时器超时 { timer_reset(&periodic_timer); //复位0.5秒定时器

//轮流处理每个TCP连接, UIP_CONNS缺省是40个 for(i=0;i0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len>0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } }

#if UIP_UDP //UIP_UDP //轮流处理每个UDP连接, UIP_UDP_CONNS缺省是10个 for(i=0;i0 //需要发送的数据在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(); } } }

void Display_Time(void) { if(t!=timer.sec) { t=timer.sec; LCD_ShowString(1,5,\星期\ LCD_ShowString(0,3,\ LCD_Shownum(0,4,(timer.w_year0)); LCD12684_Wdat(0x2d); LCD_Shownum1(timer.w_month); LCD12684_Wdat(0x2d);

LCD_Shownum1(timer.w_date); switch(timer.week) { case 0:LCD_ShowString(1,7,\日\ case 1:LCD_ShowString(1,7,\一\ case 2:LCD_ShowString(1,7,\二\ case 3:LCD_ShowString(1,7,\三\ case 4:LCD_ShowString(1,7,\四\ case 5:LCD_ShowString(1,7,\五\ case 6:LCD_ShowString(1,7,\六\ } LCD_Shownum(1,0,timer.hour); LCD12684_Wdat(0x3a); LCD_Shownum1(timer.min); LCD12684_Wdat(0x3a); LCD_Shownum1(timer.sec); } }

void received_date(u8 *str) { u8 len; len=(u8)strlen(str); switch(len) { case 13: 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; case 19: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; case 6: case 7: case 8: case 9: case 10 :

case 11 : LCD_ShowString(3,5,str); Speech(str);break; default : break; } }

u16 Process_date(u8 q,u8 b,u8 s,u8 g) { u16 temp;

temp=q*1000+b*100+(s-0x30)*10+(g-0x30); return temp ; }

HARDWARE文件夹下rtc。C文件 #include \#include \ #include \#include \

//////////////////////////////////////////////////////////////////////////////////

//本程序只供学习使用,未经作者许可,不得用于其它任何用途 //Mini STM32开发板

//RTC实时时钟 驱动代码 //正点原子@ALIENTEK

//技术论坛:www.openedv.com //修改日期:2010/12/30 //版本:V1.1

//版权所有,盗版必究。

//Copyright(C) 正点原子 2009-2019

//All rights reserved

//********************************************************************************

//V1.1修改说明

//修改了RTC_Init函数分频设置无效的bug //修改了RTC_Get函数的一个bug

//////////////////////////////////////////////////////////////////////////////////

//Mini STM32开发板

//RTC实时时钟 驱动代码 //正点原子@ALIENTEK //2010/6/6

tm timer;//时钟结构体 //实时时钟配置

//初始化RTC时钟,同时检测时钟是否工作正常 //BKP->DR1用于保存是否第一次配置的设置 //返回0:正常 //其他:错误代码 u8 RTC_Init(void) { //检查是不是第一次配置时钟 u8 temp=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)return 1;//初始化时钟失败,晶振有问题 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(\ }else//系统继续计时 { while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH|=0x01; //允许秒中断 while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 //printf(\ } MY_NVIC_Init(0,0,RTC_IRQChannel,2);//RTC,G2,P2,S2.优先级最低 RTC_Get();//更新时间 return 0; //ok }

//RTC中断服务函数 //const u8* Week[2][7]= //{

//{\//{\日\一\二\三\四\五\六\//}; //RTC时钟中断 //每秒触发一次

void RTC_IRQHandler(void) { if(RTC->CRL&0x0001)//秒钟中断 { RTC_Get();//更新时间 //printf(\ } if(RTC->CRL&0x0002)//闹钟中断 { //printf(\ RTC->CRL&=~(0x0002);//清闹钟中断 //闹钟处理

} RTC->CRL&=0X0FFA; //清除溢出,秒钟中断标志 while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 }

//判断是否是闰年函数

//月份 1 2 3 4 5 6 7 8 9 10 11 12 //闰年 31 29 31 30 31 30 31 31 30 31 30 31 //非闰年 31 28 31 30 31 30 31 31 30 31 30 31 //输入:年份

//输出:该年份是不是闰年.1,是.0,不是 u8 Is_Leap_Year(u16 year) { if(year%4==0) //必须能被4整除 { if(year0==0) { if(year@0==0)return 1;//如果以00结尾,还要能被400整除 else return 0; }else return 1; }else return 0; } //设置时钟

//把输入的时钟转换为秒钟 //以1970年1月1日为基准 //1970~2099年为合法年份

//返回值:0,成功;其他:错误代码. //月份数据表

u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正数据表 //平年的月份日期表

const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31}; u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec) { u16 t; u32 seccount=0; if(syear<1970||syear>2099)return 1; for(t=1970;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寄存器操作完成 return 0; }

//得到当前的时间

//返回值:0,成功;其他:错误代码. u8 RTC_Get(void) { static u16 daycnt=0; u32 timecount=0; u32 temp=0; u16 temp1=0; timecount=RTC->CNTH;//得到计数器中的值(秒钟数) timecount<<=16; timecount+=RTC->CNTL; temp=timecount/86400; //得到天数(秒钟数对应的) if(daycnt!=temp)//超过一天了 { daycnt=temp; temp1=1970; //从1970年开始 while(temp>=365) { if(Is_Leap_Year(temp1))//是闰年 { if(temp>=366)temp-=366;//闰年的秒钟数

else break; } else temp-=365; //平年 temp1++; } timer.w_year=temp1;//得到年份 temp1=0; while(temp>=28)//超过了一个月 { if(Is_Leap_Year(timer.w_year)&&temp1==1)//当年是不是闰年/2月份 { if(temp>=29)temp-=29;//闰年的秒钟数 else break; } else { if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年 else break; } temp1++; } timer.w_month=temp1+1;//得到月份 timer.w_date=temp+1; //得到日期 } temp=timecount?400; //得到秒钟数 timer.hour=temp/3600; //小时 timer.min=(temp600)/60; //分钟 timer.sec=(temp600)`; //秒钟 timer.week=RTC_Get_Week(timer.w_year,timer.w_month,timer.w_date);//获取星期 return 0; }

//获得现在是星期几

//功能描述:输入公历日期得到星期(只允许1901-2099年) //输入参数:公历年月日 //返回值:星期号

u8 RTC_Get_Week(u16 year,u8 month,u8 day) { u16 temp2; u8 yearH,yearL; yearH=year/100; yearL=year0; // 如果为21世纪,年份数加100 if (yearH>19)yearL+=100;

// 所过闰年数只算1900年之后的 temp2=yearL+yearL/4; temp2=temp2%7; temp2=temp2+day+table_week[month-1]; if (yearL%4==0&&month<3)temp2--; return(temp2%7); }

//比较两个字符串指定长度的内容是否相等 //参数:s1,s2要比较的两个字符串;len,比较长度 //返回值:1,相等;0,不相等

u8 str_cmpx(u8*s1,u8*s2,u8 len) { u8 i; for(i=0;i

extern const u8 *COMPILED_DATE;//获得编译日期 extern const u8 *COMPILED_TIME;//获得编译时间 const u8 Month_Tab[12][3]={\};

//自动设置时间为编译器时间 void Auto_Time_Set(void) { u8 temp[3]; u8 i; u8 mon,date; u16 year; u8 sec,min,hour; for(i=0;i<3;i++)temp[i]=COMPILED_DATE[i]; for(i=0;i<12;i++)if(str_cmpx((u8*)Month_Tab[i],temp,3))break; mon=i+1;//得到月份 if(COMPILED_DATE[4]==' ')date=COMPILED_DATE[5]-'0'; else date=10*(COMPILED_DATE[4]-'0')+COMPILED_DATE[5]-'0'; year=1000*(COMPILED_DATE[7]-'0')+100*(COMPILED_DATE[8]-'0')+10*(COMPILED_DATE[9]-'0')+COMPILED_DATE[10]-'0'; hour=10*(COMPILED_TIME[0]-'0')+COMPILED_TIME[1]-'0'; min=10*(COMPILED_TIME[3]-'0')+COMPILED_TIME[4]-'0'; sec=10*(COMPILED_TIME[6]-'0')+COMPILED_TIME[7]-'0'; RTC_Set(year,mon,date,hour,min,sec) ; //printf(\ %d:%d:%d\\n\}

Hardware文件夹下 exit。C #include \#include \#include \#include \#include \#include \#include \

//////////////////////////////////////////////////////////////////////////////////

//本程序只供学习使用,未经作者许可,不得用于其它任何用途 //Mini STM32开发板 //外部中断 驱动代码 //正点原子@ALIENTEK

//技术论坛:www.openedv.com //修改日期:2010/12/01 //版本:V1.0

//版权所有,盗版必究。

//Copyright(C) 正点原子 2009-2019 //All rights reserved

//////////////////////////////////////////////////////////////////////////////////

//外部中断0服务程序

void EXTI0_IRQHandler(void) { delay_ms(100);//消抖 if(KEY2==1) //按键2 { count++; if(count<7) { while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH&=~(0X01); //允许秒中断

while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 } switch(count)

{ case 1 : LCD_ShowString(2,4,\设置秒\ case 2 : LCD_ShowString(2,4,\设置分\ case 3 : LCD_ShowString(2,4,\设置时\ case 4 : LCD_ShowString(2,4,\设置日\ case 5 : LCD_ShowString(2,4,\设置月\ case 6 : LCD_ShowString(2,4,\设置年\ case 7

{ RTC_Set(timer.w_year,timer.w_month,timer.w_date,timer.hour,timer.min,timer.sec);

:

while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步 RTC->CRH|=0X01; //允许秒中断

while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 LCD_ShowString(2,4,\设置IP \ case 8 : LCD_ShowString(3,0,\ case 9 : LCD_ShowString(3,0,\ case 10 : LCD_ShowString(3,0,\

case 11 : count=0;LCD_ShowString(3,0,\ \ \ } } EXTI->PR=1<<0; //清除LINE0上的中断标志位 }

//外部中断15~10服务程序

void EXTI15_10_IRQHandler(void) { delay_ms(100); //消抖 if(KEY0==0) //按键0 { LED1=!LED1; switch(count) { case 1 : timer.sec--;if(timer.sec==0)timer.sec=59;LCD_Shownum(1,4,timer.sec);LCD_ShowString(2,7,\;break; case 2 : timer.min--;if(timer.min==0)timer.min=59;LCD_Shownum(1,2,timer.min);LCD_ShowString(2,7,\ case 3 : timer.hour--;if(timer.hour==0)timer.hour=12;LCD_Shownum(1,0,timer.hour);LCD_ShowString(2,7,\ case 4 : timer.w_date--;if(timer.w_date==0)timer.w_date=31;LCD_Shownum(0,4,timer.w_date);LCD_ShowString(2,7,\ case 5 : timer.w_month--;if(timer.w_month==0)timer.w_month=12;LCD_Shownum(0,2,timer.w_month);LCD_ShowString(2,7,\ case 6 : timer.w_year--;if(timer.w_year==0)timer.w_year=2099;LCD_Shownum(0,0,(timer.w_year0));LCD_ShowString(2,7,\ case 7 : Addres_1--;if(Addres_1==0) Addres_1=99;disp_IP();break; case 8 : Addres_2--;if(Addres_2==0) Addres_2=9;disp_IP();break; case 9 : Addres_3--;if(Addres_3==0)Addres_3=200;disp_IP();break;

case 10 : Addres_4--;if(Addres_4==0)Addres_4=200;disp_IP();break; }

}else if(KEY1==0)//按键1 {LED0=!LED0; switch(count) { case 1 : timer.sec++;if(timer.sec==60)timer.sec=0;LCD_Shownum(1,4,timer.sec);LCD_ShowString(2,7,\\ case 2 : timer.min++;if(timer.min==60)timer.min=0;LCD_Shownum(1,2,timer.min);LCD_ShowString(2,7,\break; case 3 : timer.hour++;if(timer.hour==12)timer.hour=0;LCD_Shownum(1,0,timer.hour);LCD_ShowString(2,7,\ case 4 : timer.w_date++;if(timer.w_date==32)timer.w_date=0;LCD_Shownum(0,4,timer.w_date);LCD_ShowString(2,7,\ case 5 : timer.w_month++;if(timer.w_month==32)timer.w_month=0;LCD_Shownum(0,2,timer.w_month);LCD_ShowString(2,7,\ case 6 : timer.w_year++;if(timer.w_year==2099)timer.w_year=2014;LCD_Shownum(0,0,(timer.w_year0));LCD_ShowString(2,7,\

case 7 : Addres_1++;if(Addres_1==100)Addres_1=0;disp_IP();break; case 8 : Addres_2++;if(Addres_2==10)Addres_2=0;disp_IP();break; case 9 : Addres_3++;if(Addres_3==1000)Addres_3=0;disp_IP();break; case 10: Addres_4++;if(Addres_4==1000)Addres_4=0;disp_IP();break; } } EXTI->PR=1<<13; //清除LINE13上的中断标志位 EXTI->PR=1<<15; //清除LINE15上的中断标志位 }

//外部中断初始化程序

//初始化PA0,PA13,PA15为中断输入. void EXTIX_Init(void) { RCC->APB2ENR|=1<<2; //使能PORTA时钟 JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入 GPIOA->CRL|=0X00000008; GPIOA->CRH&=0X0F0FFFFF;//PA13,15设置成输入 GPIOA->CRH|=0X80800000;

GPIOA->ODR|=1<<13; //PA13上拉,PA0默认下拉 GPIOA->ODR|=1<<15; //PA15上拉 Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发 Ex_NVIC_Config(GPIO_A,13,FTIR);//下降沿触发 Ex_NVIC_Config(GPIO_A,15,FTIR);//下降沿触发 MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2 MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2 }

void disp_IP(void) { LCD12864_Pos(3,2); LCD12684_Wdat(Addres_4/100+0x30); LCD12684_Wdat((Addres_40)/10+0x30); LCD12684_Wdat((Addres_40)+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,4); LCD12684_Wdat(Addres_3/100+0x30); LCD12684_Wdat((Addres_30)/10+0x30); LCD12684_Wdat((Addres_30)+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,6); LCD12684_Wdat(Addres_2+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,7);

LCD12684_Wdat(Addres_1/10+0x30); LCD12684_Wdat(Addres_1+0x30); }

其他文件用原子rtc时钟的程序就行

GPIOA->ODR|=1<<13; //PA13上拉,PA0默认下拉 GPIOA->ODR|=1<<15; //PA15上拉 Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发 Ex_NVIC_Config(GPIO_A,13,FTIR);//下降沿触发 Ex_NVIC_Config(GPIO_A,15,FTIR);//下降沿触发 MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //抢占2,子优先级2,组2 MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2 }

void disp_IP(void) { LCD12864_Pos(3,2); LCD12684_Wdat(Addres_4/100+0x30); LCD12684_Wdat((Addres_40)/10+0x30); LCD12684_Wdat((Addres_40)+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,4); LCD12684_Wdat(Addres_3/100+0x30); LCD12684_Wdat((Addres_30)/10+0x30); LCD12684_Wdat((Addres_30)+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,6); LCD12684_Wdat(Addres_2+0x30); LCD12684_Wdat(0x2e); LCD12864_Pos(3,7);

LCD12684_Wdat(Addres_1/10+0x30); LCD12684_Wdat(Addres_1+0x30); }

其他文件用原子rtc时钟的程序就行

本文来源:https://www.bwwdw.com/article/02bw.html

Top