main.c
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "encoder.h"
#include "timer.h"
int main(void)
{
OLED_Init();//初始化外设
encoder_init();
timer_init();
OLED_ShowString(1,1,"v:00000snap/s");
while(1)//死循环
{
OLED_ShowSignedNum(1,3,get_count()/4,5);//speed=count/1s
OLED_ShowNum(2,1,TIM_GetCounter(TIM4),5);
}
}
void TIM4_IRQHandler(void)//tim4中断函数 在startup文件中查找
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//检查tim4跟新中断标志位
{
TIM_SetCounter(TIM3,0);//闸门时间设为1s,定时清零
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//中断函数执行结束后清零中断标志位
}
}
改用tim4一秒定时中断
timer.c
#include "stm32f10x.h"
//extern uint16_t number;//跨文件申明变量
void timer_init(void)//初始化定时器 rcc开启时钟→选择时基单元时钟源→配置时基单元→配置输出中断控制→配置nvic打开定时器中断的通道,并分配优先级→使能运行控制
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//通用计时器tim4是apb1总线的外设,故开启apb1的rcc时钟
TIM_InternalClockConfig(TIM4);//选择内部时钟 定时器上电后默认选择,不写该行代码也行
//配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;//定义结构体 初始化时基单元中一参数
TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//滤波器采样频率 选用一分频
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInitStruct.TIM_Period=10000-1;//周期 arr
TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//预分频器 psc
//定时频率=72m/(psc+1)/(arr+1)定时一秒即一赫兹=72m/10000/7200
//注:psc和arr取值范围[0~65535]
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器 高级定时器中用
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);//初始化
TIM_ClearFlag(TIM4,TIM_IT_Update);//手动清除时基单元初始化带来的中断标志位 避免刚初始化完就立马进中断
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//使能跟新中断
//配置nvic
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置优先级分组
NVIC_InitTypeDef NVIC_InitStruct;//定义结构体 初始化nvic中一参数 结构体变量可重复使用
NVIC_InitStruct.NVIC_IRQChannel=TIM4_IRQn;//tim4在nvic中的通道
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//响应优先级
NVIC_Init(&NVIC_InitStruct);//初始化
TIM_Cmd(TIM4, ENABLE);//启动定时器
}
timer.h
#ifndef __TIMER_H
#define __TIMER_H
void timer_init(void);
#endif
encoder模块前有介绍
OLED模块前有介绍
运行效果
正交编码器接口测速
可尝试进行带有霍尔编码器的电机测速
电机测速
main.c
#include "stm32f10x.h" // Device header
#include "OLED.h"
#include "motor.h"
#include "key.h"
#include "encoder.h"
#include "timer.h"
int8_t key;
int8_t key_speed;
int16_t speed;
int main(void)
{
OLED_Init();//初始化外设
key_init();
motor_init();
encoder_init();
timer_init();
OLED_ShowString(1,1,"key_speed:");
OLED_ShowString(2,1,"speed:00000rad/s");
while(1)//死循环
{
key=key_getnumber();
if(key==1)
{
key_speed+=20;
if(key_speed>100)
{
key_speed=-100;
}
}
motor_setspeed(key_speed);
OLED_ShowSignedNum(1,11,key_speed,3);
OLED_ShowSignedNum(2,7,speed,5);//speed=count/1s
OLED_ShowNum(3,1,TIM_GetCounter(TIM4),5);
}
}
void TIM4_IRQHandler(void)//tim2中断函数 在startup文件中查找
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//检查tim2跟新中断标志位
{
speed=get_count();//闸门时间设为1s
TIM_SetCounter(TIM3,0);//speed=get_count/1s
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);//中断函数执行结束后清零中断标志位
}
}
motor模块前有介绍
key模块前有介绍
身边没有带霍尔编码器的电机,就没做运行效果演示,还不知道是否可行,实验测试后补上运行效果
运行效果补上
正交编码器接口测速霍尔编码器电机