/*这一篇笔记,介绍的是关于器件的选型和一些小技巧的记录,以及STM32的定时器的编码模式*/
主要的关于pid的代码在第二章节一个完整的、超详细的关于A,B相可读取速度的电机的项目(PID稳速)的笔记(二)
项目的所需要的器件
- 电机驱动芯片:TB6612
- 单片机:STM32F030C8T6
- 电机:一个具有A,B 相位输出得的、一圈输出11个脉冲的、减速比4.4、12V电机。
开始前的关于C的一些小笔记(面向初学者)。
位、字节、字、半字、枚举、以及位操作
位:一个bit,二进制数中的一个位,在某些编译器中可以用关键字bit的定义,像C51中的sbit的定义是外部的位。
字节:一个byte,八个位为一个字节。
字:一个word,字和处理器可以一次性处理的长度有关,32位机的字就是32位。
半字 :halfword,故名思意,字的一半。
枚举类型的定义:
typedef enum
{
I2C_OK = 1,
I2C_ERROR = !I2C_OK,
} I2C_Status、
/*定义这个的好处就是,可以可以判读这个函数执行的结果*/
/*比如我要判断数据是否通过I2C总线写到地址里去*/
I2C_Status SetI2CData(uint8_t addr,uint8_t data)
{
uint8_t Timeout=0;
LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_AUTOEND,LL_I2C_GENERATE_START_WRITE);
while(!LL_I2C_IsActiveFlag_TXIS(I2C3) && Timeout<10)
{
Timeout++;
LL_mDelay(1);
}
if( Timeout > 4 )
return I2C_ERROR;
else
LL_I2C_TransmitData8(I2C3,addr);
Timeout = 0;
while(!LL_I2C_IsActiveFlag_TXIS(I2C3))
{
Timeout++;
LL_mDelay(1);
}
if( Timeout > 4 )
return I2C_ERROR;
else
LL_I2C_TransmitData8(I2C3,data);
return I2C_OK;
}
位操作 :
/*取位,比如我要取某一个数据的,第6位(bit5)*/
data & 0x20 // 0x20 = 0b0010 0000
/*清位,比如我要清某一个数据的,第6位(bit5)*/
data & ~0x20
/*置位,比如我要置某一个数据的,第6位(bit5)*/
data | 0x20
/*看,为了方便位操作,ST把寄存的位都给提取出来了*/
#define ADC_CR_ADEN_Pos (0U)
#define ADC_CR_ADEN_Msk (0x1UL << ADC_CR_ADEN_Pos) /*!< 0x00000001 */
#define ADC_CR_ADEN ADC_CR_ADEN_Msk /*!< ADC enable */
#define ADC_CR_ADDIS_Pos (1U)
#define ADC_CR_ADDIS_Msk (0x1UL << ADC_CR_ADDIS_Pos) /*!< 0x00000002 */
#define ADC_CR_ADDIS ADC_CR_ADDIS_Msk /*!< ADC disable */
TB6612的电路图
STM32F030C8T6的STM32Cube MX的配置,以及编码模式的介绍。
编码模式 :打开手册找到tim1的Encode 模式
我们只需按上面的介绍配置寄存器,就会有下图的效果,可以看到,A,B相的相位差位为90°,一个周期会计数4次,所使用的电机一圈输出11个脉冲的、减速比4.4,也就是说,使用的电机一圈所计数值为4.4411=193.6,是不是可以在配置定时器的时候,让他自动重装载值为193,记录一下时间,然后计算出速度,然后将速度与期望的速度的差值送入PID,就行了(在实际的调试中并不是那么简单)。
STM32Cube MX的配置。
打开软件,选择型号,将所需要的引脚配置好,配置定时器,在combined channel里选取 encode mode
在encode mode 选取TI1 and TI2 ,自动重新装置值填写193。