4.蓝桥杯嵌入式速通之输入捕获,PWM输出&ADC转换

前言

输入捕获,PWM输出和ADC的使用是历届蓝桥杯嵌入式程序设计的核心考点.

  • 输入捕获的考点为捕获输入脉冲信号的频率与占空比.
  • PWM输出的考点为输出频率和占空比可调的脉冲信号.
  • ADC转换的考点为模数转换的实现&滤波除去噪声.

一.输入捕获

1.CubeMX中的配置

这里我们不妨假设外界输入的脉冲信号通过MCU的PA1引脚输入单片机内.
于是乎PA1的定时器的通道2成为了直接捕获信号的通道,该定时器的其他通道则是间接捕获信号的通道.
在这里插入图片描述
输入捕获测周期的原理是:当捕获到脉冲信号的一个上升沿时开始让计数器计数,则下一次再捕获到上升沿时的计数器计数(开启捕获模式以后,该计数会被保存到定时器相应通道的CCR中)必然与脉冲信号周期有关,随后立即重启计数器计数,重复上述操作,如此周而复始地捕获与脉冲周期有关的计数器计数.

输入捕获测占空比的原理是:当捕获到脉冲信号的一个上升沿时开始让计数器计数,则下一次再捕获到上升沿时的计数器计数与脉冲信号周期有关,而捕获到的下降沿的计数器计数与脉宽有关(脉冲高电平的持续时间),由于占空比=脉宽/脉冲周期,因而可以通过这两个计数器的计数计算出脉冲信号的占空比.

在这里插入图片描述
在这里插入图片描述

2.输入捕获的准备工作

1.定义存储频率与占空比的全局变量;
2.打开定时器对应通道的输入捕获功能.
uint8_t     PA1 = 0         ;//经PA1测量的脉冲频率
uint8_t     duty1 = 0       ;//经PA1测量的占空比

//打开定时器对应通道的输入捕获功能
HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_2);

3.输入捕获的算法逻辑

1.脉冲频率的算法:用于捕获上升沿通道的计数器的值+1得到实际计数
(因为计数器数完第一个脉冲的时候计数为0所以实际计数要+1),
实际计数乘计数一次的时间(流经计数器脉冲频率的倒数)得到脉冲周期,
对脉冲周期取倒数即可得到脉冲周期
2.占空比的算法:脉宽/脉冲周期,因为
脉宽=(捕获下降沿通道的计数器的值+1)*计数一次的时间,
脉冲周期=(捕获上降沿通道的计数器的值+1)*计数一次的时间
所以占空比(捕获下降沿通道的计数器的值+1)除以
(捕获上降沿通道的计数器的值+1)后再乘100%
//脉冲信号频率
PA1 = 1.0f/((HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1)*1.0f/1000000.0f);
//脉冲信号占空比
duty1 = (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1)*1.0f/(HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1);

二.PWM输出

1.CubeMX中的配置

以PA7输出PWM为例,展示CubeMx中的配置.
这里选择以PA1的定时器2的通道2为例演示
在这里插入图片描述

2.PWM输出的准备工作

//打开需要输出PWM的通道
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);

3.PWM输出的算法逻辑

APB1/2上的时钟频率/(定时器的预分频系数+1)得到每秒钟计数多少下,
即(定时器的预分频系数+1)/APB1/2上的时钟频率是计数一下对应的时间.
(自动重装载值+1)×计数一下的时间是脉冲周期,脉冲周期的倒数是脉冲频率.
从而输出脉冲频率=APB1/2上的时钟频率/(定时器的预分频系数+1)/(自动重装载值+1)

因为(自动重装置值+1)乘每下计数对应的时间为周期,CCR寄存器的值乘每下计数对应的时间为脉宽
这是因为当计数器数0,1,...CCR寄存器中的值-1共CCR寄存器的值个值的时候输出为高电平,
当计数器数CCR寄存器的值到自动重装置值的时候输出为低电平.
所以输出脉冲的占空比则为CCR寄存器的值/(自动重装载值+1)

综上所示,要输出频率和占空比可调的脉冲信号,只需调整预分频器中的值,自动重装载寄存器中的值和
定时器对应通道中的CCR寄存器中的值即可.
//调整预分频值,第一个参数是定时器的操作句柄,第二个参数是想要设置的值
__HAL_TIM_SET_AUTORELOAD(&htim2,50);
//调整自动重装载值,第一个参数是定时器的操作句柄,第二个参数是想要设置的值
__HAL_TIM_SET_PRESCALER(&htim2,100);
//调整CCR寄存器中的值
//第一个参数是定时器的操作句柄
//第二个参数的定时器中的对应通道
//第三个参数是想要设置的值
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,30);

三.ADC转换

1.CubeMX中的配置

这里以PB15引脚的ADC2的通道15演示配置过程:
在这里插入图片描述
选择为单端模式采样.
在这里插入图片描述
量化位数拉满以提高精度.
在这里插入图片描述
打开连续转换模式,这样只需开启一次ADC即可一直用.
然后打开DMA的连续请求,这样打开DMA即可让DMA一直将通过转换的数据搬运至单片机内存中.
在这里插入图片描述
使用常规转换模式,然后使能过采样,选择将16次采样的值作为一次采样的值,这样到软件中可以将原先的除以2的12次方改为除以2的16次方,充分利用16位数据的分辨率,提高精度.
在这里插入图片描述
无脑将采样时间拉满,这是因为采样时间越大,捕获的采样信号的细节越多,采样值越精确,且系统负担小,不易出现系统卡死的情况,但是相应的代价是降低了系统的实时性,且无法还原较高频率的信号(蓝桥杯无特定要求,意味着这样的代价是可以承受的)
在这里插入图片描述为节省CPU资源,使用DMA将转换好了的数据从外设搬运至内存中.
在这里插入图片描述

2.ADC转换的准备工作

1.准备好数据缓存区,用于在内存中缓存经DMA转换后的数据
2.开启ADC的自校准让其自动进行电压补偿,提高准确性
3.开启以DMA搬运数据模式的ADC转换,随后读取到的12位整数会被缓存入事先准备好的缓存区中
uint16_t ADC2_buff[1];

HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);

//第一个参数填入ADC操作句柄,第二个参数填入缓存区首地址,第三个参数填入缓存区大小
HAL_ADC_Start_DMA(&hadc2,(uint32_t*)ADC2_buff,1);

3.ADC转换的算法逻辑

如果我们未采用过采样模式,那么一份ADC电压值是3.3/4096,我们通过ADC读取到的是电压的份数.
所以将份数×每份电压值即可得到转换而来的电压.

由于我们采用了过采样模式,将16份电压当成一份电压读取出来,因此转换而来的电压为:
份数/16×每份电压值

float ADC22;//存储转换而来的电压值

ADC22=ADC2_buff[0]*3.3f/65536.0f;//这里的65536是4096➗16所得
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值