1 總線舵機(jī)的介紹
總線伺服舵機(jī)即串行總線智能舵機(jī),實(shí)際上可以理解為數(shù)字舵機(jī)的衍生品,數(shù)字舵機(jī)與模擬舵機(jī)相比而言是控制系統(tǒng)設(shè)計(jì)上的顛覆,而總線伺服舵機(jī)對(duì)于舵機(jī)而言則是在功能和運(yùn)用上的顛覆。舵機(jī)的運(yùn)用方式實(shí)際上只能發(fā)揮出總線伺服舵機(jī)非常小的一部分功能。這款TS-315是通過單線的串口通信對(duì)旋轉(zhuǎn)進(jìn)行控制的,控制字符串協(xié)議如下:
字符串協(xié)議:
#1P1500T100?控制舵機(jī)旋轉(zhuǎn),無返回
(1P是ID為1的舵機(jī),中間的1500是參數(shù),范圍是500-2500,控制舵機(jī)范圍,后面的參數(shù)100,表示舵機(jī)旋轉(zhuǎn)的時(shí)間參數(shù),也就是速度,意思是舵機(jī)從當(dāng)前角度達(dá)到命令中的1500的位置,所需要的時(shí)間為100ms,時(shí)間的范圍是1-50000,時(shí)間越大速度越慢,但是舵機(jī)的最快速度以實(shí)際舵機(jī)的參數(shù)而定)
#1PRAD??讀取角度,返回格式 #001P1467??
#1PULK?釋放扭力,無返回
#1PID002??改變ID (將1改成2,后面的參數(shù)必須為3位數(shù),不夠補(bǔ)0),返回格式 #002P
#1PBD1??返回 #OK!
改變波特率(9600,19200,38400,115200,128000)??(舵機(jī)重啟之后才會(huì)生效)
//1:9600 , 2:19200 , 3:38400 , 4:57600 , 5:115200 , 6:128000
#1PCSD??將當(dāng)前位置設(shè)置舵機(jī)的初始位置,返回 #OK!??(設(shè)置之后舵機(jī)上電之后會(huì)旋轉(zhuǎn)到設(shè)置的位置)
#1PCLE??(恢復(fù)出廠設(shè)置)(舵機(jī)重啟之后才會(huì)生效),返回 #OK!
#1PMOD1? ?,返回 #OK!
(最后的參數(shù)1表示工作模式,0:270度逆向,1:270度順向,2:180度逆向,3:180度順向,4:連續(xù)旋轉(zhuǎn))
逆向和順向表示舵機(jī)的旋轉(zhuǎn)方向。逆向:脈沖信號(hào)從500到2500,舵機(jī)逆時(shí)針旋轉(zhuǎn)。順向:脈沖信號(hào)從500到2500,舵機(jī)順時(shí)針旋轉(zhuǎn)。
連續(xù)旋轉(zhuǎn)模式就是普通的360度舵機(jī),連續(xù)旋轉(zhuǎn)的,無法控制角度,這個(gè)模式下控制舵機(jī)的命令#1P1500T100這樣的命令的作用就改變了,這個(gè)命令在這個(gè)模式下面的作用是:
中間的參數(shù)1500,范圍為500-2500,其中500-1500控制舵機(jī)的正轉(zhuǎn),1500-2500控制舵機(jī)的反轉(zhuǎn)。越接近1500速度越慢,越遠(yuǎn)離1500速度越快(即500和2500速度都是最快的,1500是停止)
最后的參數(shù)100,表示舵機(jī)旋轉(zhuǎn)的圈數(shù),100就是100圈(存在一兩圈的誤差,正常?。?,如果這個(gè)參數(shù)改成50000,那就是無限旋轉(zhuǎn)。如果參數(shù)是49999,那就只會(huì)轉(zhuǎn)49999圈
上面的1P 表示編號(hào)為1的舵機(jī),上面所有的命令最后都要帶回車換行符(0x0d 和 0x0a)
舵機(jī)的ID默認(rèn)是1,ID為255是廣播,廣播命令對(duì)所有舵機(jī)都有效。默認(rèn)波特率128000
2 STM32單線串口通信
參考手冊(cè)里面是這樣描述的,非常簡(jiǎn)單單線半雙方模式通過設(shè)置USART_CR3寄存器的HDSEL位選擇。在這個(gè)模式里,下面的位必須保持清零狀態(tài):
● USART_CR2寄存器的LINEN和CLKEN位
● USART_CR3寄存器的SCEN和IREN位
USART可以配置成遵循單線半雙工協(xié)議。在單線半雙工模式下,TX和RX引腳在芯片內(nèi)部互連。使用控制位”HALF DUPLEX SEL”(USART_CR3中的HDSEL位)選擇半雙工和全雙工通信。
當(dāng)HDSEL為’1’時(shí)
● RX不再被使用
● 當(dāng)沒有數(shù)據(jù)傳輸時(shí),TX總是被釋放。因此,它在空閑狀態(tài)的或接收狀態(tài)時(shí)表現(xiàn)為一個(gè)標(biāo)準(zhǔn)I/O口。這就意味該I/O在不被USART驅(qū)動(dòng)時(shí),必須配置成懸空輸入(或開漏的輸出高)。
除此以外,通信與正常USART模式類似。由軟件來管理線上的沖突(例如通過使用一個(gè)中央仲裁器)。特別的是,發(fā)送從不會(huì)被硬件所阻礙。當(dāng)TE位被設(shè)置時(shí),只要數(shù)據(jù)一寫到數(shù)據(jù)寄存器上,發(fā)送就繼續(xù)。
參考初始化源碼如下
//初始化IO 串口2
//pclk2CLK2時(shí)鐘頻率(Mhz)
//bound:波特率
void uart2_init(u32 pclk2,u32 bound)
{
u32 temp;
temp=(pclk2*1000000+bound/2)/bound; //得到USARTDIV@OVER8=0,采用四舍五入計(jì)算
RCC-》AHB1ENR|=1《《0; //使能PORTA口時(shí)鐘
RCC-》APB1ENR|=1《《17; //使能串口2時(shí)鐘
GPIO_Set(GPIOA,PIN2|PIN3,GPIO_MODE_AF,GPIO_OTYPE_OD,GPIO_SPEED_50M,GPIO_PUPD_PU);//PA2,PA3,復(fù)用功能,上拉輸出
GPIO_AF_Set(GPIOA,2,7); //PA2,AF7
GPIO_AF_Set(GPIOA,3,7);//PA3,AF7
USART2-》CR1=0; //清零CR1寄存器
USART2-》BRR=temp/2; //波特率設(shè)置@OVER8=0
//下面5行代碼是根據(jù)參考手冊(cè)設(shè)置寄存器,注意使能HDSEL放到最后
USART2-》CR3&=0《《5; //清SCEN
USART2-》CR3&=0《《1; //清IREN
USART2-》CR2&=0《《11; //清CLKEN
USART2-》CR2&=0《《14; //清LINEN
USART2-》CR3|=1《《3; //使能HDSEL
USART2-》CR1|=0《《28; //設(shè)置M1=0
USART2-》CR1|=0《《12; //設(shè)置M0=0&M1=0,選擇8位字長(zhǎng)
USART2-》CR1|=0《《15; //設(shè)置OVER8=0,16倍過采樣
USART2-》CR1|=1《《3; //串口發(fā)送使能
#if EN_USART2_RX //如果使能了接收
//使能接收中斷
USART2-》CR1|=1《《2; //串口接收使能
USART2-》CR1|=1《《5; //接收緩沖區(qū)非空中斷使能
MY_NVIC_Init(0,0,USART2_IRQn,2);//組2,最低優(yōu)先級(jí)
#endif
USART2-》CR1|=1《《0; //串口使能
}
3數(shù)據(jù)讀取時(shí)的注意點(diǎn)
通過邏輯分析儀分析,命令傳送至舵機(jī)后,舵機(jī)給出了正確的反饋,但是由于舵機(jī)回饋數(shù)據(jù)的速度非??欤斐闪藖G包問題,數(shù)據(jù)總是無法正確傳送至單片機(jī),由于在單線模式,RXD一直接收TXD發(fā)送的數(shù)據(jù),致使真正需要的數(shù)據(jù)丟包,因而只需要修改程序即可修正,更改的程序只是判斷下是否是自己發(fā)送的命令即可,若是,則不在接收,最后驗(yàn)證,已經(jīng)可以正確讀取舵機(jī)反饋值
u16 USART2_RX_STA=0; //接收狀態(tài)標(biāo)記
void USART2_IRQHandler(void)
{
u8 res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS.
OSIntEnter();
#endif
if(USART2-》ISR&(1《《5))//接收到數(shù)據(jù)
{
res=USART2-》RDR;
//if(USART2-》RDR!=USART2-》TDR)
{
if((USART2_RX_STA&0x8000)==0)//接收未完成
{
if(USART2_RX_STA&0x4000)//接收到了0x0d
{
if(res!=0x0a)USART2_RX_STA=0;//接收錯(cuò)誤,重新開始
else if (USART2_RX_BUF[5]==0x44)USART2_RX_STA=0; //防止丟包,禁止接收自己發(fā)送出去的命名
else
{
USART2_RX_STA|=0x8000; //接收完成了
}
}
else //還沒收到0X0D
{
if(res==0x0d)USART2_RX_STA|=0x4000;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3FFF]=res;
USART2_RX_STA++;
if(USART2_RX_STA》(USART2_REC_LEN-1))USART2_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開始接收
}
}
}
}
}
邏輯分析儀數(shù)據(jù)抓取
評(píng)論
查看更多