Cosas a tocar en este programa:
- UART configuracion y envio
- Funciones (vectores) de Interupciones
- Configuracion de puertos
- Fuses
- Oscilador
Bueno empecemos con las
interrupciones, ese PIC posee 2 vectores de interrupcion, uno de baja prioridad y el otro de alta prioridad. Buscando por google "interrupt XC8" tenes:
http://microchip.wikidot.com/faq:31O directamente podes ponerlo para que haga uso de un solo vector de interrupcion y usar el codigo de arriba, como hice yo.
Ahi tenes un ejemplo de un main, con sus funciones de interrupcion.
Falta aqui habilitar la interrupcion por recepcion de la UART
QUe lo podes agregar donde se configura la UART
Y al final de toda la configuracion ponemos
// Limpiar buffer y limpiar flag
int basura;
basura = RCREG;
PIR1bits.RCIF=0; // Aunque se deberia poner a 0 cuando se lee el RCREG
// Habilitamos las interrupciones
INTCONbits.PEIE=1;
INTCONbits.GIE=1;
---------------------
Configuracion de puertos... cada puerto tienen varios registros a configurar, algunos no hacen falta por que ya cuando arranca el PIC estan en 0 y es el valor que deseamos tener, otros comienzan en 1.
Para saber que registros tocar nos vamos al datasheet del micro
http://ww1.microchip.com/downloads/en/DeviceDoc/41303G.pdfEn la seccion I/O ports ( Pag 107 ) comienzan todos los puertos. Y al final de cada explicacion de cada uno de los puertos hay una tabla con todos los registros que involucran a ese puerto
PORTA (Pag 123),PORTB (Pag 126),PORTC (Pag 129)
Solo de ejemplo voy a poner todos los registros por PORT A
PORTA - Este registro sirve para leer el estado del pin de entrada
LATA - Este registro sirve para escribir un dato al pin, si es que lo usamos de salida
TRISA - Este registro indica si es entrada o salida, si uso el porta para los leds entonces lo tengo que poner a 0 para que sean salidas
ANSEL - Este registro es para indicarle si es una entrada analogica o digital, comienzan como analogicas asi que tengo que ponerlas como digital
SLRCON - Slew Rate, esto no nos interesa asi que lo desactivariamos ya que viene activado
CM1CON0
CM1CON1 - Ambos de los comparadores y vienen deshabilitado por defecto
CVRCON - Es una tension de referencia para los comparadores, tambien no necesitamos tocarlo.
Muchos registros? en realidad solo debemos tocar 3 para el PORTA, si dejamos todos los pin del PORTB como entrada entonces deberiamos tocar solo 2
// PORTA todos salidas, para los leds
LATA = 0; // Lo pongo a 0 asi quedan toso apagados
TRISA = 0; // Configurado todos como salida
ANSEL = 0; // Configurado digital
SLRCON = 0; // Desactivado el Slew Rate de todos los puertos
// PORTB todas entradas, aunque uso solo RB0
ANSELH = 0; // Configurado como digital
WPUB = 0x01; // Pull-up RB0
INTCON2 = 0; // Habilito los pull-up que seteo en WPUB
// PORTC donde esta la UART, debo ponerlos como entrada pero ya estan en el reset como entradas
// Nada a configurar ya que todo viene bien desde el reset
-------------------
FusesAbris el MPLAB X, creas tu proyecto con tu PIC, abajo dice Configuration Words y ahi elegis lo que queres.
// PIC18F25K20 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1H
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 18 // Brown Out Reset Voltage bits (VBOR set to 1.8 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config HFOFST = OFF // HFINTOSC Fast Start-up (The system clock is held off until the HFINTOSC is stable.)
#pragma config MCLRE = OFF // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
Eso como es muy largo lo podes grabar en otro archivo y luego incluirlo desde tu archivo principal.
-------------------------
UART, lo mas dificil..
Bueno el codigo de la interrupcion es simple seria un:
basura = RCREG; // Leo asi se borra el dato y el flag
PORTA ^= 0xFF; //Invierte todos los bits
La configuracion es lo que puede llevar mas lineas.
El oscilador interno es de 16Mhz
Buscamos una comunicacion asincrona, utilizamos una calculadora online para calcular los baudios de y seleccionar un valor.
http://www.nicksoft.info/el/calc/?ac=spbrg&submitted=1&mcu=PIC18F25J10&Fosc=16.000&FoscMul=1000000&FoscAutoSelector=0&MaxBaudRateError=19600 baudios = BRG16 = 1, BRGH = 1, SYNC = 0 y SPBRG:16 = 416
En la pag 240 y 246 tenes como configurarlos paso a paso en transmision y recepcion.
Transmision:
// Configuracion de velocidad
BAUDCONbits.BRG16= 1; // Habilito 16 bits para los baudios
SPBRG = 416 // cargo valor para 9600 baudios
TXSTAbits.SYNC = 0; // asincrono
TXSTAbits.BRGH = 1; // Habilito alta velocidad
// Hablitacion de la UART, TX y RX
RCSTAbits.SPEN=1; // Habilito los pines al USART
TXSTAbits.TXEN = 1; // Habilito el transmisor ya listo para enviar
// Fin de configuracion.
--------------------
Programa principalvoid main (void) {
//Aca toda la configuracion
while(1){ //Loop infinito
if (!PORTBbits.RB0) //Si esta en 0 entra
{
TXREG=0xFF; // Envio cualquier cosa
__delay_ms(100); // Espero por el rebote del boton
while(!PORTBbits.RB0); // Espero que lo suelte, sino no hago nada.
while(!TXSTAbits.TRMT); // Solo por las dudas si en el delay o cuando no se solto el boton, no llego a enviar todo, espero que envie todo antes de volver a meter algo en el buffer.
}
}
}
Para que funcione el delay si o si necesitas declarar una constante para que sepa que valor tiene el oscilador. Esto se pone al comienzo del programa
#define _XTAL_FREQ 16000000
-------------
Oscilador, como dije el oscilador es de 16Mhz, pero comienza dividido por otro valor, asiq ue hay que configurarlo
OSCCON = 0; configuramos a 16Mhz
Eso es todo, divertite juntandolo, ya que es poner una cosa dentro de otra. y listo, ya mas no te puedo dar, te di la configuracion de todos los puertos/UART/oscilador, te di los fuses, te di el codigo de adentro de la interrupcion. te di el codigo del programa principal, lo unico que falta es que lo juntes, y oficialmente eh desperdiciado 1 hora de mi vida xD