14CubeMx+Keil+Proteus仿真STM32

编程

本文例子参考《STM32单片机开发实例——基于Proteus虚拟仿真与HAL/LL库》

源代码:https://github.com/LanLinnet/STM33F103R6

项目要求

单片机每隔1s以“YYYY-MM-DD HH:MM:SS”的格式自动向串口输出日期和时间信息(“ASCII格式”),起始时间设为“2022-05-20 05:20:00”,自动走时。按下按钮BTN,时间自动恢复为起始时间。串口通信参数:波特率为19200bit/s,无校验。

硬件设计

  1. 在第一节的基础上,在Proteus中添加电路如下图所示。


    调试过程也可以添加一个虚拟仪器VIRTUAL TERMINAL,配置如下,用来查看单片机收到的串口数据,具体参考第11节。

  2. RTC简介:

    1)RTC是Real Time Clock(实时时钟)的首字母缩写形式,是一种常用的电子功能模块,有独立的RTC芯片,也有集成于单片机内的独立功能模块,常用于制作电子钟、电子表、电子万年历等计时工具。

    2)STM32单片机的RTC可以看作特殊的定时器,它可以根据输入的时钟源自动计时,此外还提供了1个“闹钟”中断源和1个“秒”中断源。

  3. 打开CubeMX,建立工程。

    首先,设置PA5为GPIO_EXTI5,点击“Categories”中的“GPIO”,将"GPIO mode"设置为External Interrupt Mode With Falling edge trigger detection,也就是下降沿触发。


    随后,点击“Timers”列表中的“RTC”进行实时时钟配置。选中“Active Clock Source”和“Active Calendar”复选框,激活时钟源和日历。在“Parameter Settings”中设置时间和日期如下图所示。其中,“Data Format”设置数据格式有2个选项:“Binary Data Format”(字面意思是二进制数据格式,实际是十进制数据格式)和“BCD Data Format”(BCD码数据格式),实际设定时间时任意选其中一个即可。


    然后,点击“Connectivity”列表中的“USART”进行串口配置。将Mode设置为Asynchronous(异步),波特率设为19200Bits/s,字长设为8Bits,校验设为None,停止位设为1,数据传送设为Receive and Transmit(接收与发送)。设置完成后,会看到右侧的PA9和PA10引脚被自动设置为USART1_TXUSART1_RX,即USART1的发送端和接收端。


    再点击“NVIC Settings”,选中USART global interruptEXTI line[9:5] interrupts,使能Enabled串口1的中断功能和GPIO的外部中断。


    最后,实践中为了追求时间的精度,我们会采用外部低速晶振LSE作为RTC的时钟源,由于本次采用Proteus进行仿真,我们选择默认的LSI作为RTC的时钟源。

  4. 点击“Generator Code”生成Keil工程。

