Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Sed P7
Sed P7
// ***************************************************
// Palabra de configuracin (verin compilador < 9.80)
// ***************************************************
#ifdef _16F84A
// FOSC : EXTRCCLK, EXTRCIO, INTOSCCLK, INTOSCIO, EC, HS, XT, LP
// PWRTE : Reset al conectar (PoWeR-up Timer Enable bit):
// WDTE : Perro Guardin (Watchdog Timer Enable bit):
// CP
: Proteccin lectura del cdigo (Code Protection bit)
#pragma config FOSC=XT, PWRTE=OFF, WDTE=OFF, CP=OFF
// Compatibilidad con ciertos bits que cambian de nombre en el 16F88
#define TMR0IF T0IF
#define TMR0IE T0IE
#define INT0IF INTF
#else
// FOSC : EXTRCCLK, EXTRCIO, INTOSCCLK, INTOSCIO, EC, HS, XT, LP
// WDTE : Perro Guardin (Watchdog Timer Enable bit):
// PWRTE : Reset al conectar (PoWeR-up Timer Enable bit):
// CP
: Proteccin lectura del cdigo (Code Protection bit):
// MCLRE : Pin de Reset (Master CLeaR Enable bit):
// BOREN : Corte parcial de alimentacin (BrOwn-out Reset ENable bit):
// LVP
: Programacin con baja tensin (Low-Voltage Programming Enable bit):
// CPD
: Proteccin lectura de la EEPROM (Code Protection Data enable bit):
// WRT
: Proteccin escritura de la EEPROM (WRiTe enable bit):
// DEBUG : Pines para depuracin (In-circuit DEBUGger mode bit
// CCPMX : Pin para el mdulo captura/comparacin/PWM (CCP1 Pin)
// FCMEN : Monitor del reloj (Fail-safe Clock Monitor ENable bit):
// IESO : Arranque con reloj interno y conmutacin al externo (Internal External
SwitchOver bit)
#pragma config FOSC=XT, WDTE=OFF, PWRTE=OFF, CP=OFF, MCLRE=OFF, BOREN=OFF,
LVP=OFF, \
CPD=OFF, WRT=OFF, DEBUG=OFF, CCPMX=RB3, FCMEN=OFF, IESO=OFF
#endif
// *******************************************
// Constantes y definiciones
// *******************************************
#define TMR0_carga -3
// Si quieren contar 3 flancos
#define int8 char
// -128 <= n <= 127
#define uint8 unsigned char // 0 <= n <= 255
}
// *******************************************
// Interrupcin
// *******************************************
static void interrupt rutinaInterrupcion(void)
{
// Interrupcin debida al desbordamiento de TMR0
if(TMR0IF)
{
if (++cuenta10==10) // cuenta10=cuenta10+1; si (cuenta10 == 10) entonces ...
{
cuenta10=0;
}
PORTB= cuenta10;
TMR0 = TMR0_carga;
// Preparamos TMR0= 253
TMR0IF = 0;
// Bajamos la bandera. Evento: desbordamiento de TMR0
}
else
{
// No debera ocurrir este caso.
RBIF =0;
INT0IF=0;
EEIF =0;
}
}
// *******************************************
// Variables globales
// *******************************************
byte TMR0_carga;
// *******************************************
// Declaracin de rutinas (excepto el main()
// *******************************************
void iniciaRegistros(void);
// *******************************************
// Mdulo principal (bucle infinito)
// *******************************************
void main(void)
{
//-----------------iniciaRegistros();
//-----------------for(;;)
// bucle infinito que no hace nada
{
// --------------------------------------------------------------// Configuracin TMR0
// --------------------------------------------------------------// Si Tosc=1us (Fosc=1Mhz), TMR0_carga, y Preescalador ->
// Tiempo= 4*1us*(256-TMR0) * Preescalador
// --------------------------------------------------------------if (RA0==1) {
// Periodo rotacin= 100ms
TMR0_carga=61;
// T= 4us*(256-61)*128= 99840us= 100ms
PS2=1; PS1=1; PS0=0; // Preescalador 1:128, [PS2,PS1,PS0]=110
TMR0IE=1;
// -------------------------------------}
else if (RA1==1) {
// Periodo rotacin= 50ms
TMR0_carga=61;
// T= 4us*(256-61)*64= 49920us= 50ms
PS2=1; PS1=0; PS0=1; // Preescalador 1:64, [PS2,PS1,PS0]=101
TMR0IE=1;
// -------------------------------------}
else if (RA2==1) {
// Periodo rotacin= 25ms
TMR0_carga=61;
// T= 4us*(256-61)*32= 24960us= 25ms
PS2=1; PS1=0; PS0=0; // Preescalador 1:32, [PS2,PS1,PS0]=100
TMR0IE=1;
// -------------------------------------}
else if (RA3==1) {
// Periodo rotacin= 8ms
TMR0_carga=6;
// T= 4us*(256-6)*8= 8000us= 8ms
PS2=0; PS1=1; PS0=0; // Preescalador 1:8, [PS2,PS1,PS0]=010
TMR0IE=1;
// -------------------------------------}
else if (RA4==1) {
// Periodo rotacin= 4ms
TMR0_carga=6;
// T= 4us*(256-6)*4= 4000us= 4ms
PS2=0; PS1=0; PS0=1; // Preescalador 1:4, [PS2,PS1,PS0]=001
TMR0IE=1;
// -------------------------------------}
else {
PORTB =0;
TMR0IE=0;
}
}
}
// *******************************************
// Rutinas
// *******************************************
void iniciaRegistros(void)
{
#ifdef _16F88
ANSEL= 0b000000000; // Los pines mixtos analgico-digitales sern digitales
TMR0_carga= 0;
TMR0IE = 0;
// Habilita interrupcion TMR0I
GIE
= 1;
// Mscara global de interrupcin activa
(Registro INTCON)
(Registro INTCON)
}
// *******************************************
// Interrupcin
// *******************************************
static void interrupt rutinaInterrupcion(void)
{
// ------------------------------------------------------------------// Temporizacin cada 8ms (Fosc=4Mhz)
//
// Tiempo= 4.Tosc.(256-TMR0_carga).Preescalador -- Tosc=0.25us (Fosc=4Mhz)
// ------------------------------------------------------------------// Interrupcin debida al desbordamiento de TMR0
if(TMR0IF)
{
TMR0 = TMR0_carga; // Preparamos TMR0=6 (TMR0_carga=6)
TMR0IF = 0;
// Bajamos la bandera que origin la interrupcin (flanco bajada en
TMR0IF)
//--------------DISPLAYS_rotar();
//--------------}
else
{
GIE=0; // bloquea todas las interrupciones si ocurre una no programada
}
}
// *******************************************
// Libreras (cdigo C)
// *******************************************
#include "DISPLAYS.c"
#include <pic.h>
// ***************************************************
// Palabra de configuracin
// ***************************************************
#ifdef _16F84A
#pragma config FOSC=XT, PWRTE=OFF, WDTE=OFF, CP=OFF
// Compatibilidad con ciertos bits que cambian de nombre en el 16F88
#define TMR0IF T0IF
#define TMR0IE T0IE
#define INT0IE INTE
#else
#pragma config FOSC=INTOSCIO, WDTE=OFF, PWRTE=OFF, CP=OFF, MCLRE=ON,
BOREN=OFF, LVP=OFF, \
CPD=OFF,
WRT=OFF, DEBUG=OFF, CCPMX=RB3, FCMEN=OFF, IESO=OFF
#endif
// *******************************************
// Constantes y definiciones
// *******************************************
#define nop() asm("nop");
#define false 0
#define true !false
// *******************************************
// Definicin de tipos
// *******************************************
typedef
char
int8;
// -128 <= n <= 127
typedef unsigned char
uint8;
// 0 <= n <= 255
typedef
int
int16;
// -32768 <= n <= 32767 -- short?
typedef unsigned int
uint16;
// 0 <= n <= 65535
// *******************************************
// Libreras (cabeceras)
// *******************************************
#include "REBOTES.h"
// *******************************************
// Declaracin de rutinas (excepto el main()
// *******************************************
void iniciaRegistros(void);
// *******************************************
// Variables globales
// *******************************************
uint8 cuentaPWM;
// Cuenta de 0 a 9 en cada interrupcin a 10khz
uint8 Ton[4]= {2, 4, 6, 8}; // Valores iniciales de los motores: 20%, 40%, 60%, 80%
uint16 lectura;
// Para leer con control de rebotes
// *******************************************
// Mdulo principal (bucle infinito)
// *******************************************
void main(void)
{
uint8 motor, potencia;
//-----------------iniciaRegistros();
//-----------------while (true)
// bucle infinito
{
// Se lee con control de rebotes el pin 4 del puerto A (RA4)
lectura= REBOTES_leerPuertoA( 0b00010000);
if (lectura!=REBOTES_ERROR)
{
// Si est a 0 el pin RA4
if ((lectura & 0b00010000)==0)
{
motor = PORTB & 0b00000011;
// El puerto B se desplazar 4 posiciones a la derecha
potencia= (PORTB >> 4) & 0b00001111;
// Se actualiza la potencia para que se tenga en cuenta en la interrupcin
Ton[ motor ] = potencia;
}
}
}
}
// *******************************************
// Rutinas
// *******************************************
void iniciaRegistros(void)
{
#ifdef _16F88
ANSEL= 0b000000000; // Los pines mixtos analgico-digitales sern digitales
// -----------------------------------------------// Configuracin del cristal interno a 4 Mhz
// -----------------------------------------------OSCCON= 0b01100110; // Configura a 4 Mhz
+-------------+--------+
// 76543210
| IRCF2:IRCF0 | Frec |
// ||| |||
+-------------+--------+
// ||| ||+- OSCCON<0> : SCS0=0 // [SCS1:SCS0]= reloj interno | 000 | 31Khz |
// ||| |+-- OSCCON<1> : SCS1=1 //
| 001 | 125Khz |
// ||| +--- OSCCON<2> : IOFS // Se pone a 1 cuando el
| 010 | 250Khz |
// |||
// reloj se ha estabilizado | 011 | 500Khz |
// ||+----- OSCCON<4> : IRCF0=0
| 100 | 1Mhz |
// |+------ OSCCON<5> : IRCF1=1
| 101 | 2Mhz |
// +------- OSCCON<6> : IRCF2=1 // [IRCF2:IRCF0]=110 --> 4Mhz -->| 110 | 4Mhz
|
//
| 111 | 8Mhz |
while (IOFS==0) { } // Mientras no se estabilice el
+-------------+--------+
// reloj interno -> esperar aqu.
// -----------------------------------------------#endif
PORTA = 0;
TRISA= 0b00010000;
TRISB= 0b11111111;
// * ************************************************************************
*
// * Configuracin Timer 0: temporizacin a 1ms (Fosc=4Mhz)
// *
// * Tiempo= 4.Tosc.(256-TMR0).Preescalador
// * Si Tosc=0.25us (Fosc=4Mhz), TMR0=206 y Preescalador= 1:2 ([PS2:PS0]=000)->
// * Tiempo= 4.(0.25us).(256-206).2= 0.1ms (10khz)
// * ************************************************************************
*
OPTION_REG = 0b00000000;
// 76543210
// ||||||||
// |||||||+- bit0 PS0 1:2 Predivisor
// ||||||+-- bit1 PS1
// |||||+--- bit2 PS2
// ||||+---- bit3 PSA El Divisor de frecuencia se asigna al TMR0
// |||+----- bit4 T0SE
// ||+------ bit5 T0CS Utiliza Fosc/4 para temporizar
// |+------- bit6 INTEDG
// +-------- bit7 nRBPU Activa los pullups internos de PORTB
10
TMR0IF = 0;
TMR0IE = 1; // Habilita interrupcion T0I
(Registro INTCON)
GIE = 1; // Mscara global de interrupcin activa
(Registro INTCON)
}
// *******************************************
// Interrupcin
// *******************************************
static void interrupt rutinaInterrupcion(void)
{
// Interrupcin debida al desbordamiento de TMR0
if(TMR0IF)
{
TMR0IF = 0;
// Bajamos la bandera. Evento: desbordamiento de TMR0
TMR0 = 206 + 11;
// Preparamos TMR0 con 206 pero hay que sumar 11 para
// ajustar el PUSH y PULL que hace el compilador sin
// que nos demos cuenta.
if (++cuentaPWM == 10)
{
cuentaPWM= 0;
PORTA=0b00001111; // Los 4 motores en marcha. Comienza el Ton
}
else
{
if (Ton[0]==cuentaPWM) { RA0=0; }
if (Ton[1]==cuentaPWM) { RA1=0; }
if (Ton[2]==cuentaPWM) { RA2=0; }
if (Ton[3]==cuentaPWM) { RA3=0; }
}
return;
}
// Este caso no debera ocurrir nunca
RBIF=0;
INTF=0;
EEIF=0;
}
// *******************************************
// Libreras (cdigo C)
// *******************************************
#include "REBOTES.c"
11
#include <pic.h>
#define _XTAL_FREQ 4000000
// Reloj a 4Mhz. Definir antes de las cabeceras
// *******************************************
// Cabeceras
// *******************************************
#include "I2C.h"
// Prametros del compilador "%1 --CHIP=16F84A" y OBJ=COF
// *******************************************
// Palabra de configuracin
// *******************************************
#ifdef _16F84A
// FOSC : EXTRCCLK, EXTRCIO, INTOSCCLK, INTOSCIO, EC, HS, XT, LP
// PWRTE : Reset al conectar (PoWeR-up Timer Enable bit):
// WDTE : Perro Guardin (Watchdog Timer Enable bit):
// CP
: Proteccin lectura del cdigo (Code Protection bit)
#pragma config FOSC=XT, PWRTE=OFF, WDTE=OFF, CP=OFF
#else
// FOSC : EXTRCCLK, EXTRCIO, INTOSCCLK, INTOSCIO, EC, HS, XT, LP
// WDTE : Perro Guardin (Watchdog Timer Enable bit):
// PWRTE : Reset al conectar (PoWeR-up Timer Enable bit):
// CP
: Proteccin lectura del cdigo (Code Protection bit):
// MCLRE : Pin de Reset (Master CLeaR Enable bit):
// BOREN : Corte parcial de alimentacin (BrOwn-out Reset ENable bit):
// LVP
: Programacin con baja tensin (Low-Voltage Programming Enable bit):
// CPD
: Proteccin lectura de la EEPROM (Code Protection Data enable bit):
// WRT
: Proteccin escritura de la EEPROM (WRiTe enable bit):
// DEBUG : Pines para depuracin (In-circuit DEBUGger mode bit
// CCPMX : Pin para el mdulo captura/comparacin/PWM (CCP1 Pin)
// FCMEN : Monitor del reloj (Fail-safe Clock Monitor ENable bit):
12
13
// Puerto A de entrada
// Puerto B de entrada
// Interrupcin INT activa por flanco de bajada (Registro
INTE = 1;
GIE = 1;
(Registro INTCON)
(Registro INTCON)
14
// internamente el cdigo de la rutina (como si fueran dos rutinas con distinto nombre;
duplicando las
// variables locales que internamente se almacenan en memoria como globales).
leeEscribe();
}
// ==================================
// PCF8574_Lee
// ==================================
byte PCF8574_Lee(void)
{
byte dato;
I2C_start();
// Enva la condicin de Start.
I2C_enviaByte(PCF8574_DireccionLectura);
// Apunta al expansor de lectura.
I2C_MASTER_PARAR=1;
byte
dato= I2C_recibeByte();
I2C_stop();
// Lee el puerto.
// Acaba de leer.
return dato;
}
// ==================================
// PCF8574_Escribe
// ==================================
void PCF8574_Escribe(byte dato)
{
I2C_start();
// Enva la condicin de Start.
I2C_enviaByte(PCF8574_DireccionEscritura); // Apunta al expansor de escritura.
I2C_enviaByte(dato);
// Escribe el puerto.
I2C_stop();
// Acaba de escribir.
}
// ==================================
// leeEscribe(void)
// ==================================
void leeEscribe(void)
{
byte dato;
// Interrupcin debida a flanco activo en INTF
dato= PCF8574_Lee();
// lee la entrada.
dato= dato ^ 0b11111111;
// Complementa el dato ledo porque los diodos (XOR)
// se activan con nivel bajo, (ver esquema).
PCF8574_Escribe(dato);
// Lo visualiza en los diodos LEDs.
}
15
// *******************************************
// Interrupcin
// *******************************************
static void interrupt rutinaInterrupcion(void)
{
if(INTF)
{
INTF = 0; // Bajamos la bandera que origin la interrupcin (flanco bajada en RB0)
leeEscribe();
}
}
#include "I2C.c"
16