Programació en mpasm del PIC 16F690

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Dau electrònic

Programa del grup 3

El programa del grup 3 té present la posició del potenciòmetre per escollir entre dos modes de funcionament. En el primer mode, quan es prem el polsador presenta el número que ha triat aleatòriament entre 1 i 6 mentre sona una melodia. Un cop finalitzada la melodia, els LED romanen indicant el número i espera que es premi altre cop el polsador.

En el segon mode, quan es prem el polsador mostra una seqüència amb els LED i després presenta el número que ha triat aleatòriament entre 1 i 9. Els LED romanen indicant el número i espera que es premi altre cop el polsador.

El programa d'aquest grup és el següent:

#include <p16F690.inc>
	__config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
	cblock 0x20
Visualit	; Una variable on guardem el que mostraran els LED
Nombre
Retard1		; Variables de retard
Retard2
Ret
Analogica	; Variable on es guarda el valor de l'entrada analògica
Mode1		; Variables on es guarda la configuració de bits necessària
Mode2		; per encendre els LED quan es mostren els números.
Mode3
Mode4
ValPR2		; Aquí hi guardarem el valor de PR2
ValCCPR1L	; Aquí hi guardarem el valor de CCPR1L
ValDC1B		; Aquí hi guardarem el valor de DC1B
ValCCP1CON	; Aquí hi guardarem el valor de CCP1CON
	endc
	org 0
Inici
	bsf		STATUS,RP0	; Tria el banc 1
	movlw		b'10000000' 	; Configuració de Timer0
	movwf		OPTION_REG	; Ho guarda al registre de configuració del Timer0
	clrf		TRISB		; Posa el port B com a sortida
	clrf		TRISC		; Posa el port C com a sortida
	movlw		0xFF		; Posa l'acumulador a FFh (tot uns)
	movwf		TRISA		; Posa tots els bits del port A com a entrada
	movlw		b'00010000'	; Posa el conversor a 1/8 de la freqüència
	movwf		ADCON1		; Copia W a la configuració del conversor A/D
	movlw		b'00100000'	; Definim com volem les E/S del port C
	movwf		TRISC		; RC5 (sortida del PWM) com a entrada
	bcf		STATUS,RP0
	bsf		STATUS,RP1	; Tria el banc 2
	movlw		0xFF		; Posa l'acumulador a FFh (tot uns)
	movwf		ANSEL		; Configura AN0-AN7 com entrades analògiques
	bcf		STATUS,RP0
	bcf		STATUS,RP1	; Tria el banc 0
	movlw		b'00000001'	; activa el conversor A/D connectat a AN0
	movwf		ADCON0		; amb el resultat justificat per l'esquerra
	clrf		PORTB
	clrf		PORTC
	movlw		b'00000000'
	movwf		Mode1
	movwf		Mode2
	movwf		Mode3
	movwf		Mode4
	movlw		b'00001100'	; Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill
					; DC1B = 00 (bits 5-4) els dos bits de menys pes són 0
					; CCP1M = 11xx en mode senzill els bit 0 i 1 no afecten
	movwf		ValCCP1CON	; Ho guarda per fer-ho servir més tard
	movwf		CCP1CON		; Ho posa com a configuració del PWM
	movlw		b'00000011'	; Configura el Timer 2
					; bits T2KCPS (bits 1-0) a 11 prescalat de 16
					; bit 2 (TMR2ON) a 0, Timer aturat
					; Postscaler TOUTPS (bits 6-3) no afecten al PWM
	movwf		T2CON		; Ho posa com a configuració del Timer 2
Polsador
	movf		Mode1,w
	movwf		PORTB		; Posa Mode1 al port B (1)
	movf		Mode3,w
	movwf		PORTC		; Posa Mode3 al port C (2)
	nop
	nop
	nop
	movf		Mode2,w
	movwf		PORTB		; Posa Mode2 al port B / Mode 1 hi ha estat durant 4 us (microsegons)
	movf		Mode4,w
	movwf		PORTC		; Posa Mode4 al port C / Mode 3 hi ha estat durant 4 us
	btfsc		PORTA,3
	goto		Polsador	; Torna a Polsador
	clrf		PORTB
	clrf		PORTC
	call		RetM
