メニュー
▼ アクセス(地図)
▼ Windowsアプリ開発 ▼ マイコン開発 ▼ CGI・PHP制作 |
▼ サイトマップ(全投稿記事)
▼ タイトル(画像一覧) ▼ 事業内容 |
お問い合わせメールフォームが開きます。
2009年03月25日
ARM(LPC2388)エレキー・ソースコード
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(;;){
}
}
スクイズ機能で不用意にキーがメモリされてしまい、速度を上げると余計な符号が出る不具合があります。
この記事へのコメント
HPを楽しく拝見しております。
2009年3月25日ARMエレキー・ソースコードに、LEDを点灯する処理があります。ここで、
*FGPIO_FIO1PIN &= ~0x00040000; となっています。
①ビット18が、右から5番目に’4’になっている理屈がわかりません。もし、ビット19なら、
*FGPIO_FIO1PIN &= ~0x00050000;となるのでしょうか?
②同様に、ビット7が、
*FGPIO_FIO0PIN |= 0x00000080;となってますが、もしビット8ならば、
*FGPIO_FIO0PIN |= 0x00000090;となるのでしょうか?
初心者ですので、このような質問しかできませんが、よろしければ、御回答お願い致します。
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の件も同様の説明となります。
> *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