历史上的今天
今天是:2024年09月16日(星期一)
2018年09月16日 | stm32的编码器模式
2018-09-16 来源:eefocus
选择编码器接口模式的方法是:如果计数器只在TI2的边沿计数,则置TIMx_SMCR寄存器中的
SMS=001;如果只在TI1边沿计数,则置SMS=010;如果计数器同时在TI1和TI2边沿计数,则
置SMS=011
TI1FP1和TI2FP2
是TI1和TI2在通过输入滤波器和极性控制后的信号;如果没有滤波和变相,则TI1FP1=TI1,
TI2FP2=TI2。根据两个输入信号的跳变顺序,产生了计数脉冲和方向信号。依据两个输入信号
的跳变顺序,计数器向上或向下计数,同时硬件对TIMx_CR1寄存器的DIR位进行相应的设置。
不管计数器是依靠TI1计数、依靠TI2计数或者同时依靠TI1和TI2计数,在任一输入端(TI1或者
TI2)的跳变都会重新计算DIR位。
编码器接口模式基本上相当于使用了一个带有方向选择的外部时钟。这意味着计数器只在0到
TIMx_ARR寄存器的自动装载值之间连续计数(根据方向,或是0到ARR计数,或是ARR到0计
数)。所以在开始计数之前必须配置TIMx_ARR;同样,捕获器、比较器、预分频器、重复计数
器、触发输出特性等仍工作如常。编码器模式和外部时钟模式2不兼容,因此不能同时操作。
在这个模式下,计数器依照增量编码器的速度和方向被自动的修改,因此计数器的内容始终指
示着编码器的位置。计数方向与相连的传感器旋转的方向对应。下表列出了所有可能的组合,
假设TI1和TI2不同时变换
表73 计数方向与编码器信号的关系
226/754
| 相对信号的电平 (TI1FP1对应TI2, TI2FP2对应TI1) | TI1FP1信号 | TI2FP2信号 | 有效边沿 | ||
| 上升 | 下降 | 上升 | 下降 | ||
| 高 | 向下计数 | 向上计数 | 不计数 | 不计数 | 仅在TI1计数 |
| 低 | 向上计数 | 向下计数 | 不计数 | 不计数 | |
| 高 | 不计数 | 不计数 | 向上计数 | 向下计数 | 仅在TI2计数 |
| 低 | 不计数 | 不计数 | 向下计数 | 向上计数 | |
| 高 | 向下计数 | 向上计数 | 向上计数 | 向下计数 | 在TI1和TI2上计数 |
| 低 | 向上计数 | 向下计数 | 向下计数 | 向上计数 |
一个外部的增量编码器可以直接与MCU连接而不需要外部接口逻辑。但是,一般会使用比较器
将编码器的差动输出转换到数字信号,这大大增加了抗噪声干扰能力。编码器输出的第三个信
号表示机械零点,可以把它连接到一个外部中断输入并触发一个计数器复位。
下图是一个计数器操作的实例,显示了计数信号的产生和方向控制。它还显示了当选择了双边
沿时,输入抖动是如何被抑制的;抖动可能会在传感器的位置靠近一个转换点时产生。在这个
例子中,我们假定配置如下:
● CC1S=’01’ (TIMx_CCMR1寄存器, IC1FP1映射到TI1)
● CC2S=’01’ (TIMx_CCMR2寄存器, IC2FP2映射到TI2)
● CC1P=’0’ (TIMx_CCER寄存器, IC1FP1不反相, IC1FP1=TI1)
● CC2P=’0’ (TIMx_CCER寄存器, IC2FP2不反相, IC2FP2=TI2)
● SMS=’011’ (TIMx_SMCR寄存器,所有的输入均在上升沿和下降沿有效).
● CEN=’1’ (TIMx_CR1寄存器,计数器使能)
图91 编码器模式下的计数器操作实例
下图为当IC1FP1极性反相时计数器的操作实例(CC1P=’1’,其他配置与上例相同)
图92 IC1FP1反相的编码器接口模式实例
当定时器配置成编码器接口模式时,提供传感器当前位置的信息。使用第二个配置在捕获模式
的定时器,可以测量两个编码器事件的间隔,获得动态的信息(速度,加速度,减速度)。指示机
械零点的编码器输出可被用做此目的。根据两个事件间的间隔,可以按照固定的时间读出计数
器。如果可能的话,你可以把计数器的值锁存到第三个输入捕获寄存器(捕获信号必须是周期的
并且可以由另一个定时器产生);也可以通过一个由实时时钟产生的DMA请求来读取它的值。
eg:
编码器A相接PB6,B相接PB7
#define ENCODENU 65536
void time4IOInit()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //①使能 GPIOB 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //PB6 7 设置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void time4CountInit()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能 TIM4 时钟
TIM4->ARR = ENCODENU-1; //设定计数器重装值(因为没有使用更新中断所以将计数器设最大值,保证1s延时不会溢出)
TIM4->PSC = 0; //预分频器
TIM4->CR1 &=~(3<<8); // 选择时钟分频:不分频
TIM4->CR1 &=~(3<<5); //边沿对齐(根据dir位向上或者向下计数)
//定时器4配置成编码器模式,双边沿触发
TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12, TIM_ICPolarity_BothEdge ,TIM_ICPolarity_BothEdge);
TIM_SetCounter(TIM4, 0); //计数器清零
}
void encoderConfig()
{
time4IOInit();
time4CountInit();
TIM_Cmd(TIM4, ENABLE); //计数器使能,开始工作
}
void main ()
{
int dir=0;
u16 nu=0;
encoderConfig();
for (;;)
{
dir=(TIM4->CR1 & 0x0010)>4; //取方向标志位
if(dir > 0){ //向下计数
nu = (ENCODENU-TIM_GetCounter(TIM4))/4; //除以4是因为一对脉冲计数器计数4次
FG_Print("down ; TIM_GetCounter=%d \r\n",nu*60/1000);//(*60是因为延时1s转换成一分钟,/1000是因为编码器转一圈是1000个脉冲)
}else{ //向上计数
nu = TIM_GetCounter(TIM4)/4;
FG_Print("up ; TIM_GetCounter=%d \r\n",nu*60/1000);
}
TIM_SetCounter(TIM4, 0);
osDelay(1000);
}
}
史海拾趣
|
2007年结束的时候,合同制造市场状况不稳。虽然当年营业额增长情况不错,但iSuppli公司修正后的合同制造产业预测显示,该产业的增长速度将在长期内放缓。 合同制造市场由电子制造服务(EMS)提供商与原始设计制造(ODM)公司构成,该市场2007年增长了15 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 09:30 编辑 那个家伙太TM狠了,把网址写在记事本里,整个压缩文件,然后收费!鄙视你 http://www.necel.com/cgi-bin/nesdis/o003_e.cgi?article=DF781235 这个就是那个记事本里的网址 … 查看全部问答> |
|
昨天去面试了一家公司,做了他们的测试题完了之后看了我简历并和我谈了很久说让我去做嵌入式开发,因为以前多用VC开发,这方面工资大概应该多少啊?我先不说我谈的了,看看大家知道的应该是多少,我也不知道,可我觉得他给我的少了… 查看全部问答> |
|
SRAM、SDRAM的Verilog模型 SRAM :IS61LV25616AL.exe SDRAM :mt48lc2m32b2.v [ 本帖最后由 dream_byxiaoyu 于 2011-11-21 10:44 编辑 ]… 查看全部问答> |
|
各位师兄师姐大牛大家好: 小弟刚开始接触DSP2812,还没有入门,真心求大家领路,真心希望大家指点迷津。我不要现成代码,有了方法,我自己来实现。 说一下我的工程背景,我在电力行业,做开关断路器机械特性的在线监测。现在要捕获欧姆龙旋转编 ...… 查看全部问答> |
|
Verilog hdl编程,按键控制,有锁相环,放大器,LCD显示器,幅值-2到—+2v,误差%0.1,频率在1khz--200khz,输出正弦波,最近毕业急用,非常感谢… 查看全部问答> |




