嵌入式智能万年历设计.docx

上传人:b****5 文档编号:5104586 上传时间:2022-12-13 格式:DOCX 页数:18 大小:19.12KB
下载 相关 举报
嵌入式智能万年历设计.docx_第1页
第1页 / 共18页
嵌入式智能万年历设计.docx_第2页
第2页 / 共18页
嵌入式智能万年历设计.docx_第3页
第3页 / 共18页
嵌入式智能万年历设计.docx_第4页
第4页 / 共18页
嵌入式智能万年历设计.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

嵌入式智能万年历设计.docx

《嵌入式智能万年历设计.docx》由会员分享,可在线阅读,更多相关《嵌入式智能万年历设计.docx(18页珍藏版)》请在冰豆网上搜索。

嵌入式智能万年历设计.docx

嵌入式智能万年历设计

任务要求:

用ARM—M3芯片设计一个智能万年历,要求能够正确显示近100年时间,星期几,时间格式为****年**月**日(星期**)**:

**:

**(时:

分:

秒),能够识别出闰年(计时范围能够从1970年1月1日到2100年左右)。

该程序设计工程里包含有main.c(相关配置、和终端联系,提醒输出初始时间、输出实时时间)/date.c(计算实时时间)/stm32f10x_it.c三个文件,各文件内容如下。

Main.c文件:

#include"stm32f10x.h"

#include"stdio.h"

#include"date.h"

__IOuint32_tTimeDisplay=0;

voidRCC_Configuration(void);

voidNVIC_Configuration(void);

voidGPIO_Configuration(void);

voidUSART_Configuration(void);

intfputc(intch,FILE*f);

voidRTC_Configuration(void);

voidTime_Regulate(structrtc_time*tm);

voidTime_Adjust(void);

voidTime_Display(uint32_tTimeVar);

voidTime_Show(void);

u8USART_Scanf(u32value);

#defineRTCClockSource_LSE

u8const*WEEK_STR[]={"日","一","二","三","四","五","六"};

structrtc_timesystmtime;

intmain()

{

RCC_Configuration();

NVIC_Configuration();

GPIO_Configuration();

USART_Configuration();

/*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5,则需重新配置时间并询问用户调整时间*/

if(BKP_ReadBackupRegister(BKP_DR1)!

=0xA5A5)

{

printf("\r\n\nRTCnotyetconfigured....");

RTC_Configuration();

printf("\r\nRTCconfigured....");

Time_Adjust();

BKP_WriteBackupRegister(BKP_DR1,0xA5A5);

}

else

{

/*启动无需设置新时钟*/

/*检查是否掉电重启*/

if(RCC_GetFlagStatus(RCC_FLAG_PORRST)!

=RESET)

{

printf("\r\n\nPowerOnResetoccurred....");

}

/*检查是否Reset复位*/

elseif(RCC_GetFlagStatus(RCC_FLAG_PINRST)!

=RESET)

{

printf("\r\n\nExternalResetoccurred....");

}

printf("\r\nNoneedtoconfigureRTC....");

/*等待寄存器同步*/

RTC_WaitForSynchro();

/*允许RTC秒中断*/

RTC_ITConfig(RTC_IT_SEC,ENABLE);

/*等待上次RTC寄存器写操作完成*/

RTC_WaitForLastTask();

}

#ifdefRTCClockOutput_Enable

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);

PWR_BackupAccessCmd(ENABLE);

BKP_TamperPinCmd(DISABLE);

BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);

#endif

RCC_ClearFlag();

Time_Show();

}

voidRCC_Configuration()

{

SystemInit();

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);

}

voidNVIC_Configuration()

{

NVIC_InitTypeDefNVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannel=RTC_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

voidGPIO_Configuration()

{

GPIO_InitTypeDefGPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

}

voidUSART_Configuration()

{

USART_InitTypeDefUSART_InitStructure;

USART_InitStructure.USART_BaudRate=115200;

USART_InitStructure.USART_WordLength=USART_WordLength_8b;

USART_InitStructure.USART_StopBits=USART_StopBits_1;

USART_InitStructure.USART_Parity=USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

USART_Init(USART1,&USART_InitStructure);

USART_Cmd(USART1,ENABLE);

}

intfputc(intch,FILE*f)

{

/*将Printf内容发往串口*/

USART_SendData(USART1,(unsignedchar)ch);

while(!

(USART1->SR&USART_FLAG_TXE));

return(ch);

}

 

voidRTC_Configuration()

{

/*允许PWR和BKP时钟*/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE);

/*允许访问BKP域*/

PWR_BackupAccessCmd(ENABLE);

/*复位备份域*/

BKP_DeInit();

#ifdefRTCClockSource_LSI

/*允许LSI*/

RCC_LSICmd(ENABLE);

/*等待LSI准备好*/

while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET)

