PSoCのUARTを使ってみる

by K.I
2005/08/12〜

Index


概要


[top]

UARTモジュールを使ってみよう

#include <m8c.h>  
#include "PSoCAPI.h"    
void main()  
{  
    char * strPtr;                        // Parameter pointer  
      
    UART_CmdReset();                      // Initialize receiver/cmd  
                                          // buffer  
    UART_IntCntl(UART_ENABLE_RX_INT);     // Enable RX interrupts  
    Counter8_WritePeriod(155);            // Set up baud rate generator  
    Counter8_WriteCompareValue(77);  
    Counter8_Start();                     // Turn on baud rate generator       
      
    UART_Start(UART_PARITY_NONE);         // Enable UART  
      
    M8C_EnableGInt ;                      // Turn on interrupts  
      
    UART_CPutString("\r\nWelcome to PSoC UART test program. V1.1 \r\n");  
      
    while(1) {  
       if(UART_bCmdCheck()) {                    // Wait for command    
          if(strPtr = UART_szGetParam()) {       // More than delimiter?  
             UART_CPutString("Found valid command\r\nCommand =>");    
             UART_PutString(strPtr);             // Print out command   
             UART_CPutString("<\r\nParamaters:\r\n");    
             while(strPtr = UART_szGetParam()) { // loop on each parameter    
                UART_CPutString("   <");    
                UART_PutString(strPtr);          // Print each parameter    
                UART_CPutString(">\r\n");    
             }   
          }   
       UART_CmdReset();                          // Reset command buffer    
       }   
   }  
}  

例によって、ちょっと悩む

サンプルプログラムを、眺めてみたが。。 とりあえず、HyperTerminalを繋いでみる。 じゃ、動かない理由は何だ? 配線をチェックしてみる。
[top]

どんな構成にしよう

表示器の構成

表示器は、以下のような構成にする。 といっても、これは「はじめてのPSoC」の回路と同じ構成だ。

プログラムは?

とりあえず、欲張らずに作ってみよう。 こんな感じでどうかな。 コマンドが来た時だけ、送信するようにした方が良いかもしれないけど。。ちゃんと考えるのも面倒なので、これで良いや。。

割込みルーチン

#pragma interrupt_handler PSoC_GPIO_ISR()

#define SW_UP   0x02
#define SW_DOWN 0x40
#define MAX_CNT 49
unsigned char   count=25;
unsigned char   psw=0xff;

// ---- show barGraph
void set_BG()
{
        char    line[16];
        
        LCD_1_Position(1,0);
        lcd_print_d(line,2,count);      // MACRO(http://bluefish.orz.hm/sdoc/psoc_memo.html#LCD数値表示マクロ) printf("%2d",count);
        LCD_1_DrawBG(1,2,14,count);
}

// ---- send count value
void send_count()
{
        UART_1_PutSHexInt(count);
        UART_1_CPutString(" ");    
        set_BG();
}

// ---- read switch
void PSoC_GPIO_ISR()
{
        unsigned char csw;
        csw = PRT0DR;                                   // 現在のSW状態を読む
        if ((csw & SW_DOWN) && (csw & SW_UP)) {         // SWが全てOFF状態
          if ((~psw & SW_DOWN) && (psw & SW_UP)) {      // 直前がSW_DOWNなら
                count = (count-1+ MAX_CNT) % MAX_CNT;   // count down!
                send_count();
          }
          if ((~psw & SW_UP) && (psw & SW_DOWN)) {      // 直前がSW_UPなら
                count = (count+1) % MAX_CNT;            // count up!
                send_count();
          }
        }
        psw = csw;                                  // save past SW
}

メイン

// ---- Main program
void main()
{
        char *strPtr;                           // Parameter pointer  

// ---- UART setup
        UART_1_CmdReset();                      // Initialize receiver/cmd buf. 
        UART_1_IntCntl(UART_1_ENABLE_RX_INT);   // Enable RX interrupts  
        UART_1_Start(UART_1_PARITY_NONE);       // Enable UART  
      
        UART_1_CPutString("\r\nWelcome to PSoC UART program\r\n");  

// ---- LCD setup
        LCD_1_Start();                          // Initialize LCD hardware  
        LCD_1_Position(0,0);                    // Position cursor  
        LCD_1_PrCString(">PsoC UART Prog.");  
        LCD_1_InitBG(LCD_1_SOLID_BG);           // Initialize BarGraph
        set_BG();

// ---- GPIO setup
        PRT0DR = SW_UP | SW_DOWN;               // Pull-up
        INT_MSK0 |= INT_MSK0_GPIO;              // enable GPIO interrupt
        M8C_EnableGInt;                         // Turn on interrupts  

// ---- UART loop
        while(1) {  
          if(UART_1_bCmdCheck()) {              // Wait for command    
            if(strPtr = UART_1_szGetParam()) {  // More than delimiter?  
                UART_1_PutString(strPtr);       // Print out command   
                LCD_1_Position(0,1);            // Position cursor  
                LCD_1_PrCString("               ");
                LCD_1_Position(0,1);            // Position cursor  
                LCD_1_PrString(strPtr);         // display command
                UART_1_CPutString(" ( ");    
                while(strPtr=UART_1_szGetParam()) {// loop on each parameter    
                  UART_1_PutString(strPtr);     // Print each parameter    
                  UART_1_CPutString(" ");    
               }   
               UART_1_CPutString(")");    
            }   
            UART_1_PutCRLF();
            UART_1_CmdReset();                  // Reset command buffer    
       }   
   }  
}
案外、すんなり動いたなー。
1C言語のルーチンは、頭にアンダーバーを付けて、ljmp _PSoC_GPIO_ISRとして呼び出す必要がある事に注意。

[top]

PC側プログラム

PCでコントロールするんだから、PC側のプログラムも必要だ。

LabViewで作ってみよう

VISAのチェック

COM1にしたら、受信出来るようになった!

波形チャートを使ってみよう

何とか作れそうだけど。。

基本的には、LabViewでシリアル入力のプログラムを作るのは、意外に簡単に出来そうなことがわかった。 それを踏まえて、プログラムを作りなおしてみようか。
[top]

表示器プログラムを考え直す

PC側プログラムのフロー

表示器のプログラム

本体のフローに合わせて、以下のような最低限のコマンドを作ろう。 コマンド駆動型のプログラムを考えてみる。
コマンド パラメータ 戻り値 説明
R なし 起動メッセージ表示 リセット
G なし カウント値 カウント値取得
S カウント値 カウント値 カウント値設定
+ なし カウント値 カウント値+1
- なし カウント値 カウント値ー1
V 文字列 なし LCDにメッセージ表示

[top]

LabViewのプログラム

起動部分

データの取得

以下は、Up,Downボタンを付けてみたもの。
comments powered by Disqus