使用单片机来作为脉冲源的好处

在定时应用中,时基电路555似乎非常合适。但在实际产品的内部电路中,却很少见到555的影子。为什么呢?根据在SUNIST实验室恶劣电磁环境下的实际经验来看,555薄弱的抗干扰能力是其致命的一环。

555作为单稳态应用,输入触发为下降沿,大多经过了微分处理,抗干扰措施很难加入。即使是触发信号前级采用光耦、继电器等防止信号串入,在恶劣的电磁环境下(比如SUNIST实验室,非常多的大电流接触器),无法避免误触发的现象。

SUNIST实际采用的控制机柜里,都采用了复杂的J-K触发器来防止误触发。

但是,如果采用单片机,比如摩托罗拉(飞斯卡尔)的MC68HC908GP32,很便宜,其触发引脚都有非常好的防抖动抑制功能,并且,可以非常方便地在程序内部加入假信号的判断和处理,循环、单次工作方式可任意选择,脉宽和延时也都可以方便地设定,非常不错。

下面是一个高压调制器的长短脉冲控制器的MC68HC908GP32汇编语言源程序:

**=========Registers
PORTA		EQU	$0000	;PORT A(0) : OUTPUT
DDRA		EQU	$0004
PORTB		equ	$0001	;PORT B(0) : OUTPUT
DDRB		equ	$0005
PORTC		equ	$0002	;PORT C(0) : INPUT ( LONG OR SHORT PULSE )
				;PORT C(1) : INPUT ( SHORT CIRCUIT OCCURED )
DDRC		equ	$0006

INTSCR		equ	$001D	;IRQ Status and Control Register

*
BEGIN		equ	$8000
*
**=========Main Program
*
		ORG	BEGIN
INIT:
*
*=========initialize for main program========
*
	SEI			;DISABLE INTERRUPT

	MOV	#$FF,DDRA
	MOV	#$FF,DDRB
	MOV	#$00,DDRC

	BCLR	0,PORTA		;OUTPUT LOW
	BCLR	0,PORTB

	BSET	1,PORTA		;CLEAR ERROR STATE, SET BIT TO TURN OFF THE LED
	BSET	1,PORTB

	LDA	#$01		;ENABLE IRQ INTERRUPT WITH EDGE TRIGGER AND LEVEL TRIGGER
	STA	INTSCR

	CLI

START:
	LDA	#$01		;TEST THE FIRST BIT OF PORTC
	BIT	PORTC		;DETERMINE LONG OR SHORT PULSE REGIME
	BNE	LONG		;IF Z!=0, LONG PULSE REGIME

SHORT:
	SEI			;SHORT PULSE REGIME, DISABLE IRQ INTERRUPT

	LDHX	#0000		;CLEAR TIME COUNTER

	BSET	0,PORTA		;OUTPUT HIGH
	BSET	0,PORTB

S_T_H_LOOP:
	LDA	#$02		;TEST THE 2ND BIT OF PORTC
	BIT	PORTC		;DETERMINE IF SHORT CIRCUIT OCCURED
	BNE	EMERGENCY	;IF Z!=0, SHORTED!

	AIX	#1		;INCREASE H:X
	CPHX	#S_T_H
	BLO	S_T_H_LOOP	;LESS THAN S_T_H, INCREASE NEXT

	LDHX	#0000		;CLEAR TIME COUNTER

	BCLR	0,PORTA		;OUTPUT LOW
	BCLR	0,PORTB

S_T_L_LOOP:
	AIX	#1		;INCREASE H:X
	CPHX	#S_T_L
	BLO	S_T_L_LOOP	;LESS THAN S_T_L, INCREASE NEXT

        BRA     START		;RETURN TO THE MAIN RUNNING LOOP

LONG:
	BRA	START		;RETURN TO THE MAIN RUNNING LOOP

*
*=========   ISR_IRQ    ========
*
ISR_IRQ:			;IRQ INTERRUPT SERVICE

	SEI
	LDA	#$03		;DISABLE IRQ INTERRUPT
	STA	INTSCR

	LDHX	#0000		;CLEAR TIME COUNTER

	BSET	0,PORTA		;OUTPUT HIGH
	BSET	0,PORTB

L_T_H_LOOP:

*	LDA	#00
*INNER_1:
*	INCA
*	CMP	#TIMES
*	BLO	INNER_1

	LDA	#$02		;TEST THE 2ND BIT OF PORTC
	BIT	PORTC		;DETERMINE IF SHORT CIRCUIT OCCURED
	BNE	EMERGENCY	;IF Z!=0, SHORTED!

	AIX	#1		;INCREASE H:X
	CPHX	#L_T_H
	BLO	L_T_H_LOOP	;LESS THAN L_T_H, INCREASE NEXT

	BCLR	0,PORTA		;OUTPUT LOW
	BCLR	0,PORTB

L_T_L_LOOP:			;ADD A LOW LEVEL AFTER OUTPUT
	LDA	#00
INNER_2:
	INCA
	CMP	#TIMES
	BLO	INNER_2
	AIX	#1		;INCREASE H:X
	CPHX	#L_T_L
	BLO	L_T_L_LOOP	;LESS THAN L_T_L, INCREASE NEXT

	LDA	#$01		;ENABLE IRQ INTERRUPT
	STA	INTSCR

	CLI
	RTI

EMERGENCY:
	BCLR	0,PORTA		;OUTPUT LOW FIRST
	BCLR	0,PORTB

	BCLR	1,PORTA		;SET ERROR STATE, SET LOW TO TURN ON THE LED
	BCLR	1,PORTB

	LDA	#$03		;DISABLE IRQ INTERRUPT
	STA	INTSCR

	

*
*=========   Vector Table   ==========
*
	        ORG     $DFFA
IRQ_VECTOR	DW      ISR_IRQ
		ORG	$DFFE
RESET_VECTOR	DW	INIT
*
*=========   DATA STORE   ==========
*
S_T_H		EQU	$0013	;SHORT PULSE WIDTH, 70us
S_T_L		EQU	$30C2	;SHORT PULSE INTERVAL, 40ms
L_T_H		EQU	$0270	;LONG PULSE WIDTH, 4.2ms
L_T_L		EQU	$FFFF	;LONG PULSE WIDTH, 25000*0.4us=10ms
TIMES		EQU	$0F