{

}

/*选择LSI作为RTC时钟源*/

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

#elifdefinedRTCClockSource_LSE

/*允许LSE*/

RCC_LSEConfig(RCC_LSE_ON);

/*等待LSE准备好*/

while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET)

{

}

/*选择LSE作为RTC时钟源*/

RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

#endif

/*EnableRTCClock*/

RCC_RTCCLKCmd(ENABLE);

#ifdefRTCClockOutput_Enable

/*禁止Tamper引脚*/

BKP_TamperPinCmd(DISABLE);/*为了将RTCCLK/64在Tamper引脚输出,Tamper功能必须被禁止*/

/*允许RTC时钟在Tamper引脚上输出*/

BKP_RTCCalibrationClockOutputCmd(ENABLE);

#endif

/*等待寄存器同步*/

RTC_WaitForSynchro();

/*等待上次RTC寄存器写操作完成*/

RTC_WaitForLastTask();

/*允许RTC秒中断*/

RTC_ITConfig(RTC_IT_SEC,ENABLE);

/*等待上次RTC寄存器写操作完成*/

RTC_WaitForLastTask();

#ifdefRTCClockSource_LSI

/*设置分频系数*/

RTC_SetPrescaler(31999);/*RTC周期=RTCCLK/RTC_PR=(32.000kHz/(31999+1))*/

#elifdefinedRTCClockSource_LSE

RTC_SetPrescaler(32767);/*RTC周期=RTCCLK/RTC_PR=(32.768kHz/(31767+1))*/

#endif

/*等待上次RTC寄存器写操作完成*/

RTC_WaitForLastTask();

}

 

voidTime_Regulate(structrtc_time*tm)

