2009年03月25日

ARM(LPC2388)エレキー・ソースコード

Interface 2009年5月号付録でエレキー

Interface 2009年5月号の付録・ARM7(LPC2388)基板で作成したエレキーのソースコードです。

機能、仕様等は下記
 Interface 2009年5月号付録でエレキー
 http://micom.hamazo.tv/e1712628.html

をご参照ください。

NXP LPC2388 のドキュメントは下記をご参照ください。
http://www.nxp.com/acrobat_download/datasheets/LPC2388_1.pdf

ソースコードはここからです。

#include <intrinsics.h>
//==============================================================
//
//      Simple Elekey Program for NXP LPC2388
//
//      Date:   2009/3/24
//
//==============================================================

/* システムコントローラのレジスタ */
#define SYS_SCS     ((volatile unsigned int *)(0xE01FC1A0))

/* クロック選択のレジスタ*/
#define CLKSRCSEL       ((volatile unsigned int *)(0xE01FC10C))
#define PCLKSEL0        ((volatile unsigned int *)(0xE01FC1A8))
#define PCLKSEL1        ((volatile unsigned int *)(0xE01FC1AC))

/* ポートコントローラのレジスタ */
#define GPIO_PINSEL0    ((volatile unsigned int *)(0xE002C000))
#define GPIO_PINMODE0   ((volatile unsigned int *)(0xE002C040))

#define GPIO_PINSEL1    ((volatile unsigned int *)(0xE002C004))
#define GPIO_PINMODE1   ((volatile unsigned int *)(0xE002C044))

/* FGPIOコントローラ */
#define FGPIO_FIO0DIR   ((volatile unsigned int *)(0x3FFFC000))
#define FGPIO_FIO0MASK  ((volatile unsigned int *)(0x3FFFC010))
#define FGPIO_FIO0PIN   ((volatile unsigned int *)(0x3FFFC014))
#define FGPIO_FIO0SET   ((volatile unsigned int *)(0x3FFFC018))
#define FGPIO_FIO0CLR   ((volatile unsigned int *)(0x3FFFC01C))

#define FGPIO_FIO1DIR   ((volatile unsigned int *)(0x3FFFC020))
#define FGPIO_FIO1MASK  ((volatile unsigned int *)(0x3FFFC030))
#define FGPIO_FIO1PIN   ((volatile unsigned int *)(0x3FFFC034))
#define FGPIO_FIO1SET   ((volatile unsigned int *)(0x3FFFC038))
#define FGPIO_FIO1CLR   ((volatile unsigned int *)(0x3FFFC03C))

/* 割り込みコントローラ(VIC)のレジスタ */
#define VIC_IntEnable   ((volatile unsigned int *)(0xFFFFF010))
#define VIC_IntSelect   ((volatile unsigned int *)(0xFFFFF00C))
#define TIMER0_INT_BIT  (0x00000010)

/* A/Dのレジスタ */
#define PCONP           ((volatile unsigned int *)(0xE01FC0C4))
#define AD0CR           ((volatile unsigned int *)(0xE0034000))
#define PINSEL1         ((volatile unsigned int *)(0xE002C004))
#define AD0DR0          ((volatile unsigned int *)(0xE0034010))
#define AD0DR1          ((volatile unsigned int *)(0xE0034014))
#define AD0DR2          ((volatile unsigned int *)(0xE0034018))

/* Timerのレジスタ */
#define TIMER0_InterruptRegister    ((volatile unsigned int *)(0xE0004000))
#define TIMER0_TimerControlRegister ((volatile unsigned int *)(0xE0004004))
#define TIMER0_TimerCounter         ((volatile unsigned int *)(0xE0004008))
#define TIMER0_PrescaleRegister     ((volatile unsigned int *)(0xE000400C))
#define TIMER0_PrescaleCounter      ((volatile unsigned int *)(0xE0004010))
#define TIMER0_MatchControlRegister ((volatile unsigned int *)(0xE0004014))
#define TIMER0_MatchRegister0       ((volatile unsigned int *)(0xE0004018))


//----------------------------------------------------------------------------
//  Define Code Parameter
//----------------------------------------------------------------------------
#define PARA_ALL_OFF    0x00
#define PARA_DOT_ON     0x01
#define PARA_DOT_OFF    0x02
#define PARA_DASH_ON    0x03
#define PARA_DASH_OFF   0x04

