嵌入式智能万年历设计_第1页
嵌入式智能万年历设计_第2页
嵌入式智能万年历设计_第3页
嵌入式智能万年历设计_第4页
嵌入式智能万年历设计_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

任务要求:

用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〃

_10uint32_tTimeDisplay=0;

voidRCC_Configuration(void);

voidNVIC_Configuration(void);

voidGPI0_Configuration(void);

voidUSART_Configuration(void);

intfputc(intch,FILE*f);

voidRTC_Configuration(void);

voidTime_Regulate(structrtc_time*tm);

voidTime_Adjust(void);

voidTime_Disp1ay(uin132_tTimeVar);

voidTime_Show(void);

u8USART_Scanf(u32value);

#defineRTCClockSource_LSE

u8const*WEEK_STR口={〃日〃,〃一〃,〃二〃,〃三〃,〃四〃,〃五〃,〃六〃};

structrtc_timesystmtime;

intmain()

(

RCC_Configuration();

NVIC_Configuration();

GPI0_Configuration();

USARTConfiguration();

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

用户调整时间*/

if(BKP_ReadBackupRegister(BKP_DRl)!=0xA5A5)

printf('\r\n\nRTCnotyetconfigured....zz);

RTC_Configuration();

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

Time_Adjust();

BKP_WriteBackupRegister(BKP_DR1,0xA5A5);

}

else

(

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

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

if(RCC_GetFlagStatus(RCC_FLAG_PORRST)!=RESET)

|

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

)

/*检查是否Reset复位*/

elseif(RCC_GetFlagStatus(RCC_FLAG_PINRST)!=RESET)

(

printf(zz\r\n\nExternalResetoccurred..../z);

)

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

/*等待寄存器同步*/

RTC_WaitForSynchro();

/*允许RTC秒中断*/

RTC_ITConfig(RTC_IT_SEC,ENABLE);

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

RTC_WaitForLastTask();

}

#ifdefRTCClockOutput_Enable

RCC_APB1PeriphC1ockCmd(RCC_APB1Periph_PWR|RCC_APBlPeriph_BKP,ENABLE);

PWR_BackupAccessCmd(ENABLE);

BKP„TamperPinCmd(DISABLE);

BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);

ttendif

RCC_ClearFlag();

Time_Show();

voidRCC_Configuration()

(

Systemlnit0;

RCC_APB2PeriphC1ockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPI0A,

ENABLE);

voidNVIC_Configuration()

(

NVIC_InitTypeDefNVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_l);

NVIC_InitStructure.NVIC_IRQChannel=RTCJRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

voidGPI0_Configuration()

(

GPIO_InitTypeDefGPIO_InitStructure;

GPIO_InitStructure.GPI0_Pin=GPI0_Pin_9;

GPIO_InitStructure.GPI0_Mode=GPIO_Mode_AF_PP;

GPIO_InitStructure.GPI0_Speed=GPI0_Speed_50MHz;

GPI0_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPI0_Pin=GPI0_Pin_10;

GPIO_InitStructure.GPI0_Mode=GPIO_Mode_IN_FLOATING;

GPI0_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_l;

USART_InitStructure.USART_Parity=USART_Parity_No;

USART_InitStructure.USART_HardwareF1owContro1

USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

USART_Init(USARTl,&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_APB1PeriphC1ockCmd(RCC_APBIPeriph_PWR|RCC_APB1Periph_BKP,ENABLE);

/*允许访问BKP域*/

PWRBackupAccessCmd(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);

SifdefRTCC1ockOutput_Enab1e

/*禁止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=OxFF,Tmp_MM=OxFF,Tmp_DD=OxFF,Tmp_HH=OxFF,TmpMI=OxFF,

Tmp_SS=OxFF;

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

printf(/z\r\n请输入年份(PleaseSetYears):20");

while(Tmp_YY==OxFF)

(

Tmp_YY=USART_Scanf(99);

)

printf(,z\n\r年份被设置为:20%0.2d\n\r",Tmp_YY);

tm->tm_year=Tmp_YY+2000;

Tmp_MM=OxFF;

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

while(Tmp_MM==OxFF)

(

Tmp_MM=USART_Scanf(12);

)

/z,,

printf(\n\r月份被设置为:%d\n\rITmp_MM);

tm->tm_mon=

Tmp_DD=OxFF;

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

while(Tmp_DD==OxFF)

(

Tmp_DD=USART_Scanf(31);

printf(z,\n\r日期被设置为:%d\n\rz,,Tmp_DD);

tm->tm_mday=Tmp_DD;

Tmp_HH=OxFF;

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

while(Tmp_HH==OxFF)

(

Tmp_HH=USART_Scanf(23);

)

printf('\n\r时钟被设置为:%d\n\r",Tmp_HH);

tm->tm_hour=Tmp_HH;

Tmp_MI=OxFF;

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

while(Tmp_MI==OxFF)

(

Tmp_MI=USART_Scanf(59);

)

printf(,z\n\r分钟被设置为:%d\n\r,/,Tmp_MI);

tm->tm_min=Tmp_MI;

Tmp_SS=OxFF;

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

while(Tmp_SS==OxFF)

(

Tmp_SS=USART_Scanf(59);

)

printf('\n\r秒钟被设置为:%d\n\r",Tmp_SS);

tm->tm_sec=TmpSS;

voidTime_Adjust()

RTC_WaitForLastTask();

Time_Regulate(&systmtime);

GregorianDay(&systmtime);

RTC_SetCounter(mktimev(&systmtime));

RTC_WaitForLastTask();

)

voidTime_Disp1ay(uin132_tTimeVar)

(

to_tm(TimeVar,&systmtime);

printfC\r当前时间为:%(1年%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.systmtime.tm_sec);

)

voidTime_Show()

(

printfCW);

/*Infiniteloop*/

while(1)

(

/*每过Is*/

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的ASCH

码为0x30至0x39*/

(

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

{

tmp[1]=tmp[0];

tmp[0]=0x30;

}

else

(

printf('\n\rPleaseentervalidnumberbetween0and9->:");

index—;

)

)

)

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

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

/*Checks*/

if(index>value)

(

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

returnOxFF;

)

returnindex;

Date.c文件内容如下:

#include"date,h”

SdefineFEBRUARY2

#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-l;

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

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=l;

)

else

(

day=0;

)

day+=lastYear*365+leapsToDate+MonthOffset;/*

计算从计数元年元旦到计数日期一共有多少天*/

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+)*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);

stm32fl0x_it.c文件内容:

#include,zstm32flOxit.h

externuint32_tTimeDisplay;

voidNMI_Handler(void)

/**

*©briefThisfunctionhandlesHardFaultexception.

*@paramNone

*@retval:None

*/

voidHardFaultJiandler(void)

(

/*GotoinfiniteloopwhenHardFaultexceptionoccurs*/

while(1)

/**

*©briefThisfunctionhandlesMemoryManageexception.

*@paramNone

*@retval:None

*/

voidMemManage_Hand1er(void)

(

/*GotoinfiniteloopwhenMemoryManageexceptionoccurs*/

while(1)

/**

*©briefThisfunctionhandlesBusFaultexception.

*@paramNone

*@retval:None

*/

voidBusFault_Handler(void)

{

/*GotoinfiniteloopwhenBusFaultexceptionoccurs*/

while(1)

/**

*©briefThisfunctionhandlesUsa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论