Sie sind auf Seite 1von 24

TALLER DE MICROCONTROLADORES

Juan David Solarte Moreno


4 de marzo de 2020

1. Describa brevemente las arquitecturas. Realice


un esquema explicando las diferencias en los mi-
crocontroladores.
Von Neumann.
Harvard.

Figura 1: Arquitectura von Neumann. Fuente propia

Figura 2: Arquitectura Harvard. Fuente propia

1
Arquitectura Von Neumannn:
La unidad central de proceso (CPU), está conectada a una memoria prin-
cipal única (casi siempre sólo RAM) donde se guardan las instrucciones
del programa y los datos. A dicha memoria se accede a través de un sis-
tema de buses único (control, direcciones y datos).
El tamaño de la unidad de datos o instrucciones está fijado por el ancho
del bus que comunica la memoria con la CPU. Ası́ un microprocesador de
8 bits con un bus de 8 bits, tendrá que manejar datos e instrucciones de
una o más unidades de 8 bits (bytes) de longitud. Si tiene que acceder a
una instrucción o dato de más de un byte de longitud, tendrá que realizar
más de un acceso a la memoria.
El tener un único bus hace que el microprocesador sea más lento en su
respuesta, ya que no puede buscar en memoria una nueva instrucción
mientras no finalicen las transferencias de datos de la instrucción ante-
rior.
Arquitectura Harvard:
Tiene la unidad central de proceso (CPU) conectada a dos memorias (una
con las instrucciones y otra con los datos) por medio de dos buses dife-
rentes.
Una de las memorias contiene solamente las instrucciones del progra-
ma (Memoria de Programa), y la otra sólo almacena datos (Memoria de
Datos).

Ambos buses son totalmente independientes lo que permite que la CPU


pueda acceder de forma independiente y simultánea a la memoria de
datos y a la de instrucciones. Como los buses son independientes éstos
pueden tener distintos contenidos en la misma dirección y también dis-
tinta lóngitud. Tambien la longitud de los datos y las instrucciones puede
ser distinta, lo que optimiza el uso de la memoria en general.

2. Explique cada uno de los siguientes registros, in-


cluyendo cada uno de sus bits.
STATUS.

TRISX.
PORTX
OPTION REG

INT CON
ADC CON

2
2.1. STATUS
Es un registro del programa para dar informacinón de los pines en ejecu-
ción. El registro STATUS contiene: el estado aritmético de datos en el registro
W, el estado RESET, los bits para seleccionar el banco para los datos de la me-
moria.

Figura 3: Registro STATUS

2.2. TRISX y PORTX


Se utiliza TRISX para configurar el PUERTO respectivo como salida o en-
trada, Se utiliza PORTX para leer y escribir los datos desde para los pines del
puerto.

El puerto PORTA es un puerto bidireccional, de 8 bits de anchura. Los


bits de los registros TRISA y ANSEL controlan los pines del PORTA. To-
dos los pines del PORTA se comportan como entradas/salidas digitales.
Cinco de ellos pueden ser entradas analógicas (denotadas por AN):

Figura 4: Puerto PORTA y registro TRISA

El puerto PORTB es un puerto bidireccional, de 8 bits de anchura. Los


bits del registro TRISB determinan la función de sus pines.

3
Figura 5: Puerto PORTA y registro TRISA

2.3. OPTION REG


Configura al TMR0 para que trabaje como temporizador ó contador y asig-
na el valor al prescale (divisor de frecuencia programable). El registro OP-
TION REG contiene varios bits de control para configurar el pre - escalador
del Temporizador 0/WDT, el temporizador Timer0, la interrupción externa y
las resistencias pull-up en el puerto PORTB.

Figura 6: Registro OPTION REG

2.4. INT CON


Da información mediante el bit TOIF cuando el TMR0 se ha desbordado.
El registro INTCON contiene varios bits de habilitación y de bandera para el
desbordamiento en el registro TMR0, e interrupciones por el cambio del estado
en el puerto PORTB y las interrupciones externas en el pin INT.

Figura 7: Registro INT CON

4
2.5. ADC CON
Un ADC convierte mide el voltaje V en un pin (que tendrá que estar decla-
rado como entrada con el correspondiente registro TRISA) y lo convierte en un
número. El voltaje se mide en referencia a un voltaje mı́nimo, Vref(-) , y a un
voltaje máximo, Vref (+):

3. Describa las siguientes instrucciones, su signifi-


cado y aplicación.
3.1. ORG
Esta instrucción es un directiva y se usa para la dirección de inicio del pro-
grama.

