stm32库开发实战读书笔记(五)

前言

该部分是pwm波的深入应用,如那个引脚输出何种形式的脉冲以及DMA的基础应用。

stm32的基本知识补充

没事的时候,可以看下stm32中文手册

在这里插入图片描述

pwm的基本配置

  • 使能定时器以及相应的端口的时钟RCC_APB2PeriphClockCmd
  • 初始化I/O口为推挽复用模式,GPIO_Mode = GPIO_Mode_AF_PP
  • 是否进行重映射配置
  • 初始化定时器,ARR,PSC等,TIM_TimeBaseInit
  • 初始化输出比较参数TIM_OC4PreloadConfig
  • 使能预装载寄存器,TIM_OC4PreloadConfig,使能定时器TIM_Cmd

定时器输出形式

TIM_SetCompare4(TIMx,i); //TIMx的ch4输出,对应mini的PA11

个人理解

  • 更换输出口的时候要查看芯片手册,找出某个引脚对应的TIMx以及CH1~4,如果需要重映射可以参考GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE)
  • Tout= ((arr+1)*(psc+1))/Tclk
    • Tclk: TIMx 的输入时钟频率(单位为 Mhz)
    • Tout: TIMx溢出时间(单位为 us)
    • arr:自动重装值
    • psc:分频系数
    • psc+arr:一般设置为入口参数,用于调节定时周期
    • 如arr = 200-1,psc = 7200-1,则其产生的脉冲周期为50hz,20ms
  • 使能相应的CHx,以及TIMx

重要
关于输出指定大小的方波来控制舵机旋转。

  • 控制PWM输出模式,寄存器TIMx_CCMR1,控制代码TIM_OCInitStructure.TIM_OCMode

  • PWM模式1:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

  • PWM模式2:在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

可以参考
stm32控制舵机旋转到不同角度
STM32控制舵机的原理及代码

完成相应配置

控制线用于传输角度控制信号。这个角度是由控制信号脉冲的持续时间决定的,这叫做脉冲编码调制(PCM)。舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围,总间隔为2ms。脉冲的宽度将决定马达转动的距离。例如:1.5毫秒的脉冲,电机将转向90度的位置(通常称为中立位置,对于180°舵机来说,就是90°位置)。如果脉冲宽度小于1.5毫秒,那么电机轴向朝向0度方向。如果脉冲宽度大于1.5毫秒,轴向就朝向180度方向。以180度舵机为例,对应的控制关系是这样的:

0.5ms————-0度;
1.0ms————45度;
1.5ms————90度;
2.0ms———–135度;
2.5ms———–180度;

计算方法

舵机配置需要满足频率为50HZ,PWM占空比是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,由于PWM周期为20ms,所以(以舵机会转动 45°为例),占空比就应该为1ms/20ms = 5%,所以TIM_SetCompare1的 TIMx 捕获比较 1 寄存器就为200-200*5% = 190

DMA的基本知识

DMA,全称为: Direct Memory Access,即直接存储器访问。 DMA 传输方式无需 CPU 直接
控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备
开辟一条直接传送数据的通路, 能使 CPU 的效率大为提高。

配置

在这里插入图片描述

.c

DMA_InitTypeDef DMA_InitStructure;

u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度 	    

/**
  * @brief DMA1的各通道配置,从存储器->外设模式/8位数据宽度/存储器增量模式
  * @param  DMA_CHx:DMA通道CHx
  * @param  cpar:外设地址
  * @param  cmar:存储器地址
  * @param  cndtr:数据传输量 
  * @retval None
  * @note 这里的传输形式是固定的,这点要根据不同的情况来修改
  * @note_time 2020-11-23 小刘同学
 **/

void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输
	
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
	DMA1_MEM_LEN=cndtr;
	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
	DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
	DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
	DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
	  	
} 


/**
  * @brief 开启一次DMA传输
  * @param  DMA_Channel_TypeDef *DMA_CHx DMA的通道口地址
  * @retval None
  * @note_time 2020-11-19 小刘同学
 **/
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{ 
	DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
 	DMA_SetCurrDataCounter(DMA1_Channel4,DMA1_MEM_LEN);//DMA通道的DMA缓存的大小
 	DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道 
}	  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值