嵌入式智能万年历设计_嵌入式智能万年历设计

2020-02-27 其他范文 下载本文

嵌入式智能万年历设计由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“嵌入式智能万年历设计”。

任务要求:

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

__IO uint32_t TimeDisplay = 0;

void RCC_Configuration(void);void NVIC_Configuration(void);void GPIO_Configuration(void);void USART_Configuration(void);int fputc(int ch, FILE *f);void RTC_Configuration(void);void Time_Regulate(struct rtc_time *tm);void Time_Adjust(void);void Time_Display(uint32_t TimeVar);void Time_Show(void);u8 USART_Scanf(u32 value);

#define RTCClockSource_LSE

u8 const *WEEK_STR[] = {“日”, “一”, “二”, “三”, “四”, “五”, “六”};

struct rtc_time systmtime;

int main(){ RCC_Configuration();

NVIC_Configuration();

GPIO_Configuration();

USART_Configuration();

/*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5,则需重新配置时间并询问用户调整时间*/ if(BKP_ReadBackupRegister(BKP_DR1)!= 0xA5A5){ printf(“rnn RTC not yet configured....”);

RTC_Configuration();printf(“rn RTC configured....”);

Time_Adjust();

BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);} else { /*启动无需设置新时钟*/ /*检查是否掉电重启*/ if(RCC_GetFlagStatus(RCC_FLAG_PORRST)!= RESET){ printf(“rnn Power On Reset occurred....”);} /*检查是否Reset复位*/ else if(RCC_GetFlagStatus(RCC_FLAG_PINRST)!= RESET){ printf(“rnn External Reset occurred....”);}

printf(“rn No need to configure RTC....”);

/*等待寄存器同步*/ RTC_WaitForSynchro();

/*允许RTC秒中断*/ RTC_ITConfig(RTC_IT_SEC, ENABLE);

/*等待上次RTC寄存器写操作完成*/ RTC_WaitForLastTask();} #ifdef RTCClockOutput_Enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

PWR_BackupAcceCmd(ENABLE);

BKP_TamperPinCmd(DISABLE);

BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);#endif

RCC_ClearFlag();

Time_Show();}

void RCC_Configuration(){

SystemInit();

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);}

void NVIC_Configuration(){ NVIC_InitTypeDef NVIC_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);}

void GPIO_Configuration(){ GPIO_InitTypeDef GPIO_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);}

void USART_Configuration(){ USART_InitTypeDef USART_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);}

int fputc(int ch, FILE *f){ /* 将Printf内容发往串口 */ USART_SendData(USART1,(unsigned char)ch);

while(!(USART1->SR & USART_FLAG_TXE));

return(ch);}

void RTC_Configuration(){ /*允许PWR和BKP时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

/*允许访问BKP域*/ PWR_BackupAcceCmd(ENABLE);

/*复位备份域*/ BKP_DeInit();

#ifdef RTCClockSource_LSI

/*允许LSI*/ RCC_LSICmd(ENABLE);

/*等待LSI准备好*/ while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET){ }

/*选择LSI作为RTC时钟源*/ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);#elif defined RTCClockSource_LSE

/*允许LSE*/ RCC_LSEConfig(RCC_LSE_ON);

/*等待LSE准备好*/ while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET){ }

/*选择LSE作为RTC时钟源*/ RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);#endif

/* Enable RTC Clock */ RCC_RTCCLKCmd(ENABLE);

#ifdef RTCClockOutput_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();

#ifdef RTCClockSource_LSI /*设置分频系数*/ RTC_SetPrescaler(31999);/*RTC周期=RTCCLK/RTC_PR=(32.000kHz/(31999+1))*/

#elif defined RTCClockSource_LSE RTC_SetPrescaler(32767);/*RTC周期=RTCCLK/RTC_PR=(32.768kHz/(31767+1))*/ #endif /*等待上次RTC寄存器写操作完成*/ RTC_WaitForLastTask();

}