3.2. MOVLW
Carga un numero en el acumulador W.
El numero que se va a cargar en al acumulador se puede representar por un
numero puede escribirse en decimal, hexadecimal o binario.

Ejemplo:
MOVLW d’255’ en decimal
MOVLW 0xFF en hexadecimal
MOVLW b’11111111’ en binario

3.3. MOVF f,d


Mueve una copia del registro f al destino d.
El destino puede ser:
Si d=0 el destino es el acumulador.
Mueve una copia del registro f al Acumulador W
Si d=1 el destino es el registro f.
Ejemplo:
MOVF Contador,W

3.4. MOVFWF f
Mueve una copia del acumulador W al registro.
Ejemplo:
MOVWF TRISA

3.5. EQU
Asigna un nombre simbólico al valor de una expreción.
Ejemplo:

LCD LINEA2 EQU 0C0


LCD CLR EQU 01

5
3.6. BCF f,b
Pone en cero el bit b del file f .
Los bits del registro f se numeran de 0 a 7.
Ejemplo:
BCF PORTB,0

3.7. BSF f,b


Pone en uno el bit b del file f.
Ejemplo:
BSF PORTB,0

3.8. BTFSS f,b


Prueba el bit b del registro f.
Salta la siguiente instrucción si bit b es 1.
Ejemplo:
BTFSS PORTA,0

3.9. BTFSC f,b


Prueba el bit b del registro f.
Salta la siguiente instrucción si bit b es 0.
Ejemplo:
BTFSC PORTA,0

3.10. DECFSZ f.d


Decrementa el registro f.
Salta la siguiente instrucción si el resultado es 0 El resultado de la operación
se coloca en el destino d.
Ejemplo
DECFSC Contador,f ; decrementa Contador.

3.11. CLRF f
El contenido del registro f se pone en ceros: 0x00.
Ejemplo:
CLRF portb

3.12. RLF f.d


Rota el contenido del registro f una posición a la izquierda.
El bit se rota a través de la bandera. La bandera carry esta en el bit 0 del registro
STATUS, que se localiza en la posición 0x03 de la memoria del microcontrola-
dor. Cada vez que se ejecuta la instrucción los bits se rotan una posición a la
izquierda, el bit menos significativo es ocupado por el contenido de la bandera
carry y el bit más significativo pasa a ocupar el lugar de la bandera.

6
El resultado de la operación se coloca en el destino d. Ejemplo:
RLF Contador,f

3.13. RRF f.d


Rota el contenido del registro f una posición a la derecha.
El bit se rota a través de la bandera. Cada vez que se ejecuta la instrucción los
bits se rotan una posición a la derecha, el bit más significativo es ocupado por
el contenido de la bandera carry y el bit menos significativo pasa a ocupar el
lugar de la bandera carry.
El resultado de la operación se coloca en el destino d.
Ejemplo:
RRF Contador,f

3.14. GOTO k
Salta a la etiqueta k. GOTO UNO

3.15. CALL k
Salta a una subrutina en la etiqueta k.
Ejemplo:
CALL bucle

3.16. RETLW k
Regresa de una subrutina. Con el numero k en el acumulador

3.17. RETFIE
Regresa de una interrupción.

3.18. ADDLW k
Suma el contenido del acumulador W con el numero k.

4. Desarrollar un proyecto para implementar un con-


tador hasta 99 en asm
Este proyecto consiste en generar un algoritmo en ASM que de un conteo
de 0 hasta 99.
este código es para los comandos de la LCD.

LCD LINEA1 EQU 80


LCD LINEA2 EQU 0C0
LCD CLR EQU 01
LCD CASA EQU 02
LCD INC EQU 06
LCD DEC EQU 04

7
LCD ON EQU 0C
LCD OFF EQU 08
CURSOR ON EQU 0E
CURSOR OFF EQU 0C
CURSOR PARP EQU 0F
LCD IZDA EQU 18
LCD DECHA EQU 1C
CURSOR IZDA EQU 10
CURSOR DECHA EQU 14
LCD FUNCION EQU 38
LCD CGRAM EQU 40
Para la localización de los caracteres en la LCD se utiliza los comandos de
la LCD.
ORG 0
INICIO
bsf STATUS , RP0
bcf STATUS , RP1

movlw b ’00011000 ’ ;CARGA AL REGISTRO W


movwf TRISA

clrf TRISB

bcf STATUS , RP0


bcf STATUS , RP1

