Raspberry pi で AP のレジスタをC言語で直接変更してモーターを PWM で操作する

目的

PWM でDCモータを操作します。 また、フルブリッジのモータードライバICを使います。

注意点

Linuxシステムコールを含む(mmap関数)ので、root 権限が必要なため sudo コマンドを利用する必要があります。 プログラム名を sample.c とするならば、

 $ gcc sample.c
 $ sudo ./a.out

のように実行してください。

モータドライバIC

TA7291P を使いました。

モータードライバー TA7291P (2個入): 半導体 秋月電子通商 電子部品 ネット通販

端子記号 端子番号 端子説明
GND 1 GND
OUT1 2 出力端子
NC 3
Vref 4 制御電源端子
IN1 5 入力端子
IN2 6 入力端子
VCC 7 ロジック側電源端子
VS 8 出力側電源端子
NC 9
OUT2 10 出力端子

回路の概要

本当は RaspberryPi 3 を使っています。

f:id:katogiso-tech:20171112200721p:plain

main() プログラム

正転と逆転をGPIO20/21 を使って切り替えています。

void main()
{
  volatile unsigned *addr;
  int count;

  //--------------------------
  // GPIO
  gpio = io_mapping(GPIO_BASE);

  // set GPIO18 mode to ALT5(PWM0)
  *(gpio + 0x4/4) = (*(gpio + 0x4/4) & ~(0x7 << 24 )) | (0b010 << 24);

  // set GPIO20/21 mode to Output
  *(gpio + 0x8/4) = (*(gpio + 0x8/4) & ~(0x7 << 0 )) | (0b001 << 0);
  *(gpio + 0x8/4) = (*(gpio + 0x8/4) & ~(0x7 << 3 )) | (0b001 << 3);

  //--------------------------
  // Clock
  clk  = io_mapping(CLK_BASE);
  // add the offset address of pwm clk manager
  clk += 0xA0/4;
  // disable
  *clk = CLK_PASSWD + (0x1<<5);
  // divided by 192
  *(clk+0x4/4) = CLK_PASSWD + (192 << 12);
  // choose oscillator(19.2MHz) as source
  *clk = CLK_PASSWD + 0x1 + (0x1 << 4);

  //--------------------------
  // PWM
  pwm  = io_mapping(PWM_BASE);
  *pwm = 0; // Disable
  usleep(10);

  *(pwm + 0x10/4) = 8; // set RNG
  *(pwm + 0x14/4) = 6; // set DAT
  *pwm = 0x1;  // Enable

  //--------------------------
  // drive motor
  for( count = 0; count < 2; count++ ){
    // set
    if( count % 2 ){
      *(gpio + 0x1C/4) = 0x1 << 20;
    } else {
      *(gpio + 0x1C/4) = 0x1 << 21;
    }
    sleep(3); 

    // clear
    *(gpio + 0x28/4) = 0x1 << 21;
    *(gpio + 0x28/4) = 0x1 << 20;
    sleep(3); 
  }

 *pwm = 0; // Disable
  usleep(10);
}

電圧、電流波形

ChannelA が電圧(PWM)で、ChannelB は電流波形です。 また、電流波形は1Ωの抵抗両端で測定しました。

f:id:katogiso-tech:20171112201431p:plain