【WB32库开发】第12章(中)PWM输入捕获——串口打印数据

本文档介绍了如何在STM32平台上配置串口和PWM输入捕获功能,并将捕获到的PWM信息通过串口发送到上位机显示。首先,通过复制和添加必要文件到工程目录,然后配置UART1并初始化相关参数。接着,设置TIM1的PWM输入捕获,并在中断服务函数中计算频率和占空比。实验结果显示,串口成功输出了PWM的频率和占空比信息。
摘要由CSDN通过智能技术生成

上节我们讲述了如何配置TIM的PWM输入捕获功能,本节内容将与串口内容结合,将捕获到的信息通过上位机显示出来。

12.3 串口配置

我们在第八章的内容中已经讲过串口是如何配置和使用的。那么如何将串口相关程序移植到我们本章的例程中呢?

1)
按照下图中的目录将Retarget_uart1.c文件复制到本节例程的目录下。
在这里插入图片描述
在这里插入图片描述

2)
将Retarget_uart1.c添加到工程目录下:
在这里插入图片描述
另外,需要注意将固件库中的串口标准库文件wb32f10x_uart.c添加到StdPeriph_Driver下:
在这里插入图片描述
所在地址为:
WB32F10x_StdPeriph_Lib_V0.1.7.1_72Mhz\WB32F10x_StdPeriph_Lib_72Mhz_V0.1.7.1\Libraries\WB32F10x_StdPeriph_Driver\src

因为wb32f10x_uart.c对应的头文件与其他标准库源文件对应的头文件放在同一个文件夹下,我们在使用其他标准库时已经包含了所有标准库头文件所在的文件夹,因此,不必再去包含该对应的.h头文件。

3)
编译后无错误即可在主函数中配置UART结构体,这里给出我添加UART功能后的整体代码,新添加的代码和配置UART的代码部分会进行注释,其他内容在第十二章(上)中已经有过详细的注释,不再赘述:

#include "wb32f10x.h"
#include <stdio.h>                                             //若使用printf()或scanf()函数,必须包含此头文件

UART_InitTypeDef  UART_InitStructure;                          //将UART_InitTypeDef宏定义为UART_InitStructure

TIM_ICInitTypeDef  TIM_ICInitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
__IO uint32_t IC1Value = 0;
__IO uint32_t IC2Value = 0;
__IO float DutyCycle = 0;
__IO float Frequency = 0;

void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);

void delay(volatile uint32_t n)                                 //延时函数,用在串口输出信息时的延时,防止输出信息太快
{
  while(n--);
}


int main(void)
{       
  //使能UART1时钟和UART1对应引脚端口时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_GPIOA |RCC_APB1Periph_UART1, ENABLE);
  //初始化UART1收发引脚(PA9、PA10)为复用推挽上拉输出模式
  GPIO_Init(GPIOA, GPIO_Pin_9 |GPIO_Pin_10, GPIO_MODE_AF |GPIO_OTYPE_PP |GPIO_PUPD_UP |GPIO_SPEED_HIGH |GPIO_AF7);

  /* UART1 配置*/
  UART_DeInit(UART1);                                                   //恢复UART默认配置
  UART_InitStructure.UART_BaudRate = 115200;                            //配置波特率为115200
  UART_InitStructure.UART_WordLength = UART_WordLength_8b;              //配置帧数据字长为8bit
  UART_InitStructure.UART_StopBits = UART_StopBits_One;                 //配置停止位为1位
  UART_InitStructure.UART_Parity = UART_Parity_None;                    //配置校验位为无校验
  UART_InitStructure.UART_AutoFlowControl = UART_AutoFlowControl_None;  //配置硬件控制流
  UART_Init(UART1, &UART_InitStructure);                                //初始化UART初始化结构体
  UART_FIFOCmd(UART1, ENABLE);                                          //使能UART的FIFO功能
	
  printf("Printf the PWM Information.\r\n");                            //开发板上电后打印的第一条信息:“Printf the PWM Information.”     
	
  RCC_Configuration();
  NVIC_Configuration();
  GPIO_Configuration();

  TIM_TimeBaseStructure.TIM_Period = 0xFFFFF;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM1, &TIM_ICInitStructure);

  TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);

  TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);

  TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);

  TIM_Cmd(TIM1, ENABLE);

  TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
		
  while (1);
}


void RCC_Configuration(void)
{
  /* TIM1 GPIOA AFIO clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 | 
                         RCC_APB1Periph_TIM1 | 
                         RCC_APB1Periph_GPIOA | 
                         RCC_APB1Periph_AFIO , 
                         ENABLE);
}


void GPIO_Configuration(void)
{
  GPIO_Init(GPIOA, GPIO_Pin_8, GPIO_MODE_AF | GPIO_AF1);
}


void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void TIM1_CC_IRQHandler(void)
{
  TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

  IC1Value = TIM_GetCapture1(TIM1);
  IC2Value = TIM_GetCapture2(TIM1);
  
  DutyCycle = ((float)(IC2Value + 1) * 100) / (IC1Value + 1);
  Frequency = (float)72000000 / (IC1Value + 1);
	
  delay(5000000);                                                       //延时函数防止串口打印数据过快        
  printf("Freq is %0.2fHz,DC is %0.2f%%\r\n",Frequency,DutyCycle);      //打印频率与占空比信息
	
}

12.4 实验现象

本次实验使用的PWM为示波器上提供的频率1KHz、占空比50%的PWM(示波器不同也可能提供不同的PWM输出,注意查看对应信息即可),使用杜邦线将PWM输出端连接在PA8上,GND与开发板GND相连。

程序编译完毕没有错误后烧录到开发板上,将USB转串口设备上的TXD接在开发板的PA10(RX)上,将RXD接在开发板的PA9(TX)上,VCC与GND对应接好 。

连接在电脑后打开串口调试软件,按下开发板复位键,串口调试器打印出“Printf the PWM Information.”后,开始打印PWM的频率和占空比信息。
请添加图片描述
可以看到,串口输出正确,打印出的PWM信息也正确,本实验结果正确。

注意:
1)此处为干扰,展示的结果不可看作正常测试结果。

2)端口号不一定为COM4,但一定是“USB-SERIAL CH340”

3)此处设置务必与我们配置串口时采用的波特率相同。

12.5 小结

在本节内容中,我们将串口打印应用在了PWM输入捕获程序中来输出捕获的PWM的频率与占空比,正确的打印出了示波器PWM输出信号的频率和占空比。

但在实际应用中,我们要测试拥有各种各样频率和占空比的PWM,我们的本节编写的例程还能准确的输出结果么?

下一节,将在本节例程的基础上通过高级定时器TIM1来捕获并打印TIM2输出的PWM频率与占空比信息。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值