clrf PORTA
clrf PORTB
movlw LCD FUNCION
call LCD COMANDO
call PAUSA 5ms
movlw LCD FUNCION
call LCD COMANDO
call PAUSA 5ms
movlw LCD FUNCION
call LCD COMANDO
call PAUSA 5ms
movlw LCD CLR
call LCD COMANDO
movlw LCD INC
call LCD COMANDO
movlw LCD ON
call LCD COMANDO
movlw 80
call LCD COMANDO
ver
movlw 80
call LCD COMANDO
movlw ’C’

8
call LCD CARACTER
movlw ’O’
call LCD CARACTER
movlw ’N’
call LCD CARACTER
movlw ’T ’
calL LCD CARACTER
movlw ’A’
calL LCD CARACTER
movlw ’D’
call LCD CARACTER
movlw ’O’
call LCD CARACTER
movlw ’R ’
call LCD CARACTER
para comenzar el conteo se crea la etiqueta, por ejemplo CERO y UNO luego
se utiliza GOTO para saltar de etiqueta, con la posición .OCO.en la LCD de la
esquina izquierda donde aparece el numero, y ası́ sucesivamente hasta 99.
CERO
movlw 0C0
call LCD COMANDO
movlw ’0 ’
call LCD CARACTER
movlw ’0 ’
call LCD CARACTER
BTFSS PORTA, 3
GOTO CERO
GOTO UNO
UNO
movlw 0C0
call LCD COMANDO
movlw ’0 ’
call LCD CARACTER
movlw ’1 ’
call LCD CARACTER
BTFSS PORTA, 3
GOTO UNO
GOTO DOS
DOS
movlw 0C0
call LCD COMANDO
movlw ’0 ’
call LCD CARACTER
movlw ’2 ’
call LCD CARACTER
BTFSS PORTA, 3
GOTO DOS
GOTO TRES
TRES

9
movlw 0C0
call LCD COMANDO
movlw ’0 ’
call LCD CARACTER
movlw ’3 ’
call LCD CARACTER
BTFSS PORTA, 3
GOTO TRES
GOTO CUATRO

Figura 8: Contador en ASM en Proteus. Fuente propia

El código es en ensamblador desde Proteus. esta en anexos. al final del do-


cumento.

10
5. Desarrollar un proyecto para implementar un con-
tador hasta 99 en C
Este proyecto consiste en generar un algoritmo en C que de un conteo de 0
hasta 99.
Hay que tener encenta la librerı́a lcd.c, en algunas ocasiones la librerı́a mar-
ca un error, se debe a que el simulador Proteus ya tiene una interna. Estas son

Figura 9: Contador en ASM en Proteus. Fuente propia

las instrucciones para elegir el pic y su frecuencia y los pines a utilizar en el


pic.
# i n c l u d e <16F874A . h>
# use d el ay ( c l o c k =20000000)
# d e f i n e LCD RS PIN PIN C0
# d e f i n e LCD RW PIN PIN C1
# d e f i n e LCD ENABLE PIN PIN C2
# d e f i n e LCD DATA4 PIN C3
# d e f i n e LCD DATA5 PIN C4
# d e f i n e LCD DATA6 PIN C5
# d e f i n e LCD DATA7 PIN C6
//End LCD module c o n n e c t i o n s
//End LCD module c o n n e c t i o n s

11
# i n c l u d e < l c d . c>
Para realizar el conteo se utiliza una variable ı̈.agregada a una estructura de
control ”for.en incremento de 0 hasta 99, con un retardo de 1 segundo por
conteo.
void main ( )
{
int i ;
lcd init ();
lcd putc ( ’\ f ’ ) ;
lcd gotoxy (1 , 1 ) ;
l c d p u t c ( ” Contador 0 a 9 9 ! ” ) ;
f o r ( i = 0 ; i < 1 0 0 ; i ++){
lcd gotoxy (7 , 2 ) ;
p r i n t f ( l c d p u t c ,” %3u ” , i ) ;
delay ms ( 1 0 0 0 ) ;
}
}

5.1. Montaje en Protoboard con modulo I2C


Se realizo el montaje el Protoboard con el pic 16f874a.
Materiales:
Protoboard.
pic 16f874a.

modulo I2C
LCD 16x20
Crystal 4MHz

12
Figura 10: Contador en ASM en Proteus. Fuente propia

6. Implementar un proyecto para medir voltaje 0-5


V y mostrarlo en una LCD
Este proyecto consiste en generar un algoritmo en C para tomar lecturas si-
muladas de voltaje. Estas son las instrucciones para elegir el pic y su frecuencia
y los pines a utilizar en el pic. En el grafico se utilizaron resistencia de 1M y
100K estas serán utilizadas para la medición del voltaje y una variable .aı̈gua-
lada a 0.

