目次
前
次
琴似工業高校マシン整備
札幌国際情報高校でMCR全国大会が開かれるのは
よく知られていることです。
全国大会会場から車で10分ほどの場所に、創世期のMCRを
支えた北海道札幌琴似工業高校があります。
非常勤講師で通っていた大学での教え子に、北海道札幌琴似工業高校
出身者がいました。「夏休みは暇だ。」というので、MCR委員会販売の
標準キットがあれば、走らせてみるかと言葉をかけると、のってきた
ので、改造することに。
使われていたH8は、H8/3687(北斗電子)だったので
H8/3048FOne(24.576MHz)に交換。
Hブリッジを使った制御基板から、次の回路に変更しました。
DCモータ2個、サーボモータ1個のためにフォトカプラと
パワートランジスタでドライバを構成。スタートトリガー
をプッシュボタンと抵抗でまとめることに。
なるべく原型を崩したくなかったので、木片の上に
H8、制御基板を載せてます。
テスト用ファームウエアは、以下としました。
#include "3052.h"
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
typedef unsigned long ULONG ;
typedef signed char SBYTE ;
typedef signed short SWORD ;
#define NO 0
#define YES 1
/*----------------*/
/* user variables */
/*----------------*/
#define ITU0_AREG 24576
#define ITU1_AREG 245
ULONG timcnt ;
#define P4DDR P4.DDR
#define P4DR P4.DR.BYTE
#define P6DDR P6.DDR
#define P6DR P6.DR.BYTE
#define P8DDR P8.DDR
#define P8DR P8.DR.BYTE
#define P7DR P7.DR.BYTE
#define P9DDR P9.DDR
#define P9DR P9.DR.BYTE
#define PADDR PA.DDR
#define PADR PA.DR.BYTE
#define PBDDR PB.DDR
#define PBDR PB.DR.BYTE
#define MASKFFFF 0xffff
#define MASKFF 0xff
#define MASKCF 0xcf
#define MASK0F 0x0f
#define MASK3F 0x3f
#define MASK07 0x07
#define OFF 0
#define ON OFF+1
#define MASK80 0x80
#define SW_START PB.DR.BIT.B4
void init_sci_1(TBaudRate x);
void rs1_putchar(UBYTE x);
void rs1_crlf(void);
void rs1_puts(UBYTE *x);
void show_help(void);
void show_value(UBYTE x);
UBYTE uflag ;
UBYTE sindex ;
UBYTE sbuf[32];
UBYTE cmd ;
UBYTE sflag ;
UBYTE start_sft ;
UBYTE asc_hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'} ;
UBYTE pcnt ;
UBYTE rduty ;
UBYTE lduty ;
UBYTE rdutyx ;
UBYTE ldutyx ;
UWORD scnt ;
UBYTE servoduty ;
UBYTE servodutyx ;
UBYTE xport ;
/*--------------------------------*/
/* Insert user functions protoype */
/*--------------------------------*/
void user_initialize(void);
void init_timer0();
void init_timer1();
UBYTE get_hex(UBYTE x);
void delay_ms(UWORD x);
/*------*/
/* main */
/*------*/
int main(void)
{
UBYTE tmp ;
UWORD tmpx ;
UBYTE i ;
/* disable interrupt */
DI ;
/* initialize */
user_initialize();
/* enable interrupt */
EI ;
/* opening message */
rs1_puts("Hello"); rs1_crlf();
/* loop */
while ( ON ) {
/* command interpreter */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* new line */
rs1_crlf();
/* get command */
cmd = *(sbuf+0) ;
/* judge */
if ( cmd == '?' ) { show_help() ; }
/* DC motor test */
if ( cmd == 'M' ) {
/* get duty ratio */
tmp = get_hex( *(sbuf+1) );
tmp *= 10 ;
tmp += get_hex( *(sbuf+2) );
/* set duty ratio */
i = *(sbuf+3) ;
if ( i == 'R' ) { rduty = tmp ; }
if ( i == 'L' ) { lduty = tmp ; }
if ( i == 'B' ) { rduty = tmp ; lduty = tmp ;}
}
/* servo motor test */
if ( cmd == 'S' ) {
/* get duty ratio */
tmp = get_hex( *(sbuf+1) );
tmp *= 10 ;
tmp += get_hex( *(sbuf+2) );
/* store */
if ( 100 <= tmp && tmp <= 200 ) {
servoduty = tmp ;
} else {
servoduty = 150 ;
}
}
}
/* test start trigger */
if ( sflag == ON ) {
/* clear flag */
sflag = OFF ;
/* show */
rs1_puts("go") ;
rs1_crlf();
}
}
return 0 ;
}
/*-----------------------*/
/* Insert user functions */
/*-----------------------*/
void user_initialize(void)
{
int i ;
/* PORT 6 */
P6DR = 0xf0 ;
P6DDR = 0xf6 ; /* P60 , P63 inputs , others output */
/* PORT 8 */
P8DR = 0x02 ;
P8DDR = MASKFF ; /* all outputs */
/* PORT B */
PBDR = 0x00 ;
PBDDR = MASKCF ; /* PB5,PB4 inputs , others are outputs */
/* PORT A */
PADR = 0 ;
PADDR = MASKFF ; /* all outputs */
/* PORT 4 */
P4DR = 0x00 ; /* disable all */
P4DDR = 0xef ; /* P44 : inputs , others : outputs */
/* initialize timers */
init_timer0();
init_timer1();
/* clear flags */
sflag = OFF ;
uflag = OFF ;
/* clear SCI buffer */
*(sbuf+0) = 0 ; sindex = 0 ;
/* initialize */
timcnt = 0 ;
pcnt = 0 ;
rduty = 0 ;
lduty = 0 ;
rdutyx = 0 ;
ldutyx = 0 ;
start_sft = 0 ;
scnt = 0 ;
servoduty = 150 ;
servodutyx = 150 ;
}
void init_timer0(void)
{
/* stop timer */
ITU.TSTR.BIT.STR0 = OFF ;
/* TOER : Timer Output Enable Register
7 **** -> 0
6 **** -> 0
5 EXB4 -> 0
4 EXA4 -> 0
3 EB3 -> 0
2 EB4 -> 0
1 EA4 -> 0
0 EA3 -> 0
*/
ITU.TOER.BYTE = 0 ;
/* TIOR : Timer I/O Control Register
7 **** -> 0
6 IOB2 -> 0 GRB is not output compare match register
5 IOB1 -> 0
4 IOB0 -> 0
3 **** -> 0
2 IOA2 -> 0 GRA is not output compare match register
1 IOA1 -> 0
0 IOA0 -> 0
*/
ITU0.TIOR.BYTE = 0 ;
/* TCR : Timer Control Register
7 **** -> 0
6 CCLR1 -> 0 clear TCNT if GRA = TCNT
5 CCLR0 -> 1
4 CKEG1 -> 0 rising edge
3 CKEG0 -> 0
2 TPSC2 -> 0 φ利用
1 TPSC1 -> 0
0 TPSC0 -> 0
*/
ITU0.TCR.BYTE = 0x20 ;
/* TIER : Timer Interrupt Enable Register
7 **** -> 0
6 *** -> 0
5 *** -> 0
4 *** -> 0
3 *** -> 0
2 OVIE -> 0
1 IMIEB -> 0
0 IMIEA -> 1 select compare match interrupt
*/
ITU0.TIER.BIT.IMIEA = ON ;
/* reference */
ITU0.GRA = ITU0_AREG ;
ITU0.GRB = MASKFFFF ;
/* counter */
ITU0.TCNT = 0 ;
/* start timer */
ITU.TSTR.BIT.STR0 = ON ;
}
void init_timer1(void)
{
/* stop timer */
ITU.TSTR.BIT.STR1 = OFF ;
/* TOER : Timer Output Enable Register
7 **** -> 0
6 **** -> 0
5 EXB4 -> 0
4 EXA4 -> 0
3 EB3 -> 0
2 EB4 -> 0
1 EA4 -> 0
0 EA3 -> 0
*/
ITU.TOER.BYTE = 0 ;
/* TIOR : Timer I/O Control Register
7 **** -> 0
6 IOB2 -> 0 GRB is not output compare match register
5 IOB1 -> 0
4 IOB0 -> 0
3 **** -> 0
2 IOA2 -> 0 GRA is not output compare match register
1 IOA1 -> 0
0 IOA0 -> 0
*/
ITU1.TIOR.BYTE = 0 ;
/* TCR : Timer Control Register
7 **** -> 0
6 CCLR1 -> 0 clear TCNT if GRA = TCNT
5 CCLR0 -> 1
4 CKEG1 -> 0 rising edge
3 CKEG0 -> 0
2 TPSC2 -> 0 φ利用
1 TPSC1 -> 0
0 TPSC0 -> 0
*/
ITU1.TCR.BYTE = 0x20 ;
/* TIER : Timer Interrupt Enable Register
7 **** -> 0
6 *** -> 0
5 *** -> 0
4 *** -> 0
3 *** -> 0
2 OVIE -> 0
1 IMIEB -> 0
0 IMIEA -> 1 select compare match interrupt
*/
ITU1.TIER.BIT.IMIEA = ON ;
/* reference */
ITU1.GRA = ITU1_AREG ;
ITU1.GRB = MASKFFFF ;
/* counter */
ITU1.TCNT = 0 ;
/* start timer */
ITU.TSTR.BIT.STR1 = ON ;
}
/*+++++++++++++++++++++++++++++++++++++*/
/* ITU0 interrupt with compare match A */
/* 1ms interval */
/*+++++++++++++++++++++++++++++++++++++*/
void int_imia0(void)
{
UBYTE dummy ;
/* clear flag */
dummy = ITU0.TSR.BIT.IMFA ;
ITU0.TSR.BIT.IMFA = OFF ;
/* increment */
timcnt++ ;
/* impress */
xport &= 0xfc ;
if ( pcnt < rdutyx ) { xport |= 0x01 ; }
if ( pcnt < ldutyx ) { xport |= 0x02 ; }
PBDR = xport ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == 100 ) {
pcnt = 0 ;
rdutyx = rduty ;
ldutyx = lduty ;
}
/* shift */
start_sft <<= 1 ;
start_sft &= 0x07 ;
/* get start trigger switch */
if ( SW_START == OFF ) { start_sft |= ON ; }
/* judge */
if ( sft == 0x01 ) { sflag = ON ; }
}
/*+++++++++++++++++++++++++++++++++++++*/
/* ITU1 interrupt with compare match A */
/* 10us interval */
/*+++++++++++++++++++++++++++++++++++++*/
void int_imia1(void)
{
UBYTE dummy ;
/* clear flag */
dummy = ITU1.TSR.BIT.IMFA ;
ITU1.TSR.BIT.IMFA = OFF ;
/* increment */
scnt++ ;
/* impress */
xport &= 0xfb ;
if ( scnt < servodutyx ) { xport |= 0x04 ; }
PBDR = xport ;
/* judge */
if ( scnt == 2000 ) {
scnt = 0 ;
servodutyx = servoduty ;
}
}
/*+++++++++++++++++++++++++*/
/* SCI_1 receive interrupt */
/*+++++++++++++++++++++++++*/
void init_sci_1(TBaudRate x)
{
volatile UWORD i;
/* SCR : Serial Control Register
7 bit TIE -> 0 Transmit Interrupt Enable(disable)
6 bit RIE -> 0 Receive Interrupt Enable(disable)
5 bit TE -> 0 Transmit Enable(disable)
4 bit RE -> 0 Receive Enable(disable)
3 bit MPIE -> 0 Multi Processor Interrupt Enable(disable)
2 bit TEIE -> 0 Transmit End Interrupt Enable(disable)
1 bit CKE1 -> 0 Clock Source (Use Internal Baud Rate Generator)
0 bit CKE0 -> 0
*/
SCI1.SCR.BYTE = 0 ;
/* SMR : Serial Mode Register
7 bit C/nA -> 0 Communication Mode(Asynchronous)
6 bit CHR -> 0 data Charactor (8 bits)
5 bit PE -> 0 Parity Enable(disable)
4 bit O/nE -> 0 Parity Mode(even)
3 bit STOP -> 0 Stop Bit(1 bit)
2 bit MP -> 0 Multi Processor(disable)
1 bit CKS1 -> 0 Clock Source ( φ )
0 bit CKS0 -> 0
*/
SCI1.SMR.BYTE = 0 ;
/* data transfer speed */
SCI1.BRR = x ;
/* wait 1 frame */
for (i = 0; i < 3000 ; i++) ;
/* enable Transmmit and Receive with interrupt */
SCI1.SCR.BYTE = 0x70 ;
}
/*+++++++++++++++++++++++++*/
/* SCI_1 receive interrupt */
/*+++++++++++++++++++++++++*/
void int_rxi1(void)
{
volatile UBYTE ch,dummy ;
/* clear flag */
dummy = SCI1.SSR.BYTE ;
SCI1.SSR.BIT.RDRF = OFF ;
/* get a character */
ch = SCI1.RDR ;
/* store */
*(sbuf+sindex) = ch ;
sindex++ ;
/* check */
if ( ch == '\r' ) {
*(sbuf+sindex) = 0 ;
sindex = 0 ;
UFLAG = ON ;
}
}
/*+++++++++++++++*/
/* SCI_1 putchar */
/*+++++++++++++++*/
void rs1_putchar(UBYTE x)
{
/* wait data transfer */
while ( SCI1.SSR.BIT.TDRE == OFF ) ;
/* put */
SCI1.TDR = x ;
SCI1.SSR.BIT.TDRE = OFF ;
}
/*++++++++++++*/
/* SCI_1 puts */
/*++++++++++++*/
void rs1_puts(UBYTE *x)
{
/* send 1 charactors */
while ( *x ) {
rs1_putchar(*x);
x++ ;
}
}
/*++++++++++++*/
/* SCI_1 crlf */
/*++++++++++++*/
void rs1_crlf(void)
{
rs1_putchar('\r');
rs1_putchar('\n');
}
/*++++++++++++++++++++*/
/* SCI_1 command help */
/*++++++++++++++++++++*/
void show_help(void)
{
rs1_puts("? help") ; rs1_crlf();
rs1_puts("M test DC motor") ; rs1_crlf();
rs1_puts("S test servo motor"); rs1_crlf();
}
void show_value(UBYTE x)
{
volatile UBYTE msg[2] ;
volatile UBYTE i ;
/* separate */
*(msg+0) = (x >> 4) & MASK0F ;
*(msg+1) = x & MASK0F ;
/* conversion */
*(msg+0) = asc_hex[ *(msg+0) ] ;
*(msg+1) = asc_hex[ *(msg+1) ] ;
/* output */
rs1_putchar( *(msg+0) ) ;
rs1_putchar( *(msg+1) ) ;
}
UBYTE get_hex(UBYTE x)
{
UBYTE result ;
/* default */
result = 0 ;
/* convert */
if ( '0' <= x && x <= '9' ) { result = x - '0' ; }
if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; }
if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; }
return result ;
}
void delay_ms(UWORD x)
{
ULONG target ;
/* calculate last value */
target = timcnt + x ;
/* wait */
while ( timcnt < target ) ;
}
目次
前
次