硬件设备
42步进电机,步进电机驱动器,正点原子F429开发板
开发软件
keil5,Cube
综述
一般要精准的控制电机,就要控制单片机的引脚输出指定个数的PWM波,有多种可实现的方法,其中最好用的方法是用定时器级联输出固定个数PWM脉冲,虽然多用了一个定时器,但大大减少了CPU的处理资源。STM32的每个定时器可以通过另外一个定时器的某一个条件被触发而启动.这里所谓某一个条件可以是定时到时、定时器超时、比较成功等许多条件.这种通过一个定时器触发另一个定时器的工作方式称为定时器的同步,发出触发信号的定时器工作于主模式,接受触发信号而启动的定时器工作于从模式。
Cube配置定时器,主定时器为PWM输出,从定时器为门控模式
1.主定时器为TIM3,其中通道1配置为PWM输出,主模式的更新事件选为触发输入
Cube的配置为参考,一切以代码为准
void MX_TIM3_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig = {};
TIM_OC_InitTypeDef sConfigOC = {}; htim3.Instance = TIM3; //设置主定时器为TIM3
htim3.Init.Prescaler = -; //设置PWM频率
htim3.Init.CounterMode = TIM_COUNTERMODE_UP; //设置计数模式为向上计数
htim3.Init.Period = -; //设置占空比
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置为无分频
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
} sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; //更新事件被选为触发输入
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; //开启主从模式
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
} sConfigOC.OCMode = TIM_OCMODE_PWM1; //设置PWM模式为PWM1
sConfigOC.Pulse = ; //设置PWM占空比为50%(50/100)
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW; //设置PWM空闲状态引脚拉低
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
} HAL_TIM_MspPostInit(&htim3); //设置PA6复用为PWM输出引脚
HAL_TIM_Base_Stop(&htim3);
}
2.从定时器为TIM4,选为门控模式——触发输入
从为TIM4,主为TIM3,根据下图,所以从模式的触发时钟为ITR2
void MX_TIM4_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {};
TIM_SlaveConfigTypeDef sSlaveConfig = {}; htim4.Instance = TIM4; //设置从定时器为TIM4
htim4.Init.Prescaler =; //设置从定时器频率为0
htim4.Init.CounterMode = TIM_COUNTERMODE_UP; //设置计数模式为向上计数
htim4.Init.Period =0xffff; //这个大于0就行
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置为无分频
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
{
Error_Handler();
} sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; //设置为内部时钟触发,即为TIM3
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
} sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED; //设置为门触发
sSlaveConfig.InputTrigger = TIM_TS_ITR2; //设置ITR2(tim3)为输入源
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; //设置触发模式为上升沿
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; //设置无预分频
sSlaveConfig.TriggerFilter = 0x0; //设置无滤波 if (HAL_TIM_SlaveConfigSynchronization(&htim4, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_Base_Stop_IT(&htim4); }
从定时器的频率一定要设为0,不然输出的PWM会加倍
中断处理函数
HAL里的中断处理函数要选HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim),当TIM4->CNT的值达到TIM4->ARR的值时触发中断,关闭主从定时器,清零中断标志位SR
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{ FLAG1_OK = ; if(htim==(&htim4))
{ //****************************************************//
if(__HAL_TIM_GET_FLAG(&htim4, TIM_FLAG_CC1) != RESET) //判断是否触发中断
{
__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC1); //清除中断标志位 HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1); //关闭主定时器的PWM输出 HAL_TIM_Base_Stop_IT(&htim4); //关闭从定时器的计数 //****************************************************// } delay_ms();
FLAG1_OK = ;
} }
脉冲输出主函数
中断函数关闭的,于此要重新开启,有始有终
while(1)
{ if(FLAG1_OK == ) //标志判断
{ she10 __HAL_TIM_SET_AUTORELOAD(&htim4,10-); //ARR装载要输出的PWM脉冲数 HAL_TIM_Base_Start_IT(&htim4); //从定时器计数开启 HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1); //主定时器PWM脉冲输出 } }
分析仪实测波形
很漂亮整洁的10个PWM波,在1MHz以下挺准的,但上去了就多了一两个波,还需要细调。
这个是单定时器的单通道的程序,已经写好单定时器多通道的了,有时间再发。
有不足之处还请各位不吝赐教。
基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序的更多相关文章
-
基于STM32F429和Cube的主从定时器多通道输出固定个数的PWM波形
主从定时器的原理已在上篇博文: 基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序 讲解了,这篇重点就讲如何实现多通道的PWM级联输出. 1.软件环境 Keil5 ...
-
定时器同步+触发三ADC采样+输出6路PWM波
为了熟悉定时器定时器和ADC 用STM32F407DIS做了一个简单的工程: 通过高级定时器TIM1溢出更新时间作为触发输出信号(TRGO),触发TIM8开始计数: 同时TIM1的通道1.2.3以及分 ...
-
STM32 HAL库学习系列---定时器TIM 输入捕获功能
基本方法 1.设置TIM2 CH1为输入捕获功能: 2.设置上升沿捕获: 3.使能TIM2 CH1捕获功能: 4.捕获到上升沿后,存入capture_buf[0],改为捕获下降沿: 5.捕获到下降沿后 ...
-
新建基于STM32F103ZET6的工程-HAL库版本
1.STM32F103ZET6简介 STM32F103ZET6的FLASH容量为512K,64K的SRAM.按照STM32芯片的容量产品划分,STM32F103ZET6属于大容量的芯片. 2.下载HA ...
-
STM32,下载HAL库写的代码后J-Link识别不到芯片,必须要按住复位才能下载?
问题描述:最近在学STM32的HAL库,据说可以统一STM32江湖,前途无量.最近一段时间参照STM32CubeMX和原子的资料自己学着建了两个HAL库的工程模板,F4的还好说,F1的出现了一个玄学问 ...
-
stm32定时器主从模式
TIM2作master:TIM3,TIM4作slave 定时器2事件更新被用作触发输出TRGO 从定时器TIM3,TIM4工作在从模式:门控模式 触发选择设为:ITR1,这样TIM2的TRGO就连到了 ...
-
基于STM32F429和HAL库的CAN收发例程
1.CAN协议介绍 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议.在当前的汽车产业中,出于对安全性.舒适性.方便性.低公 ...
-
【书籍连载】《STM32 HAL 库开发实战指南—基于F7》-第一章
从今天起,每天开始连载一章<STM32 HAL 库开发实战指南—基于F7>.欢迎各位阅读.点评.学习. 第1章 如何使用本书 1.1 本书的参考资料 本书参考资料为:<STM32 ...
-
【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&;CubeMX工程)
说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...
随机推荐
-
WinForm任务栏最小化
在C#编写的WinForm里,在FormBorderStyle设为None的时候,任务栏点击程序图标,不会自动最小化.在主窗口WinForm.cs里加入如下代码后,即可恢复该功能. protected ...
-
多线程编程2 - NSOperation
一.NSOperation 1.简介 NSOperation实例封装了需要执行的操作和执行操作所需的数据,并且能够以并发或非并发的方式执行这个操作. NSOperation本身是抽象基类,因此必须使用 ...
-
BZOJ2844: albus就是要第一个出场
Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合. 定义映射 f ...
-
TCP/IP协议分层
TCP/IP协议从上而下,层层包装: (1)应用层:HTTP (2)传输层:TCP和UDP (3)网络层(网际互联层):IP (4)数据连接层(网络接入层):为IP模块发送和接收IP数据报. (5)硬 ...
-
Hibernate理论
1.什么是Hibernate? Hibernate是数据持久层的一个轻量级框架.数据持久层的框架有很多比如:iBATIS,myBatis,Nhibernate,Siena等等.并且Hibernate是 ...
-
HDU 4793 Collision (2013长沙现场赛,简单计算几何)
Collision Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
-
二叉树的前序和中序得到后序 hdu1710
今天看学长发过来的资料上面提到了中科院机试会有一个二叉树的前序中序得到后序的题目.中科院的代码编写时间为一个小时,于是在七点整的时候我开始拍这个题目.这种类型完全没做过,只有纸质实现过,主体代码半个小 ...
-
构建高性能web站点-阅读笔记(一)
看完前9章,也算是看完一半了吧,总结一下. 郭欣这个名字或许并不响亮,但是这本书写的确实真好!百度一下他的名字也能够看到他是某些公司的创始人和投资者,当然他本人必定是大牛无疑. 从网页的动静分离到网络 ...
-
思科ASA5520防火墙telnet、SSH及DHCP设置
ASA5520远程登录telnet 注:最低安全级别的接口不支持telnet登陆,如OutsideASA(config)# telnet 172.16.0.0 255.255.0.0 inside ...
-
算法与数据结构(十一) 平衡二叉树(AVL树)(Swift版)
今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...