目次
前
次
UART処理
UART動作の確認に、次のような
システムを考えました。
送受信処理が出来たのかを、LEDの点灯による
モニタ信号で確認します。
大まかな仕様を、次のように考えました。
- マイコン動作を基板上にあるLEDの点滅で確認
- PCからADuC7026にコマンドを与え、内部動作変更
- コマンドは英大文字1文字
通信が関係するので、プロトコルを決めます。
- 通信速度 19200bps
- データ長 8ビット
- パリティ なし
- ストップビット 1ビット
- フロー制御 なし
コマンドは、?、A、Iの3種。
システム概要を決めたので、詳細な仕様を
記述していきます。
システムクロック周波数
システムクロックは、41.78MHzとする。
システムクロックを決めたので、ボーレートを
決めるレジスタの設定値は、以下となる。
COMDIV0 = 0x44 ;
COMDIV1 = 0x00 ;
タイマー割込みによるLED点滅には、タイマー0
を利用。周期割込みを使えるように初期化。
41.78MHzを256分周し、更に10Hz程度になるように
設定。また、周期割込みのパラメータ設定。
まとめると、次のコードに。
T0LD = 16320 ;
T0CON = 0xc8 ;
割込み
タイマー0の周期割込み、UARTの受信割込みを扱う
ため、割込みイネーブルレジスタIRQENにパラメータ
を設定します。
IRQEN = RTOS_TIMER_BIT | UART_BIT ;
割込みハンドラでは、割込みが発生したときに
フラグをセットして通知します。。
volatile UBYTE ch ;
/* judge UART receive interruption */
if ( (IRQSTA & UART_BIT) == UART_BIT ) {
/* judge */
if ( COMSTA0 & 1 ) {
/* clear flag */
ch = COMRX ;
*(sbuf+sindex) = ch ;
sindex++ ;
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
/* judge timer0 interruption (10us) */
if ( (IRQSTA & RTOS_TIMER_BIT) == RTOS_TIMER_BIT ) {
/* clear timer1 interrupt flag */
T0CLRI = 0xff ;
/* increment */
tflag = ON ;
}
受信割込みでは、バッファに文字を入れます。
1レコード分が溜まった時点で、フラグをセットします。
タイマー0周期割込みでは、単にフラグをセットします。
UART動作
仕様に相当するパラメータを設定します。
データ長8ビット、ストップビット1、パリティなし、
フロー制御なし。
COMCON0 = 0x03 ;
受信割込みを使うとして、レジスタCOMIEN0の相当
ビットをセットします。
COMIEN0 = 0x01 ;
動作表示
ADuC7026基板上のLED点滅で、動作を表示する。
タイマー0の周期割込で、LEDを点滅するので
割込みハンドラから通知されるトリガーフラグ
を使い、フラグ通知されるたびに、P4.7出力値
を反転します。
システム動作変更
フラットケーブルで接続したLEDの点滅制御。
タイマー0の周期割込で、P3.0に接続のLEDを点滅。
ただし、PCから設定したフラグで、消灯と点滅を
切り換えます。
コマンドインタプリタ
割込みハンドラからの通知フラグを
とらえて、バッファからコマンドと
パラメータを引き出します。
コマンドは、バッファ中の最初の文字で
判断してから、該当する関数を呼出して
対応します。
GPIO操作
GP1には、UARTの通信に利用するので、UARTを
選択して、GP1.0を入力、GP1.1を出力に指定。
/* use UART */
GP1CON = 0x00000011 ;
/* input output */
GP1DAT = 0xFE000000 ;
GP3、GP4を出力で使い、出力値を確定しておきます。
GP3DAT = 0xffff0000 ;
GP4DAT = 0xff000000 ;
UART送信
COMTXに1文字を設定するには、COMSTA0の
該当ビットを見て、空きがあることを判断
しています。
/* ? transmmit buffer empty */
while( (COMSTA0 & 0x40) == 0 ) ;
/* set value */
COMTX = x ;
まとめると、以下。
#include <ADuC7026.h>
#define OFF 0
#define ON OFF+1
/* data definitions */
typedef unsigned char UBYTE ;
typedef signed char SBYTE ;
typedef unsigned short UWORD ;
typedef signed short SWORD ;
typedef unsigned long ULONG ;
typedef signed long SLONG ;
void IRQ_Handler(void) __irq;
void init_usr(void);
#define MASKFF 0xFF
#define MASK0F 0x0F
#define MASK80 0x80
#define MASK40 0x40
#define MASK20 0x20
#define MASK10 0x10
#define MASK08 0x08
#define MASK04 0x04
#define MASK02 0x02
#define MASK01 0x01
#define MASKF0 0xF0
UBYTE timcnt ;
void rs_putchar(UBYTE x);
void crlf(void);
void rs_puts(UBYTE *x);
void show_help(void);
/* global variables */
volatile UBYTE uflag ;
volatile UBYTE tflag ;
volatile UBYTE gflag ;
volatile UBYTE sbuf[8] ;
volatile UBYTE sindex ;
volatile UBYTE cmd ;
int main(void)
{
/* initialize user */
init_usr();
/* show message */
rs_puts("Hello , World\n");
/* endless loop */
while(ON)
{
/* command interrpreter */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* judge */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
/* active */
if ( cmd == 'A' ) {
gflag = ON ;
rs_puts("Enable\n");
}
/* inactive */
if ( cmd == 'I' ) {
gflag = OFF ;
rs_puts("Disable\n");
}
}
/* debug */
if ( tflag == ON ) {
tflag = OFF ;
GP4DAT ^= (1 << 23) ;
timcnt++ ;
if ( timcnt == 5 ) {
timcnt = 0 ;
/* judge */
if ( gflag == OFF ) {
GP3DAT |= (1 << 16) ;
} else {
GP3DAT ^= (1 << 16) ;
}
}
}
}
/* dummy return */
return (0);
}
void IRQ_Handler(void) __irq
{
volatile UBYTE ch ;
/* judge UART receive interruption */
if ( (IRQSTA & UART_BIT) == UART_BIT ) {
/* judge */
if ( COMSTA0 & 1 ) {
/* clear flag */
ch = COMRX ;
*(sbuf+sindex) = ch ;
sindex++ ;
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
/* judge timer0 interruption (10us) */
if ( (IRQSTA & RTOS_TIMER_BIT) == RTOS_TIMER_BIT ) {
/* clear timer1 interrupt flag */
T0CLRI = 0xff ;
/* increment */
tflag = ON ;
}
}
void init_usr(void)
{
/* select clock 41.78MHz
initialized in start up routine
*/
PLLKEY1 = 0xaa ;
PLLCON = 0x01 ;
PLLKEY2 = 0x55 ;
/* power control
initialized in start up routine
*/
/* clear flag */
uflag = OFF ;
tflag = OFF ;
gflag = ON ;
/* clear counter */
timcnt = 0 ;
sindex = 0 ;
/* initialize UART */
{
/* set baud rate 19200 bps CD = 0 DL = 0x11 */
COMCON0 = 0x80 ; /* select COMDIV1 and COMDIV0 */
COMDIV0 = 0x44 ;
COMDIV1 = 0x00 ;
/* set conditions */
COMCON0 = 0x03 ; /* select COMRX and COMTX , 8bit data , 1 stop bit , no parity */
/* enable interrupt */
COMIEN0 = 0x01 ; /* ERBFI */
}
/* P1 */
{
/* use UART */
GP1CON = 0x00000011 ;
/* */
GP1DAT = 0xFE000000 ;
}
/* P3 */
{
GP3DAT = 0xffff0000 ;
}
/* P4 */
{
GP4DAT = 0xff000000 ;
}
/* initialize timer 0 */
{
T0LD = 16320 ; /* (41.78MHz / 256) / 16320 <10Hz> */
T0CON = 0xc8 ; /* enable , cyclic , 1/256 */
}
/* enable timer 0 interrupt and UART interrupt */
IRQEN = RTOS_TIMER_BIT | UART_BIT ;
}
/* UART putchar */
void rs_putchar(UBYTE x)
{
/* turn on LED */
GP3DAT ^= ~(1 << 23) ;
/* ? transmmit buffer empty */
while( (COMSTA0 & 0x40) == 0 ) ;
/* set value */
COMTX = x ;
/* turn off LED */
GP3DAT |= (1 << 23) ;
}
/* carriage return and line feed */
void crlf(void)
{
rs_putchar('\r');
rs_putchar('\n');
}
/* UART puts */
void rs_puts(UBYTE *x)
{
while ( *x != '\0' ) {
rs_putchar( *x ) ;
x++ ;
}
}
/* show help */
void show_help(void)
{
rs_puts("? help\n");
rs_puts("A active\n");
rs_puts("I inactive\n");
}
目次
前
次