インターフェース2009年5月号基板 シリアル制御でパルスモーター2軸制御ソフト 7segLED2個で動作確認OK

CのソースからHTMLファイルに変換する時にTABやスーペースの具合でインデントがきれいでは有りませんが参考になれば感謝です。
レジスターなどの参照方法は雑誌の方法から普通の参照方法?に変更しています。
ボーレートは19200bpsです。通信用レジスターUART0の設定は要注意です。
ハイパーターミナルから”X12345”、”X−567890”、”Y1234”、”Y−1234”、回転速度は”F10000”などのコマンドでパルス数と回転方向の正逆
と回転速度が制御できます。Timer0で基板LEDの点滅とカウント数のエコーバックをしながらTimer1の割込みでモーターを廻しています。
モーターの励磁方法は1−2相励磁、2相励磁の選択が出来ます。(コンパイル時)
文字列の数値変換などは標準関数が使えないので自前で作りました。詳細な動作確認はしていませんので要注意?

テスト中の写真 小さいモーターが廻せる様に東芝のTD62083APのオープンコレクターのドライバーを増設して有ります。

画像1

テスト中の画像です。

画像2

ここからソフトです。LEDの点灯部分は雑誌のままです。


#include <intrinsics.h>
#include "lpc2388.h"

/****************************************************************************
    インターフェース2009年5月号基板
    CPUカード オンボードLED点灯制御
    main_puw090405a.c
    2009/03/30  USBポート使用UART0 シリアル通信 追加
            31  数値を文字列に変換してタイマー割り込みでPCへ送信OK
                レジスタの参照方法を変更 インクルードファイル作成OK
       04/02  UART0受信してエコーバック OK リターンキーでバッファー文字列エコーOK
                atoi 文字列を引数->整数値を戻り値に返す関数追加
            03  拡張ボード配線TD62083 2個 PORT2[0-7]
            04  パルスモーター励磁パターン出力2相、1−2相出力OK ターミナルより速度変更OK
            05  X軸Y軸同時制御OK 速度は共通

****************************************************************************/

#define TX_BUFSIZE    80
#define UART_BUFSIZE  80

static unsigned char  txbuf[TX_BUFSIZE];
static unsigned char  UART0Buffer[UART_BUFSIZE];
static unsigned char  buf[10];
static unsigned char  pat[7];

static unsigned char  RBRValue, LSRValue;
static unsigned char  txptr = 0;
static unsigned char  ptr = 0;
static unsigned int   UART0Count = 0;
static unsigned int   no = 0 ;
static unsigned int   Xpat_no = 0 ; // X軸パルスモーター励磁位置
static unsigned char  Xcw = 0 ;     // X軸パルスモーター回転方向
static int            Xcount;       // X軸パルスモーターパルス
static unsigned int   Ypat_no = 0 ; // Y軸パルスモーター励磁位置
static unsigned char  Ycw = 0 ;     // Y軸パルスモーター回転方向
static int            Ycount;       // Y軸パルスモーターパルス

//-----------------------------------------------------------------------------
void UART0_Init(void)
{
// Fpclk = 4.000.000 MHz
// DLM,DLH = Fpclk / (19200*16) = 13
 
  PCLKSEL0 = 0x00000040;        // PCLK_UART0 = CCLK
  GPIO_PINSEL0 = 0x00000050;  // Select UART0 RXD/TXD

  U0LCR = 0x83;   // 8N1, enable Divisor latch bit on
  U0DLM = 0;
  U0DLL = 13;           // baud rate fixed to 19200 @ PCLK = 4 Mhz
  U0FCR = 7;    // Enable and clear FIFO's
  U0LCR = 0x03;   // 8N1, enable Divisor latch bit off
}

//-----------------------------------------------------------------------------
// 文字列をバッファーにコピー
static void SendString(char *text)
{
      txptr = 0;                // previous message send ?
      while(*text)
      {
   txbuf[txptr++] = *text++;
          if(txptr >= TX_BUFSIZE) txptr = 0;
      }
}

//-----------------------------------------------------------------------------
// バッファーの文字列送信
static void Send(void)
{
ptr = 0;
  while (txptr != 0)
  { 
    while (!(U0LSR && 0x20));   // THRE status, contain valid data
      U0THR = txbuf[ptr];
      txptr--;
      ptr++;
  }
}

//-----------------------------------------------------------------------------
// UART0へ文字列送信
static void StrTX(char *text)
{
  while(*text)
  {
      while (!(U0LSR && 0x20));  // THRE status, contain valid data
      U0THR = *text++;
  }
}

//-----------------------------------------------------------------------------
// UART0へ1文字送信
static void TX(char ch)
{
      while (!(U0LSR && 0x20));  // THRE status, contain valid data
      U0THR = ch;
}

