作为从机(被控制)

1.Slave Mode disable - 从模式禁止:不使用从机功能

2.Reset Mode-复位模式:使用TRGI的上升沿来复位CNT,同时超声Updata事件

3.Gated Mode-门模式:使用TRGI控制时基单元的开关

4.Trigger Mode-触发模式:使用TRGI的上升沿来启动定时器

5.External Clock Mode 1-外部时钟模式1:把TRGI作为定时器的时钟

时基单元的三种时钟来源之中的TRGI就是来自从模式的外部时钟模式1

作为主机(控制别人)

1.Enable-使能:通过TRGO把时基单元的开关状态输出出去

2.Updata-更新:每产生一个Updata事件就向TRGO输出一个脉冲

占空比测量实验

实现的功能:使用定时器3通道1产生被测PWM,定时器1通道1测量PWM参数,在TIM3_CH1加一个指示灯来观察实验现象,加一个USB转TTL模块,通过串口把测量的结果发送到电脑上。

首先进行UART的测试:打开cube---设置debug---打开uart1,选择异步模式---参数保持不变---起个名字:PWMmeasurement---生成代码

实现功能:发送“你好世界”   代码写在while前边,如下:

HAL_UART_Transmit(&huart1,(const uint8_t *)"你好世界",12,HAL_MAX_DELAY);

为什么用(const uint8_t *):"你好世界" 在 C 里是一个字符串常量,类型是const char[],HAL_UART_Transmit的原型是

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,
                                                                     uint8_t *pData,
                                                                     uint16_t Size,
                                                                     uint32_t Timeout);

所以强转成const uint8_t *

为什么是12:"你好世界"是UTF-8 编码的汉字,每个汉字占3个字节。

第一步用定时器3通道1产生周期为1ms,占空比为20%的PWM:选择内部时钟---Channel1选择PWM Generation CH1---在Counter Settings配置时基单元---PSC:7; Count Mode:UP; ARR:999; auto-reload ARR(ARR的预装载):ENABLE;---在PWM Generation Channel 1配置输出比较通道1---Mode:PWM1---Pulse:200(20%的占空比)---CH polarity:High(不翻转电平)---生成代码

启动TIM3_CH1产生PWM,写在while上面,代码如下:

HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);

接下来完成测量PWM的参数,需要测量两个物理量:PWM周期,占空比。占空比=(脉宽/周期)*100%,所以实际就是测量脉宽和周期。这需要借助上面讲的从模式控制器。下面是TRGI的来源:

这里的TI1FP1和TI2FP2即是本实验所需要的。

有了上面的知识储备,思路如下: 

在cube再次配置定时器:点击TIM1---选择Internal Clock---PSC:7; UP; ARR:65535; 0; ENABLE---Channel1:Input Capture direct mode; Channel2:Input Capture indirect mode---在下面找到Channel1 2 的配置,1:Rasing 2:Falling---最关键的一步:

选择Reset Mode 

选择TI1FP1---生成代码

原理:

编程的步骤:

写于while内部,完整代码如下:

//1.清除cc1标准位

__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_CC1);

//2.启动定时器

HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_1);

HAL_TIM_IC_Start(&htim1,TIM_CHANNEL_2);

//3.等待CC1标志位并清除

while(__HAL_TIM_GET_FLAG(&htim1,TIM_FLAG_CC1) == 0);

__HAL_TIM_CLEAR_FLAG(&htim1,TIM_FLAG_CC1);

//4.再次等待CC1标志位

 while(__HAL_TIM_GET_FLAG(&htim1,TIM_FLAG_CC1) == 0);

//5.关闭定时器

HAL_TIM_IC_Stop(&htim1,TIM_CHANNEL_1);

HAL_TIM_IC_Stop(&htim1,TIM_CHANNEL_2);

//6.计算结果

uint16_t ccr1 = __HAL_TIM_GET_COMPARE(&htim1,TIM_CHANNEL_1);

uint16_t ccr2 = __HAL_TIM_GET_COMPARE(&htim1,TIM_CHANNEL_2);

float period = ccr1 * 1e-6;

float pulseWidth = ccr2 * 1e-6;

float = pulseWidth / period;

//7.打印

在Private user code粘贴以下代码:

#include <stdarg.h>
#include <stdio.h>
#include <string.h>

static void UART_Printf(const char *format, ...)
{
    char tmp[128];
    
    va_list argptr;
    va_start(argptr, format);
    vsprintf((char* )tmp, format, argptr);
    va_end(argptr);
    
    HAL_UART_Transmit(&huart1, (const uint8_t *)&tmp, strlen(tmp), HAL_MAX_DELAY);
}

在之前代码后面加上:

UART_Printf("脉宽=%.1fus,周期=%.1fus,占空比=%1f%%",pulseWidth*1e6f,period*1e6f,duty*100);

HAL_Delay(500);

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