Pols
	btfss		PORTA,3		; Mira si està desactivada l'entrada A3
					; Si està desactivada, no fa la instrucció següent
					; Fa la instrucció si l'entrada està activada
	goto		Pols		; Si no està premut, torna a Polsador
	call		RetM
	nop				; espera un microsegon
	nop				; espera un microsegon
	nop				; espera un microsegon
	nop				; espera un microsegon
	nop				; espera un microsegon, en total 5
	bsf		ADCON0,GO	; Inicia la conversió
	btfsc		ADCON0,GO	; Quan el bit sigui 0 la conversió haurà acabat
	goto		$-1		; repetim la línia fins que deixi de ser 1
	movf		ADRESH,w	; Permuta els nibbles dels bits superiors
	movwf		Analogica
	movlw		b'01111110'
	subwf		Analogica,w	; W = variable - W, C = 1 si variable >= W
	btfss		STATUS,C	; Si C=1 salta
	goto		GenerarSis	; si Analogica < 126 va a GenerarSis
	goto		Generar		; si Analogica >= 126 va a Generar (bucle que genera números de 1 a 9)
GenerarSis				; Genera números de l'1 al 6
	movf		TMR0,w
	andlw		b'00000111'
	movwf		Nombre
	movlw		b'00000110'
	subwf		Nombre,w	; W = variable - W, C = 1 si variable >= W
	btfss		STATUS,C	; Si C=1 salta
	goto		seq1		; si Nombre < 6 va a seq1 (seqüència musical)
	goto		GenerarSis	; si el Nombre >= 6 agafa un altre número
seq1
	movlw		.141		; Valor que correspon aproximadament a re3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.71		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.0		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaCorxera	; Toca la nota configurada
	movlw		.158		; Valor que correspon aproximadament a do3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.79		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.2		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaSemiCorxera	; Toca la nota configurada
	movlw		.158		; Valor que correspon aproximadament a do3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.79		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.2		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaSemiCorxera	; Toca la nota configurada
	movlw		.141		; Valor que correspon aproximadament a re3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.71		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.0		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaCorxera	; Toca la nota configurada
	movlw		.158		; Valor que correspon aproximadament a do3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.79		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.2		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaCorxera	; Toca la nota configurada
	call		RetM
	movlw		.126		; Valor que correspon aproximadament a fa3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.63		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.2		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaCorxera	; Toca la nota configurada
	movlw		.118		; Valor que correspon aproximadament a sol3
	movwf		ValPR2		; Ho posem com a valor de PR2
	movlw		.59		; Valor que correspon a un cicle del 50 %
	movwf		ValCCPR1L	; Valor de CCPR1L
	movlw		.2		; Valor dels bits de menys pes del CCP
	movwf		ValDC1B		; Valor de DC1B
	call		TocaCorxera	; Toca la nota configurada
	call		RetM		; Espera 0,2
	goto		Visualitzar
seq2
	movlw		b'01000000'
	movwf		PORTB
	call		RetM
	clrf		PORTB
	movwf		PORTC
	call		RetM
	clrf		PORTC
	movlw		b'10010000'
	movwf		PORTB
	call		RetM
	clrf		PORTB
	movlw		b'01010000'
	movwf		PORTC
	call		RetM
	clrf		PORTC
	movlw		b'10000000'
	movwf		PORTB
	call		RetM
	clrf		PORTB
	movwf		PORTC
	call		RetM
	clrf		PORTC
	movlw		b'01010000'
	movwf		PORTB
	call		RetM
	clrf		PORTB
	movlw		b'10010000'
	movwf		PORTC
	call		RetM
	clrf		PORTC
	goto		Visualitzar