//-----------------------------------------------------------------------------
/* LEDを点灯する処理 */
void LED_ON() {
    FGPIO_FIO1PIN=0x00000000; /* P1[18] を'0'に(LEDを点ける) */
}

/* LEDを消灯する処理 */
void LED_OFF() {
    FGPIO_FIO1PIN=0x00040000; /* P1[18] を'1'に(LEDを消す)   */
}

/* LED1を点灯する処理 */
void LED1_ON() {
    FGPIO_FIO2PIN=0x00000080; /* P2[7] を'1'に(LEDを点ける) */
}

/* LED1を消灯する処理 */
void LED1_OFF() {
    FGPIO_FIO2PIN=0x00000000; /* P2[7] を'0'に(LEDを消す)   */
}

//-----------------------------------------------------------------------------
// カウンターの値をP2ポートへ出力
void COUNT_OUT() {
    FGPIO_FIO2PIN = no;
}

//-----------------------------------------------------------------------------
// 文字列を最後から先頭に並べ変える
char* strrevP(char *s)
{
char *ret = s;
char *t = s;
char c;

    while(*t != '\0')
      t++;
      t--;
    while(t > s){
      c = *s;
      *s = *t;
      *t = c;
      s++;
      t--;
    }
return ret;
}

//-----------------------------------------------------------------------------
//整数を文字に変換する。
void itoa(int value, char *buff)
{
char *p;
int mod;
      // 入力した値の正負を文字にする。
 if( 0 > value ) {
 *buff++ = '-';
 value = -value;
 }
 p = buff;

      // 入力した値を下位の桁から順に文字にする。
 do{
     mod = value % 10 + 48;
     *p++ = (char)mod;
     value /= 10;
 }while(value);
 *p = '\0';                  // 文字列の最後に '\0' を追加して締める。
}

//-----------------------------------------------------------------------------
// 文字列送信
void mesTX()
{
        StrTX("Hello LPC2388 2009/04/04a\r\n"); // UART0へ文字列送信

        no = Xcount;
        itoa(no,buf);               // 整数を文字に変換する
 strrevP(buf);               // 文字列の上位の桁から始まるように並べ替える。
//        no++;
        StrTX(buf);                 // カウンター数値送信
        StrTX("\r\n");              // CR LF送信
}
       
//-----------------------------------------------------------------------------
// IRQ 割り込み処理
__irq __arm void IRQ_Handler()
{
static int led = 0;

  // IRQ Timer0
  if((TIMER0_InterruptRegister & 1) == 1){

    if( led == 0 ) {
        led = 1;
        LED_ON();
        mesTX();                    // 文字列送信
    } else {
        led = 0;
        LED_OFF();
    }
    TIMER0_InterruptRegister = 1;   // MC0をクリア
  }

  // IRQ Timer1
  if((TIMER1_InterruptRegister & 1) == 1){

    if(Xcount >= 0){  // X軸
      if (Xcw == 0){
        if(Xpat_no == 7) Xpat_no = 0; else Xpat_no++;
      }
      else{
        if(Xpat_no == 0) Xpat_no = 7; else Xpat_no--;
      }

      Xcount--;
    }   

    if(Ycount >= 0){  // Y軸
      if (Ycw == 0){
        if(Ypat_no == 7) Ypat_no = 0; else Ypat_no++;
      }
      else{
        if(Ypat_no == 0) Ypat_no = 7; else Ypat_no--;
      }

      Ycount--;
    }   

    FGPIO_FIO2PIN = pat[Xpat_no];         // 励磁パターをポートへ出力
    FGPIO_FIO2PIN |= (pat[Ypat_no] << 4); // 励磁パターをポートへ出力

    TIMER1_InterruptRegister = 1;         // MC1をクリア
  }

}

//-----------------------------------------------------------------------------
// 文字列を引数->整数値を戻り値に返す
int a2i(char *str)
{
    int cnt;

    int num=0;

   for(cnt=0;(str[cnt]>='0')&&(str[cnt]<='9');cnt++){
      num = 10 * num + (str[cnt] - '0');
    }

    return num;
}

//-----------------------------------------------------------------------------
// 検索文字列の位置を戻り値に返す
int strstr(){
char s[] = "This is a pen. That is an apple.";
char str[] = "an";
int i,j,p;
i=j=p=0;

  while (s[i] !='\0' && str[j] != '\0'){
    if (s[i] == str[j]) {
      i++;
      j++;
      p=i-j;
    }else{
    i -= j - 1;
    j = 0;
    }
  }
  if(str[j]=='\0')
    return p;
  else
    return 0;
}

