- void APP_SpiInit(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- SPI_InitTypeDef SPI_InitStruct;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
- SPI_StructInit(&SPI_InitStruct);
- SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
- SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
- SPI_InitStruct.SPI_DataWidth = 8;
- SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
- SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
- SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
- SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
- SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
- SPI_Init(SPI1, &SPI_InitStruct);
- SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Tx);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_5);
- GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_5);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
- SPI_Cmd(SPI1, ENABLE);
- }
- void APP_SpiWriteByte(SPI_TypeDef *spix,uint8_t dat)
- {
- SPI_SendData(spix, dat);
- while (RESET == SPI_GetFlagStatus(spix, SPI_FLAG_TXEPT));
- }
- YUYY_HS12864G18B_DEV_Type lcd_dev;
- YUYY_GPIO_DEV_Type gpio_cs;
- YUYY_GPIO_DEV_Type gpio_rst;
- YUYY_GPIO_DEV_Type gpio_a0;
- void APP_LcdInit(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
- GPIO_StructInit(&GPIO_InitStruct);
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- gpio_cs.gpio = GPIOB;
- gpio_cs.pin = GPIO_Pin_6;
- gpio_a0.gpio = GPIOB;
- gpio_a0.pin = GPIO_Pin_4;
- gpio_rst.gpio = GPIOB;
- gpio_rst.pin = GPIO_Pin_7;
-
- lcd_dev.cs_pin = &gpio_cs;
- lcd_dev.a0_pin = &gpio_a0;
- lcd_dev.rst_pin = &gpio_rst;
- lcd_dev.spix = SPI1;
- lcd_dev.spi_sendbyte_func = (YUYY_HS12864G18B_SpiWriteByteFunc_Type)APP_SpiWriteByte;
- lcd_dev.gpio_setlev_func = (YUYY_HS12864G18B_GPIO_SetLevFunc_Type)YUYY_GPIO_SetLev;
- lcd_dev.delayus_func = (YUYY_HS12864G18B_DelayUsFunc_Type)YUYY_DelayUs;
-
- YUYY_HS12864G18B_Init(&lcd_dev);
- YUYY_HS12864G18B_ClearScreen(&lcd_dev);
- YUYY_HS12864G18B_DisplayString8x16(&lcd_dev,0,0,0," MM32F5330 TEST");
- YUYY_HS12864G18B_DisplayString8x16(&lcd_dev,0,2,0," LCD use SPI");
- YUYY_HS12864G18B_DisplayString8x16(&lcd_dev,0,4,0," bbs.21ic.com");
- YUYY_HS12864G18B_DisplayString8x16(&lcd_dev,0,6,0,"Code by yuyy1989");
- YUYY_HS12864G18B_DisplayFinish(&lcd_dev);
- }
运行效果
实时时钟(RTC)是嵌入式系统中的一种重要组件,它提供了精确的时间跟踪功能,即使在系统关机时也能保持准确。RTC通常由一个专用的硬件模块组成,用于跟踪当前的年、月、日、时、分、秒以及星期等时间信息。MM32F5330的RTC模块内部包含一组连续计数的计数器。它作为一个独立的定时器,在相应软件配置下,可提供时钟功能。修改计数器的值可以重新设置系统当前的时间。MM32F5330的RTC提供的是一个32位的计数器,需要自行实现秒到日期时间的转换
- enum
- {
- YUYY_TIME_WEEK_SUNDAY = 0,
- YUYY_TIME_WEEK_MONDAY,
- YUYY_TIME_WEEK_TUESDAY,
- YUYY_TIME_WEEK_WEDNESDAY,
- YUYY_TIME_WEEK_THURSDAY,
- YUYY_TIME_WEEK_FRIDAY,
- YUYY_TIME_WEEK_SATURDAY,
- };
- typedef struct
- {
- uint8_t month;
- uint8_t day;
- uint8_t week;
- uint8_t hour;
- uint8_t minutes;
- uint8_t seconds;
- uint16_t year;
- } YUYY_DateTimeType;
- const uint8_t kMonthDays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- bool YUYY_TIME_IsLeapYear(uint16_t year)
- {
- if(year%100!=0)
- {
- return (year%4==0);
- }
- else
- {
- return (year%400==0);
- }
- }
- uint32_t YUYY_TIME_GetSecondFromDateTime(YUYY_DateTimeType *datetime,uint16_t since_year)
- {
- uint16_t i = 0,leap_count = 0;
- uint32_t alldays = 0;
- if(datetime->year < since_year)
- return 0;
- i = since_year;
- while (i < datetime->year)
- {
- if(YUYY_TIME_IsLeapYear(i))
- leap_count += 1;
- i+=1;
- }
- alldays = (datetime->year - since_year)*365+leap_count;
- printf("%d \n",leap_count);
- i = 1;
- while (i < datetime->month)
- {
- if(i == 2 && YUYY_TIME_IsLeapYear(datetime->year))
- alldays += 29;
- else
- alldays += kMonthDays[i-1];
- i+=1;
- }
- alldays += datetime->day - 1;
- return alldays*24*3600 + datetime->hour*3600 + datetime->minutes*60 + datetime->seconds;
- }
- void YUYY_TIME_GetDateTimeFromSecond(uint32_t sec,YUYY_DateTimeType *datetime,uint16_t since_year,uint8_t since_week)
- {
- uint16_t i = 0,leap_count = 0;
- uint32_t alldays = 0;
- datetime->seconds = sec%60;
- sec /= 60;
- datetime->minutes = sec%60;
- sec /= 60;
- datetime->hour = sec%24;
- alldays = sec/24;
- i = since_year;
- datetime->week = ((alldays%7)+since_week)%7;
- while (alldays > 365)
- {
- alldays -= 365;
- if(YUYY_TIME_IsLeapYear(i))
- {
- if(alldays>0)
- alldays -= 1;
- else
- break;
- }
- i+=1;
- }
- datetime->year = i;
- i = 0;
- while (alldays >= kMonthDays[i])
- {
- alldays -= kMonthDays[i];
- if(i == 1 && YUYY_TIME_IsLeapYear(datetime->year))
- {
- if(alldays > 0)
- alldays -= 1;
- else
- break;
- }
- i+=1;
- }
- datetime->month = i+1;
- datetime->day = alldays+1;
- }
初始化RTC
- void APP_RTCInit(void)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWRDBG | RCC_APB1Periph_BKP, ENABLE);
- PWR_BackupAccessCmd(ENABLE);
- BKP_DeInit();
- if (BKP_ReadBackupRegister(BKP_DR1) != 0x5B5B)
- {
- RCC_LSEConfig(RCC_LSE_ON);
- while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
- {
- }
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
- RCC_RTCCLKCmd(ENABLE);
- RTC_WaitForSynchro();
- RTC_WaitForLastTask();
- RTC_WaitForLastTask();
- RTC_SetPrescaler(32767);
- RTC_WaitForLastTask();
- RTC_SetCounter(0);
- RTC_WaitForLastTask();
- BKP_WriteBackupRegister(BKP_DR1, 0x5B5B);
- }
- else
- {
- RTC_WaitForSynchro();
- RTC_WaitForLastTask();
- }
- }
按下按键后修改为指定的时间
- #define RTC_START_YEAR 2024
- #define RTC_START_WEEK YUYY_TIME_WEEK_MONDAY
- char *WeekdayStr[7]= {"SUN","MON","TUE","WED","THU","FRI","SAT"};
- void APP_SetTestRTC(void)
- {
- YUYY_DateTimeType datetime;
- datetime.year = 2024;
- datetime.month = 6;
- datetime.day = 30;
- datetime.hour = 20;
- datetime.minutes = 30;
- datetime.seconds = 30;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWRDBG | RCC_APB1Periph_BKP, ENABLE);
- PWR_BackupAccessCmd(ENABLE);
- RTC_SetCounter(YUYY_TIME_GetSecondFromDateTime(&datetime,RTC_START_YEAR));
- RTC_WaitForLastTask();
- }
打印时间到LCD屏幕
- int main(void)
- {
- char out[20];
- YUYY_DateTimeType datetime;
- uart_init();
- led_init();
- keys_init();
- exit_init();
- APP_SpiInit();
- APP_LcdInit();
- APP_RTCInit();
- while (1)
- {
- YUYY_DelayMs(1000);
- led_toggle(LED_NO_1);
- YUYY_TIME_GetDateTimeFromSecond(RTC_GetCounter(),&datetime,RTC_START_YEAR,RTC_START_WEEK);
- sprintf(out," %04d-%02d-%02d %s ",datetime.year, datetime.month, datetime.day,WeekdayStr[datetime.week]);
- YUYY_HS12864G18B_DisplayString8x16(&lcd_dev,0,2,0,out);
- sprintf(out," %02d:%02d:%02d ",datetime.hour, datetime.minutes, datetime.seconds);
- YUYY_HS12864G18B_DisplayString8x16(&lcd_dev,0,4,0,out);
- }
- }
运行效果