Generar					; Genera números de l'1 al 9
	movf		TMR0,w
	andlw		b'00001111'
	movwf		Nombre
	movlw		b'00001001'
	subwf		Nombre,w	; W = variable - W, C = 1 si variable >= W
	btfss		STATUS,C	; Si C=1 salta
	goto		seq2		; si Nombre < 9 va a seq 2 (seqüència lumínica)
	goto		Generar		; si el Nombre >= 9 agafa un altre número
Visualitzar
	movlw		b'00001000'
	xorwf		Nombre,w	; Compara Nombre amb 8, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Nou
	movlw		b'00000111'
	xorwf		Nombre,w	; Compara Nombre amb 7, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Vuit
	movlw		b'00000110'
	xorwf		Nombre,w	; Compara Nombre amb 6, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Siete
	movlw		b'00000101'
	xorwf		Nombre,w	; Compara Nombre amb 5, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Sis
	movlw		b'00000100'
	xorwf		Nombre,w	; Compara Nombre amb 4, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Cinc
	movlw		b'00000011'
	xorwf		Nombre,w	; Compara Nombre amb 3, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Quatre
	movlw		b'00000010'
	xorwf		Nombre,w	; Compara Nombre amb 2, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Tres
	movlw		b'00000001'
	xorwf		Nombre,w	; Compara Nombre amb 1, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Dos
	movlw		b'00000000'
	xorwf		Nombre,w	; Compara Nombre amb 0, si son iguals s'activa Z
	btfsc		STATUS,Z	; Si no son iguals salta
	goto		Un
Un
	movlw		b'00100000'
	movwf		Mode1
	movwf		Mode2
	movlw		b'00000000'
	movwf		Mode3
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Dos
	movlw		b'11000000'
	movwf		Mode1
	movwf		Mode2
	movlw		b'00000000'
	movwf		Mode3
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Tres
	movlw		b'11100000'
	movwf		Mode1
	movwf		Mode2
	movlw		b'00000000'
	movwf		Mode3
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Quatre
	movlw		b'11000000'
	movwf		Mode1
	movlw		b'00010000'
	movwf		Mode2
	movlw		b'00000000'
	movwf		Mode3
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Cinc
	movlw		b'11000000'
	movwf		Mode1
	movlw		b'00110000'
	movwf		Mode2
	movlw		b'00000000'
	movwf		Mode3
	movwf		Mode4
	goto		Polsador	; Torna a polsador
Sis
	clrf		PORTC
	movlw		b'11000000'
	movwf		Mode1
	movlw		b'00010000'
	movwf		Mode2
	movwf		Mode3
	movlw		b'00000000'
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Siete
	movlw		b'11100000'
	movwf		Mode1
	movlw		b'00010000'
	movwf		Mode2
	movwf		Mode3
	movlw		b'00000000'
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Vuit
	movlw		b'11000000'
	movwf		Mode1
	movwf		Mode3
	movlw		b'00010000'
	movwf		Mode2
	movwf		Mode4
	goto		Polsador	; Torna al polsador
Nou
	movlw		b'11000000'
	movwf		Mode1
	movwf		Mode3
	movlw		b'00110000'
	movwf		Mode2
	movwf		Mode4
	goto		Polsador	; Torna al polsador
RetM					; Funció de retard de 0,2 s
	decfsz		Retard1,f
	goto		RetM
	decfsz		Retard2,f
	goto		RetM
	return
corxera
	decfsz		Retard1,f
	goto		corxera
	decf		Retard2,f
	decfsz		Retard2,f
	goto		corxera
	return
semicorxera
	decfsz		Retard1,f
	goto		semicorxera
	decf		Retard2,f
	decf		Retard2,f
	decf		Retard2,f
	decfsz		Retard2,f
	goto		semicorxera
	return
