2017年06月23日

磁気エンコーダTLE5012B その2

紹介しました。

TLE5012Bの問題点はSPIインタフェース互換のSSCという通信方式で
MOSIとMISOが1つで双方向に通信を行います。

前回はMOSIとMISOに抵抗を挟んで通信しましたが、
STM32のHALライブラリにはSSCに対応したHalf Duplexモードがあるため、
そちらを使用して通信してみました。

CubeMXではHalf Duplex Masterとして設定します。
SPI.png


配線ではMISOは使用せず、
MOSIのみで双方向に通信します。
1本のみの通信のため、抵抗値を0にしています。

SPI-HalfDuplex.png



コードは下記の通りです。

uint16_t GetEncPos(){
 uint8_t    sData[6];
  uint8_t rData[6];
  uint8_t rCRCBuff[12];
  uint16_t res;

 HAL_GPIO_WritePin(ENC_CS1_GPIO_Port, ENC_CS1_Pin,0);//CS
 sData[0]=0x80;sData[1]=0x21;
 HAL_SPI_Transmit(&hspi1,sData,2,500);


 sData[0]=0x00;sData[1]=0x00;sData[2]=0x00;sData[3]=0x00;
 rData[0]=0;rData[1]=0;rData[2]=0;rData[3]=0;

 for(int i=0; i<1; i++)asm("nop");//Point

 HAL_SPI_Receive(&hspi1,(uint8_t*)&rData,4,500);

 HAL_GPIO_WritePin(ENC_CS1_GPIO_Port, ENC_CS1_Pin,1);//CS

 uint8_t rCRC;//CRC from Recieve data
  uint8_t dCRC;//Calc CRC from Data

   rCRCBuff[0]=0x80;
   rCRCBuff[1]=0x21;
   rCRCBuff[2]=rData[0];
   rCRCBuff[3]=rData[1];

   rCRC=rData[3];
   dCRC=GetCRC8(rCRCBuff, 4);//CRC check
   
    if(rCRC!=dCRC){
        ENC_Err_Count++;
        return 0;
    }
 
 res =(rData[0]<<8)+rData[1];
 return  0x7FFF&res;
}

uint8_t GetCRC8(uint8_t *buff, size_t size )
{
    uint8_t crc=0xFF;
    uint8_t i;

    while(size--){
        crc^= *buff++;
        for(i=0;i<8;i++){
            crc=crc&0x80?(crc<<1)^0x1d:crc<<1;
        }

    }
    return (~crc)&0xFF;
}

以前紹介したコードとの差はHalf Duplex Masterのため、
HAL_SPI_TransmitReceiveを使用せずに
HAL_SPI_ReceiveとHAL_SPI_Transmitを使用している点です。
自動的にMOSIの入出力がHALライブラリ内で切り替わります。
また、SafetyWordのCRCチェックを行っています。



実際に高速で通信した際に
角度読み出しコマンド実行後にすぐに角度を読み出すと、
正しい値を返さない現象が発生しました。
Infineonのフォーラムでも同じような不具合のディスカッションがされており、
角度読み出しコマンド実行後に10us待ってから読み出すことが重要なようです@2MHz


tle5012.jpg


実際にFullDuplexMasterで以前紹介したようなMOSIとMISOを使用する配線で
10us待つためには
sData[0]=0x80;sData[1]=0x21;
HAL_SPI_TransmitReceive(&hspi1,sData,rData,2,200);
sData[0]=0x00;sData[1]=0x00;sData[2]=0x00;sData[3]=0x00;
rData[0]=0;rData[1]=0;rData[2]=0;rData[3]=0;
HAL_SPI_Receive(&hspi1,(uint8_t*)&rData,4,200);
とすると丁度良い待ち時間になりました。


通信クロックに関して、
FullDuplexMasterではSPIクロック最大2MHz、
HalfDuplexMasterではSPIクロック最大4MHzという結果でした。
8MHzではビット読み違いが多発し、CRCチェックで値が落ちて通信できませんでした。



最終的に値取得周期は
TLE5012Bが2個、FullDuplexMaster@2MHzで約120us
TLE5012Bが2個、HalfDuplexMaster@4MHzで約100us
という結果となりました。


値読み出しコマンドとSafetyWord分の通信が必要なため、
1回の通信で8bit x 6回の通信が必要です。
SafetyWordを読み込まない場合でも8bit x 4回の通信が必要です。

TLE5012Bは内部更新周期42.7usで読み出すためには
SPIクロックを8MHzにしてなんとか実現可能なレベルということが分かりました。
AMS社のAS5048Aでは8bit x 2回の通信で済むため、
比べると通信量が多いことが分かります。



安さと15bit分解能、フィルタ内蔵というのは良いですが
SSCインタフェース、通信量の多さ、
角度読み出しコマンド後の待機時間の曖昧さには要注意です。


ラベル:部品 STM32 HAL
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック