Los PIC son una familia de microcontroladores tipo RISC fabricados por Microchip Technology Inc. y derivados del PIC1650, originalmente desarrollado por la división de microelectrónica de General Instrument.
El nombre actual no es un acrónimo. En realidad, el nombre completo es PICmicro, aunque generalmente se utiliza como Peripheral Interface Controller (controlador de interfaz periférico).
El PIC original se diseñó para ser usado con la nueva CPU de 16 bits CP16000. Siendo en general una buena CPU, ésta tenía malas prestaciones de entrada y salida, y el PIC de 8 bits se desarrolló en 1975 para mejorar el rendimiento del sistema quitando peso de E/S a la CPU. El PIC utilizaba microcódigo simple almacenado en ROM para realizar estas tareas; y aunque el término no se usaba por aquel entonces, se trata de un diseño RISC que ejecuta una instrucción cada 4 ciclos del oscilador.
En 1985 la división de microelectrónica de General Instrument se separa como compañía independiente que es incorporada como filial (el 14 de diciembre de 1987 cambia el nombre a Microchip Technology y en 1989 es adquirida por un grupo de inversores) y el nuevo propietario canceló casi todos los desarrollos, que para esas fechas la mayoría estaban obsoletos. El PIC, sin embargo, se mejoró con EPROM para conseguir un controlador de canal programable. Hoy en día multitud de PICs vienen con varios periféricos incluidos (módulos de comunicación serie, UARTs, núcleos de control de motores, etc.) y con memoria de programa desde 512 a 32.000 palabras (una palabra corresponde a una instrucción en lenguaje ensamblador, y puede ser de 12, 14, 16 ó 32 bits, dependiendo de la familia específica de PICmicro).
viernes, 31 de enero de 2014
jueves, 30 de enero de 2014
Variables
¿Qué son las variables? pues sencillamente el poder identificar con un nombre una o varias posiciones de memoria de la RAM de nuestro PIC y de esta manera el poder almacenar allí los datos que va a utilizar nuestro programa.
En C para poder utilizar una variable primeramente hay que declararla siguiendo la siguiente sintaxis:
tipo nombre_variable [=valor];
Lo que va entre corchetes es porque es opcional es decir, las variables se pueden inicializar ó no al declararlas.
Ejemplo de variable declarada:
int i;
Ejemplo de variable declarada e inicializada:
int i=5;
Los tipos de datos básicos que utiliza nuestro compilador son los siguientes:
Sin embargo el compilador CCS también admite los siguientes tipos de datos definidos en el estándar C y que son los que normalmente se utilizan a la hora de programar:
En C para poder utilizar una variable primeramente hay que declararla siguiendo la siguiente sintaxis:
tipo nombre_variable [=valor];
Lo que va entre corchetes es porque es opcional es decir, las variables se pueden inicializar ó no al declararlas.
Ejemplo de variable declarada:
int i;
Ejemplo de variable declarada e inicializada:
int i=5;
Los tipos de datos básicos que utiliza nuestro compilador son los siguientes:
Sin embargo el compilador CCS también admite los siguientes tipos de datos definidos en el estándar C y que son los que normalmente se utilizan a la hora de programar:
Ejemplos
int numero=0;
numero=150; //decimal
numero=0xFF; //exadecimal
numro=0b01001101; //binario
miércoles, 29 de enero de 2014
Parpadeo de Led
Ejemplo 1
#include <16f877a.h>
#use delay(clock = 4M)
#fuses HS,NOWDT,NOLVP
#use fast_IO(B)
void main ()
{
set_tris_B(0x00);
while(true)
{
output_high(pin_B0) ;
delay_ms(1000);
output_low(pin_B0);
delay_ms(1000);
}
}
Ejemplo 2
#include <16F877A.h> //libreria para el manejo del 16F877A
#use delay(clock=4000000) //declara la frecuencia del cristal
///configura los fusibles
/// HS es la configuraricion del oscilador la cual indica High speed es decir
/// frecuencias altas esto es a partir de 8 Mhz.
/// NOWDT deshabilita el Watch Dog Timer
/// NOPUT deshabilita le reseteo de power up timer
/// NOPROTECT deshabilita la proteccion del codigo del pic.
#fuses HS,NOWDT,NOPUT,NOPROTECT
/// asignamos a variable port_b el espacio memoria 0x06 que es la dir de port_b
#byte port_b=0x06
int contador; //variable global
void main()
{
set_tris_b(0); //declaramos el puerto B como salidas
port_b=0;
while (true) {
//activa todos los pins del puerto B
contador=0xff;
port_b=contador;
delay_ms(1000); //Retardo de 1000 milisegundos es decir 1 segundo
//apaga todos los pins del puerto B
contador=0x00;
port_b=contador;
delay_ms(1000);//Retardo de 1000 milisegundos es decir 1 segundo
}
}
Ejemplo 3
#include <12F629.h>
#use delay(clock = 4M)
#fuses INTRC_IO,NOWDT,NOMCLR,PUT,BROWNOUT
#use STANDARD_IO(A)
#define s1 PIN_A0
#define f1 PIN_A1
void main()
{
set_tris_a(0b100000);
while(true){
output_low(f1);
delay_ms(1000);
output_high(f1);
delay_ms(1000);
}
}
Leds secuenciales
en binario
#include <16F877A.h>
#use delay(clock=4M)
void main()
{
int i=0b10000000;
set_tris_b(0x00);
while (true){
i=i>>1;
output_b(i);
delay_ms(1000);
}
}
en decimal
#include <16F877A.h>
#use delay(clock=4M)
void main()
{
int i=0;
set_tris_b(0x00);
while (true){
i++;
output_b(i);
delay_ms(1000);
}
}
Ejemplo 1
#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use standard_io(B) //puerto B como salida
#byte portb= 0x6 //direccion port b
///PROGRAMA
void main(void)
{
int led_on=0b00000001; //led a iluminar
set_tris_b(0x00); //portb como salida (algunas desactivadas)
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{ //bucle...
do{ //iluminacion hacia izquierda
portb=led_on;
rotate_left(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,7)==0);
do{ //iluminacion hacia derecha
portb=led_on;
rotate_right(&led_on,1);
delay_ms(300);
}while(bit_test(led_on,0)==0);
}while(TRUE); //...infinito
}
Ejemplo 2
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#use delay(clock=4000000) /// declara la frecuencia del cristal
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
int conteo=0;
#use fast_io(A)
#use fast_io(B)
#use fast_io(C) /// con esta instruccion evitamos que
#use fast_io(D) /// se este configurando cada vez que usamos
#use fast_io(E) /// alguna instruccion de entrada o salida
#byte porta = 5
#byte portb = 6
#byte portc = 7 /// se definen direcciones de memoria
#byte portd = 8
#byte porte = 9
void main(void)
{
set_tris_b(0x00);
while(true) //bucle infinito
{
conteo++;
if((conteo&0x0f)>9) // aqui observamos si el primer display llego a 10
// para solo comparar los primeros 4 bit hacemos una
// operacion and con 0x0f
{
conteo=conteo+10; // hacemos que los 4 bits mas significativos incrementen
conteo=conteo&0xf0;
}
if(conteo>99) {conteo=0;} // verificamos que la cuenta se haga de 0 a 99
else{ portb=conteo; delay_ms(400);}
} //fin de ciclo while
} //fin de programa
martes, 28 de enero de 2014
Parpadeo de led 18F4550
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20M)
#use fast_io(B)
void main()
{
port_b_pullups(TRUE);
set_tris_B(0x1);
output_low(PIN_B1);
while (true){
output_high(pin_b1);
delay_ms(200);
output_low(pin_b1);
delay_ms(200);
}
}
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20M)
#use fast_io(B)
void main()
{
port_b_pullups(TRUE);
set_tris_B(0x1);
output_low(PIN_B1);
while (true){
output_high(pin_b1);
delay_ms(200);
output_low(pin_b1);
delay_ms(200);
}
}
Pulsador
Ejemplo 1
#include <16f877A.h>
#use delay (clock=4000000) // Fosc=4Mhz
#fuses xt,nowdt,noprotect // fusibles
#byte port_a=5 // declaramos el puerto a en su localidad
#byte port_b=6 // declaramos el puerto b en su localidad
void main(void)
{
set_tris_a(0b00000001); // programamos el puerto a para que RA0 sea entrada
set_tris_b(0b00000000); // programamos el puerto b para q sea salida
port_b=0x00; // inicialmente todo el puerto b estara apagado
while (true) // bucle infinito,o que el programa se ejecutara infinitamente
{
if (input(pin_a0)==0) // preguntamos si RA0 es cero
{
port_b=0b00000001; // cuando se cierra el pulsador ejecuta esta tarea
delay_ms(500); // la cual es encender un led conectado en RB0
port_b=0b00000000;
}
}
}
Ejemplo 2
#include <16F877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#use fast_io(A) /// con esta instruccion evitamos que
/// se este configurando cada vez que usamos
#use fast_io(B) /// alguna instruccion de entrada o salida
#byte porta = 0x05 // se definen las direcciones de memoria
#byte portb = 0x06
void main(void)
{
set_tris_a(0xff); // se configura el puerto B como entrada
set_tris_b(0x00); // se configura el puerto C como salida
while(true) // Bucle infinito
{
port_b_pullups(true); // activa las resistencias de pull-up
portb=porta;
}
}
lunes, 27 de enero de 2014
EEPROM interna
#include <16f877A.h>
#use delay (clock=20000000)
#fuses HS,NOWDT,NOLVP
#include<lcd.c>
void main(void)
{
long int cont2=155;
int direccion = 0;
lcd_init(); //inicializa lcd
printf(lcd_putc, "...");
WHILE (TRUE) {
write_eeprom(direccion,cont2); //Escribes byte (parte menos significativa del int16)
printf(lcd_putc, "Dato w: %Lu",cont2);
delay_ms(2000);
cont2=100;
cont2=read_eeprom(direccion);
printf(lcd_putc, "Dato r: %Lu",cont2);
delay_ms(2000);
}
}
#use delay (clock=20000000)
#fuses HS,NOWDT,NOLVP
#include<lcd.c>
void main(void)
{
long int cont2=155;
int direccion = 0;
lcd_init(); //inicializa lcd
printf(lcd_putc, "...");
WHILE (TRUE) {
write_eeprom(direccion,cont2); //Escribes byte (parte menos significativa del int16)
printf(lcd_putc, "Dato w: %Lu",cont2);
delay_ms(2000);
cont2=100;
cont2=read_eeprom(direccion);
printf(lcd_putc, "Dato r: %Lu",cont2);
delay_ms(2000);
}
}
domingo, 26 de enero de 2014
RS232
#include <16f877a.h>
#use delay (clock=4M)
#use RS232 (baud=9600, bits=8, parity=N, xmit=pin_c6, rcv=pin_c7)
void main()
{
printf("Hola mundo \r");
delay_ms(2000);
printf("aaaaaaffffa");
}
Comunicacion 2 pics
Receptor
#include <16f877a.h>
#use delay (clock=4M)
#use RS232 (baud=9600, bits=8, parity=N, xmit=pin_c6, rcv=pin_c7)
char d='x';
#int_rda
void inter_serie(){
d='x';
if(kbhit()){
d=getc();
}
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_rda);
while(true){
if(d=='1'){
output_high(pin_b0);
}
if(d=='0'){
output_low(pin_b0);
}
}
}
Emisor
#include <16f877a.h>
#use delay (clock=4M)
#use RS232 (baud=9600, bits=8, parity=N, xmit=pin_c6, rcv=pin_c7)
void main()
{
while(true){
if(input(pin_b0)){
printf("1");
delay_ms(2000);
}
if(!input(pin_b0)){
printf("0");
delay_ms(2000);
}
}
}
Display 7 segmentos
Comu. Bluetooth
#include <16F877A.h>
#use delay(clock=20M)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#use RS232 (baud=9600, bits=8, parity=N, xmit=pin_c6, rcv=pin_c7)
#use fast_IO(B)
char d='x';
#int_rda
void inter_serie(){
d='x';
if(kbhit()){
d=getc();
}}
void main(void)
{
set_tris_B(0x00);
enable_interrupts(global);
enable_interrupts(int_rda);
output_high(pin_B0) ;
delay_ms(1000);
output_low(pin_B0) ;
while(true){
if(d=='1'){
output_high(pin_B0) ;
}
if(d=='2'){
output_low(pin_B0) ;
}
delay_ms(50);
}
}
#use delay(clock=20M)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#use RS232 (baud=9600, bits=8, parity=N, xmit=pin_c6, rcv=pin_c7)
#use fast_IO(B)
char d='x';
#int_rda
void inter_serie(){
d='x';
if(kbhit()){
d=getc();
}}
void main(void)
{
set_tris_B(0x00);
enable_interrupts(global);
enable_interrupts(int_rda);
output_high(pin_B0) ;
delay_ms(1000);
output_low(pin_B0) ;
while(true){
if(d=='1'){
output_high(pin_B0) ;
}
if(d=='2'){
output_low(pin_B0) ;
}
delay_ms(50);
}
}
sábado, 25 de enero de 2014
Multiplexar
#include <16F877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPUT,NOPROTECT
#byte port_a=0x05
#byte port_b=0x06
void main()
{
BYTE data[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
set_tris_a(0x00);
set_tris_b(0x00);
output_low(pin_a0);
output_low(pin_a1);
while(true){
output_low(pin_a0);
output_low(pin_a1);
output_b(data[1]);
output_high(pin_a1);
output_low(pin_a0);
delay_ms(1); //1-20
output_low(pin_a0);
output_low(pin_a1);
output_b(data[2]);
output_high(pin_a0);
output_low(pin_a1);
delay_ms(1); //1-20
}
}
74HC595
#include <16F877A.h>
#use delay(clock=2M)
#include <74595.c>
void main() {
int i;
BYTE datos = 0xF5;
BYTE data[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
set_tris_b(0x00);
do {
for(i=0;i<10;i++){
datos= data[i];
write_expanded_outputs (&datos);
delay_ms(900);
}
} while (TRUE);
}
#use delay(clock=2M)
#include <74595.c>
void main() {
int i;
BYTE datos = 0xF5;
BYTE data[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
set_tris_b(0x00);
do {
for(i=0;i<10;i++){
datos= data[i];
write_expanded_outputs (&datos);
delay_ms(900);
}
} while (TRUE);
}
viernes, 24 de enero de 2014
Display LCD
#include <16F877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#define use_portb_lcd TRUE
#include <lcd.c>
void main(void)
{
lcd_init();
lcd_putc("Hola mundo !!!");
}
Display LCD 4x20
Libreria lcd420
#include <16F877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#include <Flex_LCD420.c>
void main(void)
{
lcd_init();
lcd_putc("Hola mundo !!!");
while(true){
lcd_gotoxy(1,1);
lcd_putc("Uno");
lcd_gotoxy(1,2);
lcd_putc("dos");
lcd_gotoxy(1,3);
lcd_putc("tres");
lcd_gotoxy(1,4);
lcd_putc("Cuatro");
delay_ms(1000);
}
}
#include <16F877A.h>
#use delay(clock=4000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT,NOPROTECT
#include <Flex_LCD420.c>
void main(void)
{
lcd_init();
lcd_putc("Hola mundo !!!");
while(true){
lcd_gotoxy(1,1);
lcd_putc("Uno");
lcd_gotoxy(1,2);
lcd_putc("dos");
lcd_gotoxy(1,3);
lcd_putc("tres");
lcd_gotoxy(1,4);
lcd_putc("Cuatro");
delay_ms(1000);
}
}
jueves, 23 de enero de 2014
Entrada analogica
Ejemplo 1
#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use fast_io(B)
#use fast_io(A)
#byte portb = 6 // se definen las direcciones de memoria
#byte porta = 5
int a=0;
void main() {
set_tris_a(0xff); // se configura el puerto A como entrada
set_tris_b(0x00);
SETUP_ADC(ADC_CLOCK_INTERNAL); // el a/d funcione con un reloj interno del micro
SETUP_ADC_PORTS(AN0); // aca determianr que el puerto RA0 será analógico
SET_ADC_CHANNEL(0); // el canal con el que trabajas, en este caso 0 por el RA0
while(true){
a=READ_ADC(); // lee el canal analogico seleccionado
output_high(pin_B0) ;
delay_ms(a);
output_low(pin_B0);
delay_ms(a);
}
}
Ejemplo 2
#include <16F877A.h>
#device adc=10 //resolucion de 1024 valores
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=4000000) //oscilador externo de 4MHz
#include <LCD.C>
float a=0;
void main()
{
setup_adc_ports(AN0_AN1_AN3); setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
while(true){
set_adc_channel(0);
a=read_adc();
printf(lcd_putc,"\f");
printf(lcd_putc,"Valor Digital");
lcd_gotoxy(1,2);
printf(lcd_putc,"%f",a);
delay_ms(100);
}
}
Ejemplo 3
#include <16F877A.h>
#use delay(clock=4000000)
#fuses NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOPROTECT,HS,NOWRT,NODEBUG
#use fast_io(A)
#use fast_io(B)
#use fast_io(C) /// con esta instruccion evitamos que
#byte porta = 5
#byte portb = 6
#byte portc = 7 /// se definen direcciones de memoria
int canal0=0;
int unidades=0;
int decenas=0;
int centenas=0;
void main ()
{
BYTE data[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
set_tris_b(0b00000000);
set_tris_c(0b00000000);
output_low(pin_c0);
output_low(pin_c1);
output_low(pin_c2);
SETUP_ADC(ADC_CLOCK_INTERNAL); // declaramos que el reloj del adc sera interno
setup_adc_ports(all_analog); // todos los canales analogicos habilitados
SET_ADC_CHANNEL(0); // seleccionamos canal 0
DISABLE_INTERRUPTS(global);
while(true)
{
canal0= READ_ADC(); // retardo para esperar que el adc termine
// conversion fabricante menciona que al
// menos 50 microsegundos
delay_ms(1);
centenas=canal0/100;
decenas=(canal0 - (centenas*100))/10;
unidades=(canal0 - (centenas*100) - (decenas*10));
output_b(data[unidades]);
output_high(pin_c1);
output_high(pin_c2);
output_low(pin_c0);
delay_ms(1);
output_b(data[decenas]);
output_high(pin_c0);
output_high(pin_c2);
output_low(pin_c1);
delay_ms(1);
output_b(data[centenas]);
output_high(pin_c1);
output_high(pin_c0);
output_low(pin_c2);
delay_ms(1);
}
}
#include <16F877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use fast_io(B)
#use fast_io(A)
#byte portb = 6 // se definen las direcciones de memoria
#byte porta = 5
int a=0;
void main() {
set_tris_a(0xff); // se configura el puerto A como entrada
set_tris_b(0x00);
SETUP_ADC(ADC_CLOCK_INTERNAL); // el a/d funcione con un reloj interno del micro
SETUP_ADC_PORTS(AN0); // aca determianr que el puerto RA0 será analógico
SET_ADC_CHANNEL(0); // el canal con el que trabajas, en este caso 0 por el RA0
while(true){
a=READ_ADC(); // lee el canal analogico seleccionado
output_high(pin_B0) ;
delay_ms(a);
output_low(pin_B0);
delay_ms(a);
}
}
Ejemplo 2
#include <16F877A.h>
#device adc=10 //resolucion de 1024 valores
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=4000000) //oscilador externo de 4MHz
#include <LCD.C>
float a=0;
void main()
{
setup_adc_ports(AN0_AN1_AN3); setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
while(true){
set_adc_channel(0);
a=read_adc();
printf(lcd_putc,"\f");
printf(lcd_putc,"Valor Digital");
lcd_gotoxy(1,2);
printf(lcd_putc,"%f",a);
delay_ms(100);
}
}
Ejemplo 3
#include <16F877A.h>
#use delay(clock=4000000)
#fuses NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,NOLVP,NOPROTECT,HS,NOWRT,NODEBUG
#use fast_io(A)
#use fast_io(B)
#use fast_io(C) /// con esta instruccion evitamos que
#byte porta = 5
#byte portb = 6
#byte portc = 7 /// se definen direcciones de memoria
int canal0=0;
int unidades=0;
int decenas=0;
int centenas=0;
void main ()
{
BYTE data[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
set_tris_b(0b00000000);
set_tris_c(0b00000000);
output_low(pin_c0);
output_low(pin_c1);
output_low(pin_c2);
SETUP_ADC(ADC_CLOCK_INTERNAL); // declaramos que el reloj del adc sera interno
setup_adc_ports(all_analog); // todos los canales analogicos habilitados
SET_ADC_CHANNEL(0); // seleccionamos canal 0
DISABLE_INTERRUPTS(global);
while(true)
{
canal0= READ_ADC(); // retardo para esperar que el adc termine
// conversion fabricante menciona que al
// menos 50 microsegundos
delay_ms(1);
centenas=canal0/100;
decenas=(canal0 - (centenas*100))/10;
unidades=(canal0 - (centenas*100) - (decenas*10));
output_b(data[unidades]);
output_high(pin_c1);
output_high(pin_c2);
output_low(pin_c0);
delay_ms(1);
output_b(data[decenas]);
output_high(pin_c0);
output_high(pin_c2);
output_low(pin_c1);
delay_ms(1);
output_b(data[centenas]);
output_high(pin_c1);
output_high(pin_c0);
output_low(pin_c2);
delay_ms(1);
}
}
miércoles, 22 de enero de 2014
PWM
Ejemplo 1
#include <16F877A.h>
#use delay(clock=4M)
#define MAX_DUTY 255
void main()
{
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,254,8);
set_tris_b(0xff);
set_tris_c(0x00);
while (true){
if(input(pin_b0)){
set_pwm1_duty(255);
}
if(input(pin_b1)){
set_pwm1_duty(100);
}
if(!input(pin_b0) && !input(pin_b1)){
set_pwm1_duty(0);
}
}
}
Ejemplo 2
#include <16F877A.h>
#use delay(clock=40M)
#fuses HS,NOWDT,NOLVP
#define MAX_DUTY 255
void main(){
int i;
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,254,8);
set_tris_b(0xff);
set_tris_c(0x00);
while(true){
for(i=0;i<=255;i++){
set_pwm1_duty(i);
delay_ms(50);
}
}
}
#include <16F877A.h>
#use delay(clock=4M)
#define MAX_DUTY 255
void main()
{
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,254,8);
set_tris_b(0xff);
set_tris_c(0x00);
while (true){
if(input(pin_b0)){
set_pwm1_duty(255);
}
if(input(pin_b1)){
set_pwm1_duty(100);
}
if(!input(pin_b0) && !input(pin_b1)){
set_pwm1_duty(0);
}
}
}
Ejemplo 2
#include <16F877A.h>
#use delay(clock=40M)
#fuses HS,NOWDT,NOLVP
#define MAX_DUTY 255
void main(){
int i;
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,254,8);
set_tris_b(0xff);
set_tris_c(0x00);
while(true){
for(i=0;i<=255;i++){
set_pwm1_duty(i);
delay_ms(50);
}
}
}
martes, 21 de enero de 2014
Reloj real
ds1307.c
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#fuses XT
#use delay(clock=4M)
#include <DS1307.c>
#define use_portd_lcd TRUE
#include <LCD.c>
int sec=3,min=3,hora=3,dia=1, mes=1,anio=14,dow=1;
char fecha[4];
void main(){
lcd_init();
ds1307_set_date_time(dia,mes,anio,dow,hora,min,sec);
while(true){
ds1307_get_date(dia,mes,anio,dow);
ds1307_get_time(hora,min,sec);
ds1307_get_day_of_week(fecha);
lcd_gotoxy(2,1);
printf(lcd_putc, "%s %02u/%02u/20%02u",fecha,dia,mes,anio);
lcd_gotoxy(5,2);
printf(lcd_putc, "%02u:%02u:%02u",hora, min, sec);
delay_ms(200);
}}
#include <16F877A.h> /// libreria para el manejo del pic16f877a
#fuses XT
#use delay(clock=4M)
#include <DS1307.c>
#define use_portd_lcd TRUE
#include <LCD.c>
int sec=3,min=3,hora=3,dia=1, mes=1,anio=14,dow=1;
char fecha[4];
void main(){
lcd_init();
ds1307_set_date_time(dia,mes,anio,dow,hora,min,sec);
while(true){
ds1307_get_date(dia,mes,anio,dow);
ds1307_get_time(hora,min,sec);
ds1307_get_day_of_week(fecha);
lcd_gotoxy(2,1);
printf(lcd_putc, "%s %02u/%02u/20%02u",fecha,dia,mes,anio);
lcd_gotoxy(5,2);
printf(lcd_putc, "%02u:%02u:%02u",hora, min, sec);
delay_ms(200);
}}
lunes, 20 de enero de 2014
Matrix 8x8
#include <16F877a.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=20M)
#use fast_io(B)
#use fast_io(D)
void main()
{
int y=0,p=0,tiempo=20,ml=5;
BYTE ay[8]={0b10000000,0b01000000,0b00100000,0b00010000,0b00001000,0b00000100,0b00000010,0b00000001};
BYTE carita[8]={
0b11000011,
0b10111101,
0b01011010,
0b01111110,
0b01111110,
0b01000010,
0b10111101,
0b11000011};
port_b_pullups(TRUE);
set_tris_B(0x0);
set_tris_D(0x0);
output_b(0x0);
output_d(0x0);
while (true){
for(p=0;p<=tiempo;p++){
for(y=0;y<=7;y++){
output_b(carita[y]);
output_d(ay[y]);
delay_ms(ml);
}
}
}
}
Medir distancia SR04
#include <16F877.h>
#FUSES XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include <lcd.c>
int16 distancia, tiempo;
#define trig pin_B1
#define echo pin_B0
#USE standard_io(b)
void main()
{
lcd_init();
printf(LCD_PUTC, "\f Iniciando.");
delay_ms(500);
printf(LCD_PUTC, "\f Iniciando..");
delay_ms(500);
printf(LCD_PUTC, "\f Iniciando...");
delay_ms(500);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
while(true)
{
output_high(trig);
delay_us(20);
output_low(trig);
while(!input(echo))
{}
set_timer1(0);
while(input(echo))
{}
tiempo=get_timer1();
distancia=(tiempo*10)/(58.0);
printf(LCD_PUTC, "\fTiempo :%Lu \nDistancia = %Lu",tiempo,distancia);
delay_ms(500);
}
}
domingo, 19 de enero de 2014
Sonido
Ejemplo 1
#include <16f877a.h> // Tipo de microcontrolador
#use delay(clock=4000000) // Delay con xtal de 4MHz
#use fast_io(B) // I/O todas rápidas, de esta forma cuando se
// escribe en los puertos, no se configura el tris
// acelerando el proceso.
#fuses HS // FUSES cristal HS >=4MHz
#FUSES NOPUT // No power up Timer, no espera a estabilizar la tension
#FUSES NOBROWNOUT // No Brown out reset, no se resetea si cae la tension
#define Speaker PIN_B0 // Altavoz conectado a RB0
void main(){
set_tris_b(2); // RB<7:2> Salida RB1 entrada (Pulsador) RB0 Salida (Speaker)
do{ // Bucle infinito
while(input(PIN_B1)){ // Mientras se presione el
// interruptor conectado a RB1.
output_high(Speaker); // Altavoz encendido
delay_us(769); // espera 769 uS
output_low(Speaker); // Altavoz apagado
delay_us(769); // espera 769 uS
}
}while(true);
}
Ejemplo 2
#include <16f877a.h> // Tipo de microcontrolador
#use delay(clock=4000000) // Delay con xtal de 4MHz
#use fast_io(B) // I/O todas rápidas, de esta forma cuando se
// escribe en los puertos, no se configura el tris
// acelerando el proceso.
#FUSES HS // FUSES cristal HS >=4MHz
#FUSES NOPUT // No power up Timer, no espera a estabilizar la tension
#FUSES NOBROWNOUT // No Brown out reset, no se resetea si cae la tension
#define Speaker PIN_B0 // Altavoz conectado a RB0
void Sound(int16 frecuencia, int16 duracion);
void main(){
int t;
set_tris_b(2);
while(true){ //Bucle infinito
if (input(PIN_B1)){ // Si se activa el pulsador
for (t=0;t<30;t++) // Bucle ascendente incrementando la
sound(((int16)t*15)+1600,20); // frecuencia del sonido
for (t=30;t>0;t--) // Bucle decrementando
sound(((int16)t*15)+1600,20); // la frecuencia del sonido
}
}
}
void Sound(int16 frecuencia, int16 duracion){
int16 mS_Transcurridos=0;
int16 CiclosL=0;
int16 uS;
int32 tmp;
if (frecuencia>=20&&frecuencia<=20000){ //si la frecuancia se encuentra entre
// los margenes de 20Hz y 20 KHz se ejecuta
tmp=100000; // de los contrario no.
tmp/=frecuencia; // convierte los Hz a microsegundos para la pausa
tmp*=5;
uS=tmp;
do{
output_high(Speaker); // Genera la frecuancia deseada
delay_us(uS); // con los retardos mientras
CiclosL+=(uS); // aumenta el contador de ciclos transcurridos
output_low(Speaker); // en dos partes para repartir el
delay_us(uS); // trabajo entre estado alto y bajo.
CiclosL+=(uS); //
CiclosL+=25; // Compensador.
while(CiclosL>999){ // Se queda en el bucle mientras CiclosL sea
// menor a 1000 (1 mS)
CiclosL-=1000; // Le resta 1000 a CiclosL
mS_Transcurridos++; // y le suma 1 a mS_Transcurridos.
CiclosL+=25; // Compensador.
}
}while (duracion>mS_Transcurridos);// Repite el bucle hasta que haya pasado el
// tiempo indicado.
}
}
Ejemplo 3
#include <16f877a.h>
#use delay(clock=4000000)
#use fast_io(B)
#fuses HS
#FUSES NOPUT
#FUSES NOBROWNOUT
#define Speaker PIN_B0
#define nDO 0 // DO
#define nDO_ 1 // DO#
#define nRE 2 // RE
#define nRE_ 3 // RE#
#define nMI 4 // MI
#define nFA 5 // FA
#define nFA_ 6 // FA#
#define nSOL 7 // SOL
#define nSOL_ 8 // SOL#
#define nLA 9 // LA
#define nLA_ 10 // LA#
#define nSI 11 // SI
int16 FreqNota[12]={ // retardos entre estado alto
// y bajo para generar las notas
15289, // DO
14430, // DO#
13620, // RE
12856, // RE#
12134, // MI
11453, // FA
10810, // FA#
10204, // SOL
9631, // SOL#
9090, // LA
8580, // LA#
8099 // SI
};
void Play(int nota,int octava,int16 duracion);
void PlayCancion(int cancion);
void main(){
set_tris_b(14); // B<3:1>: Pulsadores B0: Speaker
while (true){
if(input(PIN_B1))PlayCancion(1); //Si pulso switch 1 toca
// Pop Corn
if(input(PIN_B2))PlayCancion(2); //Si pulso switch 2 toca
// Ecuador
if(input(PIN_B3))PlayCancion(3); //Si pulso switch 3 toca
// The lion sleep tonight
}
}
void Play(int nota, int octava, int16 duracion){
int16 fn;
int16 mS_Transcurridos=0;
int16 CiclosL=0;
fn=FreqNota[nota]; // Define los retardos para generar
// la frecuencia de cada nota
fn>>=(octava); // Adapta la frecuencia
// a la octava actual
do{
output_high(Speaker); // Genera la frecuancia
delay_us(fn); // con los retardos mientras
CiclosL+=(fn); // aumenta el contador de
// ciclos transcurridos
output_low(Speaker); // en dos partes para repartir el
delay_us(fn); // trabajo entre estado alto y bajo.
CiclosL+=(fn); //
CiclosL+=25; // Compensador.
while(CiclosL>999){ // Se queda en el bucle mientras
// CiclosL sea menor a 1000 (1 mS)
CiclosL-=1000; // Le resta 1000 a CiclosL
mS_Transcurridos++; // y le suma 1 a mS_Transcurridos.
CiclosL+=25; // Compensador.
}
}while (duracion>mS_Transcurridos); // Repite el bucle hasta
// que haya pasado el
// tiempo indicado.
}
void PlayCancion(int cancion){
switch (cancion){
case 1:
//POP CORN
play (nDO ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nSOL ,4,166);
play (nRE_ ,4,166);
play (nSOL ,4,166);
play (nDO ,4,166);
delay_ms (166);
play (nDO ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nSOL ,4,166);
play (nRE_ ,4,166);
play (nSOL ,4,166);
play (nDO ,4,166);
delay_ms (166);
play (nDO ,5,166);
play (nRE ,5,166);
play (nRE_ ,5,166);
play (nRE ,5,166);
play (nRE_ ,5,166);
play (nDO ,5,166);
play (nRE ,5,166);
play (nDO ,5,166);
play (nRE ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nSOL_ ,4,166);
play (nDO ,5,166);
break;
case 2:
//ECUADOR
play (nLA ,3,100);
delay_ms (200);
play (nMI ,3,100);
delay_ms (200);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nSOL ,3,100);
delay_ms (100);
play (nLA ,3,100);
delay_ms (200);
play (nMI ,3,100);
delay_ms (200);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nSOL ,3,100);
delay_ms (100);
play (nDO ,4,100);
delay_ms (200);
play (nSOL ,3,100);
delay_ms (200);
play (nMI ,4,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nMI ,4,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nSOL ,3,100);
delay_ms (100);
play (nDO ,4,100);
delay_ms (200);
play (nLA ,3,100);
delay_ms (200);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nSOL ,3,100);
break;
case 3:
//The lion sleep tonight
play (nDO ,3,125);
delay_ms (250);
play (nRE ,3,125);
delay_ms (125);
play (nMI ,3,125);
delay_ms (250);
play (nRE ,3,125);
delay_ms (250);
play (nMI ,3,125);
play (nFA ,3,125);
delay_ms (250);
play (nMI ,3,125);
delay_ms (125);
play (nRE ,3,125);
delay_ms (250);
play (nDO ,3,125);
delay_ms (250);
play (nRE ,3,125);
play (nMI ,3,125);
delay_ms (250);
play (nRE ,3,125);
delay_ms (125);
play (nDO ,3,125);
delay_ms (250);
delay_ms (125);
play (nMI ,3,125);
delay_ms (125);
play (nRE ,3,500);
break;
}
}
#include <16f877a.h> // Tipo de microcontrolador
#use delay(clock=4000000) // Delay con xtal de 4MHz
#use fast_io(B) // I/O todas rápidas, de esta forma cuando se
// escribe en los puertos, no se configura el tris
// acelerando el proceso.
#fuses HS // FUSES cristal HS >=4MHz
#FUSES NOPUT // No power up Timer, no espera a estabilizar la tension
#FUSES NOBROWNOUT // No Brown out reset, no se resetea si cae la tension
#define Speaker PIN_B0 // Altavoz conectado a RB0
void main(){
set_tris_b(2); // RB<7:2> Salida RB1 entrada (Pulsador) RB0 Salida (Speaker)
do{ // Bucle infinito
while(input(PIN_B1)){ // Mientras se presione el
// interruptor conectado a RB1.
output_high(Speaker); // Altavoz encendido
delay_us(769); // espera 769 uS
output_low(Speaker); // Altavoz apagado
delay_us(769); // espera 769 uS
}
}while(true);
}
Ejemplo 2
#include <16f877a.h> // Tipo de microcontrolador
#use delay(clock=4000000) // Delay con xtal de 4MHz
#use fast_io(B) // I/O todas rápidas, de esta forma cuando se
// escribe en los puertos, no se configura el tris
// acelerando el proceso.
#FUSES HS // FUSES cristal HS >=4MHz
#FUSES NOPUT // No power up Timer, no espera a estabilizar la tension
#FUSES NOBROWNOUT // No Brown out reset, no se resetea si cae la tension
#define Speaker PIN_B0 // Altavoz conectado a RB0
void Sound(int16 frecuencia, int16 duracion);
void main(){
int t;
set_tris_b(2);
while(true){ //Bucle infinito
if (input(PIN_B1)){ // Si se activa el pulsador
for (t=0;t<30;t++) // Bucle ascendente incrementando la
sound(((int16)t*15)+1600,20); // frecuencia del sonido
for (t=30;t>0;t--) // Bucle decrementando
sound(((int16)t*15)+1600,20); // la frecuencia del sonido
}
}
}
void Sound(int16 frecuencia, int16 duracion){
int16 mS_Transcurridos=0;
int16 CiclosL=0;
int16 uS;
int32 tmp;
if (frecuencia>=20&&frecuencia<=20000){ //si la frecuancia se encuentra entre
// los margenes de 20Hz y 20 KHz se ejecuta
tmp=100000; // de los contrario no.
tmp/=frecuencia; // convierte los Hz a microsegundos para la pausa
tmp*=5;
uS=tmp;
do{
output_high(Speaker); // Genera la frecuancia deseada
delay_us(uS); // con los retardos mientras
CiclosL+=(uS); // aumenta el contador de ciclos transcurridos
output_low(Speaker); // en dos partes para repartir el
delay_us(uS); // trabajo entre estado alto y bajo.
CiclosL+=(uS); //
CiclosL+=25; // Compensador.
while(CiclosL>999){ // Se queda en el bucle mientras CiclosL sea
// menor a 1000 (1 mS)
CiclosL-=1000; // Le resta 1000 a CiclosL
mS_Transcurridos++; // y le suma 1 a mS_Transcurridos.
CiclosL+=25; // Compensador.
}
}while (duracion>mS_Transcurridos);// Repite el bucle hasta que haya pasado el
// tiempo indicado.
}
}
Ejemplo 3
#include <16f877a.h>
#use delay(clock=4000000)
#use fast_io(B)
#fuses HS
#FUSES NOPUT
#FUSES NOBROWNOUT
#define Speaker PIN_B0
#define nDO 0 // DO
#define nDO_ 1 // DO#
#define nRE 2 // RE
#define nRE_ 3 // RE#
#define nMI 4 // MI
#define nFA 5 // FA
#define nFA_ 6 // FA#
#define nSOL 7 // SOL
#define nSOL_ 8 // SOL#
#define nLA 9 // LA
#define nLA_ 10 // LA#
#define nSI 11 // SI
int16 FreqNota[12]={ // retardos entre estado alto
// y bajo para generar las notas
15289, // DO
14430, // DO#
13620, // RE
12856, // RE#
12134, // MI
11453, // FA
10810, // FA#
10204, // SOL
9631, // SOL#
9090, // LA
8580, // LA#
8099 // SI
};
void Play(int nota,int octava,int16 duracion);
void PlayCancion(int cancion);
void main(){
set_tris_b(14); // B<3:1>: Pulsadores B0: Speaker
while (true){
if(input(PIN_B1))PlayCancion(1); //Si pulso switch 1 toca
// Pop Corn
if(input(PIN_B2))PlayCancion(2); //Si pulso switch 2 toca
// Ecuador
if(input(PIN_B3))PlayCancion(3); //Si pulso switch 3 toca
// The lion sleep tonight
}
}
void Play(int nota, int octava, int16 duracion){
int16 fn;
int16 mS_Transcurridos=0;
int16 CiclosL=0;
fn=FreqNota[nota]; // Define los retardos para generar
// la frecuencia de cada nota
fn>>=(octava); // Adapta la frecuencia
// a la octava actual
do{
output_high(Speaker); // Genera la frecuancia
delay_us(fn); // con los retardos mientras
CiclosL+=(fn); // aumenta el contador de
// ciclos transcurridos
output_low(Speaker); // en dos partes para repartir el
delay_us(fn); // trabajo entre estado alto y bajo.
CiclosL+=(fn); //
CiclosL+=25; // Compensador.
while(CiclosL>999){ // Se queda en el bucle mientras
// CiclosL sea menor a 1000 (1 mS)
CiclosL-=1000; // Le resta 1000 a CiclosL
mS_Transcurridos++; // y le suma 1 a mS_Transcurridos.
CiclosL+=25; // Compensador.
}
}while (duracion>mS_Transcurridos); // Repite el bucle hasta
// que haya pasado el
// tiempo indicado.
}
void PlayCancion(int cancion){
switch (cancion){
case 1:
//POP CORN
play (nDO ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nSOL ,4,166);
play (nRE_ ,4,166);
play (nSOL ,4,166);
play (nDO ,4,166);
delay_ms (166);
play (nDO ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nSOL ,4,166);
play (nRE_ ,4,166);
play (nSOL ,4,166);
play (nDO ,4,166);
delay_ms (166);
play (nDO ,5,166);
play (nRE ,5,166);
play (nRE_ ,5,166);
play (nRE ,5,166);
play (nRE_ ,5,166);
play (nDO ,5,166);
play (nRE ,5,166);
play (nDO ,5,166);
play (nRE ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nLA_ ,4,166);
play (nDO ,5,166);
play (nSOL_ ,4,166);
play (nDO ,5,166);
break;
case 2:
//ECUADOR
play (nLA ,3,100);
delay_ms (200);
play (nMI ,3,100);
delay_ms (200);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nSOL ,3,100);
delay_ms (100);
play (nLA ,3,100);
delay_ms (200);
play (nMI ,3,100);
delay_ms (200);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nSOL ,3,100);
delay_ms (100);
play (nDO ,4,100);
delay_ms (200);
play (nSOL ,3,100);
delay_ms (200);
play (nMI ,4,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nMI ,4,100);
delay_ms (100);
play (nRE ,4,100);
delay_ms (100);
play (nSOL ,3,100);
delay_ms (100);
play (nDO ,4,100);
delay_ms (200);
play (nLA ,3,100);
delay_ms (200);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nDO ,4,100);
delay_ms (100);
play (nSI ,3,100);
delay_ms (100);
play (nSOL ,3,100);
break;
case 3:
//The lion sleep tonight
play (nDO ,3,125);
delay_ms (250);
play (nRE ,3,125);
delay_ms (125);
play (nMI ,3,125);
delay_ms (250);
play (nRE ,3,125);
delay_ms (250);
play (nMI ,3,125);
play (nFA ,3,125);
delay_ms (250);
play (nMI ,3,125);
delay_ms (125);
play (nRE ,3,125);
delay_ms (250);
play (nDO ,3,125);
delay_ms (250);
play (nRE ,3,125);
play (nMI ,3,125);
delay_ms (250);
play (nRE ,3,125);
delay_ms (125);
play (nDO ,3,125);
delay_ms (250);
delay_ms (125);
play (nMI ,3,125);
delay_ms (125);
play (nRE ,3,500);
break;
}
}
sábado, 18 de enero de 2014
Teclado PS2
#include <16F877A.h>
#use delay(clock=20M)
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
#zero_ram
#include <lcd.c>
unsigned char edge, bitcount;
char got_interrupt;
char interrupt_count;
char status_b3;
#bit INTF_BIT = 0x0B.1
unsigned char const unshifted[68][2] = {
0x0d,9,
0x0e,'º', 0x15,'q', 0x16,'1', 0x1a,'z', 0x1b,'s', 0x1c,'a', 0x1d,'w',
0x1e,'2', 0x21,'c', 0x22,'x', 0x23,'d', 0x24,'e', 0x25,'4', 0x26,'3',
0x29,' ', 0x2a,'v', 0x2b,'f', 0x2c,'t', 0x2d,'r', 0x2e,'5', 0x31,'n',
0x32,'b', 0x33,'h', 0x34,'g', 0x35,'y', 0x36,'6', 0x39,',', 0x3a,'m',
0x3b,'j', 0x3c,'u', 0x3d,'7', 0x3e,'8', 0x41,',', 0x42,'k', 0x43,'i',
0x44,'o', 0x45,'0', 0x46,'9', 0x49,'.', 0x4a,'-', 0x4b,'l', 0x4c,'ñ',
0x4d,'p', 0x4e,''', 0x52,'´', 0x54,'`', 0x55,'¡', 0x5a,13, 0x5b,'+',
0x5d,'ç', 0x61,'<', 0x66,8, 0x69,'1', 0x6b,'4', 0x6c,'7', 0x70,'0',
0x71,'.', 0x72,'2', 0x73,'5', 0x74,'6', 0x75,'8', 0x79,'+', 0x7a,'3',
0x7b,'-', 0x7c,'*', 0x7d,'9',
0,0
};
unsigned char const shifted[68][2] = {
0x0d,9,
0x0e,'ª', 0x15,'Q', 0x16,'!', 0x1a,'Z', 0x1b,'S', 0x1c,'A', 0x1d,'W',
0x1e,'"', 0x21,'C', 0x22,'X', 0x23,'D', 0x24,'E', 0x25,'$', 0x26,'·',
0x29,' ', 0x2a,'V', 0x2b,'F', 0x2c,'T', 0x2d,'R', 0x2e,'%', 0x31,'N',
0x32,'B', 0x33,'H', 0x34,'G', 0x35,'Y', 0x36,'&', 0x39,'L', 0x3a,'M',
0x3b,'J', 0x3c,'U', 0x3d,'/', 0x3e,'(', 0x41,';', 0x42,'K', 0x43,'I',
0x44,'O', 0x45,'=', 0x46,')', 0x49,':', 0x4a,'_', 0x4b,'L', 0x4c,'Ñ',
0x4d,'P', 0x4e,'?', 0x52,'¨', 0x54,'^', 0x55,'¿', 0x5a,13, 0x5b,'*',
0x5d,'Ç', 0x61,'>', 0x66,8, 0x69,'1', 0x6b,'4', 0x6c,'7', 0x70,'0',
0x71,'.', 0x72,'2', 0x73,'5', 0x74,'6', 0x75,'8', 0x79,'+', 0x7a,'3',
0x7b,'-', 0x7c,'*', 0x7d,'9',
0,0
};
void init_kb(void);
void decode(unsigned char sc);
#int_ext
void int_ext_isr(void){
unsigned char data;
if(bitcount < 11 && bitcount > 2){
data = (data >> 1);
status_b3 = input(PIN_B3);
if((status_b3) == 1){
data = data | 0x80;
}
}
if(--bitcount == 0){
decode(data);
data = 0;
bitcount = 11;
got_interrupt = TRUE;
}
got_interrupt = TRUE;
interrupt_count++;
disable_interrupts(INT_EXT);
}
void main(void)
{
lcd_init();
delay_ms(100);
init_kb();
output_float(PIN_B0);//clock
output_float(PIN_B3);//data
port_b_pullups(TRUE);
delay_us(5);
interrupt_count = 0;
got_interrupt = FALSE;
status_b3 = 0;
ext_int_edge(H_TO_L);
INTF_BIT = 0;
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(true){
if(got_interrupt == TRUE){
got_interrupt = FALSE;
INTF_BIT = 0;
enable_interrupts(INT_EXT);
}
}
}
void init_kb(void){
bitcount = 11;
lcd_gotoxy(1,1);
printf(lcd_putc,"connected ..." );
}
void decode(unsigned char sc){
static unsigned char is_up=0, shift = 0, mode = 0;
unsigned char i;
lcd_gotoxy(1,1);
printf(lcd_putc," " );
lcd_gotoxy(1,1);
printf(lcd_putc,"Num [%X]",sc);
if (!is_up){
switch (sc){
case 0xF0 :
is_up = 1;
break;
case 0x12 :
shift = 1;
break;
case 0x59 :
shift = 1;
break;
case 0x5A :
shift = 0;
//printf("\n\r" );
break;
default:
if(!shift){
for(i = 0; unshifted[ i ][ 0 ]!=sc && unshifted[ i ][ 0 ]; i++);
if (unshifted[ i ][ 0 ] == sc){
lcd_gotoxy(1,2);
printf(lcd_putc," " );
lcd_gotoxy(1,2);
printf(lcd_putc,"Car <%c>", unshifted[i][1]);
}
} else {
for(i = 0; shifted[ i ][ 0 ]!=sc && shifted[ i ][ 0 ]; i++);
if (shifted[ i ][ 0 ] == sc){
lcd_gotoxy(1,2);
printf(lcd_putc," " );
lcd_gotoxy(1,2);
printf(lcd_putc,"Car <%c>", shifted[i][1]);
}
}
break;
}
} else {
is_up = 0;
switch (sc){
case 0x12 :
shift = 0;
break;
case 0x59 :
shift = 0;
break;
}
}
}
Suscribirse a:
Entradas (Atom)