# i n c l u d e <16F874A . h>
#use d el ay ( c l o c k =20000000)
# d e f i n e LCD RS PIN PIN C0
# d e f i n e LCD RW PIN PIN C1
# d e f i n e LCD ENABLE PIN PIN C2
# d e f i n e LCD DATA4 PIN C3
# d e f i n e LCD DATA5 PIN C4
# d e f i n e LCD DATA6 PIN C5

13
Figura 11: Contador en ASM en Proteus. Fuente propia

# d e f i n e LCD DATA7 PIN C6


# i n c l u d e < l c d . c>
f l o a t a =0;
f l o a t r1 =1000000;
f l o a t r2 =100000;
f l o a t vcc = 2 0 . 3 5 ;
En código tiene por entrada el pin analógico A0 para tomar la lectura de un
potenciometro que variara la entrada del voltaje.
se lee la lectura en la variable a y se la convierte en una lectura de 0 a 5V
en terminos de 0 a 1024 en una variable flotante, que es la lectura de una
resistencia variable.
En otra variable flotante se calcula el voltaje y se imprime en la LCD.
void main ( )
{
s e t u p a d c p o r t s (AN0 ) ;
s e t u p a d c ( ADC CLOCK DIV 2 ) ;
s e t u p s p i ( SPI SS DISABLED ) ;
s e t u p t i m e r 0 (RTCC INTERNAL | RTCC DIV 1 ) ;
s e t u p t i m e r 1 ( T1 DISABLED ) ;
s e t u p t i m e r 2 ( T2 DISABLED , 0 , 1 ) ;
setup comparator (NC NC NC NC ) ;
s e t u p v r e f ( FALSE ) ;
lcd init ();
while ( t r u e ) {
set adc channel ( 0 ) ;
a=r e a d a d c ( ) ;
f l o a t v1 = ( a * vcc ) / 1 0 2 4 . 0 ;
f l o a t v2 = v1 / ( r2 / ( r1 + r2 ) ) ;
p r i n t f ( lcd putc , ” \ f ” ) ;
p r i n t f ( l c d p u t c , ” Valor D i g i t a l ” ) ;

14
lcd gotoxy ( 1 , 2 ) ;
p r i n t f ( l c d p u t c ,” % f ” , v2 ) ;
delay ms ( 1 0 0 ) ;
}
}

7. Implementar un proyecto para medir temperatu-


ra, nivel de gas, presión etc, y mostrarlo por LCD.
Este proyecto consiste en generar un algoritmo en C para tomar lecturas
simuladas de temperatura y preció n. Estas son las instrucciones para elegir el

Figura 12: Contador en ASM en Proteus. Fuente propia

pic y su frecuencia y los pines a utilizar en el pic. es usa la resolución de 1024


valores en adc=10 para la lectura del lm35 en valores de de milivoltios.
# i n c l u d e <16F874A . h>
# d e v i c e adc=10
# d e f i n e LCD RS PIN PIN D0
# d e f i n e LCD RW PIN PIN D1
# d e f i n e LCD ENABLE PIN PIN D2
# d e f i n e LCD DATA4 PIN D3
# d e f i n e LCD DATA5 PIN D4
# d e f i n e LCD DATA6 PIN D5
# d e f i n e LCD DATA7 PIN D6
#FUSES NOWDT
#FUSES HS
#FUSES NOPUT
#FUSES NOPROTECT
#FUSES NODEBUG
#FUSES NOBROWNOUT

15
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
#FUSES RESERVED
#use d el ay ( c l o c k =20000000)
# i n c l u d e <LCD. C>