TocaSemiCorxera
	movf		ValPR2,w	; Valor de PR2 per a la nota desitjada
	bsf		STATUS,RP0	; Tria el banc 1
	bsf		TRISC,5		; Posem RC5 (sortida del PWM) com a entrada
	movwf		PR2		; Ho posem com a comparació al Timer 2
	bcf		STATUS,RP0	; Tria el banc 0
	movf		ValCCP1CON,w	; Agafa la configuració de CCP1CON
	andlw		b'11001111'	; Posa els bits que corresponen a DC1B a zero per precaució
	movwf		ValCCP1CON	; I ho torna a guardar
	swapf		ValDC1B,w	; Agafa el valor que ha d'anar a DC1B
					; I el guarda, permutat, a W
					; Els dos bits han de quedar a les posicions 4-5
	andlw		b'00110000'	; Posa els altres sis bits a zero per precaució
	iorwf		ValCCP1CON,w	; I ho afegeix a CCP1CON
	movwf		CCP1CON		; Ho posa com a configuració del PWM
	movf		ValCCPR1L,w	; Valor de CCPR1L
	movwf		CCPR1L		; Registre que ens dona l'amplada de tON
	bcf		PIR1,TMR2IF	; Desactiva el bit d'interrupció del Timer 2
	bsf		T2CON,TMR2ON	; Activa el Timer 2
					; No convé engegar el PWM fins que el Timer 2 no ha fet un cicle
	btfss		PIR1,TMR2IF	; Espera l'activació del bit d'interrupció del Timer 2
	goto		$-1
	bsf		STATUS,RP0	; Tria el banc 1
	bcf		TRISC,5		; Posem RC5 (sortida del PWM) com a sortida
	bcf		STATUS,RP0	; Tria el banc 0
	call		semicorxera	; Espera
	bsf		STATUS,RP0	; Tria el banc 1
	bsf		TRISC,5		; Posem RC5 (sortida del PWM) com a entrada
					; Fem silenci
	bcf		STATUS,RP0	; Tria el banc 0
	call		semicorxera	; Espera
	return
TocaCorxera
	movf		ValPR2,w	; Valor de PR2 per a la nota desitjada
	bsf		STATUS,RP0	; Tria el banc 1
	bsf		TRISC,5		; Posem RC5 (sortida del PWM) com a entrada
	movwf		PR2		; Ho posem com a comparació al Timer 2
	bcf		STATUS,RP0	; Tria el banc 0
	movf		ValCCP1CON,w	; Agafa la configuració de CCP1CON
	andlw		b'11001111'	; Posa els bits que corresponen a DC1B a zero per precaució
	movwf		ValCCP1CON	; I ho torna a guardar
	swapf		ValDC1B,w	; Agafa el valor que ha d'anar a DC1B
					; I el guarda, permutat, a W
					; Els dos bits han de quedar a les posicions 4-5
	andlw		b'00110000'	; Posa els altres sis bits a zero per precaució
	iorwf		ValCCP1CON,w	; I ho afegeix a CCP1CON
	movwf		CCP1CON		; Ho posa com a configuració del PWM
	movf		ValCCPR1L,w	; Valor de CCPR1L
	movwf		CCPR1L		; Registre que ens dona l'amplada de tON
	bcf		PIR1,TMR2IF	; Desactiva el bit d'interrupció del Timer 2
	bsf		T2CON,TMR2ON	; Activa el Timer 2
					; No convé engegar el PWM fins que el Timer 2 no ha fet un cicle
	btfss		PIR1,TMR2IF	; Espera l'activació del bit d'interrupció del Timer 2
	goto		$-1
	bsf		STATUS,RP0	; Tria el banc 1
	bcf		TRISC,5		; Posem RC5 (sortida del PWM) com a sortida
	bcf		STATUS,RP0	; Tria el banc 0
	call		corxera		; Espera
	call		semicorxera
	bsf		STATUS,RP0	; Tria el banc 1
	bsf		TRISC,5		; Posem RC5 (sortida del PWM) com a entrada
					; Fem silenci
	bcf		STATUS,RP0	; Tria el banc 0
	call		corxera		; Espera
	return

	end

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.