//-----------------------------------------------------------------------------
/* main関数 */
int main(void)
{
    SYS_SCS = SYS_SCS | 1;      // FGPIO Select

    FGPIO_FIO1DIR =0x00040000; // P1[18] を出力端子にする
    FGPIO_FIO1MASK=0x00000000; // P1には一切マスクをかけない

    FGPIO_FIO2DIR =0x000000FF;    // P2[0-7] を出力端子にする
    FGPIO_FIO2MASK=0xFFFFFF00;   // P2にマスクをかける

    // 割り込みがかかると初めて点灯するようにLEDを消しておく
    LED_OFF();

    // 割り込み種類選択 (全ての割り込みをFIQではなくIRQにする)
    VIC_IntSelect = 0;

    // Timer0のパラメータ設定
    TIMER0_PrescaleRegister     = 0x00000000;     // プリスケール無
    TIMER0_MatchRegister0       = 500000;         // MC0 ≒ 0.5 * 1M
    TIMER0_MatchControlRegister = 0x00000003;     // Match時にTCクリア & 割り込み
    VIC_IntEnable = TIMER0_INT_BIT;               // VICに割り込み許可

    // Timer1のパラメータ設定
    TIMER1_PrescaleRegister     = 0x00000000;     // プリスケール無
    TIMER1_MatchRegister0       = 0x00010000;     // MC1
    TIMER1_MatchControlRegister = 0x00000003;     // Match時にTCクリア & 割り込み
    VIC_IntEnable = TIMER1_INT_BIT;               // VICに割り込み許可

    __enable_interrupt();         // CPUに割り込み許可を指示する

    // タイマスタート
    TIMER0_TimerControlRegister = 1;
    TIMER1_TimerControlRegister = 1;

//#define reiji
#ifdef reiji
    //2相励磁パターン
    pat[0] = 0x03;
    pat[1] = 0x06;
    pat[2] = 0x0c;
    pat[3] = 0x09;
    pat[4] = 0x03;
    pat[5] = 0x06;
    pat[6] = 0x0c;
    pat[7] = 0x09;
#else
    //1−2相励磁パターン
    pat[0] = 0x01;
    pat[1] = 0x03;
    pat[2] = 0x02;
    pat[3] = 0x06;
    pat[4] = 0x04;
    pat[5] = 0x0c;
    pat[6] = 0x08;
    pat[7] = 0x09;
#endif
    UART0_Init();
    no = 0;

    char str[256];
    Xcw = 1;
    Xcount = 16;
   
    // メインループ(文字のエコーバックとリターンキーで受信バッファー文字列エコー)
    for(;;){

      LSRValue = U0LSR;                   // 受信フラグ読出し
   
      if (LSRValue & LSR_RDR)    // 受信可   
      {
        RBRValue = U0RBR;                 // 受信データ読出し
        UART0Buffer[UART0Count] = RBRValue;
    UART0Count++;
         
        if(RBRValue == '\r'){             // リターンキー?
          UART0Buffer[UART0Count] = '\0';
          StrTX(UART0Buffer);             // 受信バッファー文字列送信 
          StrTX("\r\n");                  // CR LF送信
          UART0Count = 0;

          if(UART0Buffer[0]=='F'){
            UART0Buffer[0]='0';
            no = a2i(UART0Buffer);          // 文字列を引数->整数値
            TIMER1_TimerControlRegister = 2;// Timer1 reset
            TIMER1_MatchRegister0 = no;     // Timerマッチレジスター変更
            TIMER1_TimerControlRegister = 1;// Timer1 start
            goto LE;
          }
         
          if(UART0Buffer[0]=='X'){
            UART0Buffer[0]='0';
            if(UART0Buffer[1]=='-'){
              UART0Buffer[1]='0';
              Xcw = 1;
            }else{ Xcw = 0;}
            no = a2i(UART0Buffer);        // 文字列を引数->整数値
            Xcount = no;
            goto LE;
          }

          if(UART0Buffer[0]=='Y'){
            UART0Buffer[0]='0';
            if(UART0Buffer[1]=='-'){
              UART0Buffer[1]='0';
              Ycw = 1;
            }else{ Ycw = 0;}
            no = a2i(UART0Buffer);        // 文字列を引数->整数値
            Ycount = no;
            goto LE;
          }

          StrTX("Error\r\n");             // Error CR LF送信
         
        }else{ 
          TX(RBRValue);                   // 1文字送信 エコーバック
        }
LE: if(UART0Count == UART_BUFSIZE) UART0Count = 0;// buffer overflow
      }
    }
}

ここまでです。

//--------------------------------------------------------------------------------------------------------------------

ソフト追加 USB(シリアルポート)からの制御ソフト
レジスターのリード、ライト、割り込みのON/OFF 0-7cHADCの入力、DAC出力

 2009年4月15日追加

まごのてメカトロソフトに戻る