float a =0;
float t =0;
float e =0;
float p=0;
float n=0;
Se asignan los puertos analógicos A0 y A1. con un siclo while se empieza la
lectura de los puertos AN0 y AN1, en AN0 se toma la lectura del lm35 en
milivontios, de forma abreviada se hace la conversión de los valores analógicos
a digitales en orden de 10 bits entre valores de 0 y 1024, .a*0.48999”.
para la entrada AN1 se da la lectura de un MPX4115 de valores entre 15KPa
hasta 115KPa.
void main ( )
{
s e t u p a d c p o r t s (AN0 AN1 ) ;
s e t u p a d c ( ADC CLOCK DIV 2 ) ;
s e t u p s p i ( SPI SS DISABLED ) ;
s e t u p t i m e r 0 (RTCC INTERNAL | RTCC DIV 1 ) ;
s e t u p t i m e r 1 ( T1 DISABLED ) ;
s e t u p t i m e r 2 ( T2 DISABLED , 0 , 1 ) ;
setup comparator (NC NC NC NC ) ;
s e t u p v r e f ( FALSE ) ;
lcd init ();
p r i n t f ( lcd putc , ” \ f ” ) ;
lcd gotoxy ( 1 , 1 ) ;
p r i n t f ( lcd putc , ”T : ” ) ;
lcd gotoxy (10 ,1);
p r i n t f ( l c d p u t c , ” °C ” ) ;
lcd gotoxy ( 1 , 2 ) ;
p r i n t f ( l c d p u t c , ” Pa : ” ) ;
lcd gotoxy (11 ,2);
p r i n t f ( l c d p u t c , ” KPa ” ) ;
lcd gotoxy (21 ,1);
p r i n t f ( l c d p u t c , ” Nivel : ” ) ;

while ( t r u e ) {
s e t a d c c h a n n e l ( 0 ) ; / / Temperatura
a=r e a d a d c ( ) ;
t=a * 0 . 4 8 9 9 9 ;
lcd gotoxy ( 3 , 1 ) ;
p r i n t f ( l c d p u t c ,” % f ” , t ) ;
delay ms ( 1 0 0 ) ;

16
set adc channel ( 1 ) ; / / Presi \ ’{ o }n
e=r e a d a d c ( ) ;
p=(0.108* e )+10 ,55;
n=(p * 1 0 0 ) / 1 1 5 ; / / Nivel de gas
lcd gotoxy ( 4 , 2 ) ;
p r i n t f ( l c d p u t c ,” % f ” , ( p − 1 + 0 . 1 ) ) ;
lcd gotoxy (27 ,1);
p r i n t f ( l c d p u t c ,” % f ” , n ) ;
delay ms ( 1 0 0 ) ;
}
}

8. Diseñar e implementar una alarma digital


Este proyecto consiste en generar un algoritmo en C para un reloj con alar-
ma.

Figura 13: Contador en ASM en Proteus. Fuente propia

# d e f i n e LCD RS PIN PIN D0


# d e f i n e LCD RW PIN PIN D1
# d e f i n e LCD ENABLE PIN PIN D2
# d e f i n e LCD DATA4 PIN D3
# d e f i n e LCD DATA5 PIN D4
# d e f i n e LCD DATA6 PIN D5
# d e f i n e LCD DATA7 PIN D6
//End LCD module c o n n e c t i o n s

# i n c l u d e <16F877A . h>
# f u s e s HS ,NOWDT,NOPROTECT,NOLVP

17
#use d el ay ( c l o c k = 8MHz)
#use f a s t i o ( B )
#use f a s t i o (D)
# i n c l u d e < l c d . c>
#use I2C ( master , I2C1 , FAST = 100000)

int1 alarm1 status , alarm2 status ;