#define LIMIT_VALUE     0x03
#define LIMIT_VALUE2    0x02

#define MAX_SPEED       35
#define MIN_SPEED       80


//----------------------------------------------------------------------------
//  Define User Memory
//----------------------------------------------------------------------------
unsigned int    ParaTime;
unsigned int    ADCData;
unsigned char   TimerTest;
unsigned char   Timer100ms;

unsigned char   ParaCode;
unsigned char   CntDotOn;
unsigned char   CntDashOn;

unsigned char   CodeData;

unsigned char   CntP10_On;
unsigned char   CntP10_Off;
unsigned char   P10_buf;


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

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

//----------------------------------------------------------------------------
/* Buzzer On する処理 */
//----------------------------------------------------------------------------
void BUZZER_ON() {
    *FGPIO_FIO0PIN |= 0x00000080;       /* P0[7] を'1'に(Buzz On) */
}

//----------------------------------------------------------------------------
/* Buzzer Off する処理 */
//----------------------------------------------------------------------------
void BUZZER_OFF() {
    *FGPIO_FIO0PIN &= ~0x00000080;      /* P0[7] を'0'に(Buzz Off) */
}

//----------------------------------------------------------------------------
//  Check A/D port
//----------------------------------------------------------------------------
void ChkADCPort()
{
    //開始
    *AD0CR = (*AD0CR & 0xf8ffffff) | (1 << 24);

    //変換待ち
    while ((*AD0DR0 & 0x80000000) == 0x80000000);
   
    // 10bit --> 8bit
    ADCData = 0xff - ((*AD0DR0 >> 8) & 0xff) + MAX_SPEED;
}



//----------------------------------------------------------------------------
//  Set Output port
//----------------------------------------------------------------------------
void SetOutput()
{

    if ((ParaCode == PARA_DASH_ON) || (ParaCode == PARA_DOT_ON)) {
        LED_ON();
        BUZZER_ON();
    }
    else {
        LED_OFF();
        BUZZER_OFF();
    }

}

//----------------------------------------------------------------------------
//  Check Input port
//----------------------------------------------------------------------------
void ChkInputPort()
{
    // for Dot
    if (ParaCode != PARA_DOT_ON) {
        if (CntDotOn < LIMIT_VALUE) {
            if ( (*FGPIO_FIO0PIN & 0x00000100) == 0) {
                CntDotOn ++;
            }
            else {
                CntDotOn = 0;
            }
        }
    }
   
    // for Dash
    if (ParaCode != PARA_DASH_ON) {
        if (CntDashOn < LIMIT_VALUE) {
            if ( (*FGPIO_FIO0PIN & 0x00000200) == 0)
                CntDashOn ++;
            else
                CntDashOn = 0;
        }
    }
}

//----------------------------------------------------------------------------
//  Set Parameter Dash
//----------------------------------------------------------------------------
char SetParaDash()
{
    if (CntDashOn >= LIMIT_VALUE) {
        CntDashOn = 0;
        ParaCode = PARA_DASH_ON;
        ParaTime = (ADCData * 3);
        return 1;
    }
    return 0;
}

//----------------------------------------------------------------------------
//  Set Parameter Dot
//----------------------------------------------------------------------------
char SetParaDot()
{
    if (CntDotOn >= LIMIT_VALUE) {
        CntDotOn = 0;
        ParaCode = PARA_DOT_ON;
        ParaTime = ADCData;
        return 1;
    }
    return 0;
}


//----------------------------------------------------------------------------
//  1msec Timer Interrupt routine
//----------------------------------------------------------------------------
void intsrv_tim(void)
{
    if (ParaTime != 0) {
        ParaTime --;
        if (ParaTime == 0) {
            if (ParaCode == PARA_DOT_ON) {
                ParaCode = PARA_DOT_OFF;
                ParaTime = ADCData;
            }
            else if (ParaCode == PARA_DASH_ON) {
                ParaCode = PARA_DASH_OFF;
                ParaTime = ADCData;
            }
            else if (ParaCode == PARA_DOT_OFF) {
                if (!SetParaDash())
                    ParaCode = PARA_ALL_OFF;
            }
            else if (ParaCode == PARA_DASH_OFF) {
                if (!SetParaDot())
                    ParaCode = PARA_ALL_OFF;
            }
            else {
                ParaCode = PARA_ALL_OFF;
            }
            SetOutput();
        }
    }

    ChkInputPort();
    if (ParaCode == PARA_ALL_OFF) {
        if (!SetParaDot())
            SetParaDash();
    }
    SetOutput();
}