void Time_Regulate(struct rtc_time *tm){ u32 Tmp_YY = 0xFF, Tmp_MM = 0xFF, Tmp_DD = 0xFF, Tmp_HH = 0xFF, Tmp_MI = 0xFF, Tmp_SS = 0xFF;

printf(“rn=========================Time Settings==================”);

printf(“rn 请输入年份(Please Set Years): 20”);

while(Tmp_YY == 0xFF){ Tmp_YY = USART_Scanf(99);}

printf(“nr 年份被设置为: 20%0.2dnr”, Tmp_YY);

tm->tm_year = Tmp_YY+2000;

Tmp_MM = 0xFF;

printf(“rn 请输入月份(Please Set Months): ”);

while(Tmp_MM == 0xFF){ Tmp_MM = USART_Scanf(12);}

printf(“nr 月份被设置为: %dnr”, Tmp_MM);

tm->tm_mon= Tmp_MM;

Tmp_DD = 0xFF;

printf(“rn 请输入日期(Please Set Dates): ”);

while(Tmp_DD == 0xFF){ Tmp_DD = USART_Scanf(31);} printf(“nr 日期被设置为: %dnr”, Tmp_DD);

tm->tm_mday= Tmp_DD;

Tmp_HH = 0xFF;

printf(“rn 请输入时钟(Please Set Hours): ”);

while(Tmp_HH == 0xFF){ Tmp_HH = USART_Scanf(23);}

printf(“nr 时钟被设置为: %dnr”, Tmp_HH);

tm->tm_hour= Tmp_HH;

Tmp_MI = 0xFF;

printf(“rn 请输入分钟(Please Set Minutes): ”);

while(Tmp_MI == 0xFF){ Tmp_MI = USART_Scanf(59);}

printf(“nr 分钟被设置为: %dnr”, Tmp_MI);

tm->tm_min= Tmp_MI;

Tmp_SS = 0xFF;

printf(“rn 请输入秒钟(Please Set Seconds): ”);

while(Tmp_SS == 0xFF){ Tmp_SS = USART_Scanf(59);}

printf(“nr 秒钟被设置为: %dnr”, Tmp_SS);

tm->tm_sec= Tmp_SS;}

void Time_Adjust(){ RTC_WaitForLastTask();

Time_Regulate(&systmtime);

GregorianDay(&systmtime);

RTC_SetCounter(mktimev(&systmtime));

RTC_WaitForLastTask();}

void Time_Display(uint32_t TimeVar){

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);}

void Time_Show(){ printf(“nr”);

/* Infinite loop */ while(1){ /* 每过1s */ if(TimeDisplay == 1){ Time_Display(RTC_GetCounter());TimeDisplay = 0;} } }

u8 USART_Scanf(u32 value){ u32 index = 0;u32 tmp[2] = {0, 0};

while(index

}

tmp[index++] =(USART_ReceiveData(USART1));if((tmp[index1] > 0x39))/*数字0到9的ASCII码为0x30至0x39*/ {

if((index == 2)&&(tmp[index0x30)+((tmp[0]1])

static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

/*计算公历*/ void GregorianDay(struct rtc_time * tm){ int leapsToDate;int lastYear;int day;int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };

lastYear=tm->tm_year-1;

/*计算到计数的前一年之中一共经历了多少个闰年*/ leapsToDate = lastYear/4tm->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;}

void to_tm(u32 tim, struct rtc_time * tm){ register u32 i;register long hms, 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” extern uint32_t TimeDisplay;

void NMI_Handler(void){ } /** * @brief This function handles Hard Fault exception.* @param None * @retval : None */ void HardFault_Handler(void){ /* Go to infinite loop when Hard Fault exception occurs */ while(1){ } } /** * @brief This function handles Memory Manage exception.* @param None * @retval : None */ void MemManage_Handler(void){ /* Go to infinite loop when Memory Manage exception occurs */ while(1){ } } /** * @brief This function handles Bus Fault exception.* @param None * @retval : None */ void BusFault_Handler(void){ /* Go to infinite loop when Bus Fault exception occurs */ while(1){ } } /** * @brief This function handles Usage Fault exception.* @param None * @retval : None */ void UsageFault_Handler(void){ /* Go to infinite loop when Usage Fault exception occurs */ while(1){ } } /** * @brief This function handles SVCall exception.* @param None * @retval : None */ void SVC_Handler(void){ } /** * @brief This function handles Debug Monitor exception.* @param None * @retval : None */ void DebugMon_Handler(void){ } /** * @brief This function handles PendSVC exception.* @param None * @retval : None */ void PendSV_Handler(void){ } /** * @brief This function handles SysTick Handler.* @param None * @retval : None */ void SysTick_Handler(void){ }

void RTC_IRQHandler(void){ if(RTC_GetITStatus(RTC_IT_SEC)!= RESET){ /* Clear the RTC Second interrupt */ RTC_ClearITPendingBit(RTC_IT_SEC);

/* Enable time update */ TimeDisplay = 1;

/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();

/* Reset RTC Counter when Time is 23:59:59 */ if(RTC_GetCounter()== 0x00015180){ RTC_SetCounter(0x0);/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();} } }

《嵌入式智能万年历设计.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
嵌入式智能万年历设计
点击下载文档
相关专题 嵌入式智能万年历设计 设计 万年历 嵌入式 嵌入式智能万年历设计 设计 万年历 嵌入式
[其他范文]相关推荐
    [其他范文]热门文章
      下载全文