2017-08-30 80 views
2

我尝试生成正交信号,但操作可能最低。我使用STM32和GPIO引脚B8和B9来发送信号。 引脚8和9的几个引脚有四种可能的选项: 0/0 1/0 1/1和0/1 和逆时针 0/0 0/1 1/1 1/0 I无法按位寻找方式以便能够快速设置或重置选定引脚的位。此外,我必须能够进行时钟或反向旋转,并随时改变感觉,如果它是旋转或线性编码器。通过位操作生成正交信号

谢谢您的帮助

+0

递增/递减(模4)? – wildplasser

+0

这将不会产生所需的0,1,3,2序列 – berendi

回答

2

位拆裂

按位思考,B9得到B8的前值,并计算下来的时候B8得到B9的倒数,或者反过来。您可以交换这两个位,并根据方向进行排除或与0x1000x200排除。

inline void incB89(int down) { 
    uint32_t temp; 

    /* read the current output state */ 
    temp = GPIOB->ODR; 

    /* modifying the significant bit-pair 
     don't care about overflow */ 
    temp = (((temp & 0x100) << 1) | ((temp & 0x200) >> 1))^(0x100 << down); 

    /* Setting the reset bits BR8 and BR9. This has the effect that 
     bits 8 and 9 will be copied into the ODR, and the rest will 
     be left alone */ 
    temp |= ((1 << 24) | (1 << 25)); 

    GPIOB->BSRR = temp; 
} 

使用计时器(或两个)

在大多数STM32系列控制器,TIM4通道3和4级的输出可以被映射到PB8及PB9。如果您有其中之一,则此计时器可以自主控制输出,不受代码,内存或中断延迟的影响。

  • 根据控制器的参考手册设置GPIO模式和备用功能寄存器。
  • 将通道3和通道4都配置为切换模式,将位设置为TIM4->CCMR10b011
  • 将输入时钟,预分频器PSC和重新加载ARR设置为实现所需频率的两倍,因为每个输出在每个定时器周期内都会切换一次。
  • 设置为TIM4->CCR3=0TIM4->CCR4=(TIM4->ARR+1)/2用于在一个方向上进行计数。交换它们(在计数器停止时)以反转方向。
  • 启用TIM4->CCER中的输出。
  • 您可以通过设置或重置CENTIM4->CR1来启动和停止计数。
  • 要计数周期,您可以在TIM4->DIER中配置切换或更新事件的中断,或使用另一个计时器作为TIM4的从属设备。

要使用例如TIM3数:

  • 设置MMSTIM4->CR2比特0b010到输出上的每个溢出的触发脉冲。
  • TIM3->SMCR配置为外部时钟模式1,并选择TIM4的内部触发。
  • TIM3->ARR设置为需要的半周期数 - 1.
  • 在更新时配置中断。
  • 启动计数器。

有一些可能具有定时器更多的花样,例如使用由从触发以从“wawelength”值的表更新主定时器的ARRCCR寄存器DMA脉冲串。

+0

嗨,berendi,谢谢你的帮助。 我想了解使用变量down?我应该用什么? 我正在使用定时器读取正交编码器。你的设置似乎是非常详细的,我会仔细研究它.. – vib

+0

'下来'倒转的方向。当'down == 0'时,位移无效,位8在交换后反转。当'down == 1'时,掩码将被移位,并且位9将被反转。 – berendi

+0

好的非常感谢。 您是否介意使用所述的计时器设置main.c文件? 我尝试了一些,但我不明白所有参数,所以我没有得到所需的方波。 这将是非常善良;) – vib