实验课程

THIS NAME

实验课程

当前位置: 首页 >> 实验课程 >> 正文

嵌入式Cortex-M应用-基本定时器

发布日期:2024-08-19    作者:陆其美     来源:     点击:

基本定时器

一、实验目的

1.cubemx工程配置,

2定时器用户代码实现

二、实验内容

利用基本定时完成1s延时,并打印相关内容的输出

三、实验原理及说明

STM32F1 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成。STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。  使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

STM3F1 的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能包括:

1)16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。

2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。

3)4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:

A.输入捕获

B.输出比较

C.PWM 生成(边缘或中间对齐模式)

D.单脉冲模式输出

4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。

5)如下事件发生时产生中断/DMA:

A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)

B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)

C.输入捕获

D.输出比较

E.支持针对定位的增量(正交)编码器和霍尔传感器电路

F.触发输入作为外部时钟或者按周期的电流管理

四、实验设备

一套STM32实验设备、头歌实践教学平台。

五、实验步骤

1.1 双击打开软件 stm32cubemx。

undefined

1.2 开始创建工程,本次实训采用的开发板MCU型号为STM32F103C8T6,所以直接根据MCU配置工程,打开软件后选择 access to mcu selector。

undefined

1.3 搜索芯片STM32F103C8T6,并选择芯片型号 STM32F103C8T6 ,并点击“start project”创建工程。

undefined

1.4 芯片选择完成后,进入配置界面,配置分为如下几类:

a) System Core 用于配置MCU核心功能,如时钟,中断,调试接口等;

b) Analog 用于配置MCU的ADC功能;

c) Timers 用于配置MCU的定时器;

d) Connectivity 用于配置MCU外设接口,如SPI,USART,CAN等;

e) Computing 用于配置MCU的CRC校验

f) Middleware 用于配置MCU的中间件,如文件系统,实时操作系统等; 学院可以根据实际需要,选择相应的功能配置,过程如下: 展开“system core”标签,找到“SYS"选项,在右边选择如图所示配置调试接口为JTAG 5脚接口,如果是其他接口,按照需要选择,配置完成后,右边的MCU预览图相应管脚会显示为绿色。

undefined

1.5 切换到”RCC“标签,配置系统时钟,本实验用到的开发板主时钟使用8MHz晶振,备份域时钟使用32.768kHz时钟,分别接在MCU的相应引脚上,所以在配置的时候HSE(高速外部时钟)选择使用外部晶振(crystal),LSE(低速外部时钟)选择使用外部晶振(crystal),具体如图所示。

undefined

1.6 切换到“Connectivity”标签,在实验过程中需要使用串口打印信息,所以需要配置串口功能,此处选择USART1,配置为异步通信,其他参数(奇偶校验,波特率等)使用默认即可,按照如图所示配置“USART1”。

undefined

到此,MCU核心功能的相关配置完成,接下来配置用户代码部分。

用户代码目前用到的主要是针对基本输入输出端口的配置,主要如下:

a) GPIO_Input 配置为输入端口,同时可选择上拉或者下拉,用于获取IO电平

b) GPIO_Output 配置为输出端口,同时可选择上拉或者下拉,用于输出高低电平

c) GPIO_Analog 配置为模拟功能,主要用于ADC采集使用

d) GPIO_EXIT 配置为外部中断模式,同时可选择上拉或者下拉

1.7 鼠标定位到右侧MCU引脚图,选择PB12和PB13引脚,单击相应引脚,开发板的按键连接到此IO引脚,故将其配置成输入,同时使用中断方法检测按键,故需要使能外部中断,为了同时检测上升沿与下降沿,需要选择GPIO mode为“Rising/Falling Edge”,具体如图所示配置:

undefined

1.8 切换到“System Core”的“GPIO”标签,找到刚才配置的GPIO引脚PB12,按如图所示配置名称和引脚,名称输入“KEY2”,相当于在生成的工程项目中为此IO口添加宏定义,便于程序阅读和维护。

undefined

按照同样的方法配置PB13引脚,最后如图所示

undefined

以上为按键部分的配置,接下来添加LED部分的配置,LED输出电平控制LED的亮灭,所以需要配置为输出模式,同时从原理图知道,每个LED都自带上拉电阻,所以不需要再使用内部上拉或者下拉,为了同时能输出高低电平,需要配置为推挽输出,即“push pull”,为了保证默认状态下LED为熄灭状态,设置“GPIO Output level”为“High",具体如图所示:

undefined

以下为定时器配置

undefined

定时器模式配置部分说明,如下所示:

Slave Mode:用于使能主从模式,本次不需要

Triger Source:用于设置触发源,本次不需要

Clock Source:用于设置定时器时钟源,此处设置为内部时钟源

Channel1~4:用于设置定时器捕获与输出通道,本次不需要

Combined Channels:设置混合功能,如互补PWM输出

定时器参数设置说明,如下所示:

Prescaler (PSC - 16 bits value):设置时钟分频

Counter Mode:设置计数模式(向上,向下,中间)

Counter Period:定时周期

Internal Clock division:设置内部时钟分频

Auto-Reload:自动重装载使能设置

后面为定时器触发相关设置,本次用不到;

