完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
波形分析
在使用ULN控制28BYJ-48步进电机的时候,采用1-2相8拍(天龙八步)控制步进电机运转时的波形如下: 八步波形图 图中已经标注出了一个周期中八步的执行过程:A相->AB相->B相->BC相->C相->CD相->D相->DA相。八步一个周期,周而复始进行。本篇拟采用STM32的定时器输出比较功能,通过控制捕获比较寄存器的值改变波形,从而影响IO口输出高低电平而控制步进电机运行。 TIM波形控制 使用TIM波形控制最重要的原因是不会阻塞主程序中其他任务进行,提高了系统的及时响应,同时TIM波形也非常简单,但有个缺点,严重依耐定时器及其通道。 具体程序如下:
/* 函数定义 -------------------------------------------------------- */ /** * @name: TIM_Configuration * @description: 初始化TIM及其各个捕获比较寄存器和通道 * @param {*} * @return {*} */ void TIM_Configuration(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(TIMx_GPIO_CLK_EN1 | TIMx_GPIO_CLK_EN2, ENABLE); /* TIM通道GPIO配置 */ GPIO_InitStruct.GPIO_Pin = TIMx_GPIO_Pin1 | TIMx_GPIO_Pin2; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TIMx_GPIO_Port1, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = TIMx_GPIO_Pin3 | TIMx_GPIO_Pin4; GPIO_Init(TIMx_GPIO_Port2, &GPIO_InitStruct); TIM_TimeBaseInitTypeDef TIM_TBInitStruct; TIMx_CLK_FUNC(TIMx_CLK_EN, ENABLE); /* TIM时基配置 */ TIM_TBInitStruct.TIM_Prescaler = TIMx_PSC - 1; TIM_TBInitStruct.TIM_Period = TIMx_ARR - 1; TIM_TBInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TBInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIMx, &TIM_TBInitStruct); /* TIM捕获输出配置 */ TIM_OCInitTypeDef TIM_OCInitStruct; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStruct.TIM_Pulse = (uint16_t)(TIMx_ARR / PERIOD * c1[0]); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; /* TIM ch1通道1配置 */ TIM_OC1Init(TIMx, &TIM_OCInitStruct); /* TIM ch2通道2配置 */ TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_Pulse = (uint16_t)(TIMx_ARR / PERIOD * c2[0]); TIM_OC2Init(TIMx, &TIM_OCInitStruct); /* TIM ch3通道3配置 */ TIM_OCInitStruct.TIM_Pulse = (uint16_t)(TIMx_ARR / PERIOD * c3[0]); TIM_OC3Init(TIMx, &TIM_OCInitStruct); /* TIM ch4通道4配置 */ TIM_OCInitStruct.TIM_Pulse = (uint16_t)(TIMx_ARR / PERIOD * c4[0]); TIM_OC4Init(TIMx, &TIM_OCInitStruct); /* TIM通道中断使能 */ TIM_ITConfig(TIMx, TIM_IT_CC1, ENABLE); TIM_ITConfig(TIMx, TIM_IT_CC2, ENABLE); TIM_ITConfig(TIMx, TIM_IT_CC3, ENABLE); TIM_ITConfig(TIMx, TIM_IT_CC4, ENABLE); TIM_ClearITPendingBit(TIMx, TIM_IT_CC1); TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); TIM_ClearITPendingBit(TIMx, TIM_IT_CC3); TIM_ClearITPendingBit(TIMx, TIM_IT_CC4); /* TIM中断配置 */ NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = TIMx_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); /* TIM使能 */ TIM_Cmd(TIMx, ENABLE); } 配置TIM对应的四个ch通道TIMx_GPIO_Pinx,本篇中进行了宏定义,大家可以根据自己需求进行定义。
/* 创建常量数组,保存toggle的时机 */ const uint8_t c1[] = {2, 7}; const uint8_t c2[] = {1, 4}; const uint8_t c3[] = {3, 6}; const uint8_t c4[] = {5, 8}; /* 宏定义8步 */ #define PERIOD (8) 如果对数组定义有疑问,请翻到本页顶部查看八步的时序图
* @name: TIMx_IRQHandler * @description: TIM中断函数,进行各个通道电平翻转 * @param {*} * @return {*} */ void TIMx_IRQHandler(void) { /* 定义变量,操作数组下标 */ static uint8_t c1_index = 0; static uint8_t c2_index = 0; static uint8_t c3_index = 0; static uint8_t c4_index = 0; /* ch1通道下次翻转电平设置 */ if(TIM_GetITStatus(TIMx, TIM_IT_CC1) == SET) { c1_index ^= 0x01; /* 数组下标变换 */ TIM_SetCompare1(TIMx, TIMx_ARR / PERIOD * c1[c1_index]); /* 设置下次toggle电平的时机 */ TIM_ClearITPendingBit(TIMx, TIM_IT_CC1); } /* ch2通道下次翻转电平设置 */ if(TIM_GetITStatus(TIMx, TIM_IT_CC2) == SET) { c2_index ^= 0x01; TIM_SetCompare2(TIMx, TIMx_ARR / PERIOD * c2[c2_index]); TIM_ClearITPendingBit(TIMx, TIM_IT_CC2); } if(TIM_GetITStatus(TIMx, TIM_IT_CC3) == SET) { c3_index ^= 0x01; TIM_SetCompare3(TIMx, TIMx_ARR / PERIOD * c3[c3_index]); TIM_ClearITPendingBit(TIMx, TIM_IT_CC3); } if(TIM_GetITStatus(TIMx, TIM_IT_CC4) == SET) { c4_index ^= 0x01; TIM_SetCompare4(TIMx, TIMx_ARR / PERIOD * c4[c4_index]-1); TIM_ClearITPendingBit(TIMx, TIM_IT_CC4); } } TIMx_IRQHandler是TIMx的中断函数。
{ uint32_t t = 0; initSysTick(); NVIC_PriorityGroupConfig(2); Usart1_Init(115200); LED1_Init(); TIM_Configuration(); for(;;) { t++; /* 其他任务 */ if(t % 100 == 1) { LED1_Toggle(); printf("led togglen"); } if(t >= 2000) t = 0; delay_ms(10); } }
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1561 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1501 浏览 1 评论
933 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
665 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1555 浏览 2 评论
1848浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
610浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
504浏览 3评论
508浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
489浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 17:09 , Processed in 0.514097 second(s), Total 48, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号