⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lampe.asm

📁 CCP1模块使用的有关PIC应用程序Trabicom On Board Engine Controller
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; ******************************************************************************
; * Programm zur Steuerung der Halogenlampe
; * erstellt im August 2002 von Hannes Studeny
; *
; * Taktrate: 4 MHz --> 1 Mio Befehle pro Sekunde -->  1 Befehl ben鰐igt 1 Microsekunde
; ******************************************************************************
; *
; * Funktionalit鋞:
; * ===============
; * an RA0 wird die Spannung des Akkus gemessen
; * an RC2 wird ein PWM Signal, in Abh鋘gigkeit der gemessenen Spannung, erzeugt.
; * an RB2 wird der Taster angeschlossen
; * mit dem Taster wird die Lampe durch einen langen Tastendruck (mehr als 5 Sekunden) ein- bzw. ausgeschaltet
; * wenn die Lampe eingeschaltet ist, kann durch kurze Tastendr點ke (1 bis 2,5 Sekunden) zwischen folgenden
; * Modi gewechselt werden:
; * 	100%
; * 	80%
; * 	50%
; * 	SOS
; *
; * am A/D Wandler k鰊nen Spannungen von 15V bis 10V gemessen werden
; * werden weniger als 11,3 Volt gemessen, wird die Lampe automatisch abgeschaltet (PWM wird auf 0% eingestellt).
; * werden mehr als 12 Volt gemessen, regelt der PWM Ausgang die Spannung auf 12 Volt herunter
; *
; *
; * Programmablauf:
; * ===============
; * zuerst wird das PWM-Modul und der AD-Wandler initialisiert
; * in einer Endlosschleife erfolgt folgende Verarbeitung:
; * 	1. die Akku-Spannung wird gemessen
; * 	2. der PWM Output wird angepasst
; * 	3. der Taster wird abgefragt und entsprechend verarbeitet
; *
; * die Ausgangsspannung vom OpAmp errechnet sich folgendermassen:
; *	Ua = 2/3*Ue - 5
; * 15V entsprechen 5V und 10V entsprechen 1,67V
; *
; * Ua = 5/256*ADRESH
; * Ue = (Ua+5)*3/2
; * PWM = 12 / Ue
; * CCPR1L = 249*PWM
; *

	list p=16f870
	include	"p16f870.inc"

;	__CONFIG	_CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_ON & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC

; #define DEBUG

; ****************
; *** Definitionen
; ****************

BIT_ARRAY		equ	0x20
CCPR1L_TMP		equ	0x21
SOS_COUNTER		equ	0x22
BIT_ARRAY2		equ	0x23
BLINK_COUNTER		equ	0x24
LOWBAT_COUNTER		equ	0x25

W_TEMP			equ	0x28
STATUS_TEMP		equ     0x2A
PCLATH_TEMP         	equ     0x2B
FSR_TEMP		equ     0x2C
COUNTER_TMR0		equ	0x2D

d1			equ	0x2E
d2			equ	0x2F
d3			equ	0x30

PIN_TASTER		equ	0
PWM_OUT			equ	2
ON_OFF			equ	3
LOWBAT			equ	4
BLINKEN			equ	5

LED_GREEN		equ	1
LED_RED			equ	2


BIT_LED100		equ	0
BIT_LED80		equ	1
BIT_LED50		equ	2
BIT_LEDSOS		equ	3
BIT_ONOFF		equ	4
BIT_TASTER		equ	5
BIT_TASTER_LONG		equ	6

BIT_BLINKEN		equ 	0
BIT_LOWBAT		equ	1

PROZENT_100		equ 	D'249'
PROZENT_80		equ	D'199'
PROZENT_50		equ 	D'125'

COUNTER_VALUE_BLINK	equ	D'40'
COUNTER_VALUE_LOWBAT	equ	D'30'

; Ziele
w	equ	 0		; W-Register ist Zielregister
f	equ	 1		; f-Register ist Zielregister

; *********************
; *** Macrodefinitionen
; *********************

BANK_0	macro			; Select Bank 0
	bcf	STATUS,RP0
	bcf	STATUS,RP1
	errorlevel +302
	endm

BANK_1	macro			; Select Bank 1
	bsf	STATUS,RP0
	bcf	STATUS,RP1
	endm

BANK_2	macro			; Select Bank 2
	bcf	STATUS,RP0
	bsf	STATUS,RP1
	endm

BANK_3	macro			; Select Bank 3
	bsf	STATUS,RP0
	bsf	STATUS,RP1
	endm