{

u32Tmp_YY=0xFF,Tmp_MM=0xFF,Tmp_DD=0xFF,Tmp_HH=0xFF,Tmp_MI=0xFF,Tmp_SS=0xFF;

printf("\r\n=========================TimeSettings==================");

printf("\r\n请输入年份(PleaseSetYears):

20");

while(Tmp_YY==0xFF)

{

Tmp_YY=USART_Scanf(99);

}

printf("\n\r年份被设置为:

20%0.2d\n\r",Tmp_YY);

tm->tm_year=Tmp_YY+2000;

Tmp_MM=0xFF;

printf("\r\n请输入月份(PleaseSetMonths):

");

while(Tmp_MM==0xFF)

{

Tmp_MM=USART_Scanf(12);

}

printf("\n\r月份被设置为:

%d\n\r",Tmp_MM);

tm->tm_mon=Tmp_MM;

Tmp_DD=0xFF;

printf("\r\n请输入日期(PleaseSetDates):

");

while(Tmp_DD==0xFF)

{

Tmp_DD=USART_Scanf(31);

}

printf("\n\r日期被设置为:

%d\n\r",Tmp_DD);

tm->tm_mday=Tmp_DD;

Tmp_HH=0xFF;

printf("\r\n请输入时钟(PleaseSetHours):

");

while(Tmp_HH==0xFF)

{

Tmp_HH=USART_Scanf(23);

}

printf("\n\r时钟被设置为:

%d\n\r",Tmp_HH);

tm->tm_hour=Tmp_HH;

Tmp_MI=0xFF;

printf("\r\n请输入分钟(PleaseSetMinutes):

");

while(Tmp_MI==0xFF)

{

Tmp_MI=USART_Scanf(59);

}

printf("\n\r分钟被设置为:

%d\n\r",Tmp_MI);

tm->tm_min=Tmp_MI;

Tmp_SS=0xFF;

printf("\r\n请输入秒钟(PleaseSetSeconds):

");

while(Tmp_SS==0xFF)

{

Tmp_SS=USART_Scanf(59);

}

printf("\n\r秒钟被设置为:

%d\n\r",Tmp_SS);

tm->tm_sec=Tmp_SS;

}

voidTime_Adjust()

{

RTC_WaitForLastTask();

Time_Regulate(&systmtime);

GregorianDay(&systmtime);

RTC_SetCounter(mktimev(&systmtime));

RTC_WaitForLastTask();

}

 

voidTime_Display(uint32_tTimeVar)

{

to_tm(TimeVar,&systmtime);

printf("\r当前时间为:

%d年%d月%d日(星期%s)%0.2d:

%0.2d:

%0.2d",

systmtime.tm_year,systmtime.tm_mon,systmtime.tm_mday,

WEEK_STR[systmtime.tm_wday],systmtime.tm_hour,

systmtime.tm_min,systmtime.tm_sec);

}

voidTime_Show()

{

printf("\n\r");

/*Infiniteloop*/

while

(1)

{

/*每过1s*/

if(TimeDisplay==1)

{

Time_Display(RTC_GetCounter());

TimeDisplay=0;

}

}

}

u8USART_Scanf(u32value)

{

u32index=0;

u32tmp[2]={0,0};

while(index<2)

{

while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET)

{

}

tmp[index++]=(USART_ReceiveData(USART1));

if((tmp[index-1]<0x30)||(tmp[index-1]>0x39))/*数字0到9的ASCII码为0x30至0x39*/

{

if((index==2)&&(tmp[index-1]=='\r'))

{

tmp[1]=tmp[0];

tmp[0]=0x30;

}

else

{

printf("\n\rPleaseentervalidnumberbetween0and9-->:

");

index--;

}

}

}

/*计算输入字符的相应ASCII值*/

index=(tmp[1]-0x30)+((tmp[0]-0x30)*10);

/*Checks*/

if(index>value)

{

printf("\n\rPleaseentervalidnumberbetween0and%d",value);

return0xFF;

}

returnindex;

}

 

Date.c文件内容如下:

#include"date.h"

#defineFEBRUARY2

#defineSTARTOFTIME1970

#defineSECDAY86400L

#defineSECYR(SECDAY*365)

#defineleapyear(year)((year)%4==0)

#definedays_in_year(a)(leapyear(a)?

366:

365)

#definedays_in_month(a)(month_days[(a)-1])

staticintmonth_days[12]={31,28,31,30,31,30,31,31,30,31,30,31};

/*计算公历*/

voidGregorianDay(structrtc_time*tm)

{

intleapsToDate;

intlastYear;

intday;

intMonthOffset[]={0,31,59,90,120,151,181,212,243,273,304,334};

lastYear=tm->tm_year-1;

/*计算到计数的前一年之中一共经历了多少个闰年*/

leapsToDate=lastYear/4-lastYear/100+lastYear/400;

/*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/

if((tm->tm_year%4==0)&&((tm->tm_year%100!

=0)||(tm->tm_year%400==0))&&(tm->tm_mon>2))

{

day=1;

}

else

{

day=0;

}

day+=lastYear*365+leapsToDate+MonthOffset[tm->tm_mon-1]+tm->tm_mday;/*计算从计数元年元旦到计数日期一共有多少天*/

tm->tm_wday=day%7;

}

 

u32mktimev(structrtc_time*tm)

{

if(0>=(int)(tm->tm_mon-=2))

{

tm->tm_mon+=12;

tm->tm_year-=1;

}

return((((u32)(tm->tm_year/4-tm->tm_year/100+tm->tm_year/400+367*tm->tm_mon/12+tm->tm_mday)

+tm->tm_year*365-719499)*24+tm->tm_hour)*6+tm->tm_min)*60+tm->tm_sec;

}

voidto_tm(u32tim,structrtc_time*tm)

{

registeru32i;

registerlonghms,day;

day=tim/SECDAY;

hms=tim%SECDAY;

tm->tm_hour=hms/3600;

tm->tm_min=(hms%3600)/60;

tm->tm_sec=(hms%3600)%60;

/*算出当前年份,起始的计数年份为1970年*/

for(i=STARTOFTIME;day>=days_in_year(i);i++)

{

day-=days_in_year(i);

}

tm->tm_year=i;

/*计算当前的月份*/

if(leapyear(tm->tm_year))

{

days_in_month(FEBRUARY)=29;

}

for(i=1;day>=days_in_month(i);i++)

{

day-=days_in_month(i);

}

days_in_month(FEBRUARY)=28;

tm->tm_mon=i;

/*计算当前日期*/

tm->tm_mday=day+1;

GregorianDay(tm);

}

 

stm32f10x_it.c文件内容:

 

#include"stm32f10x_it.h"

externuint32_tTimeDisplay;

 

voidNMI_Handler(void)

{

}

/**

*@briefThisfunctionhandlesHardFaultexception.

*@paramNone

*@retval:

None

*/

voidHardFault_Handler(void)

{

/*GotoinfiniteloopwhenHardFaultexceptionoccurs*/

while

(1)

{

}

}

/**

*@briefThisfuncti

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

当前位置:首页 > 高等教育 > 军事

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

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