对于四轮车,只要电机的输出保持恒定,速度基本是恒定的。
但平衡直立车要控制直立,就算是原地不动,电机的输出每时每刻都在发生变化。
所以,要进行速度控制,获得当前小车的实际速度相当重要。
编码器有好多种,主要区别是单向双向,200线500线等不同精度,AB相输出,AZ相输出等区别。
其实对于平衡直立车,左右轮各一个200线的单向编码器就足够了。(大概100元一个)
200线的单向编码器,有一个A相输出,简单地说,就是轮子转一圈,就输出200个脉冲,也就是每转1/200圈,编码器就输出一个脉冲。
通过统计单位时间的脉冲,即可得到小车当前的行走速度。
K60有两个脉冲计数模块,够用。
XS128只有一个脉冲计数模块,需要在电路上另加一个加计数器(74LS系列即可)进行计数。
K60
初始化模块。
//初始化外部测速
FTM_QUAD_DIR_init(FTM1); //依米:左轮编码器
FTM_QUAD_DIR_init(FTM2); //依米:右轮编码器
FTM_QUAD_DIR_init(FTM1); //依米:左轮编码器
FTM_QUAD_DIR_init(FTM2); //依米:右轮编码器
读数
/******************************************
测速(每隔1s读出编码器读数,并清空)
测试时,要先关闭PIT中断
******************************************/
int16 countL = FTM_CNT_REG(FTM1_BASE_PTR);
FTM_CNT_REG(FTMx[FTM1]) = 0;
int16 countR = FTM_CNT_REG(FTM2_BASE_PTR);
FTM_CNT_REG(FTMx[FTM2]) = 0;
uartPrintf("Lcount = %d \t Rcount = %d \t \n",countL,countR);
delayms(1000);
测速(每隔1s读出编码器读数,并清空)
测试时,要先关闭PIT中断
******************************************/
int16 countL = FTM_CNT_REG(FTM1_BASE_PTR);
FTM_CNT_REG(FTMx[FTM1]) = 0;
int16 countR = FTM_CNT_REG(FTM2_BASE_PTR);
FTM_CNT_REG(FTMx[FTM2]) = 0;
uartPrintf("Lcount = %d \t Rcount = %d \t \n",countL,countR);
delayms(1000);
XS128
初始化TIM累加计数模块
/**************** For Encoder Counting ********************/
TCNT =0x00;
TSCR1=0x80; //TIMER 定时器使能
//禁止定时器溢出中断,分频因子p=16
TSCR2 = 0x06; // Timer Prescale.
PACTL=0xc0; //PT7 PIN,PACN32 16BIT,FALLing edge,NO INTERRUPT 0xc0 = 1100 0000
TFLG1=0xFF; //清中断标志位
TCNT =0x00;
TSCR1=0x80; //TIMER 定时器使能
//禁止定时器溢出中断,分频因子p=16
TSCR2 = 0x06; // Timer Prescale.
PACTL=0xc0; //PT7 PIN,PACN32 16BIT,FALLing edge,NO INTERRUPT 0xc0 = 1100 0000
TFLG1=0xFF; //清中断标志位
读数
//获得速度L
SPEED_EN_L=0;//16b计数禁止
NowSpeedL=SPEED_DATA_L;
SPEED_DATA_L=0;
SPEED_EN_L=1;//16b计数允许
//获得速度R
NowSpeedR=SPEED_DATA_R;
SPEED_EN_R=1; //高电平清空计数值
Delay_200ns();
SPEED_EN_R=0; //低电平使能计数
SPEED_EN_L=0;//16b计数禁止
NowSpeedL=SPEED_DATA_L;
SPEED_DATA_L=0;
SPEED_EN_L=1;//16b计数允许
//获得速度R
NowSpeedR=SPEED_DATA_R;
SPEED_EN_R=1; //高电平清空计数值
Delay_200ns();
SPEED_EN_R=0; //低电平使能计数