1.9 切换到“System Core”的“NVIC”标签,由于需要使用外部中断,所以要使能中断,并配置中断优先级,中断优先级使用默认就可以,找到外部中断,并使能,其他中断相关配置可以先不用理会,后续使用到了会详细说明,同时使能定时器TIM2中断,配置如图所示

undefined

1.10 切换到 “Clock configuration”,结合HSE(高速外部时钟)和LSE(低速外部时钟),设置MCU系统时钟为72MHz,GPIO时钟使用APB2的时钟,时钟部分将在后续章节讲解,目前按如下配置。

undefined

以上为用户代码部分的配置,由于本次实验只用到了GPIO口相关的操作,所以只需要配置GPIO口相关的部分,以下为串口相关的配置。

本课程所有的实验据使用stm32cubeIDE编译,由于该集成开发环境不带有串口输出功能,所以为了实现串口输出,需要将串口重映射到之前配置的“USART1”,以下为串口重映射相关的操作,具体会在串口相关章节讲解。

1.11 配置工程并生成代码,输入工程名称“project",具体如图所示。

undefined

切换到code generator“标签,按如图所示生成代码。

undefined

1.12 打开STM32CubeIDE,打开之前生成的工程。

点击File--> open project from file system......”。

undefined

1.13 找到生成文件的文件夹,并打开

undefined

1.14 按下右边的标签“MX",即可显示项目文件。

undefined

1.15 为项目添加一个C语言源文件,命名为“retarget.c”,如图所示

undefined

在文件中添加如下代码:

#include "retarget.h"

#include <_ansi.h>

#include <_syslist.h>

#include <errno.h>

#include <sys/time.h>

#include <sys/times.h>

#include "retarget.h"

#include <stdint.h>

//#include "usart.h"

#if !defined(OS_USE_SEMIHOSTING)

#define STDIN_FILENO  0

#define STDOUT_FILENO 1

#define STDERR_FILENO 2

UART_HandleTypeDef *gHuart;

void RetargetInit(UART_HandleTypeDef *huart)

{

   gHuart = huart;

   /* Disable I/O buffering for STDOUT stream, so that

    * chars are sent out as soon as they are printed. */

   setvbuf(stdout, NULL, _IONBF, 0);

}

int _isatty(int fd)

{

   if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)

       return 1;

   errno = EBADF;

   return 0;

}

int _write(int fd, char *ptr, int len)

{

   HAL_StatusTypeDef hstatus;

   if (fd == STDOUT_FILENO || fd == STDERR_FILENO)

   {

       hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);

       if (hstatus == HAL_OK)

           return len;

       else

           return EIO;

   }

   errno = EBADF;

   return -1;

}

int _close(int fd)

{

   if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)

       return 0;

   errno = EBADF;

   return -1;

}

int _lseek(int fd, int ptr, int dir)

{

   (void) fd;

   (void) ptr;

   (void) dir;

   errno = EBADF;

   return -1;

}

int _read(int fd, char *ptr, int len)

{

   HAL_StatusTypeDef hstatus;

   if (fd == STDIN_FILENO)

   {

       hstatus = HAL_UART_Receive(gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);

       if (hstatus == HAL_OK)

           return 1;

       else

           return EIO;

   }

   errno = EBADF;

   return -1;

}

int _fstat(int fd, struct stat *st)

{

   if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)

   {

       st->st_mode = S_IFCHR;

       return 0;

   }

   errno = EBADF;

   return 0;

}

#endif //#if !defined(OS_USE_SEMIHOSTING)

1.16 为项目添加一个C语言头文件,命名为“retarget.h”,如图所示

undefined

添加头文件代码如下:

#ifndef FIRMWARE_RETARGET_H

#define FIRMWARE_RETARGET_H

#ifndef _RETARGET_H__

#define _RETARGET_H__

#include "stm32f1xx_hal.h"

#include <sys/stat.h>

#include <stdio.h>

void RetargetInit(UART_HandleTypeDef *huart);

int _isatty(int fd);

int _write(int fd, char *ptr, int len);

int _close(int fd);

int _lseek(int fd, int ptr, int dir);

int _read(int fd, char *ptr, int len);

int _fstat(int fd, struct stat *st);

#endif //#ifndef _RETARGET_H__

#endif //FIRMWARE_RETARGET_H

1.17 打开项目文件Core->Src->syscalls.c,为避免重定义,将以下几行注释:

undefined

1.18 打开项目文件Core->Src->main.c ,在如下位置添加一行代码实现串口重映射初始化,如图所示:

undefined

以上是为了打印调试信息添加的串口重映射配置,下面开始实现任务代码部分

1.19 打开项目文件Core->Src->tim.c,在如下位置添加代码,如图所示:

undefined

undefined

打开项目文件Core->Src->main.c,在如下位置添加代码,如图所示:

undefined

1.20 编译项目,并将生成的hex文件下载到开发板,观察现象。

任务代码

需要准时定时1s需要配置下面的的两个空的参数

undefined

测试说明

定时器设定定时时间为1s,1s时间到了之后就会打印 timer 1s elapsed

上一条:嵌入式Cortex-M应用-串口通信 下一条:嵌入式Cortex-M应用-外部中断实验

关闭