软件编写

  1. 本次我们需要实现实时时钟自动走时,并通过串口发送输出,需要用到RTC相关函数其API文档如下:

    HAL_RTC_GetTime RTC时间获取函数

    HAL_RTC_GetDate RTC日期获取函数

    HAL_RTC_SetTime RTC时间设定函数

    HAL_RTC_SetDate RTC日期设定函数

    其中,介绍两个结构体:

    时间结构体sTime有以下3个元素

    • Hours(时),数据类型为uint8_t。
    • Minutes(分),数据类型为uint8_t。
    • Seconds(秒),数据类型为uint8_t。

    日期结构体sDate有以下4个元素

    • Year(年),数据类型为uint8_t,取值范围为0-99(BIN格式)或0-0x99(BCD格式)。
    • Month(月),数据类型为uint8_t,取值范围为1-12(BIN格式)或1-0x12(BCD格式)。
    • Date(日),数据类型为uint8_t,取值范围为1-31(BIN格式)或1-0x31(BCD格式)。
    • WeekDay(星期),数据类型为uint8_t,取值范围为1-7。

    另外,Format有以下2个宏定义选项

    • RTC_FORMAT_BIN:字面意思是二进制数据格式,实际是十进制数据格式
    • RTC_FORMAT_BCD:BCD码数据格式

  2. 点击“Open Project”在Keil中打开工程,双击“main.c”文件。

  3. 首先我们需要在main.c文件中的最前面引入标准输入输出头文件

    /* USER CODE BEGIN Includes */

    #include "stdio.h"

    /* USER CODE END Includes */

    在main函数中定义日期结构体和时间结构体

    /* USER CODE BEGIN 1 */

    //定义日期结构体和时间结构体

    RTC_DateTypeDef sDateStructure;

    RTC_TimeTypeDef sTimeStructure;

    char sYear[5];

    char sMonth[3];

    char sDate[3];

    char sHour[3];

    char sMin[3];

    char sSec[3];

    /* USER CODE END 1 */

    随后,在/* USER CODE BEGIN 4 *//* USER CODE END 4 */中插入外部中断回调函数,代码如下

    /* USER CODE BEGIN 4 */

    //外部中断回调函数

    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

    {

    //定义日期结构体和时间结构体

    RTC_DateTypeDef sDateStructure;

    RTC_TimeTypeDef sTimeStructure;

    if(GPIO_Pin == GPIO_PIN_5) //检测到EXTI5线产生外部中断事件

    {

    //设置日期

    sDateStructure.Year = 22;

    sDateStructure.Month = 5;

    sDateStructure.Date = 20;

    sDateStructure.WeekDay = 5;

    //十进制格式

    HAL_RTC_SetDate(&hrtc, &sDateStructure, RTC_FORMAT_BIN);

    //设置时间

    sTimeStructure.Hours = 0x05;

    sTimeStructure.Minutes = 0x20;

    sTimeStructure.Seconds = 0;

    //BCD码格格式

    HAL_RTC_SetTime(&hrtc, &sTimeStructure, RTC_FORMAT_BCD);

    while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET); //直到按键松开

    }

    }

    /* USER CODE END 4 */

    最后,在while(1)中插入代码如下,进行RTC和串口发送相关操作

    /* USER CODE BEGIN WHILE */

    while (1)

    {

    //十进制格式

    HAL_RTC_GetTime(&hrtc, &sTimeStructure, RTC_FORMAT_BIN); //RTC时间获取函数

    //BCD码格式

    HAL_RTC_GetDate(&hrtc, &sDateStructure, RTC_FORMAT_BCD); //RTC日期获取函数

    //格式转换为字符串

    sprintf(sYear, "%04x", 0x2000+sDateStructure.Year);

    sprintf(sMonth, "%02x", sDateStructure.Month);

    sprintf(sDate, "%02x", sDateStructure.Date);

    sprintf(sHour, "%02d", sTimeStructure.Hours);

    sprintf(sMin, "%02d", sTimeStructure.Minutes);

    sprintf(sSec, "%02d", sTimeStructure.Seconds);

    //打印日期

    HAL_UART_Transmit(&huart1, (uint8_t *)sYear, 4, 4);

    HAL_UART_Transmit(&huart1, (uint8_t *)&"-", 1, 1);

    HAL_UART_Transmit(&huart1, (uint8_t *)sMonth, 2, 2);

    HAL_UART_Transmit(&huart1, (uint8_t *)&"-", 1, 1);

    HAL_UART_Transmit(&huart1, (uint8_t *)sDate, 2, 2);

    HAL_UART_Transmit(&huart1, (uint8_t *)&" ", 1, 2);

    //打印时间

    HAL_UART_Transmit(&huart1, (uint8_t *)sHour, 2, 2);

    HAL_UART_Transmit(&huart1, (uint8_t *)&":", 1, 1);

    HAL_UART_Transmit(&huart1, (uint8_t *)sMin, 2, 2);

    HAL_UART_Transmit(&huart1, (uint8_t *)&":", 1, 1);

    HAL_UART_Transmit(&huart1, (uint8_t *)sSec, 2, 2);

    HAL_UART_Transmit(&huart1, (uint8_t *)&"

    ", 2, 2);

    //延时

    HAL_Delay(1000);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

    }

    /* USER CODE END 3 */

联合调试

  1. 点击运行,生成HEX文件。
  2. 在Proteus中加载相应HEX文件,点击运行。可以看到“Virtual Terminal”从“2022-05-20 05:20:00”开始自动走时,每秒输出一个结果,按下BTN按键,又重新从“2022-05-20 05:20:00”开始自动走时。

以上是 14CubeMx+Keil+Proteus仿真STM32 的全部内容, 来源链接: utcz.com/z/520518.html

回到顶部