; *******************************************************
; *** hier beginnt das eigentliche Programm
; *******************************************************

	org		0x00
	goto		main
	org		0x04
; hier steht die Interruptroutine
	; PROLOG
	movwf	W_TEMP
	swapf	STATUS,w
	clrf	STATUS
	movwf	STATUS_TEMP
	movf	PCLATH,w
	movwf	PCLATH_TEMP
	clrf	PCLATH
	bcf	STATUS,IRP
	movf	FSR,w
	movwf	FSR_TEMP

	BANK_0

	btfsc	INTCON,T0IF
	call	TIMER0_INTERRUPT

	btfsc	INTCON,INTF
	call	PORT_CHANGE_INTERRUPT

	btfsc	PIR1,TMR1IF
	call	TEST_OP_AMP

INTERRUPT_EPILOG
	movf	PCLATH_TEMP,w
	movwf	PCLATH
	swapf	STATUS_TEMP,w
	movwf	STATUS
	swapf	W_TEMP,f
	swapf	W_TEMP,w
	retfie

main
; jetzt gehts erst so richtig los...


	BANK_1
	errorlevel -302
	bcf	TRISC,PWM_OUT	; 0...Output
	bcf	TRISC,ON_OFF
	bsf	TRISC,LOWBAT	; 1...Input
	bsf	TRISC,BLINKEN
	BANK_0

	call	LAMP_OFF

	clrf	PORTB         	; PORTB initialisieren
	clrf	BIT_ARRAY
	clrf	BIT_ARRAY2

	movlw	COUNTER_VALUE_BLINK
	movwf	BLINK_COUNTER
	movlw	COUNTER_VALUE_LOWBAT
	movwf	LOWBAT_COUNTER

 	call InitPwm

	BANK_1
	errorlevel -302
	clrf	TRISB			; alle Pins von PORTB ausser RB0 als Output definieren
	bsf	TRISB,PIN_TASTER	; 1...Input

	bcf	OPTION_REG,T0CS		; internal Cycle clock for Timer0
	bcf	OPTION_REG,NOT_RBPU     ; activate Pullups on RBx
	bcf	OPTION_REG,PSA		; assign prescaler to Timer0
	bcf	OPTION_REG,INTEDG	; Interrupt on falling edge of RB0
 ifdef DEBUG
	bsf	OPTION_REG,PSA	; assign prescaler to WDT
	bcf	OPTION_REG,PS2	; prescaler rate 1:1
	bcf	OPTION_REG,PS1
	bcf	OPTION_REG,PS0
 else
	bsf	OPTION_REG,PS2	; prescaler rate 1:256
	bsf	OPTION_REG,PS1
	bsf	OPTION_REG,PS0
 endif
	BANK_0

; ************ TIMER1 Initialisieren
	bsf	T1CON,TMR1ON	; Timer1 einschalten
	BANK_1
	bsf	PIE1,TMR1IE	; Timer1 Interrupt enablen
	BANK_0

	clrf	INTCON		; zuerst alle Interrupts deaktivieren und l鰏chen
	bsf	INTCON,INTE	; Interrupt an RB0 aktivieren
	bsf	INTCON,PEIE	; f黵 Timer1 Interrupt notwendig
	bsf	INTCON,GIE	; globales Interrupt enable Bit

	movlw	D'0'
	movwf	CCPR1L

	bsf	PORTB,LED_GREEN	; test
	call	Delay1
	bcf	PORTB,LED_GREEN	; test
	bsf	PORTB,LED_RED	; test
	call	Delay1
	bcf	PORTB,LED_RED	; test


LOOP
	; call	TEST_OP_AMP	wir als Interrupt gel鰏t

	btfsc	BIT_ARRAY2,BIT_BLINKEN
	call	LAMP_BLINKEN

	btfsc	BIT_ARRAY2,BIT_LOWBAT
	call	LAMP_LOWBAT

	btfss	BIT_ARRAY,BIT_ONOFF
	goto	LOOP

	btfsc	BIT_ARRAY,BIT_LEDSOS
	call	SOS_MODE

	btfss	BIT_ARRAY,BIT_ONOFF
	call	LAMP_OFF

	bcf	BIT_ARRAY,BIT_TASTER
	goto	LOOP


LAMP_LOWBAT
	bcf	INTCON,GIE	; keine Interrupts (Schalter) mehr zulassen
	bsf	PORTB,LED_RED
	call	RESET

	bsf	PORTB,LED_GREEN	; test
