Академический Документы
Профессиональный Документы
Культура Документы
MICROCONTROLADORES
1
INFOCAL MLPQ
Figura 1.2. El microcontrolador es un sistema cerrado. Todas las partes del computador
están contenidas en su interior y sólo salen al exterior las líneas que gobiernan
los periféricos.
2
INFOCAL MLPQ
3
INFOCAL MLPQ
Cada vez existen más productos que incorporan un microcontrolador con el fin de
aumentar sustancialmente sus prestaciones, reducir su tamaño y coste, mejorar su
fiabilidad y disminuir el consumo.
4
INFOCAL MLPQ
5
INFOCAL MLPQ
¿Qué es lo que ocurre con los PIC?, ¿Por qué están en boca de todos?. Hemos
buscado en multitud de bibliografía y realmente nadie da una respuesta concreta, pero una
aproximación a la realidad puede ser esta:
Los PIC tienen “ángel”, tienen “algo” que fascina a los diseñadores, puede ser la
velocidad, el precio, la facilidad de uso, la información, las herramientas de apoyo... .
Quizás un poco de todo eso es lo que produce esa imagen de sencillez y utilidad. Es
probable que en un futuro próximo otra familia de microcontroladores le arrebate ese
“algo”.
6
INFOCAL MLPQ
Queremos constatar que para las aplicaciones más habituales (casi un 90%) la
elección de una versión adecuada de PIC es la mejor solución; sin embargo, dado su
carácter general, otras familias de microcontroladores son más eficaces en aplicaciones
específicas, especialmente si en ellas predomina una característica concreta, que puede
estar muy desarrollada en otra familia.
Una de las razones del éxito de los PIC se basa en su utilización. Cuando se aprende
a manejar uno de ellos, conociendo su arquitectura y su repertorio de instrucciones, es
muy fácil emplear otro modelo.
7
INFOCAL MLPQ
Una de las labores más importantes del ingeniero de diseño es la elección del
microcontrolador que mejor satisfaga las necesidades del proyecto con el mínimo
presupuesto.
8
INFOCAL MLPQ
El pic 16F877A que pertenece a la gama media, es uno de los más utilizados. Aquí les
presentamos la configuración externa y la distribución de pines, este esquema nos servirá
de mucho al momento de armar el circuito, ya que nos indica también en la distribución de
pines los recursos que posee, y según el programa que se gravo en el microcontralor.
podremos ensamblar el proyecto.
El pic 16F84A que pertenece a la gama media, es otro microcontrolador pero más pequeño
de solo 18 pines, pero con un gran potencial y de igual manera utilizado en muchos
proyectos.
El pic 18F4550A de gama alta se utiliza en proyectos más grandes ya que tiene nuevas
tecnologías de programación, junto a nuevas armas para enfrentarnos casi a cualquier
reto de la automatización. En gama alta también encontramos los dspic’s, los pic’s que ya
tienen incorporado su dirección IP, y la tecnología sigue avanzando…
Recuerden que estos microcontroladores citados solo de la línea MOTOROLA uno de los
muchos fabricantes de microcontroladores.
9
INFOCAL MLPQ
10
INFOCAL MLPQ
• Temporizadores o “Timers”.
• Conversor A/D.
• Conversor D/A.
• Comparador analógico.
• Puertas de comunicación.
11
INFOCAL MLPQ
3 REGISTROS ESPECIFICOS
C: Acarreo en el 8º bit.
1 = acarreo en la suma y no en la resta. 0 = acarreo en la resta y no en la suma
DC: Acarreo en el 4º bit de menor peso.
Igual que C.
Z: Zero.
1 = El resultado de alguna operación es 0. 0 = El resultado es distinto de 0
/PD: Power Down.
1 = Recién encendido o tras CLRWDT. 0 = Tras ejecutar una instrucción SLEEP
/TO: Timer Out.
1 = Recién encendido, tras CLRWDT, o SLEEP. 0 = Saltó el WDT
12
INFOCAL MLPQ
PS2 PS1 PS0 División del TMR0 PS2 PS1 PS0 División del WDT
0 0 0 1/2 0 0 0 1/1
0 0 1 1/4 0 0 1 1/2
0 1 0 1/8 0 1 0 1/4
0 1 1 1/ 16 0 1 1 1/8
1 0 0 1 / 32 1 0 0 1 / 16
1 0 1 1 / 64 1 0 1 1 / 32
1 1 0 1 / 128 1 1 0 1 / 64
1 1 1 1 / 256 1 1 1 1 / 128
13
INFOCAL MLPQ
14
INFOCAL MLPQ
15
INFOCAL MLPQ
4. REPERTORIO DE INSTRUCCIONES
16
INFOCAL MLPQ
5.1 Introducción
INICIO
17
INFOCAL MLPQ
¿ERRORES?
FIN
Las herramientas o programas se pueden encontrar y bajar gratuitamente de Internet en la
dirección www.microchip.com. Aunque se les facilitara estos programas en el laboratorio.
6. DIAGRAMAS DE FLUJO
18
INFOCAL MLPQ
Finalmente, decirles que para ustedes es una experiencia nueva y que como toda prueba
tiene sus riesgos, aunque espero y deseo que, de una u otra forma logre prender la llama
de la ilusión, o por lo menos despertar el interés por el estudio de la electrónica y en
particular de este mundo inacabado de la programación en C y los microcontroladores.
Construccion if
if (condición)
{
sentencia;
}
19
INFOCAL MLPQ
if (condición)
{
sentencia 1;
}
Else
{
sentencia 2;
}
Construcción switch
switch ( expressions )
{
case constante 1 :
grupo de sentencias 1;
break;
case constante 2 :
grupo de sentencias 2;
break;
...
case constante N :
grupo de sentencias N;
break;
default :
grupo de sentencias por defecto;
20
INFOCAL MLPQ
break;
}
Construcción while
while (condición)
{
grupo de sentencias;
}
Construcción do-while
21
INFOCAL MLPQ
Esta construcción funciona de manera muy similar a la construcción while. Sin embargo,
al contrario que esta, do-while ejecuta primero el cuerpo del bucle y después evalúa la
condición. Por lo cual, el cuerpo del bucle se ejecuta como mínimo una vez.
La forma general de la construcción do-while es la siguiente:
do
{
grupo de sentencias;
}
while (condición);
Construcción for
Esta construcción iterativa no presenta un formato fijo estricto, sino que admite numerosas
variantes, lo que la dota de gran potencia y flexibilidad.
Su forma mas general para la ejecución repetida de las sentencias es:
22
INFOCAL MLPQ
TIPOS DE DATOS
CONSTANTES
23
INFOCAL MLPQ
CARACTERES ESPECIALES
OPERADORES ARITMETICOS
OPERADORES RELACIONALES
24
INFOCAL MLPQ
OPERADORES LOGICOS
FUNCIONES GENERALES
25
INFOCAL MLPQ
26
INFOCAL MLPQ
27
INFOCAL MLPQ
28
INFOCAL MLPQ
29
INFOCAL MLPQ
30
INFOCAL MLPQ
LABORATORIO DE MICROCONTROLADORES
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
void main()
{
inicio:
output_high(pin_a0);
delay_ms(500);
output_low(pin_a0);
delay_ms(500);
goto inicio;
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
void main()
{
output_low(pin_a0);
inicio:
output_toggle(pin_a0);
delay_ms(500);
goto
inicio;
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
void main()
{
inicio:
31
INFOCAL MLPQ
output_b(0);
delay_ms(500);
output_b(255);
delay_ms(500);
goto inicio;
}
//// Grafico 2
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
int a;
void main()
{
inicio:
for (a=0;a<256;a++)
{
output_b(a);
delay_ms(400);
}
goto inicio;
}
32
INFOCAL MLPQ
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
int a;
void main()
{
inicio:
a=0;
while(a<256)
{
output_b(a);
delay_ms(500);
a++;
}
goto inicio;
}
5.- rote de un 1 lógico por el Puerto B utiliza for y vector. Copiar grafico 2
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
int a;
int v[8]={1,2,4,8,16,32,64,128};
void main()
{
inicio:
for(a=0;a<8;a++)
{
output_b(V[a]);
delay_ms(500);
}
goto inicio;
}
33
INFOCAL MLPQ
if (input(pin_A0)==1)
{
delay_ms(300);
cont++;
output_b(v[cont]);
if (cont==10)
{
cont=0;
output_b(V[cont]);
}
}
goto inicio;
34
INFOCAL MLPQ
}
7.1 realizar el mismo ejemplo pero el conteo sea en formato hexadecimal 0-f.
8.- cuenta en un display en el puerto C el número de veces que el efecto del puerto B
se reinicia “for anidado”.
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
int a,b;
int v[10]={63,6,91,79,102,109,125,7,127,111};
int x[8]={1,2,4,8,16,32,64,128};
void main()
{
inicio:
for(a=0;a<10;a++)
{
output_d(v[a]);
for(b=0;b<8;b++)
{
output_b(x[b]);
delay_ms(500);
}
}
goto inicio;
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
int cont;
void main()
{
conteo:
if(input(pin_a0)==1)
{
output_b(cont);
cont++;
if (cont==255)
{
cont=0;
}
delay_ms(400);
}
35
INFOCAL MLPQ
else
{
output_b(cont);
cont--;
if(cont==0)
{
cont=255;
}
delay_ms(400);
}
goto conteo;
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
signed int8 cont;
int v[10]={63,6,91,79,102,109,125,7,127,111};
void main()
{
conteo:
if(input(pin_a0)==1)
{
output_b(v[cont]);
cont++;
if (cont>9)
{
cont=0;
}
delay_ms(400);
}
else
{
output_b(v[cont]);
cont--;
if(cont<0)
{
cont=9;
}
delay_ms(400);
}
goto conteo;
}
36
INFOCAL MLPQ
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
signed int8 cont;
int v[10]={1,2,4,8};
void main()
{
conteo:
if(input(pin_a0)==1)
{
output_b(v[cont]);
cont++;
if (cont>3)
{
cont=0;
}
delay_ms(400);
}
else
{
output_b(v[cont]);
cont--;
if(cont<0)
{
cont=3;
}
delay_ms(400);
}
goto conteo;
}
#include <16f877a.h>
#use delay(clock=11059200)
#fuses hs,nowdt
int tabla[10]={63,6,91,79,102,109,125,7,127,111};
int cont=0,uni=0,dec=0,barrido=0;
void main()
{
inicio:
for(cont=0;cont<60;cont++)
{
if(cont<10)
37
INFOCAL MLPQ
{
uni=cont;
dec=0;
}
else
{
uni=cont%10;
dec=cont/10;
}
for(barrido=0;barrido<50;barrido++)
{
output_a(1);
output_b(tabla[uni]);
delay_ms(10);
output_a(2);
output_b(tabla[dec]);
delay_ms(10);
}
}
goto inicio;
}
38
INFOCAL MLPQ
#include <16f877a.h>
#use delay(clock=11059200)
#fuses hs,nowdt
int tabla[10]={63,6,91,79,102,109,125,7,127,111};
int uni=0,dec=0;
void main()
{
port_b_pullups(true);
ext_int_edge(h_to_l);
enable_interrupts(global);
enable_interrupts(int_ext);
ini:
output_d(1);
output_c(tabla[uni]);
delay_ms(10);
output_d(2);
output_c(tabla[dec]);
delay_ms(10);
goto ini;
}
#int_ext
void incremento()
{
delay_ms(20);
uni++;
if (uni>9)
{
uni=0;
dec++;
if (dec>9)
{
dec=0;
}
}
}
39
INFOCAL MLPQ
#include<16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include<lcd.c>
void main()
{
lcd_init();
lcd_putc(“COMPILADOR C”);
lcd_gotoxy(1,2);
lcd_putc(“para PIC’s”);
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
void main()
{
char mens1[]="pic16f877a";
char mens2[]="LABORATORIO DE MICROPROCESADORES II #";
int i;
inicio:
lcd_init();
printf(lcd_putc,mens1);
lcd_gotoxy(1,2);
for(i=0;i<16;i++)
{
lcd_putc(mens2[i]);
delay_ms(150);
}
lcd_send_byte(0,0b00000111);
while(mens2[i]!='#')
{
lcd_putc(mens2[i]);
delay_ms(150);
i++;
}
goto inicio;
40
INFOCAL MLPQ
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
void main()
{
int i,j;
lcd_init();
while(true)
{
j=1;
for(i=1;i<14;i++)
{
lcd_gotoxy(i,j);
printf(lcd_putc,"hola");
delay_ms(200);
lcd_putc("\f"); // limpiar pantalla
}
j=2;
for(i=13;i>0;i--)
{
lcd_gotoxy(i,j);
printf(lcd_putc,"hola");
delay_ms(200);
lcd_putc("\f"); // limpiar pantalla
}
}
}
41
INFOCAL MLPQ
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
#define use_portb_kbd TRUE
#include <kbd.c>
void main()
{
char tecla;
int i=0;
char mem[20];
lcd_init();
kbd_init();
port_b_pullups(true);
lcd_putc("\fpresionar teclas\n");
for(;;)
{
tecla=kbd_getc();
if (tecla!=0)
{
mem[i]=tecla;
//almacenar teclas presionadas
lcd_putc(tecla);
i++;
if(i==16) lcd_send_byte(0,0b00000111);
// LCD desplazandose
}
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
#define use_portb_kbd TRUE
#include <kbd.c>
#rom 0x2100={'1','2','3'}
void main()
42
INFOCAL MLPQ
{
int i;
char k;
char datos[3],clave[3];
lcd_init();
kbd_init();
port_b_pullups(true);
for(i=0;i<=2;i++)
clave[i]=read_eeprom(i);
printf(lcd_putc,"\fINTRODUCIR CLAVE\n");
i=0;
while(true)
{
k=kbd_getc();
if(k!=0)
{
datos[i]=k;
lcd_putc("*");
i++;
if(i==3)
{
if((datos[0]==clave[0])&&(datos[1]==clave[1])&&(datos[2]==clave[2]))
{
printf(lcd_putc,"\fPUERTA ABIERTA");
output_high(pin_a0);
delay_ms(2000);
output_low(pin_a0);
}
else
{
printf(lcd_putc,"\fCLAVE ERRONEA");
delay_ms(3000);
}
printf(lcd_putc,"\fINTRODUCIR CLAVE\n");
i=0;
}
}
}
}
43
INFOCAL MLPQ
#include <16f877a.h>
#device adc=10
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
int16 q;
float p;
#int_ad
void conversion()
{
q=read_adc(adc_read_only);
p=5.0*q/1023.0;
printf(lcd_putc,"\nTENSION = %1.2fV",p);
}
void main()
{
lcd_init();
setup_adc(adc_clock_internal);
setup_adc_ports(RA0_RA1_RA3_ANALOG);
enable_interrupts(int_ad);
enable_interrupts(global);
set_adc_channel(0);
44
INFOCAL MLPQ
lcd_putc("**VOLTIMETRO**");
s:
read_adc(adc_start_only);
sleep();
delay_ms(200);
goto s;
}
45
INFOCAL MLPQ
#include <16f877a.h>
#device adc=10
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
int16 lectura;
float grados;
#int_ad
void temperatura()
{
lectura = read_adc(adc_read_only);
grados = (4.888*lectura)/10;
printf(lcd_putc,"\nTEMP = %3.1f C",grados);
}
void main()
{
lcd_init();
setup_adc(adc_clock_internal);
setup_adc_ports(ALL_ANALOG);
enable_interrupts(int_ad);
enable_interrupts(global);
set_adc_channel(2);
lcd_putc("**TERMOMETRO**");
s:read_adc(adc_start_only);
sleep();
delay_ms(200);
goto s;
}
21.- Barómetro – termómetro, múltiplexación del CAD
46
INFOCAL MLPQ
#include <16f877a.h>
#device adc=10
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
void main()
{
int16 lectura;
float Vout,presion;
float temp;
setup_adc_ports(RA0_RA1_RA3_ANALOG);
setup_adc(adc_clock_internal);
lcd_init();
while(true)
{ set_adc_channel(0);
delay_us(20);
lectura= read_adc();
Vout = 5*lectura/1023.0;
presion=(Vout+0.475)/0.045;
set_adc_channel(1);
delay_us(20);
lectura= read_adc();
temp =(4.888*lectura)/10;
lcd_gotoxy(1,1);
printf(lcd_putc,"P = %5.2f Kpa",presion);
47
INFOCAL MLPQ
#include <16f877a.h>
#device adc=10
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
int16 lectura;
float grados,prog=15.0;
#int_ad
void temperatura()
{
lcd_gotoxy(1,1);
printf(lcd_putc,"T.PRG = %3.1f C\n",prog);
lectura = read_adc(adc_read_only);
grados = (4.888*lectura)/10;
printf(lcd_putc,"T.ACT = %3.1f C",grados);
if(grados<prog)output_high(pin_c0);
else output_low(pin_c0);
}
void main()
{
lcd_init();
port_b_pullups(true);
setup_adc(adc_clock_internal);
setup_adc_ports(all_analog);
enable_interrupts(int_ad);
enable_interrupts(global);
set_adc_channel(2);
48
INFOCAL MLPQ
s:
read_adc(adc_start_only);
sleep();
delay_ms(200);
if(input(pin_b0)==0)prog=prog+0.5;
if(prog>30)prog=30;
if(input(pin_b1)==0)prog=prog-0.5;
if(prog<1)prog=1;
goto s;
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
int cont=0;
int seg=0;
int min=0;
int hor=0;
void actualizar_lcd()
{
seg++;
if(seg==60)
{
seg=0;
min++;
}
49
INFOCAL MLPQ
if(min==60)
{
min=0;
hor++;
}
if(hor==24)hor=0;
lcd_gotoxy(1,2);
printf(lcd_putc,"%02u:%02u:%02u",hor,min,seg);
}
#int_ext
void externa()
{
delay_ms(100);
if(input(pin_b7)==1)
{
min++;
if(min==60)min=0;
lcd_gotoxy(4,2);
printf(lcd_putc,"%02u",min);
}
if(input(pin_b6)==1)
{
hor++;
if(hor==24)hor=0;
lcd_gotoxy(1,2);
printf(lcd_putc,"%02u",hor);
}
}
#int_timer1
void segundos(void)
{
set_timer1(8050);//7936
if(cont==6)
{
actualizar_lcd();
cont=0;
}
cont++;
}
void main()
{
port_b_pullups(true);
lcd_init();
lcd_putc("RELOJ CON TEMP1\n");
lcd_putc("00:00:00");
setup_timer_1(t1_internal|t1_div_by_8);
50
INFOCAL MLPQ
set_timer1(8050);//7936
ext_int_edge(h_to_l);
enable_interrupts(int_timer1);
enable_interrupts(int_ext);
enable_interrupts(global);
sleep();
while(true);
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
int cont=0;
int seg=0;
int min=0;
int hor=0;
int tabla[10]={63,6,91,79,102,109,125,7,127,111};
int h1,h2,m1,m2;
#int_ext
void externa()
{
if(input(pin_b7)==1)
{
min++;
if(min==60)min=0;
}
if(input(pin_b6)==1)
{
hor++;
if(hor==24)hor=0;
}
}
#int_timer1
void segundos(void)
{
set_timer1(8050);//7936
if(cont==6)
{
seg++;
output_toggle(pin_b2);
cont=0;
}
cont++;
}
void main()
51
INFOCAL MLPQ
{
port_b_pullups(true);
setup_timer_1(t1_internal|t1_div_by_8);
set_timer1(8050); // 7936
ext_int_edge(h_to_l);
enable_interrupts(int_timer1);
enable_interrupts(int_ext);
enable_interrupts(global);
output_low(pin_b2);
while(true)
{
output_d(~1);
output_c(tabla[h2]);
delay_ms(5);
output_d(~2);
output_c(tabla[h1]);
delay_ms(5);
output_d(~4);
output_c(tabla[m2]);
delay_ms(5);
output_d(~8);
output_c(tabla[m1]);
delay_ms(5);
if (min>9)
{
m1=min%10;
m2=min/10;
}
else
{
m2=0;
m1=min;
}
if (hor>9)
{
h1=hor%10;
h2=hor/10;
}
else
{
h2=0;
h1=hor;
}
if(seg>=60)
{
seg=0;
min++;
52
INFOCAL MLPQ
}
if(min>=60)
{
min=0;
hor++;
}
if(hor>=24)hor=0;
}
}
#include <16f877a.h>
#device adc=10
#fuses hs,nowdt
#use delay(clock=11059200)
int cont=0;
int seg=0;
int min=0;
int hor=0;
int tabla[10]={63,6,91,79,102,109,125,7,127,111};
int h1,h2,m1,m2,s1,s2;
int16 lectura;
int g1, int g2, int gx;
int g=0;
#int_ad
void temperatura()
{
lectura = read_adc(adc_read_only);
gx = (4.888*lectura)/10;
}
#int_ext
void externa()
{
if(input(pin_b7)==1)
{
min++;
if(min==60)min=0;
}
if(input(pin_b6)==1)
{
hor++;
if(hor==24)hor=0;
}
}
#int_timer1
53
INFOCAL MLPQ
void segundos(void)
{
set_timer1(8050);
if(cont==6)
{
seg++;
cont=0;
read_adc(adc_start_only);
g++;
}
cont++;
}
void main()
{
port_b_pullups(true);
setup_adc(adc_clock_internal);
setup_adc_ports(0x02);
enable_interrupts(int_ad);
setup_timer_1(t1_internal|t1_div_by_8);
set_timer1(8050);
ext_int_edge(h_to_l);
enable_interrupts(int_timer1);
enable_interrupts(int_ext);
enable_interrupts(global);
set_adc_channel(2);
while(true)
{
output_d(~1);
output_c(tabla[h2]);
delay_ms(4);
output_d(~2);
output_c(tabla[h1]);
delay_ms(4);
output_d(~4);
output_c(tabla[m2]);
delay_ms(4);
output_d(~8);
output_c(tabla[m1]);
delay_ms(4);
output_d(~16);
output_c(tabla[s2]);
54
INFOCAL MLPQ
delay_ms(4);
output_d(~32);
output_c(tabla[s1]);
delay_ms(4);
55
INFOCAL MLPQ
m1=min%10;
m2=min/10;
}
else
{
m2=0;
m1=min;
}
if (hor>9)
{
h1=hor%10;
h2=hor/10;
}
else
{
h2=0;
h1=hor;
}
if(seg>=60)
{
seg=0;
min++;
}
if(min>=60)
{
min=0;
hor++;
}
if(hor>=24)hor=0;
}
}
26.- control de velocidad de un motor DC con PWM y un motor servo con PCM.
(proteus 6.5)
56
INFOCAL MLPQ
#include <16f877a.h>
#fuses xt,nowdt
#device adc=10
#use delay(clock=4m)
int16 valor;
#int_ad
void ad_int(){
valor=read_adc(adc_read_only);
set_pwm1_duty(valor);
output_b(valor);
}
void main(){
disable_interrupts(global);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_timer_2(T2_DIV_BY_16,255,1);
setup_ccp1(CCP_PWM);
enable_interrupts(INT_AD);
enable_interrupts(global);
s:
read_adc(adc_start_only);
sleep();
delay_ms(200);
goto s;
}
27.- Contador y llenado de envases con interrupción externa .
57
INFOCAL MLPQ
#include <16f877a.h>
#use delay(clock=11059200)
#fuses hs,nowdt
#include <lcd.c>
int x=0,z=0,uni=0,dec=0,cen=0,mil=0;
void main()
{
enable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge(L_to_H);
lcd_init();
printf(lcd_putc,"*** CONTADOR ***\n");
printf(lcd_putc,"ENVASES = %1u%1u%1u%1u",uni,dec,cen,mil);
sleep();
delay_ms(100);
circular:
if(z==1)
{
if(x>0)
{
x--;
lcd_gotoxy(1,2);
printf(lcd_putc,"ENVASES = %1u%1u%1u%1u",mil,cen,dec,uni);
delay_ms(300);
output_high(pin_c0);
}
else
{
output_low(pin_c0);
z=0;
}
}
else
{
sleep();
delay_ms(100);
}
goto circular;
}
#int_ext
void incremento()
{
delay_ms(100);
uni++;
if(uni>9)
{
58
INFOCAL MLPQ
dec++;
uni=0;
if(dec>9)
{
cen++;
dec=0;
if(cen>9)
{
mil++;
cen=0;
if(mil>9)
{
mil=0;
}
}
}
}
z=1;
x=3;
}
#include <16f877a.h>
#device adc=8
#fuses hs,nowdt
#use delay(clock=11059200)
int LD1,LD2,LD3;
int v[4]={3,6,12,9};
signed int8 i=0;
void main()
{
setup_adc_ports(all_analog);
setup_adc(adc_clock_internal);
output_b(v[0]);
ini:
set_adc_channel(0);
delay_ms(1);
LD1=read_adc();
set_adc_channel(1);
delay_ms(1);
LD2=read_adc();
set_adc_channel(2);
delay_ms(1);
LD3=read_adc();
if(LD2>LD1)
{
59
INFOCAL MLPQ
output_b(v[i]);
delay_ms(100);
i++;
if(i>3)i=0;
}
if(LD2>LD3)
{
output_b(v[i]);
delay_ms(100);
i--;
if(i<0)i=3;
}
goto ini;
}
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#rom 0x0090={
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0xff,0x91,0x91,0x91,0x0,0x0,//e
60
INFOCAL MLPQ
0xff,0x01,0x01,0x01,0x0,0x0,//l
0xff,0x91,0x91,0x91,0x0,0x0,//e
0xff,0x81,0x81,0x81,0x0,0x0,//c
0x80,0x80,0xff,0x80,0x80,0x0,0x0,//t
0xff,0x98,0x94,0x92,0x71,0x0,0x0,//r
0xff,0x81,0x81,0xff,0x0,0x0,//o
0xff,0x10,0x08,0x04,0xff,0x0,0x0,//n
0x81,0xff,0x81,0x0,0x0,//i
0xff,0x81,0x81,0x81,0x0,0x0,//c
0x3f,0x48,0x88,0x48,0x3f,0x0,0x0,//a
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,//_
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0//_
}
int col,barr,ind,mux;
long aux,desp,tam;
void main()
{
output_a(6);
inicio:
col=0;
desp=0x0090;
barr=0;
ind=0;
tam=116;
mux=1;
ini:
aux=desp+ind;
output_b(read_program_eeprom(aux));
output_d(col);
delay_ms(1);
ind++;
if (ind==48)
{
ind=0;
}
col++;
if (col==16)
{
col=0;
mux++;
if(mux>3)
{
mux=1;
61
INFOCAL MLPQ
}
if(mux==1)
{
output_a(6);
}
if(mux==2)
{
output_a(5);
}
if(mux==3)
{
output_a(3);
}
}
barr++;
if (barr==96)
{
barr=0;
desp++;
tam--;
if(tam==0)
{
goto inicio;
}
else
{
goto ini;
}
}
else
{
goto ini;
}
}
62
INFOCAL MLPQ
#include <16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#include <hdm64gs12.c>
#include <graphics.c>
void main()
{
char a0[]="A0";
char a1[]="A1";
char a2[]="A2";
char a3[]="A3";
char a4[]="A4";
char a5[]="A5";
char mens[]="PUERTO A";
glcd_init(on);
glcd_text57(113,30,a0,1,1);
glcd_text57(97,30,a1,1,1);
glcd_text57(81,30,a2,1,1);
glcd_text57(65,30,a3,1,1);
glcd_text57(49,30,a4,1,1);
glcd_text57(33,30,a5,1,1);
glcd_text57(30,5,mens,2,1);
while(true)
{
if(input_state(pin_a0))
glcd_rect(112,40,126,60,1,1);
else
63
INFOCAL MLPQ
glcd_rect(112,40,126,60,1,0);
glcd_rect(112,40,126,60,0,1);
if(input_state(pin_a1))
glcd_rect(96,40,110,60,1,1);
else
glcd_rect(96,40,110,60,1,0);
glcd_rect(96,40,110,60,0,1);
if(input_state(pin_a2))
glcd_rect(80,40,94,60,1,1);
else
glcd_rect(80,40,94,60,1,0);
glcd_rect(80,40,94,60,0,1);
if(input_state(pin_a3))
glcd_rect(64,40,78,60,1,1);
else
glcd_rect(64,40,78,60,1,0);
glcd_rect(64,40,78,60,0,1);
if(input_state(pin_a4))
glcd_rect(48,40,62,60,1,1);
else
glcd_rect(48,40,62,60,1,0);
glcd_rect(48,40,62,60,0,1);
if(input_state(pin_a5))
glcd_rect(32,40,46,60,1,1);
else
glcd_rect(32,40,46,60,1,0);
glcd_rect(32,40,46,60,0,1);
delay_ms(500);
}
}
64
INFOCAL MLPQ
#include <16f877a.h>
#device adc=10
#fuses hs,nowdt
#use delay(clock=11059200)
#include <lcd.c>
#define use_portb_kbd TRUE
#include <kbd.c>
int16 lectura;
float grados;
int cont=0;
char u[3]={'0','0','0'},k;
char uu='0';
char dd='0';
char cc='0';
short f=0;
int sg=0;
int mn=0;
int h1,h2,h3,h4,h5;
#int_timer1
void segundos(void)
{
65
INFOCAL MLPQ
set_timer1(19000);//7936
if(cont==7)
{
cont=0;
uu++;
sg++;
}
cont++;
}
#int_ad
void temperatura()
{
lectura = read_adc(adc_read_only);
grados = (4.888*lectura)/10;
}
void main()
{
port_b_pullups(true);
output_e(0);
lcd_init();
kbd_init();
h5 = read_eeprom(0x2100);
h4 = read_eeprom(0x2101);
h3 = read_eeprom(0x2102);
h2 = read_eeprom(0x2103);
h1 = read_eeprom(0x2104);
mn = read_eeprom(0x2105);
sg = read_eeprom(0x2106);
setup_adc(adc_clock_internal);
setup_adc_ports(0x02);
enable_interrupts(int_ad);
set_adc_channel(2);
setup_timer_1(t1_internal|t1_div_by_8);
ext_int_edge(h_to_l);
enable_interrupts(global);
test:
if(sg>=60)
{
sg=0;
mn++;
}
if(mn>=60)
{
mn=0;
h1++;
}
if(h1>=9)
66
INFOCAL MLPQ
{
h1=0;
h2++;
}
if(h2>=9)
{
h2=0;
h3++;
}
if(h3>=9)
{
h3=0;
h4++;
}
if(h4>=9)
{
h4=0;
h5++;
}
if(h5>=9)
{
h5=0;
}
k=kbd_getc();
if((k!=0)&&(k!='*')&&(k!='#'))
{
u[0]=u[1];
u[1]=u[2];
u[2]=k;
}
if(k=='*')//start
{
read_adc(adc_start_only);
delay_ms(10);
if (grados>50)
{
output_e(0);
lcd_putc("\f");
lcd_putc("**TERMOMETRO**");
printf(lcd_putc,"\nTEMP = %3.1f C",grados);
delay_ms(15000);
}
else
{
output_e(1);
delay_ms(1000);//tiempo de espera antes del encendido
}
67
INFOCAL MLPQ
output_e(0);
delay_ms(2000);
set_timer1(19000);//7936
f=1;
enable_interrupts(int_timer1);
output_e(2);
lcd_putc("\f");
}
if(k=='#')//stop
{
f=0;
uu='0';
dd='0';
cc='0';
u[0]='0';
u[1]='0';
u[2]='0';
disable_interrupts(int_timer1);
output_e(0);
}
if(input(pin_c1)==0)
{
read_adc(adc_start_only);
delay_ms(1000);
lcd_putc("\f");
lcd_putc("**TERMOMETRO**");
printf(lcd_putc,"\nTEMP = %3.1f C",grados);
delay_ms(3000);
lcd_putc("\f");
}
if(input(pin_c0)==0)
{
lcd_gotoxy(1,1);
lcd_putc(" **HOROMETRO** ");
lcd_gotoxy(1,2);
printf(lcd_putc,"T = %1u%1u%1u%1u%1u Horas",h5,h4,h3,h2,h1);
delay_ms(3000);
if(input(pin_c0)==0)
{
delay_ms(2000);
if(input(pin_c0)==0)
{
delay_ms(2000);
lcd_gotoxy(1,2);
lcd_putc("BORRAR HOROMETRO");
delay_ms(4000);
if(input(pin_c0)==0)
68
INFOCAL MLPQ
{
disable_interrupts(int_timer1);
write_eeprom (0x2100,0);
write_eeprom (0x2101,0);
write_eeprom (0x2102,0);
write_eeprom (0x2103,0);
write_eeprom (0x2104,0);
write_eeprom (0x2105,0);
write_eeprom (0x2106,0);
lcd_gotoxy(1,2);
lcd_putc("REALIZO BORRADO");
delay_ms(3000);
}
}
}
lcd_putc("\f");
}
if (uu>'9')
{
uu='0';
dd++;
}
if (dd>'9')
{
dd='0';
cc++;
}
if (cc>'9')
{
disable_interrupts(int_timer1);
f=0;
output_e(0);
cc='0';
}
lcd_gotoxy(1,1);
lcd_putc("T.Prg.= ");
lcd_gotoxy(9,1);
lcd_putc(u[0]);
lcd_gotoxy(10,1);
lcd_putc(u[1]);
lcd_gotoxy(11,1);
lcd_putc(u[2]);
lcd_gotoxy(1,2);
lcd_putc("T.act.= ");
lcd_gotoxy(9,2);
lcd_putc(cc);
lcd_gotoxy(10,2);
69
INFOCAL MLPQ
lcd_putc(dd);
lcd_gotoxy(11,2);
lcd_putc(uu);
if((uu>=u[2])&&(dd>=u[1])&&(cc>=u[0])&&(f==1))
{
f=0;
output_e(0);
disable_interrupts(int_timer1);
write_eeprom (0x2100,h5);
write_eeprom (0x2101,h4);
write_eeprom (0x2102,h3);
write_eeprom (0x2103,h2);
write_eeprom (0x2104,h1);
write_eeprom (0x2105,mn);
write_eeprom (0x2106,sg);
uu='0';
dd='0';
cc='0';
}
goto test;
}
#include <16f877a.h>
#use delay(clock=11059200)
#fuses hs,nowdt
#define use_portd_kbd TRUE
#include <kbd.c>
int tabla[10]={63,6,91,79,102,109,125,7,127,111};
signed int8 uni=0,dec=0,cen=0,mil=0;
char k;
void main()
{
port_b_pullups(true);
ext_int_edge(h_to_l);
enable_interrupts(global);
enable_interrupts(int_ext);
kbd_init();
ini:
k=kbd_getc();
if(k!=0)
{
if(k!='*'&&k!='#')
{
k=k&15;
mil=cen;
70
INFOCAL MLPQ
cen=dec;
dec=uni;
uni=k;
}
if(k=='*')
{
output_high(pin_e0);
}
if(k=='#')
{
uni=0;
cen=0;
dec=0;
mil=0;
}
}
if(uni==0&&dec==0&&cen==0&&mil==0)
{
output_low(pin_e0);
}
output_a(~1);
output_c(tabla[mil]);
delay_ms(4);
output_a(~2);
output_c(tabla[cen]);
delay_ms(4);
output_a(~4);
output_c(tabla[dec]);
delay_ms(4);
output_a(~8);
output_c(tabla[uni]);
delay_ms(4);
goto ini;
}
#int_ext
void incremento()
{
delay_ms(20);
uni--;
if (uni<0)
{
uni=9;
dec--;
if (dec<0)
{
dec=9;
cen--;
71
INFOCAL MLPQ
if(cen<0)
{
cen=9;
mil--;
if(mil<0)
{
mil=9;
}
}
}
}
if(uni==9&&dec==9&&cen==9&&mil==9)
{
uni=0;
cen=0;
dec=0;
mil=0;
}
}
72
INFOCAL MLPQ
73
INFOCAL MLPQ
Modulo II
#include <16f877a.h>
#use delay(clock=11059200)
#fuses hs,nowdt
#define LCD_DATA_PORT getenv("SFR:PORTc")
#include <lcd.c>
#include <kbd.c>
int16 cont=0,seg=0,a,b,c,x;
char tecla;
#INT_timer1
void segundos()
{
if(cont==6)
{
cont=0;
seg--;
if(seg==0)
{
disable_interrupts(int_timer1);
output_low(pin_a1);
delay_ms(200);
output_high(pin_a0);
}
}
printf(lcd_putc,"\nT.Act = %03lu",seg);
cont++;
set_timer1(7936);
}
#INT_ext
void parada()
{
seg=x;
output_low(pin_a0);
delay_ms(200);
output_high(pin_a1);
enable_interrupts(int_timer1);
}
void main()
{
output_a(0);
port_b_pullups(true);
setup_timer_1(t1_internal|t1_div_by_8);
set_timer1(7936);
ext_int_edge(h_to_l);
74
INFOCAL MLPQ
disable_interrupts(int_timer1);
disable_interrupts(int_ext);
enable_interrupts(global);
lcd_init();
kbd_init();
x=read_eeprom(0);
seg=x;
printf(lcd_putc,"\fT.Prog = %03lu",x);
printf(lcd_putc,"\nT.Act = %03lu",seg);
inicio:
tecla=kbd_getc();
if((tecla!=0)&&(tecla!='#')&&(tecla!='*'))
{
a=b;
b=c;
c=tecla&15;
x=c+b*10+a*100;
printf(lcd_putc,"\fT.Prog = %03lu",x);
printf(lcd_putc,"\nT.Act = %03lu",seg);
}
if(tecla=='#')
{
if(x<256)
{
write_eeprom(0,x);
lcd_putc("\fGRABANDO...");
delay_ms(1000);
seg=x;
}
else
{
lcd_putc("\f**MAX 255 Seg**");
delay_ms(3000);
}
printf(lcd_putc,"\fT.Prog = %03lu",x);
printf(lcd_putc,"\nT.Act = %03lu",seg);
}
if(tecla=='*')
{
seg=x;
output_high(pin_a0);
output_low(pin_a1);
clear_interrupt(int_ext);
enable_interrupts(int_ext);
}
goto inicio;
}
75
INFOCAL MLPQ
#include <16f877a.h>
#fuses xt,nowdt
#use delay(clock=4M)
#use rs232(baud = 9600,xmit=pin_C6,rcv=pin_c7)
#include <lcd.c>
#define use_portb_kbd true
#include<kbd.c>
Char envio,recibo;
#int_rda
void recepcion()
{
recibo=getc();
lcd_putc(recibo);
}
void main()
{
lcd_init();
76
INFOCAL MLPQ
kbd_init();
port_b_pullups(true);
enable_interrupts(global);
enable_interrupts(int_rda);
while(true)
{
envio=kbd_getc();
if(envio!=0)
{
lcd_putc(envio);
putc(envio);
}
}
}
#include <16f877a.h>
#device adc=10
#fuses xt,nowdt
#use delay(clock=4M)
#use rs232(baud = 9600,xmit=pin_C6,rcv=pin_c7)
#include <lcd.c>
int16 lectura;
77
INFOCAL MLPQ
float grados;
Char envio;
#int_ad
void temperatura()
{
lectura = read_adc(adc_read_only);
grados = (4.888*lectura)/10;
printf(lcd_putc,"\nTEMP = %1.2f C",grados);
printf("TEMP = %1.2f C\r",grados);
}
void main()
{
lcd_init();
setup_adc(adc_clock_internal);
setup_adc_ports(an0);
enable_interrupts(int_ad);
enable_interrupts(global);
set_adc_channel(0);
lcd_putc("**TERMOMETRO**");
ini:
read_adc(adc_start_only);
sleep();
delay_ms(1000);
goto ini;
}
78
INFOCAL MLPQ
#include<16f877a.h>
#fuses hs,nowdt
#use delay(clock=11059200)
#use i2C(master,scl=pin_c3,sda=pin_c4)
#include<lcd.c>
void main()
{
char texto[]={"microcontrolador"};
char dato;
int i;
lcd_init();
lcd_putc("Memoria i2c\n");
79
INFOCAL MLPQ
i2c_start();
i2c_write(0xa0);
i2c_write(0x10);
for(i=0;i<16;i++)
{
i2c_write(texto[i]);
}
i2c_stop();
delay_ms(20);
inicio:
i2c_start();
i2c_write(0xa0);
i2c_write(0x10);
i2c_start();
i2c_write(0xa1);
for(i=0;i<16;i++)
{
dato=i2c_read();
lcd_putc(dato);
delay_ms(250);
}
i2c_stop();
lcd_putc("\fMemoria i2c\n");
goto inicio;
}
80
INFOCAL MLPQ
#include<18f4550.h>
#fuses xt,nowdt,nomclr
#use delay(clock=4000000)
#use rs232(UART1,BAUD=9600)
#use RTOS(timer=0,minor_cycle=50ms)
#task(rate=1s,max=10ms)
void tarea1()
{
printf("tarea1\r");
}
#task(rate=2s,max=10ms)
void tarea2()
{
printf("tarea2\r");
}
#task(rate=3s,max=10ms)
void tarea3()
{
printf("tarea3\r");
}
void main()
{
setup_timer_0(RTCC_internal|RTCC_DIV_1);
rtos_run();
}
81
INFOCAL MLPQ
#include<18f4550.h>
#fuses xt,nowdt,nomclr
#use delay(clock=4000000)
#use RTOS(timer=0,minor_cycle=10ms)
#include<lcd.c>
int cuenta;
#task(rate=500ms,max=1ms)
void activo()
{
OUTPUT_TOGGLE(PIN_c0);
}
#task(rate=1s,max=10ms,queue=1)
void mostrar()
{
if(rtos_msg_poll()>0)
{
printf(lcd_putc,"\nNumero = %3u",rtos_msg_read());
}
}
#task(rate=200ms,max=2ms)
void generator()
{
cuenta++;
82
INFOCAL MLPQ
if(input(pin_c7)==0)
{
rtos_msg_send(mostrar,cuenta);
}
output_b(cuenta);
}
void main()
{
lcd_init();
output_b(0);
lcd_putc("Presionar boton");
setup_timer_0(RTCC_internal|RTCC_DIV_1);
rtos_run();
}
#include <18f4550.h>
#fuses xt,nowdt,nomclr
#use delay(clock=4000000)
#use RTOS(timer=0,minor_cycle=1ms)
#include <lcd.c>
#define use_portb_kbd true
#include <kbd.c>
int digito;
int semaforo=0;
#task(rate=250ms,max=1ms)
void activo()
83
INFOCAL MLPQ
{
output_toggle(pin_c0);
rtos_yield();
}
#task(rate=1ms,max=1ms)
void barrido()
{
digito=kbd_getc();
if(digito!=0)rtos_signal(semaforo);
}
#task(rate=1ms,max=1ms)
void generator()
{
rtos_wait(semaforo);
lcd_putc(digito);
}
void main()
{
lcd_init();
kbd_init();
lcd_putc("Presionar teclas\n");
output_low(pin_c0);
setup_timer_0(RTCC_internal|RTCC_DIV_1);
rtos_run();
ini:
sleep();
goto ini;
}
84
INFOCAL MLPQ
85
INFOCAL MLPQ
86