完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1.什么是PID?
PID知识学习指南: https://www.bilibili.com/video/BV1Ds411t7Hr 2.为什么要用PID来对电机进行控制? https://www.zhihu.com/question/353181256/answer/883991821 3.PWM输出配置 通过以上两个链接的学习,我们知道了使用PID对电机速度进行控制,就是通过调节PWM方波的占空比来对电机的速度进行调节。接下来我们就介绍PWM输出是如何配置的。 void TIM8_PWM_Init(u32 arr,u32 psc)//运用TIM8输出PWM方波 { GPIO_InitTypeDef GPIO_InitStructure; //定义初始化GPIO口的结构体 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM8时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTC时钟 GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8); //GPIOF8复用为定时器 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOF8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化PF8 TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频 初始化定时器的时基单元 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM8,&TIM_TimeBaseStructure);//初始化定时器8 //初始化TIM14 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 设置为模式一即小于CCRX为有效 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_Pulse =250; //CCRx TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出的有效极性 高 TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM8 OC3 TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //使能TIM8在CCR1上的预装载寄存器 TIM_ARRPreloadConfig(TIM8,ENABLE);//ARPE使能 //这个周期生效或下个周起生效 TIM_Cmd(TIM8, ENABLE); //使能TIM8 TIM_CtrlPWMOutputs(TIM8, ENABLE); //高级定时器必须加这句才能输出PWM!!!!!! } 注意: STM32FF4和STM32F1引脚复用功能配置不相同,F4为“GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);”同时注意需要将引脚配置为复用功能。 使用高级定时器输出PWM时需要,在最后加一句TIM_CtrlPWMOutputs(TIM8, ENABLE);才能输出PWM通用编码器可以不用加。 4.怎么配置TIM定时器为编码模式 说完了PWM输出怎么配置,接下来我们说说如何运用定时器的编码器模式对电机编码器进行读值。 想对定时器,编码模式进行深入了解可根据《STM32F4中文参考手册》进行了解。 void encoder_tim3_init(void) { GPIO_InitTypeDef GPIO_InitStructure; // GPIO口的输入模式配置很重要,不正确的话会读不到数据 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; //开时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //开启GPIOx口时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3作为编码器读取 // GPIO口初始化 //初始化编码器的GPIO口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //设置为为复用 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; //设置为开漏 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //无上下拉 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//指定操作管脚 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); //复用功能配置 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3); //将TIM3接到AF2 将PA6 PA7映射到TIM3时钟线上 // 定时器编码器模式初始化 //配置时基单元 TIM_DeInit(TIM3); //复位TIM3相关寄存器 TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化 TIM_TimeBaseStructure.TIM_Prescaler = 0; //分频值 TIM_TimeBaseStructure.TIM_Period = 65535; //自动重装载 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; // 这里可以自己设置,或使用默认值 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //此处:TIM_ICPolarity_Rising 意思是不反相 TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising ,TIM_ICPolarity_Rising); // 这里配置了编码器模式 //配置编码器 TIM_ICStructInit(&TIM_ICInitStructure); //该结构中按缺省值(默认)填入 TIM_ICInitStructure.TIM_Channel=TIM_Channel_1 |TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection =TIM_ICSelection_DirectTI; //设置 TIM_ICInitStructure.TIM_ICFilter = 0; //配置滤波器值 TIM_ICInit(TIM3, &TIM_ICInitStructure); //设置通道 TIM_SetCounter(TIM3, 0); TIM_Cmd(TIM3, ENABLE); } 5.该怎么吧TIM的CNT中的值读出来呢 因为读值我们不能时时刻刻都对编码器的计数器进行读值这样出来的数值意义不大所以我们需要没10ms对定时器的计数器中进行读值。(B站视频中有说明) 由于我们需要有一个10ms的定时所以我们还需要开启一个定时器来计时每10ms去读一次。并且我们可以定义一个全局变量,用来接收计数器中的数值。 void TIM2_IRQHandler(void) { extern int encoder_num; if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET) //判断中断是否溢出 //注意将TIM2改正确 { encoder_num = (int)((int16_t)(TIM3-》CNT)); // 这里尤其需要注意数据类型 TIM_SetCounter(TIM3, 0); } TIM_ClearITPendingBit(TIM2,TIM_IT_Update); //清除中断标志位 } 这里对定时器的配置不加以赘述了。(使用的计数器为TIM2) 这里encoder_num就是全局变量。 注意: 1.若编码器读出来的值为0xEEEEExx,说明该电机为反转。 最后:我们通过1中视频的讲解直接将该全局变量的值作为当前值,按照B站视频中的PID方式编写控制函数即可。 移植例程踩过的坑 检查开时钟时钟 函数名,总线名,传入参数 是否对应改变了。 中断服务函数中判断溢出是否更换了,判断的时钟 。 是否清楚了中断标志位 。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1792 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1626 浏览 1 评论
1094 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
732 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1682 浏览 2 评论
1943浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
740浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
577浏览 3评论
600浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
562浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-26 03:26 , Processed in 1.075807 second(s), Total 79, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号