目次
前
次
動作テスト(PIC)
ハーフブリッジICのSN754410NEを
基板に半田付けして、動作テスト
してみます。
コネクタは、以下のように接続。
- 1 GND
- 2 right motor control
- 3 left motor control
- 4 enable
- 5 LED flashing
- 6 start trigger input
- 7 test input
- 8 Vcc
テストには、PIC16F873を利用。
ポートAは、次のように使います。
- RA0 right motor control
- RA1 left motor control
- RA2 enable
- RA3 LED flashing
- RA4 start trigger input
- RA5 test input
ポートBは、センサーからの入力にします。
MSBが左、LSBが右になります。
ポートA、Bの初期設定は、以下。
PORTA = 0x03 ; /* left , right must be '1' */
PORTB = 0x00 ;
TRISA = 0xf0 ; /* upper : inputs , lower : outputs */
TRISB = 0xf0 ; /* all bits : inputs */
ポートAに関係する処理を定義していきます。
スタートトリガー
スタートトリガーは、テスト車両の後部にあります。
このスイッチを利用して、ドライバICのEnable端子の
論理値を決定します。
スイッチの状態をタイマー割込みで、入力。
シフトレジスタのLSBに格納後、変化を検出
したなら、Enableに論理値を変更。
タイマー割込みで、トリガーを与えられたなら
次のコードが実行されるようにします。
typedef unsigned char UBYTE
UBYTE xflags ;
UBYTE swsft ;
UBYTE mcnt ;
#define SFLAG xflas.F1
#define XEN PORTA.F2
#define XSW PORTA.F4
if ( SFLAG == ON ) {
/* clear flag */
SFLAG = OFF ;
/* shift */
swsft = swsft + swsft ;
/* mask */
swsft = swswft & 3 ;
/* get switch state */
if ( XSW == OFF ) { swsft = swsft | ON ; }
/* judge */
if ( swsft == 1 ) {
mcnt = mcnt + 1 ;
mcnt = mcnt & ON ;
/* update flag */
XEN = mcnt ;
}
}
MikroCを利用することを考えているので
ビットごとの処理が単純になっています。
モード設定
モードは、移動とテストの2種で、トグルスイッチで
指定します。電源投入したら、トグルスイッチの状態
をリードして、モードを指定します。
モードは、次のように決めました。
0 移動
1 テスト
単純に、次のように定義。
#define MFLAG xflas.F2
#define TSW PORTA.F5
MFLAG = OFF ;
if ( TSW == ON ) { MFLAG = ON ; }
PWM波形生成
PWM波形は、ポートAのビット1、0に出力すると
して、タイマー割込みの中に、次のように組み入れ
します。
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize */
TMR0 = CNTBEGIN ;
/* get now state */
aport = PORTA :
/* judge */
if ( pcnt < llx ) { aport = aport & 0xfd ; }
if ( pcnt < rrx ) { aport = aport & 0xfe ; }
/* impress */
PORTA = aport ;
/* increment */
pcnt = pcnt + 1 ;
/* initialize */
if ( pcnt == PCNTMX ) {
pcnt = 0 ;
llx = left ;
rrx = right ;
}
}
タイマー割込みの周期は、1ms程度としておきます。
LED点滅
コンピュータが、動作しているのかを示すために
LEDを点滅させます。人間にとって、わかりやすく
するためだけに使います。
1秒ごとに、LEDに対して0か1を設定していきます。
タイマー割込みの中に、組み込んでしまいます。
#define LOUT PORTA.F3
typedef unsigned short UWORD ;
UWORD lcnt ;
UBYTE lcntx ;
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize */
TMR0 = CNTBEGIN ;
/* get now state */
aport = PORTA :
/* judge */
if ( pcnt < llx ) { aport = aport & 0xfd ; }
if ( pcnt < rrx ) { aport = aport & 0xfe ; }
/* impress */
PORTA = aport ;
/* increment */
pcnt = pcnt + 1 ;
/* initialize */
if ( pcnt == PCNTMX ) {
pcnt = 0 ;
llx = left ;
rrx = right ;
}
/* LED handling */
lcnt = lcnt + 1
if ( lcnt == 1000 ) {
lcnt = 0 ;
lcntx = lcntx + 1 ;
LOUT = lcntx & 1 ;
}
}
PIC16F873、ドライバIC基板、モータその他を
接続すると、次のようになります。
ハードウエアの動作テストまで含めたプログラムは以下。
/*
file name mcrx.c
abstract control MCR machine
CPU PIC16F876
CLOCK 20MHz
PORTA
5 mode
4 start trigger
3 LED
2 enable
1 left
0 right
PORTB (sensor)
white => '0'
black => '1'
*/
#define OFF 0
#define ON OFF+1
#define CNTBEGIN 6
#define PCNTMAX 100
#define SCNTMAX 50
#define MSW PORTA.F5
#define XSW PORTA.F4
#define XLED PORTA.F3
#define XEN PORTA.F2
typedef unsigned char UBYTE ;
volatile UBYTE xflag ;
/* set flag bit */
#define TFLAG xflag.F0
#define SFLAG xflag.F1
#define MFLAG xflag.F2
#define RFLAG xflag.F3
#define UFLAG xflag.F4
volatile UBYTE swsft ;
volatile UBYTE sensor ;
volatile UBYTE lcnt ;
volatile UBYTE mcnt ;
volatile UBYTE pcnt ;
volatile UBYTE scnt ;
volatile UBYTE rrx ;
volatile UBYTE llx ;
volatile UBYTE right ;
volatile UBYTE left ;
volatile UBYTE aport ;
volatile UBYTE cmd ;
volatile UBYTE ch ;
volatile UBYTE sbuf[8] ;
volatile UBYTE sindex ;
/* interrupt handler */
void interrupt(void)
{
/* timer0 interrupt */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize */
TMR0 = CNTBEGIN ;
/* impress */
aport = PORTA ;
if ( pcnt < rrx ) { aport.F0 = OFF ; }
if ( pcnt < llx ) { aport.F1 = OFF ; }
PORTA = aport ;
/* increment */
pcnt = pcnt + 1 ;
/* judge */
if ( pcnt == PCNTMAX ) {
/* clear counter */
pcnt = 0 ;
/* reload */
rrx = right ;
llx = left ;
}
/* increment */
scnt = scnt + 1 ;
/* judge */
if ( scnt == SCNTMAX ) {
/* clear counter */
scnt = 0 ;
/* set flags */
SFLAG = ON ;
TFLAG = ON ;
/* increment */
lcnt = lcnt + 1 ;
/* update LED state */
XLED = lcnt & ON ;
}
}
/* judge interrupt term */
if ( PIR1.RCIF == ON ) {
/* clear flag */
PIR1.RCIF = OFF ;
/* get data */
ch = RCREG ;
/* store */
*(sbuf+sindex) = ch ;
/* update pointer */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
UFLAG = ON ;
}
}
}
/* function prototype */
void init_usr(void);
UBYTE get_sensor(void);
void rs_putc(UBYTE x);
void rs_puts(UBYTE *ptr);
void crlf(void);
void show_help(void);
void show_sensor(void);
void show_mode(void);
void main(void)
{
/* initialize */
init_usr() ;
/* endless loop */
while ( ON ) {
/* update */
XEN = RFLAG ;
/* test mode */
if ( MFLAG == ON )
{
/* command interpreter */
if ( UFLAG == ON ) {
/* clear flag */
UFLAG = OFF ;
/* get command */
cmd = *(sbuf+0) ;
/* help */
if ( cmd == '?' ) { show_help(); }
if ( cmd == 'E' ) { RFLAG = ON ; }
if ( cmd == 'D' ) { RFLAG = OFF; }
if ( cmd == 'R' ) { right = 75 ; }
if ( cmd == 'r' ) { right = 5 ; }
if ( cmd == 'L' ) { left = 75 ; }
if ( cmd == 'l' ) { left = 5 ; }
if ( cmd == 'S' ) { show_sensor(); }
if ( cmd == 'M' ) { show_mode(); }
}
} else {
/* shift register handling */
if ( SFLAG == ON ) {
/* clear flag */
SFLAG = OFF ;
/* shift */
swsft = swsft + swsft ;
/* mask */
swsft = swsft & 3 ;
/* get switch state */
if ( XSW == OFF ) { swsft = swsft | ON ; }
/* judge */
if ( swsft == 1 ) {
mcnt = mcnt + 1 ;
mcnt = mcnt & ON ;
RFLAG = mcnt ;
}
}
/* move handling */
if ( TFLAG == ON ) {
/* clear flag */
TFLAG = OFF ;
/* get sensor */
sensor = get_sensor() ;
/* default */
right = 50 ;
left = 50 ;
/* judge */
if ( sensor == 1 ) {
right = 60 ;
left = 40 ;
}
if ( sensor == 4 ) {
right = 40 ;
left = 60 ;
}
}
}
}
}
/* define function body */
void init_usr(void)
{
/* I/O values */
PORTA = 0x03 ;
PORTB = 0x00 ;
/* I/O directions */
TRISA = 0xf0 ; /* upper : inputs , lower : outputs */
TRISB = 0xff ; /* all : inputs */
TRISC = 0x80 ;
/* initialize Timer 0 */
{
/*
20MHz/4 = 5MHz (BUS clock) -> 5MHz/4 = 1.25MHz prescaler = 1:4
*/
OPTION_REG = 0x01 ;
/* 256 - 6 = 250 */
TMR0 = CNTBEGIN ;
/* enable timer0 overflow interrupt */
INTCON.TMR0IE = ON ;
}
/* initialize UART */
{
/* enable TxD */
TXSTA = (1 << BRGH) | (1 << TXEN);
/* enable RxD */
RCSTA = (1 << SPEN) | (1 << CREN) ;
/* 9600 bps */
SPBRG = 129 ;
/* enable receive interrupt */
PIE1.RCIE = ON ;
/* clear */
sindex = 0 ;
/* periheral interrupt */
INTCON.PEIE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* clear flags */
xflag = 0 ;
/* set flag */
if ( MSW == ON ) { MFLAG = ON ; }
/* initialize variables */
pcnt = 0 ;
right = 50 ;
left = 50 ;
scnt = 0 ;
mcnt = 0 ;
sindex = 0 ;
}
UBYTE get_sensor(void)
{
UBYTE result ;
UBYTE tmp ;
/* get sensor data */
tmp = PORTB ;
tmp = tmp ^ 0xff ;
/* default */
result = 0 ;
/* 6,3,1 bit */
if ( tmp & 0x40 ) { result = result | 4 ; }
if ( tmp & 0x08 ) { result = result | 2 ; }
if ( tmp & 0x02 ) { result = result | 1 ; }
return result ;
}
void rs_putc(UBYTE x)
{
/* judge empty */
while ( TXSTA.TRMT == OFF ) ;
/* transmit */
TXREG = x ;
}
void rs_puts(UBYTE *ptr)
{
while ( *ptr != '\0' ) {
rs_putc(*ptr);
ptr++ ;
}
}
void crlf(void)
{
rs_putc('\r');
rs_putc('\n');
}
void show_help(void)
{
rs_puts("? help") ; crlf();
rs_puts("E enable") ; crlf();
rs_puts("D disable") ; crlf();
rs_puts("R rotate right") ; crlf();
rs_puts("r stop right") ; crlf();
rs_puts("L rotate left") ; crlf();
rs_puts("l stop left") ; crlf();
rs_puts("S show sensor value") ; crlf();
rs_puts("M show mode") ; crlf();
}
void show_sensor(void)
{
UBYTE tmp ;
UBYTE smsg[4] ;
/* get sensor */
tmp = get_sensor() ;
/* separate */
*(smsg+3) = '\0' ;
*(smsg+2) = (tmp & ON) + '0' ; tmp = tmp >> 1 ;
*(smsg+1) = (tmp & ON) + '0' ; tmp = tmp >> 1 ;
*(smsg+0) = (tmp & ON) + '0' ;
/* show */
rs_puts(smsg);
/* new line */
crlf();
}
void show_mode(void)
{
if ( MFLAG == ON ) { rs_puts("TEST"); }
else { rs_puts("MOVE"); }
/* new line */
crlf();
}
目次
前
次