目次
前
次
Clock Generator
Clock Generatorは、PIC12F629を利用して実現します。
回路図は、以下。
内蔵4MHzをタイマー0に入力し、500Hzを生成します。
この500Hzを分周して10Hz、1Hzを作り出します。
タイマー割込みでは、1MHzを8分周後、さらに250分周
して500Hzを生成します。
割込み関係コードは、以下。
#define CNTBEGIN 6
void interrupt(void)
{
/* generate 500Hz */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize (/250) */
TMR0 = CNTBEGIN ;
/* set flag */
eflag = ON ;
}
}
タイマーハンドラは、500Hzごとにイベントフラグeflag
で、main関数に指定時間経過を通知します。
10Hzは500Hzを50分周して生成しますが、25分周して20Hzにします。
20Hzで、出力ピンに0か1を印加します。
1Hzは500Hzを250分周して2Hzにします。
2Hzで、出力ピンに0か1を印加します。
mainの中にある無限ループ内で、次のコードで10Hz、1Hzを生成。
if ( eflag == ON ) {
/* clear flag */
eflag = OFF ;
/* counter increment */
xcnt++ ;
ycnt++ ;
/* generate 20Hz */
if ( xcnt == XCNTMAX ) {
xcnt = 0 ;
cnt10 = cnt10 + 1 ;
}
/* generate 2Hz */
if ( ycnt == YCNTMAX ) {
ycnt = 0 ;
cnt++ ;
}
/* impress */
OUT10 = cnt10 & ON ;
OUT1 = cnt & ON ;
}
20Hz、2Hzで担当するカウンタのLSBを出力して
いきます。
マニュアルクロックは、プッシュスイッチの状態を
読込んで、反転出力します。
チャタリングが発生しますが、出力にキャパシタを
接続して、波形をなまらせます。
該当コードは、以下としました。
/* get and mask */
tmp = GPIO & (1 << 5);
/* shift */
tmp >>= 5 ;
/* impress */
OUTM = !(tmp & ON) ;
ソースコードは、以下。
/* redefine data type */
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
#define OFF 0
#define ON OFF+1
#define MASK0F 0x0f
#define OUT10 GPIO.B0
#define OUT1 GPIO.B1
#define OUTM GPIO.B2
#define CNTBEGIN 6
#define XCNTMAX 25
#define YCNTMAX 250
volatile UBYTE eflag ;
volatile UBYTE tmp ;
volatile UBYTE xcnt ;
volatile UBYTE ycnt ;
volatile UBYTE cnt10 ;
volatile UBYTE cnt ;
/* function prototype */
void init_usr(void);
/* interrupt handler */
void interrupt(void)
{
/* generate 500Hz */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize (/250) */
TMR0 = CNTBEGIN ;
/* set flag */
eflag = ON ;
}
}
void main(void)
{
/* user initialize */
init_usr();
/* endless loop */
while ( ON ) {
/* generate 10Hz and 1Hz */
if ( eflag == ON ) {
/* clear flag */
eflag = OFF ;
/* counter increment */
xcnt++ ;
ycnt++ ;
/* generate 20Hz */
if ( xcnt == XCNTMAX ) {
xcnt = 0 ;
cnt10 = cnt10 + 1 ;
}
/* generate 2Hz */
if ( ycnt == YCNTMAX ) {
ycnt = 0 ;
cnt++ ;
}
/* impress */
OUT10 = cnt10 & ON ;
OUT1 = cnt & ON ;
}
/* manual clock generator */
{
/* get and mask */
tmp = GPIO & (1 << 5);
/* shift */
tmp >>= 5 ;
/* impress */
OUTM = !(tmp & ON) ;
}
}
}
/* define function body */
void init_usr(void)
{
/* I/O state */
GPIO = 0x00 ;
/* I/O directions */
TRISIO = 0x38 ; /* bit0,1,2 as output , others as input */
/* disable compare module */
CMCON = 0x07 ;
/* pull-up */
WPU = 0x30 ;
/* initialize Timer 0 */
{
/*
4MHz/4 = 1MHz -> 1MHz/8 = 125kHz prescaler = 1:8
*/
OPTION_REG = 0x02 ;
/* 256 - 6 = 250 */
TMR0 = CNTBEGIN ;
/* enable timer0 overflow interrupt */
INTCON.T0IE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* clear flag */
eflag = OFF ;
/* others */
xcnt = 0 ;
ycnt = 0 ;
cnt10 = 0 ;
cnt = 0 ;
}
基板上に実装すると、以下。
ヘッダピンをたてて、インバータに
2ピンワイヤーケーブルで接続します。
他にもマイコンを利用することがあるとして、GPIO4ピンから
クロックを出力します。
GPIO4ピンからのクロック出力を加えると、次のソースコード
になります。
/* redefine data type */
typedef unsigned char UBYTE ;
typedef unsigned int UWORD ;
#define OFF 0
#define ON OFF+1
#define MASK0F 0x0f
#define OUT10 GPIO.B0
#define OUT1 GPIO.B1
#define OUTM GPIO.B2
#define OUTX GPIO.B4
#define CNTBEGIN 6
#define XCNTMAX 25
#define YCNTMAX 250
volatile UBYTE eflag ;
volatile UBYTE tmp ;
volatile UBYTE xcnt ;
volatile UBYTE ycnt ;
volatile UBYTE zcnt ;
volatile UBYTE cnt10 ;
volatile UBYTE cnt ;
/* function prototype */
void init_usr(void);
/* interrupt handler */
void interrupt(void)
{
/* generate 500Hz */
if ( INTCON.T0IF == ON ) {
/* clear flag */
INTCON.T0IF = OFF ;
/* initialize (/250) */
TMR0 = CNTBEGIN ;
/* set flag */
eflag = ON ;
}
}
void main(void)
{
/* user initialize */
init_usr();
/* endless loop */
while ( ON ) {
/* generate 10Hz and 1Hz */
if ( eflag == ON ) {
/* clear flag */
eflag = OFF ;
/* counter increment */
xcnt++ ;
ycnt++ ;
zcnt++ ;
/* generate 20Hz */
if ( xcnt == XCNTMAX ) {
xcnt = 0 ;
cnt10 = cnt10 + 1 ;
}
/* generate 2Hz */
if ( ycnt == YCNTMAX ) {
ycnt = 0 ;
cnt++ ;
}
/* impress */
OUT10 = cnt10 & ON ;
OUT1 = cnt & ON ;
OUTX = zcnt & ON ;
}
/* manual clock generator */
{
/* get and mask */
tmp = GPIO & (1 << 5);
/* shift */
tmp >>= 5 ;
/* impress */
OUTM = !(tmp & ON) ;
}
}
}
/* define function body */
void init_usr(void)
{
/* I/O state */
GPIO = 0x00 ;
/* I/O directions */
TRISIO = 0x28 ; /* bit0,1,2,4 as output , others as input */
/* disable compare module */
CMCON = 0x07 ;
/* pull-up */
WPU = 0x20 ;
/* initialize Timer 0 */
{
/*
4MHz/4 = 1MHz -> 1MHz/8 = 125kHz prescaler = 1:8
*/
OPTION_REG = 0x02 ;
/* 256 - 6 = 250 */
TMR0 = CNTBEGIN ;
/* enable timer0 overflow interrupt */
INTCON.T0IE = ON ;
}
/* enable general interrupt */
INTCON.GIE = ON ;
/* clear flag */
eflag = OFF ;
/* others */
xcnt = 0 ;
ycnt = 0 ;
zcnt = 0 ;
cnt10 = 0 ;
cnt = 0 ;
}
目次
前
次