Stm32F407 AB相编码器配置 寄存器配置篇
Stm32关于AB相编码器的寄存器配置
// 编辑于2020.1.6
本人目前大四…第一次写博客…感觉起步已经晚了很多…
之前有做过几个小项目…虽然都是小打小闹吧…最近在做毕业设计…果然基础不扎实导致了很多地方有问题…在此记录一下自己的经验与心得…希望能帮助到大家…
技术有限,希望厉害的同学不要笑话我…
先提一下背景…用的是正点原子配置好的工程…下面这个函数是正点原子sys.c里的
Stm32_Clock_Init(336,8,2,7);
初始化系统时钟…一开始没加的时候也能执行.不确定这句话会不会影响编码器的定时器时钟…个人感觉应该不影响
RCC->AHB1ENR|=1<<4;
RCC->APB2ENR|=1<<0;
GPIOE->MODER&=~(3<<9*2);
GPIOE->MODER|=2<<(9*2);
GPIOE->OSPEEDR&=~(3<<(9*2));
GPIOE->OSPEEDR|=3<<(9*2);
GPIOE->OTYPER&=~(1<<9);
GPIOE->OTYPER|=1<<9;
GPIOE->PUPDR&=~(3<<(9*2));
GPIOE->PUPDR|=1<<(9*2);
GPIOE->MODER&=~(3<<11*2);
GPIOE->MODER|=2<<(11*2);
GPIOE->OSPEEDR&=~(3<<(11*2));
GPIOE->OSPEEDR|=3<<(11*2);
GPIOE->OTYPER&=~(1<<11);
GPIOE->OTYPER|=1<<11;
GPIOE->PUPDR&=~(3<<(11*2));
GPIOE->PUPDR|=1<<(11*2);
GPIOE->AFR[1] &=~(15<<(4*1));
GPIOE->AFR[1] &=~(15<<(4*3));
GPIOE->AFR[1] |=(1<<(4*1));
GPIOE->AFR[1] |=(1<<(4*3));
最上面的两句话分别是使能PTE的时钟,以及使能TIM1的时钟…注意看手册的时候别移位移错了…之前把1<<4写成了1<<5,找了半天问题…汗(lll¬ω¬)…
然后就是更改寄存器配置,先清空引脚功能,设置成复用输出,然后改输出频率大小以及开漏和上拉电阻…最后复用功能为tim功能
虽然没测试过…但是感觉上述写起来可能有些麻烦…感觉可以精简写成
RCC->AHB1ENR|=1<<4;
RCC->APB2ENR|=1<<0;
GPIOE->MODER&=~(3<<9*2);
GPIOE->MODER|=2<<(9*2);
GPIOE->MODER&=~(3<<11*2);
GPIOE->MODER|=2<<(11*2);
GPIOE->AFR[1] &=~(15<<(4*1));
GPIOE->AFR[1] &=~(15<<(4*3));
GPIOE->AFR[1] |=(1<<(4*1));
GPIOE->AFR[1] |=(1<<(4*3));
感觉这几句就可以了…因为毕竟要复用成别的功能…感觉输出频率和输出方式似乎可以不用设置…而且查到一个资料也有这种写法…这里先打一个问号?
下面是编码器模式的设置
TIM1->DIER|=1<<0;
TIM1->DIER|=1<<6;
TIM1->PSC=0X0;
TIM1->CCMR1&=0xFCFC;
TIM1->CCMR1|=1<<0;
TIM1->CCMR1|=1<<8;
TIM1->CCMR1|=3<<4;
TIM1->ARR=65534;
TIM1->CCER|=0<<1;
TIM1->CCER|=1<<0;
TIM1->EGR|=1<<0;
TIM1->CR1&=~(3<<8);
TIM1->CR1&=~(3<<5);
TIM1->CR1|=0<<7;
TIM1->SMCR&=0xFFF8;
TIM1->SMCR|=3<<0;
TIM1->CNT|=1000;
TIM1->CR1|=1<<0;
最上面两句关于dier寄存器的设置分别是更新中断使能位和触发中断使能位…是我查书关于输入捕捉脉冲的程序上有此使能,但是不确定编码器模式是否需要这两位使能
PSC寄存器,预分配值…这里直接0x0,表示计数器时钟频率就等于输入到预分频器的时钟频率…也就是不分频…这里的复位值也是0x00…所以感觉这句话也没啥用
CCMR1寄存器,前两句话的意思是配置为输入,将IC1 2映射到TI1 2上,这两句必须存在…因为我使用的是TIM1_CH1和CH2,如果你用的是CH3和CH4,就需要配置CCMR2这个寄存器…配置方法是一样的…第三句是一个滤波器…不确定效果如何…感觉我做的小项目不需要太高的精度…所以这里这句话有没有问题不大…
ARR寄存器,自动重载值…这个值越大…采集到的脉冲也越多…因为采集脉冲的时间也多…这个值最大0xffff
CCER寄存器,输入捕获用的寄存器…这里的配置是上升沿捕获脉冲…不过感觉开启编码器模式之后…这两句话并不需要
EGR寄存器,也是输入捕获用的寄存器…感觉也不需要
SMCR寄存器,这个是用来开启编码器模式的寄存器…
这里我是设置的编码器模式3
CNT寄存器…从这里可以读出记录的脉冲个数…这里初值写的1000,实际上写任何数都可以
CR1寄存器,使能计数器…这里就不赘述了
实际上,感觉比较有用的语句精简一下
TIM1->ARR = 0xFFFF;
TIM1->PSC = 0;
TIM1->CCMR1 |= 1<<0;
TIM1->CCMR1 |= 1<<8;
TIM1->SMCR |=3<<0;
TIM1->CR1 |= 1<<0;
没有试验过这样能不能用,可以试试…
然后就是再写一个定时器来读取CNT的值
RCC->APB1ENR|=1<<1;
TIM3->ARR=999;
TIM3->PSC=7199;
TIM3->DIER|=1<<0;
TIM3->CR1|=0X01;
MY_NVIC_Init(1,3,TIM3_IRQn,2);
int read_encoder(void)
{
encoder_num = (short)TIM1 ->CNT;
TIM1 ->CNT = 0;
return encoder_num;
}
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001)
{
a=read_encoder();
}
TIM3->SR&=~(1<<0);
}
a是全局变量,打开调试看看a的变化就可以了…
可以看到*在转
可以看到watch窗口里的变量也的确在变化
有错误的话请留言!