char time [ ] = ” : : ”,
calendar [ ] = ” / /20 ” ,
alarm1 [ ] = ”A1 : : : 0 0 ” , alarm2 [ ] = ”A2 : : :00” ,
temperature [ ] = ”T : . C” ;
i n t 8 i , second , minute , hour , day , date , month , year ,
alarm1 minute , alarm1 hour , alarm2 minute , alarm2 hour ,
status reg ;
#INT EXT
void e x t i s r ( void ) {
o u t p u t h i g h ( PIN B4 ) ;
c l e a r i n t e r r u p t ( INT EXT ) ;
}
void DS3231 read ( ) {
i2c start ();
i 2 c w r i t e ( 0xD0 ) ;
i2c write ( 0 ) ;
i2c start ();
i 2 c w r i t e ( 0xD1 ) ;
second = i 2 c r e a d ( 1 ) ;
minute = i 2 c r e a d ( 1 ) ;
hour = i2c read ( 1 ) ;
day = i2c read ( 1 ) ;
date = i2c read ( 1 ) ;
month = i 2 c r e a d ( 1 ) ;
year = i2c read ( 0 ) ;
i2c stop ( ) ;
}
void a l a r m s r e a d d i s p l a y ( ) {
int8 control reg , temperature lsb ;
si gne d i n t 8 temperature msb ;
i2c start ();
i 2 c w r i t e ( 0xD0 ) ;
i 2 c w r i t e ( 0 x08 ) ;
i2c start ();
i 2 c w r i t e ( 0xD1 ) ;
alarm1 minute = i 2 c r e a d ( 1 ) ;
alarm1 hour = i2c read ( 1 ) ;
i2c read ( 1 ) ;
alarm2 minute = i 2 c r e a d ( 1 ) ;
alarm2 hour = i2c read ( 1 ) ;
i2c read ( 1 ) ;
control reg = i2c read ( 1 ) ;
status reg = i2c read ( 1 ) ;

18
i2c read ( 1 ) ;
temperature msb = i 2 c r e a d ( 1 ) ;
temperature lsb = i2c read ( 0 ) ;
i2c stop ( ) ;
// Convert BCD t o decimal
alarm1 minute = ( alarm1 minute >> 4 ) * 10 + ( alarm1 minute & 0x0F ) ;
alarm1 hour = ( alarm1 hour >> 4 ) * 10 + ( alarm1 hour & 0x0F ) ;
alarm2 minute = ( alarm2 minute >> 4 ) * 10 + ( alarm2 minute & 0x0F ) ;
alarm2 hour = ( alarm2 hour >> 4 ) * 10 + ( alarm2 hour & 0x0F ) ;
// End c o n v e r s i o n
alarm1 [ 8 ] = alarm1 minute % 10 + 4 8 ;
alarm1 [ 7 ] = alarm1 minute / 10 + 4 8 ;
alarm1 [ 5 ] = alarm1 hour % 10 + 4 8 ;
alarm1 [ 4 ] = alarm1 hour / 10 + 4 8 ;
alarm2 [ 8 ] = alarm2 minute % 10 + 4 8 ;
alarm2 [ 7 ] = alarm2 minute / 10 + 4 8 ;
alarm2 [ 5 ] = alarm2 hour % 10 + 4 8 ;
alarm2 [ 4 ] = alarm2 hour / 10 + 4 8 ;
alarm1 status = b i t t e s t ( control reg , 0 ) ;
alarm2 status = b i t t e s t ( control reg , 1 ) ;
i f ( temperature msb < 0 ) {
temperature msb = abs ( temperature msb ) ;
temperature [ 2 ] = ’ − ’ ;
}
else
temperature [ 2 ] = ’ ’ ;
t e m p e r a t u r e l s b >>= 6 ;
temperature [ 4 ] = temperature msb % 10 + 4 8 ;
temperature [ 3 ] = temperature msb / 10 + 4 8 ;
i f ( t e m p e r a t u r e l s b == 0 | | t e m p e r a t u r e l s b == 2 ) {
temperature [ 7 ] = ’ 0 ’ ;
i f ( t e m p e r a t u r e l s b == 0 ) temperature [ 6 ] = ’ 0 ’ ;
else temperature [ 6 ] = ’ 5 ’ ;
}
i f ( t e m p e r a t u r e l s b == 1 | | t e m p e r a t u r e l s b == 3 ) {
temperature [ 7 ] = ’ 5 ’ ;
i f ( t e m p e r a t u r e l s b == 1 ) temperature [ 6 ] = ’ 2 ’ ;
else temperature [ 6 ] = ’ 7 ’ ;
}
temperature [ 8 ] = 2 2 3 ;
lcd gotoxy (11 , 1 ) ;
p r i n t f ( l c d p u t c , temperature ) ;
lcd gotoxy (21 , 1 ) ;
p r i n t f ( l c d p u t c , alarm1 ) ;
lcd gotoxy (38 , 1 ) ;
i f ( a l a r m 1 s t a t u s ) l c d p u t c ( ”ON ” ) ;
else l c d p u t c ( ” OFF ” ) ;
lcd gotoxy (21 , 2 ) ;
p r i n t f ( l c d p u t c , alarm2 ) ;
lcd gotoxy (38 , 2 ) ;

19
i f ( alarm2 status ) l c d p u t c ( ”ON ” ) ;
else l c d p u t c ( ” OFF ” ) ;

}
void c a l e n d a r d i s p l a y ( ) {
s w i t c h ( day ) {
c a s e 1 : s t r c p y ( calendar , ”Sun / /20 ” ) ; break ;
c a s e 2 : s t r c p y ( calendar , ”Mon / /20 ” ) ; break ;
c a s e 3 : s t r c p y ( calendar , ”Tue / /20 ” ) ; break ;
c a s e 4 : s t r c p y ( calendar , ”Wed / /20 ” ) ; break ;
c a s e 5 : s t r c p y ( calendar , ”Thu / /20 ” ) ; break ;
c a s e 6 : s t r c p y ( calendar , ” F r i / /20 ” ) ; break ;
c a s e 7 : s t r c p y ( calendar , ” S a t / /20 ” ) ; break ;
d e f a u l t : s t r c p y ( calendar , ” S a t / /20 ” ) ; break ;
}
c a l e n d a r [ 1 3 ] = y e a r % 10 + 4 8 ;
c a l e n d a r [ 1 2 ] = y e a r / 10 + 4 8 ;
c a l e n d a r [ 8 ] = month % 10 + 4 8 ;
c a l e n d a r [ 7 ] = month / 10 + 4 8 ;
c a l e n d a r [ 5 ] = date % 10 + 4 8 ;
c a l e n d a r [ 4 ] = date / 10 + 4 8 ;
lcd gotoxy (1 , 2 ) ;
p r i n t f ( lcd putc , calendar ) ;
}
void DS3231 display ( ) {
// Convert BCD t o decimal
second = ( second >> 4 ) * 10 + ( second & 0x0F ) ;
minute = ( minute >> 4 ) * 10 + ( minute & 0x0F ) ;
hour = ( hour >> 4 ) * 10 + ( hour & 0x0F ) ;
date = ( date >> 4 ) * 10 + ( date & 0x0F ) ;
month = ( month >> 4 ) * 10 + ( month & 0x0F ) ;
y e a r = ( y e a r >> 4 ) * 10 + ( y e a r & 0x0F ) ;
// End c o n v e r s i o n
time [ 7 ] = second % 10 + 4 8 ;
time [ 6 ] = second / 10 + 4 8 ;
time [ 4 ] = minute % 10 + 4 8 ;
time [ 3 ] = minute / 10 + 4 8 ;
time [ 1 ] = hour % 10 + 4 8 ;
time [ 0 ] = hour / 10 + 4 8 ;
calendar display ( ) ;
lcd gotoxy (1 , 1 ) ;
p r i n t f ( l c d p u t c , time ) ;
}
void b l i n k ( ) {
int8 j = 0;
while ( j < 10 && ( input ( PIN B1 ) | | i >= 5 ) && input ( PIN B2 ) && ( input ( PIN B3 )
j ++;
delay ms ( 2 5 ) ;
}
}

20
i n t 8 e d i t ( parameter , x , y ) {
while ( ! input ( PIN B1 ) | | ! input ( PIN B3 ) ) ;
while (TRUE ) {
while ( ! input ( PIN B2 ) ) {
parameter ++;
i f ( ( ( i == 0 ) | | ( i == 5 ) ) && parameter > 23)
parameter = 0 ;
i f ( ( ( i == 1 ) | | ( i == 6 ) ) && parameter > 59)
parameter = 0 ;
i f ( i == 2 && parameter > 31)
parameter = 1 ;
i f ( i == 3 && parameter > 12)
parameter = 1 ;
i f ( i == 4 && parameter > 99)
parameter = 0 ;
i f ( i == 7 && parameter > 1 )
parameter = 0 ;
lcd gotoxy ( x , y ) ;
i f ( i == 7 ) {
i f ( parameter == 1 ) l c d p u t c ( ”ON ” ) ;
else l c d p u t c ( ” OFF ” ) ;
}
else
p r i n t f ( l c d p u t c ,” %02u ” , parameter ) ;
i f ( i >= 5 ) {
DS3231 read ( ) ;
DS3231 display ( ) ;
}
delay ms ( 2 0 0 ) ;
}
lcd gotoxy ( x , y ) ;
lcd putc (” ”);
i f ( i == 7 ) l c d p u t c ( ” ” ) ;
blink ( ) ;
lcd gotoxy ( x , y ) ;
i f ( i == 7 ) {
i f ( parameter == 1 ) l c d p u t c ( ”ON ” ) ;
else l c d p u t c ( ” OFF ” ) ;
}
else
p r i n t f ( l c d p u t c ,” %02u ” , parameter ) ;
blink ( ) ;
i f ( i >= 5 ) {
DS3231 read ( ) ;
DS3231 display ( ) ; }
i f ( ( ! input ( PIN B1 ) && i < 5 ) | | ( ! input ( PIN B3 ) && i >= 5 ) ) {
i ++;
r e t u r n parameter ;
}
}

21
}
void main ( ) {
output b ( 0 ) ;
s e t t r i s b ( 0 x0F ) ;
set tris d (0);
p o r t b p u l l u p s (TRUE ) ;
e n a b l e i n t e r r u p t s (GLOBAL ) ;
e n a b l e i n t e r r u p t s ( INT EXT H2L ) ;
lcd init ();
lcd putc ( ’\ f ’ ) ;
while (TRUE ) {
i f ( ! input ( PIN B1 ) ) {
i = 0;
hour = e d i t ( hour , 1 , 1 ) ;
minute = e d i t ( minute , 4 , 1 ) ;
while ( ! input ( PIN B1 ) ) ;
while (TRUE ) {
while ( ! input ( PIN B2 ) ) {
day ++;
i f ( day > 7 ) day = 1 ;
calendar display ( ) ;
lcd gotoxy (1 , 2 ) ;
p r i n t f ( lcd putc , calendar ) ;
delay ms ( 2 0 0 ) ;
}
lcd gotoxy (1 , 2 ) ;
lcd putc (” ”);
blink ( ) ;
lcd gotoxy (1 , 2 ) ;
p r i n t f ( lcd putc , calendar ) ;
blink ( ) ;
i f ( ! input ( PIN B1 ) )
break ;
}
date = e d i t ( date , 5 , 2 ) ;
month = e d i t ( month , 8 , 2 ) ;
y e a r = e d i t ( year , 13 , 2 ) ;
// Convert decimal t o BCD
minute = ( ( minute / 10) << 4 ) + ( minute % 1 0 ) ;
hour = ( ( hour / 10) << 4 ) + ( hour % 1 0 ) ;
date = ( ( date / 10) << 4 ) + ( date % 1 0 ) ;
month = ( ( month / 10) << 4 ) + ( month % 1 0 ) ;
y e a r = ( ( y e a r / 10) << 4 ) + ( y e a r % 1 0 ) ;
// End c o n v e r s i o n
// Write time & c a l e n d a r data t o DS3231 RTC
i2c start ();
i 2 c w r i t e ( 0xD0 ) ;
i2c write ( 0 ) ;
i2c write ( 0 ) ;
i 2 c w r i t e ( minute ) ;

22
i 2 c w r i t e ( hour ) ;
i 2 c w r i t e ( day ) ;
i 2 c w r i t e ( date ) ;
i 2 c w r i t e ( month ) ;
i 2 c w r i t e ( year ) ;
i2c stop ( ) ;
delay ms ( 2 0 0 ) ;
}
i f ( ! input ( PIN B3 ) ) {
while ( ! input ( PIN B3 ) ) ;
i = 5;
alarm1 hour = e d i t ( alarm1 hour , 25 , 1 ) ;
alarm1 minute = e d i t ( alarm1 minute , 28 , 1 ) ;
a l a r m 1 s t a t u s = e d i t ( a l a r m 1 s t a t u s , 38 , 1 ) ;
i = 5;
alarm2 hour = e d i t ( alarm2 hour , 25 , 2 ) ;
alarm2 minute = e d i t ( alarm2 minute , 28 , 2 ) ;
a l a r m 2 s t a t u s = e d i t ( a l a r m 2 s t a t u s , 38 , 2 ) ;
alarm1 minute = ( ( alarm1 minute / 10) << 4 ) + ( alarm1 minute % 1 0 ) ;
alarm1 hour = ( ( alarm1 hour / 10) << 4 ) + ( alarm1 hour % 1 0 ) ;
alarm2 minute = ( ( alarm2 minute / 10) << 4 ) + ( alarm2 minute % 1 0 ) ;
alarm2 hour = ( ( alarm2 hour / 10) << 4 ) + ( alarm2 hour % 1 0 ) ;
// Write alarms data t o DS3231
i2c start ();
i 2 c w r i t e ( 0xD0 ) ;
i2c write ( 7 ) ;
i2c write ( 0 ) ;
i 2 c w r i t e ( alarm1 minute ) ;
i 2 c w r i t e ( alarm1 hour ) ;
i 2 c w r i t e ( 0 x80 ) ;
i 2 c w r i t e ( alarm2 minute ) ;
i 2 c w r i t e ( alarm2 hour ) ;
i 2 c w r i t e ( 0 x80 ) ;
i 2 c w r i t e ( 4 | a l a r m 1 s t a t u s | ( a l a r m 2 s t a t u s << 1 ) ) ;
i2c write ( 0 ) ;
i2c stop ( ) ;
delay ms ( 2 0 0 ) ;
}
i f ( ! input ( PIN B2 ) && input ( PIN B4 ) ) {
output low ( PIN B4 ) ;
i2c start ();
i 2 c w r i t e ( 0xD0 ) ;
i 2 c w r i t e ( 0 x0E ) ;
i 2 c w r i t e (4 | ( ! b i t t e s t ( status reg , 0) & alarm1 status ) | ( ( ! b i t t e s t ( st
i2c write ( 0 ) ;
i2c stop ( ) ;
}
DS3231 read ( ) ;
alarms read display ( ) ;
DS3231 display ( ) ;

23
delay ms ( 5 0 ) ;
}
}

24

Das könnte Ihnen auch gefallen