//----------------------------------------------------------------------------
/* IRQ 割り込み処理 */
//----------------------------------------------------------------------------
__irq __arm void IRQ_Handler()
{
    intsrv_tim();
   
    Timer100ms ++;
    if (Timer100ms > 100) {
        Timer100ms = 0x00;
        ChkADCPort();
    }
   
    *TIMER0_InterruptRegister = 1; /* MC0をクリア */
}

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

    *FGPIO_FIO0DIR =0x00000080; /* P0[7] を出力端子にする       */
    *FGPIO_FIO0MASK=0x00000000; /* P0には一切マスクをかけない    */

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

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

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

    /* Timer0のパラメータを設定        */
    *TIMER0_PrescaleRegister     = 0x00000000;      /* プリスケール無し  */
    //*TIMER0_MatchRegister0     = 0x00080000;      /* MC0 ≒ 0.5 * 1M   */
    //*TIMER0_MatchRegister0     = 0x00002800;      /* 約 10msec   */
    *TIMER0_MatchRegister0       = 0x00000418;      /* 約 1msec   */
    *TIMER0_MatchControlRegister = 0x00000003;      /* Match時にTCクリア & 割り込み */

    /* A/Dのパラメータを設定 */
    *PCONP = (*PCONP & 0xffffefff) | (1 << 12);
    *PCLKSEL0 = (*PCLKSEL0 & 0xfcffffff) | (1 << 24);
    *AD0CR = (*AD0CR & 0xffff00ff) | (16 << 8);
    *AD0CR = (*AD0CR & 0xffdfffff) | (1 << 21);
    *PINSEL1 = (*PINSEL1 & 0xffff3fff) | (1 << 14);
    *AD0CR = (*AD0CR & 0xffffffff) | (1 << 0);
   
    // ユーザメモリの初期化
    CntDashOn = 0;
    CntDotOn = 0;
    ADCData = MAX_SPEED;
    ParaTime = 0;
    ParaCode = PARA_ALL_OFF;

    /* VICに割り込み許可を指示する        */
    *VIC_IntEnable = TIMER0_INT_BIT;

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

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

    /* 無限ループ(ここでは何もしない。1msごとにIRQ_Handler()関数が呼び出される  */
    for(;;){
    }
}






スクイズ機能で不用意にキーがメモリされてしまい、速度を上げると余計な符号が出る不具合があります。



同じカテゴリー(マイコン開発)の記事
Fusion PCBでエレキー
Fusion PCBでエレキー(2020-04-01 19:00)


この記事へのコメント
HPを楽しく拝見しております。

2009年3月25日ARMエレキー・ソースコードに、LEDを点灯する処理があります。ここで、
*FGPIO_FIO1PIN &= ~0x00040000; となっています。

①ビット18が、右から5番目に’4’になっている理屈がわかりません。もし、ビット19なら、
*FGPIO_FIO1PIN &= ~0x00050000;となるのでしょうか?

②同様に、ビット7が、
*FGPIO_FIO0PIN |= 0x00000080;となってますが、もしビット8ならば、
*FGPIO_FIO0PIN |= 0x00000090;となるのでしょうか?

初心者ですので、このような質問しかできませんが、よろしければ、御回答お願い致します。
Posted by T at 2009年12月03日 09:57
例えば下記の例ですが

> *FGPIO_FIO0PIN |= 0x00000080;となってますが、もしビット8ならば、
> *FGPIO_FIO0PIN |= 0x00000090;となるのでしょうか?

16進数で下記の数字は
 0x00000080

2進数では下記になります。(上位ビットは省略)
 1000 0000

したからビット0、1、2、・・・・ と数えると
「1」の部分は7番目になります。
したがって、ビット7です。

ちなみに
 (16進数) 0x00000090 → (2進数) 1001 0000
となるので
 「ビット7」と「ビット4」がOnすることになります。

ビット19の件も同様の説明となります。
Posted by 宇都宮宇都宮 at 2009年12月05日 13:24
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

削除
ARM(LPC2388)エレキー・ソースコード
    コメント(2)