目次
前
次
モーターを回す(割込み利用)
複数のモータを一度に動かすことを扱いますが、DUTY比と
回転方向を同時に変更できるようにします。
利用するシステムは、以下。
スイッチには、次の機能を持たせます。
- SW1 モータを回すか止めるかをトグルで切替え
- SW2 回転方向変更
- SW3 回転数を増やす
- SW4 回転数を減らす
ポートBの下位4ビットを入力に、上位4ビットを出力に設定。
TRISB = 0x0f ;
PWMで回転を制御するには、DUTY比を変えます。
DUTY比は0%から99%になるので、内部カウンタを用意して
タイマー割込みが発生するたびに、増やしていきます。
カウンタを定義しておけば、割込みハンドラは次のように
記述できます。
#define PCNTMAX 100
typedef unsigned char UBYTE ;
UBYTE pcnt ;
void interrupt(void)
{
/* timer0 overflow */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == PCNTMAX ) {
pcnt = 0 ;
}
}
}
DUTY比は、1サイクルにおける'1'の数と考えれば
カウンタの最大値が100なら、次のようにピン出力
を指定すればよくなります。
/* compare */
lout = OFF ;
if ( pcnt < lcntx ) {
lout = ON ;
}
/* impress */
PORTB.F4 = lout ;
このカラクリでみると、回転数を変えるということは
変数lcntxの値を増減させることと等価になります。
スイッチでモータの回転数を増減するには、スイッチの
0から1(1から0)の変化を捉えて、対応する変数値
を増減するとなります。
4つのスイッチの変化を、フラグで表現すると動作を
制御できます。
/* endless loop */
while (ON) {
/* run or stop */
if ( RFLAG == ON ) {
/* clear flag */
RFLAG = OFF ;
/* update */
if ( state == RUN ) {
state = IDLE ;
} else {
state = RUN ;
}
}
/* direction */
if ( DFLAG == ON ) {
/* clear flag */
DFLAG = OFF ;
/* change */
dcnt++ ;
/* get LSB */
dcnt &= ON ;
}
/* increment */
if ( PFLAG == ON ) {
/* clear flag */
PFLAG = OFF ;
/* change */
lcnt++ ;
/* judge */
if ( lcnt > LCNTMAX ) {
lcnt = LCNTMAX ;
}
}
/* decrement */
if ( MFLAG == ON ) {
/* clear flag */
MFLAG = OFF ;
/* change */
if ( lcnt > 0 ) {
lcnt-- ;
}
}
}
上のコードから、フラグを用意することになるので定義します。
typedef union {
struct {
unsigned B7:1;
unsigned B6:1;
unsigned B5:1;
unsigned B4:1;
unsigned B3:1;
unsigned B2:1;
unsigned B1:1;
unsigned B0:1;
} BIT ;
unsigned char DR ;
} FLAGSP ;
volatile FLAGSP xflags ;
#define RFLAG xflags.BIT.B0
#define DFLAG xflags.BIT.B1
#define PFLAG xflags.BIT.B2
#define MFLAG xflags.BIT.B3
スイッチの変化があったことは、シフトレジスタを利用して検出します。
if ( TFLAG == ON ) {
/* clear flag */
TFLAG = OFF ;
/* shift */
rsft <<= 1;
dsft <<= 1;
psft <<= 1;
msft <<= 1;
/* update */
if ( PORTB.F0 == SWON ) { rsft |= ON ; }
if ( PORTB.F1 == SWON ) { dsft |= ON ; }
if ( PORTB.F2 == SWON ) { psft |= ON ; }
if ( PORTB.F3 == SWON ) { msft |= ON ; }
/* judge */
if ( rsft == 0x01 ) { RFLAG = ON ; }
if ( dsft == 0x01 ) { DFLAG = ON ; }
if ( psft == 0x01 ) { PFLAG = ON ; }
if ( msft == 0x01 ) { MFLAG = ON ; }
}
シフトレジスタを利用するときは、タイマー割込みでチャタリングを
除去できる程度のインターバルを用意して対応します。
割込みハンドラで、次のようにタイマー割込み発生を扱います。
void interrupt(void)
{
/* timer0 overflow */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == PCNTMAX ) {
pcnt = 0 ;
}
}
/* timer1 overflow interrupt */
if ( PIR1.TMR1IF == ON ) {
/* clear flag */
PIR1.TMR1IF = OFF ;
/* initialize */
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* set flag */
TFLAG = ON ;
}
}
main関数をまとめてみます。
void main(void)
{
/* initialize */
usr_init();
/* endless loop */
while (ON) {
/* switch handling */
if ( TFLAG == ON ) {
/* clear flag */
TFLAG = OFF ;
/* shift */
rsft <<= 1;
dsft <<= 1;
psft <<= 1;
msft <<= 1;
/* update */
if ( PORTB.F0 == SWON ) { rsft |= ON ; }
if ( PORTB.F1 == SWON ) { dsft |= ON ; }
if ( PORTB.F2 == SWON ) { psft |= ON ; }
if ( PORTB.F3 == SWON ) { msft |= ON ; }
/* judge */
if ( rsft == 0x01 ) { RFLAG = ON ; }
if ( dsft == 0x01 ) { DFLAG = ON ; }
if ( psft == 0x01 ) { PFLAG = ON ; }
if ( msft == 0x01 ) { MFLAG = ON ; }
}
/* run or stop */
if ( RFLAG == ON ) {
/* clear flag */
RFLAG = OFF ;
/* update */
if ( state == RUN ) {
state = IDLE ;
} else {
state = RUN ;
}
}
/* direction */
if ( DFLAG == ON ) {
/* clear flag */
DFLAG = OFF ;
/* change */
dcnt++ ;
/* get LSB */
dcnt &= ON ;
/* standby stop */
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
}
/* increment */
if ( PFLAG == ON ) {
/* clear flag */
PFLAG = OFF ;
/* change */
lcnt++ ;
/* judge */
if ( lcnt > LCNTMAX ) {
lcnt = LCNTMAX ;
}
}
/* decrement */
if ( MFLAG == ON ) {
/* clear flag */
MFLAG = OFF ;
/* change */
if ( lcnt > 0 ) {
lcnt-- ;
}
}
/* motor control */
if ( state == IDLE ) {
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
} else {
/* set value */
lout = OFF ;
if ( pcnt < lcntx ) { lout = ON ; }
/* impress */
if ( dcnt ) {
PORTB.F5 = lout ;
PORTB.F4 = OFF ;
} else {
PORTB.F5 = OFF ;
PORTB.F4 = lout ;
}
}
}
}
回転数を扱う変数は、2種用意します。
ひとつだけだと、回転数を変えたときに挙動がおかしくなります。
2種の変数を用意したなら、割込みハンドラは、次のように変更。
void interrupt(void)
{
/* timer0 overflow */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == PCNTMAX ) {
pcnt = 0 ;
lcntx = lcnt ;
}
}
/* timer1 overflow interrupt */
if ( PIR1.TMR1IF == ON ) {
/* clear flag */
PIR1.TMR1IF = OFF ;
/* initialize */
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* set flag */
TFLAG = ON ;
}
}
初期設定を考えていきます。
シフトレジスタ
4つのシフトレジスタをゼロクリアします。
rsft = 0 ;
dsft = 0 ;
psft = 0 ;
msft = 0 ;
フラグ類
フラグ類は、共用体で定義してあるので1行ですみます。
xflags.DR = 0 ;
状態変数
状態変数は、モータを回すか、止めるかなので
パワーオンでは、止めた状態にします。
state = IDLE ;
文字列を利用してわかりやすくしておきます。
PWM関係変数
4つの変数をゼロクリアします。
pcnt = 0 ;
lcnt = 0 ;
lcntx = 0 ;
lout = OFF ;
タイマー0
タイマー0は、PWMのDUTY比を担当するので1kHz程度で
カウンタを動かせるようにパラメータを設定します。
また、オーバーフロー割込みを指定。
/*
10MHz/4 = 2.5MHz -> 2.5MHz/8 = 312.5kHz prescaler = 1:8
*/
OPTION_REG = 0x02 ;
/* 256 - 250 = 6 */
TMR0 = SINTX ;
/* enable timer0 overflow interrupt */
INTCON.T0IE = ON ;
タイマー1
タイマー1は、スイッチのチャタリング除去のための
タイミングを生成するので、10Hz程度で周期を扱うと
します。
タイマー1は、使うか否かを指定することができるので
それを忘れないようにします。
また、オーバーフロー割込みを指定。
/*
10MHz/4 = 2.5MHz -> 2.5MHz/8 = 312.5kHz prescaler = 1:8
*/
T1CON = (3 << 4) | 1 ;
/*
65536 - 62500
*/
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* enable timer1 overflow interrupt */
PIE1.TMR1IE = ON ;
まとめると、以下。
#define OFF 0
#define ON OFF+1
#define IDLE 0
#define RUN IDLE+1
#define SWON 0
#define SWOFF SWON+1
#define PCNTMAX 100
#define LCNTMAX 100
#define STARTV 62500
#define SINTX 6
typedef union {
struct {
unsigned B7:1;
unsigned B6:1;
unsigned B5:1;
unsigned B4:1;
unsigned B3:1;
unsigned B2:1;
unsigned B1:1;
unsigned B0:1;
} BIT ;
unsigned char DR ;
} FLAGSP ;
volatile FLAGSP xflags ;
#define RFLAG xflags.BIT.B0
#define DFLAG xflags.BIT.B1
#define PFLAG xflags.BIT.B2
#define MFLAG xflags.BIT.B3
#define TFLAG xflags.BIT.B4
typedef unsigned char UBYTE ;
volatile UBYTE rsft ;
volatile UBYTE dsft ;
volatile UBYTE psft ;
volatile UBYTE msft ;
volatile UBYTE state ;
volatile UBYTE dcnt ;
volatile UBYTE pcnt ;
volatile UBYTE lcnt ;
volatile UBYTE lcntx ;
volatile UBYTE lout ;
void interrupt(void)
{
/* timer0 overflow */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* 256 - 250 = 6 */
TMR0 = SINTX ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == PCNTMAX ) {
pcnt = 0 ;
lcntx = lcnt ;
}
}
/* timer1 overflow interrupt */
if ( PIR1.TMR1IF == ON ) {
/* clear flag */
PIR1.TMR1IF = OFF ;
/* initialize */
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* set flag */
TFLAG = ON ;
}
}
/* prototype */
void usr_init(void);
void main(void)
{
/* initialize */
usr_init();
/* endless loop */
while (ON) {
/* switch handling */
if ( TFLAG == ON ) {
/* clear flag */
TFLAG = OFF ;
/* shift */
rsft <<= 1;
dsft <<= 1;
psft <<= 1;
msft <<= 1;
/* update */
if ( PORTB.F0 == SWON ) { rsft |= ON ; }
if ( PORTB.F1 == SWON ) { dsft |= ON ; }
if ( PORTB.F2 == SWON ) { psft |= ON ; }
if ( PORTB.F3 == SWON ) { msft |= ON ; }
/* judge */
if ( rsft == 0x01 ) { RFLAG = ON ; }
if ( dsft == 0x01 ) { DFLAG = ON ; }
if ( psft == 0x01 ) { PFLAG = ON ; }
if ( msft == 0x01 ) { MFLAG = ON ; }
}
/* run or stop */
if ( RFLAG == ON ) {
/* clear flag */
RFLAG = OFF ;
/* update */
if ( state == RUN ) {
state = IDLE ;
} else {
state = RUN ;
}
}
/* direction */
if ( DFLAG == ON ) {
/* clear flag */
DFLAG = OFF ;
/* change */
dcnt++ ;
/* get LSB */
dcnt &= ON ;
/* standby stop */
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
}
/* increment */
if ( PFLAG == ON ) {
/* clear flag */
PFLAG = OFF ;
/* change */
lcnt++ ;
/* judge */
if ( lcnt > LCNTMAX ) {
lcnt = LCNTMAX ;
}
}
/* decrement */
if ( MFLAG == ON ) {
/* clear flag */
MFLAG = OFF ;
/* change */
if ( lcnt > 0 ) {
lcnt-- ;
}
}
/* motor control */
if ( state == IDLE ) {
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
} else {
/* set value */
lout = OFF ;
if ( pcnt < lcntx ) { lout = ON ; }
/* impress */
if ( dcnt ) {
PORTB.F5 = lout ;
PORTB.F4 = OFF ;
} else {
PORTB.F5 = OFF ;
PORTB.F4 = lout ;
}
}
}
}
void usr_init(void)
{
/* stop motor */
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
/* direction */
TRISB = 0x0f ;
/* clear flags */
xflags.DR = 0 ;
/* clear shift register */
rsft = 0 ;
dsft = 0 ;
psft = 0 ;
msft = 0 ;
/* set state value */
state = IDLE ;
/* PWM duty ratio */
pcnt = 0 ;
lcnt = 0 ;
lcntx = 0 ;
lout = OFF ;
/* initialize Timer 0 */
{
/*
10MHz/4 = 2.5MHz -> 2.5MHz/8 = 312.5kHz prescaler = 1:8
*/
OPTION_REG = 0x02 ;
/* 256 - 250 = 6 */
TMR0 = SINTX ;
/* enable timer0 overflow interrupt */
INTCON.T0IE = ON ;
}
/* initialize Timer 1 */
{
/*
10MHz/4 = 2.5MHz -> 2.5MHz/8 = 312.5kHz prescaler = 1:8
*/
T1CON = (3 << 4) | 1 ;
/*
65536 - 62500
*/
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* enable timer1 overflow interrupt */
PIE1.TMR1IE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
}
ひとつのマイコンで2モータを制御するシステムを考えます。
トグルスイッチを用意して、どちらのモータに対する
指定なのかを判断できるようにします。
/* run or stop */
if ( RFLAG == ON ) {
/* clear flag */
RFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* update */
if ( lstate == RUN ) {
lstate = IDLE ;
} else {
lstate = RUN ;
}
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* update */
if ( rstate == RUN ) {
rstate = IDLE ;
} else {
rstate = RUN ;
}
}
}
/* direction */
if ( DFLAG == ON ) {
/* clear flag */
DFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* change */
ldcnt++ ;
/* get LSB */
ldcnt &= ON ;
/* standby stop */
PORTB.F6 = OFF ;
PORTB.F7 = OFF ;
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* change */
rdcnt++ ;
/* get LSB */
rdcnt &= ON ;
/* standby stop */
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
}
}
/* increment */
if ( PFLAG == ON ) {
/* clear flag */
PFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* change */
lcnt++ ;
/* judge */
if ( lcnt > LCNTMAX ) {
lcnt = LCNTMAX ;
}
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* change */
rcnt++ ;
/* judge */
if ( rcnt > LCNTMAX ) {
rcnt = LCNTMAX ;
}
}
}
/* decrement */
if ( MFLAG == ON ) {
/* clear flag */
MFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* change */
if ( lcnt > 0 ) {
lcnt-- ;
}
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* change */
if ( rcnt > 0 ) {
rcnt-- ;
}
}
}
/* left motor control */
if ( lstate == IDLE ) {
PORTB.F6 = OFF ;
PORTB.F7 = OFF ;
} else {
/* set value */
lout = OFF ;
if ( pcnt < lcntx ) { lout = ON ; }
/* impress */
if ( ldcnt ) {
PORTB.F6 = lout ;
PORTB.F7 = OFF ;
} else {
PORTB.F6 = OFF ;
PORTB.F7 = lout ;
}
}
/* right motor control */
if ( rstate == IDLE ) {
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
} else {
/* set value */
lout = OFF ;
if ( pcnt < rcntx ) { lout = ON ; }
/* impress */
if ( rdcnt ) {
PORTB.F5 = lout ;
PORTB.F4 = OFF ;
} else {
PORTB.F5 = OFF ;
PORTB.F4 = lout ;
}
}
2つのモータのDUTY比を更新するので、割込みハンドラも
変更します。
void interrupt(void)
{
/* timer0 overflow */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* 256 - 250 = 6 */
TMR0 = SINTX ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == PCNTMAX ) {
pcnt = 0 ;
lcntx = lcnt ;
rcntx = rcnt ;
}
}
/* timer1 overflow interrupt */
if ( PIR1.TMR1IF == ON ) {
/* clear flag */
PIR1.TMR1IF = OFF ;
/* initialize */
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* set flag */
TFLAG = ON ;
}
}
まとめると、以下。
#define OFF 0
#define ON OFF+1
#define IDLE 0
#define RUN IDLE+1
#define SWON 0
#define SWOFF SWON+1
#define PCNTMAX 100
#define LCNTMAX 100
#define STARTV 62500
#define SINTX 6
typedef union {
struct {
unsigned B7:1;
unsigned B6:1;
unsigned B5:1;
unsigned B4:1;
unsigned B3:1;
unsigned B2:1;
unsigned B1:1;
unsigned B0:1;
} BIT ;
unsigned char DR ;
} FLAGSP ;
volatile FLAGSP xflags ;
#define RFLAG xflags.BIT.B0
#define DFLAG xflags.BIT.B1
#define PFLAG xflags.BIT.B2
#define MFLAG xflags.BIT.B3
#define TFLAG xflags.BIT.B4
typedef unsigned char UBYTE ;
volatile UBYTE rsft ;
volatile UBYTE dsft ;
volatile UBYTE psft ;
volatile UBYTE msft ;
volatile UBYTE lstate ;
volatile UBYTE rstate ;
volatile UBYTE ldcnt ;
volatile UBYTE rdcnt ;
volatile UBYTE pcnt ;
volatile UBYTE lcnt ;
volatile UBYTE lcntx ;
volatile UBYTE rcnt ;
volatile UBYTE rcntx ;
volatile UBYTE lout ;
void interrupt(void)
{
/* timer0 overflow */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* 256 - 250 = 6 */
TMR0 = SINTX ;
/* increment */
pcnt++ ;
/* judge */
if ( pcnt == PCNTMAX ) {
pcnt = 0 ;
lcntx = lcnt ;
rcntx = rcnt ;
}
}
/* timer1 overflow interrupt */
if ( PIR1.TMR1IF == ON ) {
/* clear flag */
PIR1.TMR1IF = OFF ;
/* initialize */
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* set flag */
TFLAG = ON ;
}
}
/* prototype */
void usr_init(void);
void main(void)
{
/* initialize */
usr_init();
/* endless loop */
while (ON) {
/* switch handling */
if ( TFLAG == ON ) {
/* clear flag */
TFLAG = OFF ;
/* shift */
rsft <<= 1;
dsft <<= 1;
psft <<= 1;
msft <<= 1;
/* update */
if ( PORTB.F0 == SWON ) { rsft |= ON ; }
if ( PORTB.F1 == SWON ) { dsft |= ON ; }
if ( PORTB.F2 == SWON ) { psft |= ON ; }
if ( PORTB.F3 == SWON ) { msft |= ON ; }
/* judge */
if ( rsft == 0x01 ) { RFLAG = ON ; }
if ( dsft == 0x01 ) { DFLAG = ON ; }
if ( psft == 0x01 ) { PFLAG = ON ; }
if ( msft == 0x01 ) { MFLAG = ON ; }
}
/* run or stop */
if ( RFLAG == ON ) {
/* clear flag */
RFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* update */
if ( lstate == RUN ) {
lstate = IDLE ;
} else {
lstate = RUN ;
}
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* update */
if ( rstate == RUN ) {
rstate = IDLE ;
} else {
rstate = RUN ;
}
}
}
/* direction */
if ( DFLAG == ON ) {
/* clear flag */
DFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* change */
ldcnt++ ;
/* get LSB */
ldcnt &= ON ;
/* standby stop */
PORTB.F6 = OFF ;
PORTB.F7 = OFF ;
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* change */
rdcnt++ ;
/* get LSB */
rdcnt &= ON ;
/* standby stop */
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
}
}
/* increment */
if ( PFLAG == ON ) {
/* clear flag */
PFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* change */
lcnt++ ;
/* judge */
if ( lcnt > LCNTMAX ) {
lcnt = LCNTMAX ;
}
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* change */
rcnt++ ;
/* judge */
if ( rcnt > LCNTMAX ) {
rcnt = LCNTMAX ;
}
}
}
/* decrement */
if ( MFLAG == ON ) {
/* clear flag */
MFLAG = OFF ;
/* left motor */
if ( PORTA.F4 == ON ) {
/* change */
if ( lcnt > 0 ) {
lcnt-- ;
}
}
/* right motor */
if ( PORTA.F4 == OFF ) {
/* change */
if ( rcnt > 0 ) {
rcnt-- ;
}
}
}
/* left motor control */
if ( lstate == IDLE ) {
PORTB.F6 = OFF ;
PORTB.F7 = OFF ;
} else {
/* set value */
lout = OFF ;
if ( pcnt < lcntx ) { lout = ON ; }
/* impress */
if ( ldcnt ) {
PORTB.F6 = lout ;
PORTB.F7 = OFF ;
} else {
PORTB.F6 = OFF ;
PORTB.F7 = lout ;
}
}
/* right motor control */
if ( rstate == IDLE ) {
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
} else {
/* set value */
lout = OFF ;
if ( pcnt < rcntx ) { lout = ON ; }
/* impress */
if ( rdcnt ) {
PORTB.F5 = lout ;
PORTB.F4 = OFF ;
} else {
PORTB.F5 = OFF ;
PORTB.F4 = lout ;
}
}
}
}
void usr_init(void)
{
/* stop motor */
PORTB.F4 = OFF ;
PORTB.F5 = OFF ;
PORTB.F6 = OFF ;
PORTB.F7 = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x0f ;
/* clear flags */
xflags.DR = 0 ;
/* clear shift register */
rsft = 0 ;
dsft = 0 ;
psft = 0 ;
msft = 0 ;
/* set state value */
lstate = IDLE ;
rstate = IDLE ;
/* PWM duty ratio */
pcnt = 0 ;
lcnt = 0 ;
lcntx = 0 ;
rcnt = 0 ;
rcntx = 0 ;
lout = OFF ;
/* initialize Timer 0 */
{
/*
10MHz/4 = 2.5MHz -> 2.5MHz/8 = 312.5kHz prescaler = 1:8
*/
OPTION_REG = 0x02 ;
/* 256 - 250 = 6 */
TMR0 = SINTX ;
/* enable timer0 overflow interrupt */
INTCON.T0IE = ON ;
}
/* initialize Timer 1 */
{
/*
10MHz/4 = 2.5MHz -> 2.5MHz/8 = 312.5kHz prescaler = 1:8
*/
T1CON = (3 << 4) | 1 ;
/*
65536 - 62500
*/
TMR1L = STARTV % 256 ;
TMR1H = STARTV / 256 ;
/* enable timer1 overflow interrupt */
PIE1.TMR1IE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
}
使っているフラッシュROMと内蔵メモリの容量は、それぞれ32%、10%と
なっているので、最大容量まで余裕があります。
イベントフラグを利用し、対応する処理を入れていけば、より
複雑なシステムを構築できるようになります。
割込みの基本は、タイマー割込みなので、ワンチップマイコンは
複数個のタイマーを用意していることが多いです。
目次
前
次