ENDE
	bcf	PORTB,LED_GREEN
	bcf	INTCON,GIE
	call	LAMP_OFF
	goto	ENDE


; *********************************************************************************
; * nur wenn der Schwellenwert 5 mal hintereinander unterschritten wird, gilt er...
; *********************************************************************************

TEST_OP_AMP
	bcf	PIR1,TMR1IF			; Interruptflag Timer0 wieder l鰏chen

	btfsc	PORTC,BLINKEN
	goto	TEST_OP_BLINKEN
	movlw	COUNTER_VALUE_BLINK
	movwf	BLINK_COUNTER

TEST_OP_AMP_1
	btfsc	PORTC,LOWBAT
	goto	TEST_OP_LOWBAT
	movlw	COUNTER_VALUE_LOWBAT
	movwf	LOWBAT_COUNTER

TEST_OP_AMP_2
	btfsc	BIT_ARRAY,BIT_LEDSOS		; bei SOS gibt es kein Blinken wegen Low-Bat
	bcf	BIT_ARRAY2,BIT_BLINKEN

	return


TEST_OP_BLINKEN
	decfsz	BLINK_COUNTER,f
	goto	TEST_OP_AMP_1
	bsf	BIT_ARRAY2,BIT_BLINKEN
	goto	TEST_OP_AMP_1


TEST_OP_LOWBAT
	decfsz	LOWBAT_COUNTER,f
	goto	TEST_OP_AMP_2
	bsf	BIT_ARRAY2,BIT_LOWBAT
	goto	TEST_OP_AMP_2


; **************************************************************************************

LAMP_BLINKEN
	bsf	PORTB,LED_GREEN
	btfss	BIT_ARRAY,BIT_ONOFF	; Lampe ist ausgeschaltet
	return

	call	LAMP_OFF

	call	Delay10

	call	LAMP_ON
	call 	Delay1
	call	TEST_OP_AMP
	call 	Delay1
	call	TEST_OP_AMP
	call 	Delay1
	call	TEST_OP_AMP

	return


;************************************************
;* Lampe ausschalten
;************************************************
LAMP_OFF
	bsf	PORTC,ON_OFF	; Lampe ausschalten
	return

;************************************************
;* Lampe einschalten
;* PWM wird eingeschaltet und mit dem Wert vom CCPR1L_TMP initialisiert
;************************************************
LAMP_ON
	movlw	D'0'
	movwf	CCPR1L		; CCPR1L = 0%
	call	Delay1000	; ein bisschen warten, damit sich die PWM einstellen kann
	bcf	PORTC,ON_OFF	; Lampe mit Softstart einschalten

	call	SOFTSTART	; Lampe sanft hochfahren
	return

;************************************************
;* in einer Schleife wird das Tastverh鋖tnis von 0% bis auf
;* den in CCPR1L_TMP vorhandenen Wert gesteigert
;* daf黵 werden ca. 250 ms ben鰐igt.
;************************************************
SOFTSTART
	movlw	D'0'
	movwf	CCPR1L		; CCPR1L = 0%

SOFTSTART_LOOP
	incf	CCPR1L,f
	incf	CCPR1L,f
 ifdef 	DEBUG
	movlw	D'250'
	movwf	CCPR1L
 else
	call	Delay1000
 endif
	movf	CCPR1L,w
 	subwf	CCPR1L_TMP,w	; w = CCPR1L_TMP - w
	btfsc	STATUS,C
	goto	SOFTSTART_LOOP

	movf	CCPR1L_TMP,w
	movwf	CCPR1L		; urspr黱glichen Wert von CCPR1L wieder herstellen
	return


SOS_MODE
	movlw	3
	movwf	SOS_COUNTER
SOS_MODE_1
	call	PAUSE_SHORT
	btfsc	BIT_ARRAY,BIT_TASTER
	goto 	SOS_MODE_ENDE		; Taster wurde gedr點kt
	call	PAUSE_LONG		; lang
	btfsc	BIT_ARRAY,BIT_TASTER
	goto 	SOS_MODE_ENDE		; Taster wurde gedr點kt

	decfsz	SOS_COUNTER,f
	goto	SOS_MODE_1

	movlw	3
	movwf	SOS_COUNTER
SOS_MODE_2
	call	PAUSE_SHORT
	btfsc	BIT_ARRAY,BIT_TASTER
	goto 	SOS_MODE_ENDE		; Taster wurde gedr點kt

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -