Hola! Buenisimo que se vayan sumando y subiendo ejemplos para avanzar... En el código de Rseliman hay un ; en el define de LED1 que causa el problema. Saludos!
/*
* File: main.c
* Author: Ramiro Seliman
*
* Created on 26 de abril de 2013, 18:07
*/
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <htc.h>
//*************************** funciones grab y lee eeprom ***************************************
void write_eeprom(char address, char data)
{
EEADR = address;
EEDATA = data;
EECON1bits.WREN = 1; // habilito escritura
INTCONbits.GIE = 0; // desabilito las interrupciones
EECON2 = 0x55; // destrabo escritura
EECON2 = 0xAA; //destrabo escritura
EECON1bits.WR = 1; // habilito escritura
INTCONbits.GIE = 1; // habilito la interrupcion
EECON1bits.WREN = 0; // desabilito escritura
while (EECON1bits.WR); // espero hasta que WR se haga 0 por hard
}
char read_eeprom(char address)
{
EEADR = address;
EECON1bits.RD = 1 ;
return EEDAT;
}
//****************************************************************************************************
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
char tiempo, address, data ; // defino variable tiempo para leer eeprom
#define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
#define ledverde GPIO,GP1
#define ledrojo GPIO,GP4
#define buzzer GPIO,GP0
#define microswitch GPIO,GP2
#define teclado GPIO,GP3
/***********************************************************************************************************/
/* PROGRAMA PRINCIPAL */
/***********************************************************************************************************/
int main (void)
{
CMCON0 = 7; // Disable comparators
TRISIO = 0b00001100; // GP3 y GP4 entradas las demas salidas
ANSEL = 0; // No ADC
write_eeprom(0,6); //leo la primer posicion memoria eeprom
_delay(500);
tiempo = read_eeprom(0); //la cargo en tiempo
write_eeprom(2,tiempo); //cargo la 3r posicion de la eeprom con el valor de tiempo
_delay(500); // espero
write_eeprom(5,tiempo); //cargo la 6ta posicion de la eeprom con la variable tiempo
_delay(500);
while(1) // bucle infiinito
{
ledverde = 0; // apago led verde en GP1
_delay(1000); // espero 1 seg
ledverde = 1; // prendo led verde en GP1
_delay(1000); // espero 1 seg
}
}
¿Qué es lo que pasa? ¿Por qué dices que no funciona? ¿Genera algún error de compilación o no establece bien el tiempo?
Hola , sigo con mis preguntas , la verdad , me esta costando bastante adaptarme a este lenguaje , vengo de Mikroc que era muchisimo mas facil ...
Bueno las preguntas son dos
si tengo definido esto
void sonido(int x)
{
while (x > 0)
{
buzzer = 1;
_delay(500);
buzzer = 0;
_delay(500);
x--;
}
pero esta en el main , y si sigo metiendo voids en el main se me va complicando , como hago para ponerlo como una libreria o sonido.h o sonido.c , no se explicarme para mi seria una macro que la llamo desde el main ...no se si me explico ...muchas gracias
La otra pregunta era ...porque no puedo utilizar _delay_ms ?? veo en muchos ejemplos que la usan y yo no puedo uso #include delay y delays.h y de todas maneras no me deja usar esa funcion ....tampoco pùedo usar delay1ktcyx(50) ....porque me cuesta tanto entender este lenguaje ??
Gracias
/*
programa: prueba oscilador interno y módulo usart
pic: 18f4550
crystal: NO
CPU: 8Mhz (valor establecido dentro de main cambiando los bits IRCF2, IRCF1 e IRCF0 del registro OSCCON)
en RA6 sale la frecuencia de Fosc/4 -------> 8Mhz/4 = 2Mhz
CONEXIONES: los cambios se pueden hacer en el archivo configuracion_hard.c
1 led en port b0 con una resistencia en serie de 470ohms
1 led en port b1 con una resistencia en serie de 470ohms
Los leds cambian de estado cada 1 segundo. Uno enciende y el otro se apaga cada vez.
*/
#define _XTAL_FREQ 8000000 // Linea necesario para los cálculos de la función
// de delay. CUIDADO. no es para la configuración
// de la frecuencia de trabajo del cpu del pic.
// eso se determina en otro lado. :)
/*Includes globales*/
#include <pic18.h>
#include <xc.h>
#include <delays.h> /* Para utilizar demoras en nuestro código debemos incluir la librería delays.h.*/
#include <plib/usart.h> //Libreria para el manejo del modulo USART
/*Includes locales*/
#include "configuracion_de_fuses.c"
#include "configuracion_hard.c"
/*declaración de variables globales*/
char CaracterRx;
char MensajeTx[] = "COMUNICACION SATISFACTORIA";
/*declaración de funciones*/
void MyMsDelay(int ms);
//void interrupt Interrupcion();
///////////////////////////////////////////////////////////////////////////////
// Programa Principal //
///////////////////////////////////////////////////////////////////////////////
void main(void)
{
// cambiamos la frecuencia del oscilador interno del valor por defecto de 32khz
// a 8mhz mediante los bits del registro OSCCON
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 1;
ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07; //puerto A con todos los pines digitales
TRISA = 0X00; // puertos A B y C como salida. Recordar Tip: el 0 es una o de ouput y el 1 una I de input!!!
TRISB = 0X00;
TRISC = 0X00;
LATA = 0X00; // ponemos los puertos en cero
LATB = 0X00;
LATC = 0X00;
PINLED0 = 0; // Seteamos el pin como salida para el LED
PINLED1 = 0; // Seteamos el pin como salida para el LED
// configuramos el puerto serie
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_ON & //Activar la interrupcion por la recepcion de dato del buffer de Rx del USART
USART_ASYNCH_MODE & //Modo asincrono (fullduplex)
USART_EIGHT_BIT & //8 bits de datos
USART_CONT_RX & //Recepción continua
USART_BRGH_HIGH, 51); //9600 Baudios
// (frecuencia a la que trabaja el cpu/dbaudrate)/16)-1
// (8.000.000/9600)/16)-1=51
INTCONbits.PEIE = 1; //Activamos interrupcion de perifericos
INTCONbits.GIE = 1; //Activamos las interrupciones globales
while(BusyUSART()); //Se espera a que el buffer de Tx este libre
putsUSART(MensajeTx); //Se envía un string de bienvenida
while(1){ //Bucle infinito
LED0 = ~LED0; // Intercambiamos el estado del pin del led (Toggle LED)
Delay10KTCYx(200); //ver como se hacen los cálculos del delay más abajo
LED1 = ~LED1; // Intercambiamos el estado del pin del led (Toggle LED)
}
}
void interrupt Interrupcion() //Funcion que atiende las interrupciones
{
CaracterRx = ReadUSART(); //Se lee el dato que esta en el buffer de Rx del USART
while(BusyUSART());
putsUSART("\n\rUsted digito la tecla: ");
while(BusyUSART());
WriteUSART(CaracterRx);
PIR1bits.RCIF = 0; //Desactivamos la bandera de recepción en el buffer de entrada del USART
}
void MyMsDelay(int ms)
{
while(ms--)
{
__delay_ms(1);
}
}
#include <xc.h>
#define _XTAL_FREQ 8000000
#include <stdio.h>
#include <stdlib.h>
#include "lcd_pic16.c"
#include "delay.h"
// PIC16F819 Configuration Bit Settings
//variables globales
unsigned char buffer [14];
// unsigned int contador=0;
//funciones prototipo
void init(void);
void main(void)
{
OSCCONbits.IRCF2 = 1; //
OSCCONbits.IRCF1 = 1; // defino oscilador interno en 4 mhz
OSCCONbits.IRCF0 = 0; //
init();
SetDDRamAddr(0x00);
putrsXLCD("Ramiro Seliman");
putsXLCD(buffer);
SetDDRamAddr(0x40);
putrsXLCD("Victoria E.R");
}
void init(void)
{
ADCON0bits.ADON = 0;
TRISB=0; //todo el PORTB como salidas digitales
PORTB=0;
OpenXLCD(FOUR_BIT & LINES_5X7 );
}/*
*
* Notes:
* - These libraries routines are written to support the
* Hitachi HD44780 LCD controller.
* - The user must define the following items:
* - The LCD interface type (4- or 8-bits)
* - If 4-bit mode
* - whether using the upper or lower nibble
* - The data port
* - The tris register for data port
* - The control signal ports and pins
* - The control signal port tris and pins
* - The user must provide three delay routines:
* - DelayFor18TCY() provides a 18 Tcy delay
* - DelayPORXLCD() provides at least 15ms delay
* - DelayXLCD() provides at least 5ms delay
*/
/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
// #define BIT8
/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
#define UPPER
/* When in 6-10-bit interface comment the #define BUSY_LCD and conected PIN
* R/W to GND in LCD
*/
//#define BUSY_LCD
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTB
#define TRIS_DATA_PORT TRISB
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN PORTBbits.RB0 /* PORT for RW */
#define TRIS_RW TRISBbits.TRISB0 /* TRIS for RW */
#define RS_PIN PORTBbits.RB1 /* PORT for RS */
#define TRIS_RS TRISBbits.TRISB1 /* TRIS for RS */
#define E_PIN PORTBbits.RB2 /* PORT for D */
#define TRIS_E TRISBbits.TRISB2 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00000100 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00000101 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00000110 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00000111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */
#ifdef _OMNI_CODE_
#define PARAM_SCLASS
#else
#define PARAM_SCLASS auto
#endif
/* CLS_Line2
* Clear Screen Line 2
*/
void CLS_Line2(void);
/* CLS_Line1
* Clear Screen Line 1
*/
void CLS_Line1(void);
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in to the LCD
*/
void putrsXLCD(const char *);
// Rutinas de tiempo auxiliares para la libreria XLCD
void DelayFor18TCY(void)
{
__delay_us(18);
}
void DelayPORXLCD(void)
{
__delay_ms(20); //Delay de 15 ms
}
void DelayXLCD(void)
{
__delay_ms(20); //Delay de 20 ms
}
void CLS_Line2(void)
{
SetDDRamAddr(0x40);
putrsXLCD(" ");
}
void CLS_Line1(void)
{
SetDDRamAddr(0x00);
putrsXLCD(" ");
}
/********************************************************************
* Function Name: OpenXLCD *
* Return Value: void *
* Parameters: lcdtype: sets the type of LCD (lines) *
* Description: This routine configures the LCD. Based on *
* the Hitachi HD44780 LCD controller. The *
* routine will configure the I/O pins of the *
* microcontroller, setup the LCD for 4- or *
* 8-bit mode and clear the display. The user *
* must provide three delay routines: *
* DelayFor18TCY() provides a 18 Tcy delay *
* DelayPORXLCD() provides at least 15ms delay *
* DelayXLCD() provides at least 5ms delay *
********************************************************************/
void OpenXLCD(unsigned char lcdtype)
{
// The data bits must be either a 8-bit port or the upper or
// lower 4-bits of a port. These pins are made into inputs
#ifdef BIT8 // 8-bit mode, use whole port
DATA_PORT = 0;
TRIS_DATA_PORT = 0x00;
#else // 4-bit mode
#ifdef UPPER // Upper 4-bits of the port
DATA_PORT &= 0x0f;
TRIS_DATA_PORT &= 0x0F;
#else // Lower 4-bits of the port
DATA_PORT &= 0xf0;
TRIS_DATA_PORT &= 0xF0;
#endif
#endif
TRIS_RW = 0; // All control signals made outputs
TRIS_RS = 0;
TRIS_E = 0;
RW_PIN = 0; // R/W pin made low
RS_PIN = 0; // Register select pin made low
E_PIN = 0; // Clock pin made low
// Delay for 15ms to allow for LCD Power on reset
DelayPORXLCD();
//-------------------reset procedure through software----------------------
WriteCmdXLCD(0x30);
__delay_ms(5);
WriteCmdXLCD(0x30);
__delay_ms(1);
WriteCmdXLCD(0x32);
while( BusyXLCD() );
//------------------------------------------------------------------------------------------
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd
// Turn the display on then off
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF); // Display OFF/Blink OFF
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON); // Display ON/Blink ON
// Clear display
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x01); // Clear display
// Set entry mode inc, no shift
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(SHIFT_CUR_RIGHT); // Entry Mode
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x06); // Incremente
while(BusyXLCD()); // Wait if LCD busy
SetDDRamAddr(0x80); // Set Display data ram address to 0
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(CURSOR_OFF); // Cursor OFF
return;
}
/********************************************************************
* Function Name: WriteDataXLCD *
* Return Value: void *
* Parameters: data: data byte to be written to LCD *
* Description: This routine writes a data byte to the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is written to the character generator RAM or*
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
void WriteDataXLCD(char data)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data into LCD
DelayFor18TCY();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteCmdXLCD *
* Return Value: void *
* Parameters: cmd: command to send to LCD *
* Description: This routine writes a command to the Hitachi*
* HD44780 LCD controller. The user must check *
* to see if the LCD controller is busy before *
* calling this routine. *
********************************************************************/
void WriteCmdXLCD(unsigned char cmd)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
DelayFor18TCY();
E_PIN = 1; // Clock the command in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= cmd&0x0f;
#endif
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetDDRamAddr *
* Return Value: void *
* Parameters: CGaddr: display data address *
* Description: This routine sets the display data address *
* of the Hitachi HD44780 LCD controller. The *
* user must check to see if the LCD controller*
* is busy before calling this routine. *
********************************************************************/
void SetDDRamAddr(unsigned char DDaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make port input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetCGRamAddr *
* Return Value: void *
* Parameters: CGaddr: character generator ram address *
* Description: This routine sets the character generator *
* address of the Hitachi HD44780 LCD *
* controller. The user must check to see if *
* the LCD controller is busy before calling *
* this routine. *
********************************************************************/
void SetCGRamAddr(unsigned char CGaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}
/********************************************************************
* Function Name: ReadDataXLCD *
* Return Value: char: data byte from LCD controller *
* Parameters: void *
* Description: This routine reads a data byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
char ReadDataXLCD(void)
{
char data;
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data
#endif
E_PIN = 0; // Reset the clock line
DelayFor18TCY();
E_PIN = 1; // Clock the next nibble out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}
/*********************************************************************
* Function Name: ReadAddrXLCD *
* Return Value: char: address from LCD controller *
* Parameters: void *
* Description: This routine reads an address byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The address*
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
*********************************************************************/
unsigned char ReadAddrXLCD(void)
{
char data; // Holds the data retrieved from the LCD
#ifdef BIT8 // 8-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble of data
#endif
E_PIN = 0; // Reset the clock
DelayFor18TCY();
E_PIN = 1; // Clock out the lower nibble
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}
/********************************************************************
* Function Name: putsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putsXLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/********************************************************************
* Function Name: putrsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putrsXLCD(const char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/********************************************************************
* Function Name: BusyXLCD *
* Return Value: char: busy status of LCD controller *
* Parameters: void *
* Description: This routine reads the busy status of the *
* Hitachi HD44780 LCD controller. *
********************************************************************/
unsigned char BusyXLCD(void)
{
#ifdef BUSY_LCD
RW_PIN = 1; // Set the control bits for read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock in the command
DelayFor18TCY();
#ifdef BIT8 // 8-bit interface
if(DATA_PORT&0x80) // Read bit 7 (busy bit)
{ // If high
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Bit 7 low
{
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
if(DATA_PORT&0x80)
#else // Lower nibble interface
if(DATA_PORT&0x08)
#endif
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Busy bit is low
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#endif
#else
__delay_ms(5);
return 0;
#endif
}// PIC16F819 Configuration Bit Settings
#include <xc.h>
// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTRC oscillator; CLKO function on RA6/OSC2/CLKO pin and port I/O function on RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has PGM function, Low-Voltage Programming enabled)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
//#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable #include <xc.h>
#define _XTAL_FREQ 4000000
#include <stdio.h>
#include <stdlib.h>
#include "lcd_pic16.c"
#include "delay.h"
// PIC16F819 Configuration Bit Settings
//variables globales
unsigned char buffer [14];
// unsigned int contador=0;
//funciones prototipo
void init(void);
void main(void)
{
//OSCCONbits.IRCF2 = 1; //
//OSCCONbits.IRCF1 = 1; // defino oscilador interno en 4 mhz
//OSCCONbits.IRCF0 = 0; //
init(); // inicio lcd
while(1)
{
SetDDRamAddr(0x00);
putrsXLCD("Ramiro Seliman");
putsXLCD(buffer);
SetDDRamAddr(0x40);
putrsXLCD("Victoria E.R");
}
}
void init(void)
{
ADCON0bits.ADON = 0;
ADCON1bits.PCFG3 = 0;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 1;
ADCON1bits.ADCS2 = 0;
TRISB=0; //todo el PORTb como salidas digitales
PORTB=0;
// TRISA=0;
// PORTA=0;
OpenXLCD(FOUR_BIT & LINES_5X7 );
}
//*
*
* Notes:
* - These libraries routines are written to support the
* Hitachi HD44780 LCD controller.
* - The user must define the following items:
* - The LCD interface type (4- or 8-bits)
* - If 4-bit mode
* - whether using the upper or lower nibble
* - The data port
* - The tris register for data port
* - The control signal ports and pins
* - The control signal port tris and pins
* - The user must provide three delay routines:
* - DelayFor18TCY() provides a 18 Tcy delay
* - DelayPORXLCD() provides at least 15ms delay
* - DelayXLCD() provides at least 5ms delay
*/
/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
// #define BIT8
/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
//#define UPPER
/* When in 6-10-bit interface comment the #define BUSY_LCD and conected PIN
* R/W to GND in LCD
*/
#define BUSY_LCD
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTA
#define TRIS_DATA_PORT TRISA
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN PORTAbits.RA6 /* PORT for RW */
#define TRIS_RW TRISAbits.TRISA6 /* TRIS for RW */
#define RS_PIN PORTAbits.RA7 /* PORT for RS */
#define TRIS_RS TRISAbits.TRISA7 /* TRIS for RS */
#define E_PIN PORTAbits.RA4 /* PORT for D */
#define TRIS_E TRISAbits.TRISA4 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00000100 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00000101 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00000110 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00000111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */
#ifdef _OMNI_CODE_
#define PARAM_SCLASS
#else
#define PARAM_SCLASS auto
#endif
/* CLS_Line2
* Clear Screen Line 2
*/
void CLS_Line2(void);
/* CLS_Line1
* Clear Screen Line 1
*/
void CLS_Line1(void);
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in to the LCD
*/
void putrsXLCD(const char *);
// Rutinas de tiempo auxiliares para la libreria XLCD
void DelayFor18TCY(void)
{
__delay_us(18);
}
void DelayPORXLCD(void)
{
__delay_ms(20); //Delay de 15 ms
}
void DelayXLCD(void)
{
__delay_ms(20); //Delay de 20 ms
}
void CLS_Line2(void)
{
SetDDRamAddr(0x40);
putrsXLCD(" ");
}
void CLS_Line1(void)
{
SetDDRamAddr(0x00);
putrsXLCD(" ");
}
/********************************************************************
* Function Name: OpenXLCD *
* Return Value: void *
* Parameters: lcdtype: sets the type of LCD (lines) *
* Description: This routine configures the LCD. Based on *
* the Hitachi HD44780 LCD controller. The *
* routine will configure the I/O pins of the *
* microcontroller, setup the LCD for 4- or *
* 8-bit mode and clear the display. The user *
* must provide three delay routines: *
* DelayFor18TCY() provides a 18 Tcy delay *
* DelayPORXLCD() provides at least 15ms delay *
* DelayXLCD() provides at least 5ms delay *
********************************************************************/
void OpenXLCD(unsigned char lcdtype)
{
// The data bits must be either a 8-bit port or the upper or
// lower 4-bits of a port. These pins are made into inputs
#ifdef BIT8 // 8-bit mode, use whole port
DATA_PORT = 0;
TRIS_DATA_PORT = 0x00;
#else // 4-bit mode
#ifdef UPPER // Upper 4-bits of the port
DATA_PORT &= 0x0f;
TRIS_DATA_PORT &= 0x0F;
#else // Lower 4-bits of the port
DATA_PORT &= 0xf0;
TRIS_DATA_PORT &= 0xF0;
#endif
#endif
TRIS_RW = 0; // All control signals made outputs
TRIS_RS = 0;
TRIS_E = 0;
RW_PIN = 0; // R/W pin made low
RS_PIN = 0; // Register select pin made low
E_PIN = 0; // Clock pin made low
// Delay for 15ms to allow for LCD Power on reset
DelayPORXLCD();
//-------------------reset procedure through software----------------------
WriteCmdXLCD(0x30);
__delay_ms(5);
WriteCmdXLCD(0x30);
__delay_ms(1);
WriteCmdXLCD(0x32);
while( BusyXLCD() );
//------------------------------------------------------------------------------------------
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd
// Turn the display on then off
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF); // Display OFF/Blink OFF
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON); // Display ON/Blink ON
// Clear display
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x01); // Clear display
// Set entry mode inc, no shift
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(SHIFT_CUR_RIGHT); // Entry Mode
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x06); // Incremente
while(BusyXLCD()); // Wait if LCD busy
SetDDRamAddr(0x80); // Set Display data ram address to 0
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(CURSOR_OFF); // Cursor OFF
return;
}
/********************************************************************
* Function Name: WriteDataXLCD *
* Return Value: void *
* Parameters: data: data byte to be written to LCD *
* Description: This routine writes a data byte to the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is written to the character generator RAM or*
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
void WriteDataXLCD(char data)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data into LCD
DelayFor18TCY();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteCmdXLCD *
* Return Value: void *
* Parameters: cmd: command to send to LCD *
* Description: This routine writes a command to the Hitachi*
* HD44780 LCD controller. The user must check *
* to see if the LCD controller is busy before *
* calling this routine. *
********************************************************************/
void WriteCmdXLCD(unsigned char cmd)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
DelayFor18TCY();
E_PIN = 1; // Clock the command in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= cmd&0x0f;
#endif
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetDDRamAddr *
* Return Value: void *
* Parameters: CGaddr: display data address *
* Description: This routine sets the display data address *
* of the Hitachi HD44780 LCD controller. The *
* user must check to see if the LCD controller*
* is busy before calling this routine. *
********************************************************************/
void SetDDRamAddr(unsigned char DDaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make port input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetCGRamAddr *
* Return Value: void *
* Parameters: CGaddr: character generator ram address *
* Description: This routine sets the character generator *
* address of the Hitachi HD44780 LCD *
* controller. The user must check to see if *
* the LCD controller is busy before calling *
* this routine. *
********************************************************************/
void SetCGRamAddr(unsigned char CGaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}
/********************************************************************
* Function Name: ReadDataXLCD *
* Return Value: char: data byte from LCD controller *
* Parameters: void *
* Description: This routine reads a data byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
char ReadDataXLCD(void)
{
char data;
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data
#endif
E_PIN = 0; // Reset the clock line
DelayFor18TCY();
E_PIN = 1; // Clock the next nibble out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}
/*********************************************************************
* Function Name: ReadAddrXLCD *
* Return Value: char: address from LCD controller *
* Parameters: void *
* Description: This routine reads an address byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The address*
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
*********************************************************************/
unsigned char ReadAddrXLCD(void)
{
char data; // Holds the data retrieved from the LCD
#ifdef BIT8 // 8-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble of data
#endif
E_PIN = 0; // Reset the clock
DelayFor18TCY();
E_PIN = 1; // Clock out the lower nibble
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}
/********************************************************************
* Function Name: putsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putsXLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/********************************************************************
* Function Name: putrsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putrsXLCD(const char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/********************************************************************
* Function Name: BusyXLCD *
* Return Value: char: busy status of LCD controller *
* Parameters: void *
* Description: This routine reads the busy status of the *
* Hitachi HD44780 LCD controller. *
********************************************************************/
unsigned char BusyXLCD(void)
{
#ifdef BUSY_LCD
RW_PIN = 1; // Set the control bits for read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock in the command
DelayFor18TCY();
#ifdef BIT8 // 8-bit interface
if(DATA_PORT&0x80) // Read bit 7 (busy bit)
{ // If high
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Bit 7 low
{
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
if(DATA_PORT&0x80)
#else // Lower nibble interface
if(DATA_PORT&0x08)
#endif
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Busy bit is low
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#endif
#else
__delay_ms(5);
return 0;
#endif
}
// PIC16F819 Configuration Bit Settings
#include <xc.h>
// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTRC oscillator; CLKO function on RA6/OSC2/CLKO pin and port I/O function on RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has PGM function, Low-Voltage Programming enabled)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
//#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable Rseliman:
Gracias por compartir. ((:-)).-
Poco a poco iremos subiendo más y más ejemplos.
Saludos.
Jukinch
// bitfield definitions
typedef union {
struct {
unsigned RB0 :1;
unsigned RB1 :1;
unsigned RB2 :1;
unsigned RB3 :1;
unsigned RB4 :1;
unsigned RB5 :1;
unsigned RB6 :1;
unsigned RB7 :1;
};
struct {
unsigned INT0 :1;
unsigned INT1 :1;
unsigned INT2 :1;
unsigned :2;
unsigned PGM :1;
unsigned PGC :1;
unsigned PGD :1;
};
struct {
unsigned :3;
unsigned CCP2_PA2 :1;
};
} PORTBbits_t;
extern volatile PORTBbits_t PORTBbits @ 0xF81;
// Register: T1CON
extern volatile unsigned char T1CON @ 0x010;
#ifndef _LIB_BUILD
asm("T1CON equ 010h");
#endif
// bitfield definitions
typedef union {
struct {
unsigned TMR1ON :1;
unsigned TMR1CS :1;
unsigned nT1SYNC :1;
unsigned T1OSCEN :1;
unsigned T1CKPS :2;
unsigned TMR1GE :1;
unsigned T1GINV :1;
};
struct {
unsigned :2;
unsigned T1INSYNC :1;
unsigned :1;
unsigned T1CKPS0 :1;
unsigned T1CKPS1 :1;
unsigned :1;
unsigned T1GIV :1;
};
struct {
unsigned :2;
unsigned T1SYNC :1;
};
} T1CONbits_t;
extern volatile T1CONbits_t T1CONbits @ 0x010;
Con ese registro tenemos acceso, por ejemplo, al timer1.... está bueno, es similar al ARM.1.2. ¡Hola mundo! en C (o como hacer destellar un LED)
Hacer destellar un LED es muy sencillo. Tanto como crear un bucle infinito, escribir en un pin, generar una demora y volver a escribir. El ejemplito:Código: C
/* * File: main.c * Author: lucas * Created on 1 de abril de 2013, 22:20 * Microcontrolador: PIC16F648A * * ¡Hola Mundo! en C (o como hacer destellar un LED) */ #include <stdio.h> #include <stdlib.h> #include <xc.h> // Librería XC8 #define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro // PIC16F648A Configuration Bit Settings #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD) #pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled) #pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // FUNCION PRINCIPAL void main () { TRISB = 0b00000000; // Configuro puerto B como salidas while (1) // Bucle infinito { PORTBbits.RB0 = 0; // Apago pin RB0 __delay_ms(500); PORTBbits.RB0 = 1; // Enciendo pin RB0 __delay_ms(500); } }
* Podríamos hacer el cambio de estado del pin RB0 (toggle) utilizando la siguiente instrucción: PORTBbits.RB0 ^= 1;
Hola yamilongiano. Para encender todo el puerto debés hacer referencia a todo el puerto con el identificador PORTB
así:
PORTB = b00010001; // Fijate que la sintaxis del valor del entero es diferente al assembler b'00010001'
#pragma interrupt isr_main
void isr_low_main(void) {
// Rutina de interrupción
}
#pragma code high_vector=0x08
void isr_high(void) {
_asm GOTO isr_main _endasm
}
#pragma code low_vector=0x18
void isr_low(void) {
_asm GOTO isr_main _endasm
}
void interrupt isr(void) {
// Rutina de interrupción
}
void isr(void) {
// Rutina de atención a interrupciones
...
}
void interrupt high_isr(void) {
#asm
GOTO _isr
#endasm
}
void interrupt low_priority low_isr(void) {
#asm
GOTO _isr
#endasm
}
#include <xc.h>
#define _XTAL_FREQ 4000000
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#pragma config FOSC = XT, WDTE = ON, PWRTE = OFF, CP = OFF
void main(void){
PORTB = 0;
TRISB = 0;
while(1){
PORTBbits.RB1 = 0b1;
__delay_ms(1);
PORTBbits.RB1 = 0b0;
__delay_ms(1);
}
}
hola a todos como puedo hacer unos retardos de uS
e encontrado puros retardos en milisegundos. y me gustaria tener los dos tipos de retardos tanto de milisegundos como microsegundos.Código: [Seleccionar]#include <xc.h>
#define _XTAL_FREQ 4000000
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#pragma config FOSC = XT, WDTE = ON, PWRTE = OFF, CP = OFF
void main(void){
PORTB = 0;
TRISB = 0;
while(1){
PORTBbits.RB1 = 0b1;
__delay_ms(1);
PORTBbits.RB1 = 0b0;
__delay_ms(1);
}
}
muchas gracias.
Aquí dejo una parte del programa que me da problemas en XC8.
En C18 funciona perfectamente. El programa envía por la UART cada segundo el valor contado por el timer1 y sus desbordamientos.
En total es una cuenta de 48bits de longitud. Esa cuenta se pasa a ASCII y se envía.
En XC8, después de unos segundos, el programa se bloquea o se resetea. En otras versiones el micro se resetea. Sospecho que se debe a los punteros, pero no se que puede pasar.
El micro funciona con un xtal externo de 20Mhz. La frecuencia interna a partir del PLL es de 48Mhz.
Saludos.
void interrupt ISR_HIGH(void)
{
NOP();
}
void interrupt low_priority ISR_LOW(void)
{
if(PIR1bits.RC1IF)
IntRx1();
}
void IntRx1(void)
{
unsigned char dato;
if(RCSTA1bits.FERR && !PORTCbits.RC7)
RESET(); //Si se recibio BREAK reiniciamos para entrar
//al bootloader
else
dato = RCREG; //Para procesar otro dato recibido
}
1.4. Utilizando PWM
Vamos a utilizar una señal PWM de 8 bits para controlar el brillo de un LED. Para configurar el módulo CCP1 en modo PWM solo basta con escribir 0x0C en el registro CCP1CON.
Frecuencia PWM: el periodo de la onda PWM lo determina el tiempo que dura el conteo del Timer2 desde 0 hasta el valor cargado en el registro PR2. Y como la frecuencia es la inversa del período podemos deducir:(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=40649.0;attach=20531)
Donde:
* PR2 es el valor del registro PR2 (entre 0 y 255)
* FOSC es la frecuencia del cristal utilizado
* Prescaler es el prescaler del Timer2 (1, 4 ó 16). Se configura en el registro T2CON.
Ciclo de trabajo (duty cicle): es la cantidad de tiempo que en un periodo la salida PWM permanece en estado alto. El valor es determinado por el contenido del registro CCPR1L. Podemos deducir el tiempo utilizando la formula:(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=40649.0;attach=20533)
Donde:
* CCPR1L es el valor del registro CCPR1L (entre 0 y 255)
* FOSC es la frecuencia del cristal
* Prescaler es el prescaler del Timer2 (1, 4 ó 16)
Ejemplo dimerizado de un LED conectado a RB3Código: C
/* * File: main.c * Author: lucas * Created on 1 de abril de 2013, 22:20 * Microcontrolador: PIC16F648A * * Utilizando PWM para dimerizar un LED */ #include <stdio.h> #include <stdlib.h> #include <xc.h> // Librería XC8 #define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro // PIC16F648A Configuration Bit Settings #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD) #pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled) #pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // FUNCION PRINCIPAL void main(void) { TRISB = 0; // Puerto B como salidas PORTB = 0; // Limpio el puerto B // CONFIGURANDO PWM CCP1CON = 0b00001100; // Activamos el modo PWM PR2 = 250; // Frecuencia 250Hz T2CONbits.T2CKPS = 0b10; // Prescaler del timer 2 en 1:16 T2CONbits.TMR2ON = 1; // Arranca el PWM // BUCLE INFINITO unsigned char i; // Declaramos una variable while (1){ for(i=0; i=50; i++) { CCPR1L = CCPR1L++; // Seteando el ciclo de trabajo __delay_ms (100); } i=0; // Reiniciamos la variable para comenzar el ciclo de nuevo } }
Hola Amigos ....alguno de uds me puede explicar por favor si existe la forma de hacer una funcion que devuelva dos valores ...de este tipo
creo que estas estan escritas en css ...las quiero hacer porsupuesto en xc8
prototipo de la funcion
void bmp085Convert(long *temperature, long *pressure,unsigned char readings);
y para usar en el main asi :
void bmp085Convert(float *temperature, float *pressure)
Muchas gracias
Hola Amigos ....alguno de uds me puede explicar por favor si existe la forma de hacer una funcion que devuelva dos valores ...de este tipo
creo que estas estan escritas en css ...las quiero hacer porsupuesto en xc8
prototipo de la funcion
void bmp085Convert(long *temperature, long *pressure,unsigned char readings);
y para usar en el main asi :
void bmp085Convert(float *temperature, float *pressure)
Muchas gracias
La llamada a la función tiene que coincidir con el prototipo. Si necesitas llamarla y obtener valores float, debes crearla también con float dentro de los paréntesis.
Creo que deberías leer un poco más respecto a la creación de funciones. Para refrescar y/o aclarar algunos conceptos.
void interrupt low_priority low_isr(void) {
// CCP1 interrupt
if (PIR1bits.CCP1IF == 1) {
PIR1bits.CCP1IF = 0;
PIE1bits.CCP1IE = 0;
timer_read(); // Esta instrucción da error
st.timer_read = 1;
}
}
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12522. undefined symbol "?i1_sl48"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12614. undefined symbol "??i1_timer_read"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12717. undefined symbol "?i1___wmul"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12893. undefined symbol "i1___wmul@product"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12904. undefined symbol "i1___wmul@multiplier"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 12913. undefined symbol "i1___wmul@multiplicand"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s3m4.; 13008. undefined symbol "i1sl48@a"
void interrupt low_priority low_isr(void) {
// CCP1 interrupt
if (PIR1bits.CCP1IF == 1) {
PIR1bits.CCP1IF = 0;
for(char i=0; i<BUF_LEN; ) {
time_buf[i++] = time_buf[i];
}
}
}
void interrupt low_priority low_isr(void) {
// CCP1 interrupt
if (PIR1bits.CCP1IF == 1) {
PIR1bits.CCP1IF = 0;
fill_buffer();
}
}
void fill_buffer(void) {
for(char i=0; i<BUF_LEN; ) {
time_buf[i++] = time_buf[i];
}
}
typedef union {
unsigned char byte[6];
unsigned int word[3];
struct {
unsigned int __word;
unsigned long dword;
};
struct {
unsigned b0:1; // LSB
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
unsigned b8:1;
unsigned b9:1;
unsigned b10:1;
unsigned b11:1;
unsigned b12:1;
unsigned b13:1;
unsigned b14:1;
unsigned b15:1;
unsigned b16:1;
unsigned b17:1;
unsigned b18:1;
unsigned b19:1;
unsigned b20:1;
unsigned b21:1;
unsigned b22:1;
unsigned b23:1;
unsigned b24:1;
unsigned b25:1;
unsigned b26:1;
unsigned b27:1;
unsigned b28:1;
unsigned b29:1;
unsigned b30:1;
unsigned b31:1;
unsigned b32:1;
unsigned b33:1;
unsigned b34:1;
unsigned b35:1;
unsigned b36:1;
unsigned b37:1;
unsigned b38:1; // MSB
unsigned b39:1; // MANTISSA SIGN
unsigned b40:1;
unsigned b41:1;
unsigned b42:1;
unsigned b43:1;
unsigned b44:1;
unsigned b45:1;
unsigned b46:1;
unsigned b47:1;
unsigned b48:1;
};
} uint48;
uint48 time_buf[BUF_LEN];
El programa es bastante grande, pero he conseguido acotar el problema a unas pocas instrucciones.
Si ejecuto lo siguiente dentro de la rutina de interrupción no me da error:Código: [Seleccionar]void interrupt low_priority low_isr(void) {
// CCP1 interrupt
if (PIR1bits.CCP1IF == 1) {
PIR1bits.CCP1IF = 0;
for(char i=0; i<BUF_LEN; ) {
time_buf[i++] = time_buf[i];
}
}
}
Por el contrario, si lo ejecuto en una función separada, me da error:Código: [Seleccionar]
void interrupt low_priority low_isr(void) {
// CCP1 interrupt
if (PIR1bits.CCP1IF == 1) {
PIR1bits.CCP1IF = 0;
fill_buffer();
}
}
void fill_buffer(void) {
for(char i=0; i<BUF_LEN; ) {
time_buf[i++] = time_buf[i];
}
}
El error es:
Microchip MPLAB XC8 C Compiler V1.12
Copyright (C) 2012 Microchip Technology Inc.
License type: Node Configuration
Advisory[1233] Employing 18F2550 errata work-arounds:
Advisory[1234] * Corrupted fast interrupt shadow registers
Warning [1273] ; . Omniscient Code Generation not available in Free mode
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s368.; 11618. undefined symbol "??_fill_buffer"
Error [800] C:\DOCUME~1\Usuario\CONFIG~1\Temp\s368.; 11620. undefined symbol "fill_buffer@i"
(908) exit status = 1
********** Build failed! **********
Saludos.
Hola a todos ...por favor alguien sabe de que se trata este error en xc8 ..
:: warning: Omniscient Code Generation not available in Free mode
C:\Users\Ramiro\AppData\Local\Temp\s4e8.:712: error: undefined symbol "_STATUS"
(908) exit status = 1
make[2]: *** [dist/default/production/Rs232Prueba.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
make[2]: Leaving directory `C:/Users/Ramiro/pic/pic16f819/Rs232Prueba.X'
make[1]: Leaving directory `C:/Users/Ramiro/pic/pic16f819/Rs232Prueba.X'
BUILD FAILED (exit value 2, total time: 2s)
Muchas gracias Saludos
¿Tienes la definición de la función fill_bufer() antes que la interrupción? ¿La variable I, es global? Porque no la veo definida dentro de la función fill_buffer.
A su vez, los bit de tu buffer deberían ir de 0 a 47 para que sean justo 6 bytes y no de 0 a 48 ya que eso serían 49 bits.
#define _XTAL_FREQ 8000000 // esto es de HiTech para los delays
#include <stdio.h>
#include <stdlib.h>
#include <htc.h>
#include "uart.c"
void init (void);
void main ()
{
OSCCONbits.IRCF2 = 1; //
OSCCONbits.IRCF1 = 1; // defino oscilador interno en 8 mhz
OSCCONbits.IRCF0 = 1; //
TRISAbits.TRISA0 = 0 ;
TRISAbits.TRISA1 = 1 ;
const char *pantalla = "Mundo";
InitSoftUart;
putst_s ("Hola"); // envia el string "Hola" al puerto serie
putst_s ("\n"); // envia el salto de linea al puerto serie
putst_s (pantalla); // envia el string apuntado por pantalla al puerto serie
}
void init (void)
{
ADCON0bits.ADON = 0; //
ADCON1bits.PCFG3 = 0; //
ADCON1bits.PCFG2 = 1; // pongo todas las entradas digitales porta
ADCON1bits.PCFG1 = 1; //
ADCON1bits.PCFG0 = 1; //
ADCON1bits.ADCS2 = 0; //
TRISB =1;
PORTB =0;
}
/**************************************************************************
* Libreria para emular puerto serie asincronico (UART) para HiTech *
***************************************************************************
***************************************************************************
* Con clock de 4MHz la velocidad maxima de transmision es de 38400 Baud *
* Con clock de 8MHz en adelante la velocidad minima de transmision es de *
* 2400 Baud *
***************************************************************************
***************************************************************************
* *
* Antes de incluir este archivo en nuestro programa hay que definir *
* algunos parametros. Estos son *
* *
* PIC_CLK (es necesario para los delay usados internamente) *
* *
* TxPin (puerto de salida) *
* RxPin (puerto de entrada) *
* BaudRate (velocidad de transferencia) *
* *
***************************************************************************
***************************************************************************
* *
* Las rutinas de delay se encuentran en el archivo "delayhd.h" *
* El nombre original del archivo es: *
* "delay_alternative_enchanced_precision.h" y esta incluido dentro de *
* "PIC_Hi-Tech_C_delay_and_timeout_routines_for_PIC16xxxx_v7-1.zip" *
* Bajado de www.microchipc.com *
* *
* Hay que tener este archivo dentro de la carpeta de trabajo. *
* *
* Si se quiere transmitir, el pin que se utilice como TX tiene que *
* configurarse como salida. *
* Si se quiere recibir, el pin que se utilice como RX tiene que *
* configurarse como entrada. *
* *
***************************************************************************
***************************************************************************
* *
* En esta libreria se encuentran las siguientes funciones *
* *
* InitSoftUart() (inicializa el puerto serie) *
* char getch_s() (lee un byte del puerto serie) *
* putch_s(char) (envia un byte al puerto serie) *
* putst_s(char*) (envia un string al puerto serie) *
* char * getst_s(char*) (lee una cadena que termine con '\r') *
* *
* El parametro de la funcion anterior puede ser un puntero a un String *
* o el propio String *
* *
***************************************************************************
* Ejemplo de configuracion y utilizacion
#define PIC_CLK 10000000
#define TxPin RA0
#define RxPin RB1
#define BaudRate 9600
#include "SoftUart.c"
void main (void)
{
const char * pantalla = "Mundo";
.....
.....
.....
TRISA0 = 0;
TRISB1 = 1;
InitSoftUart();
Putst_s ("Hola"); // envia el string "Hola" al puerto serie
Putst_s ("\n"); // envia el salto de linea al puerto serie
Putst_s (pantalla) // envia el string apuntado por pantalla al puerto serie
}
*/
#include <htc.h>
#include "delayhd.h"
/*******************funcionrd prototipos*************************/
//void InitSoftUart(void);
unsigned char getch_s();
unsigned char getch_s();
extern void putch_s (unsigned char data);
void putst_s (const char *word);
char * getst_s (char * st);
#define TxPin PORTAbits.RA0
#define RxPin PORTAbits.RA1
#define BaudRate 9600
#if defined (PIC_CLK) && defined (BaudRate) && defined (TxPin) && defined (RxPin)
#if (PIC_CLK < 16000000)
#define BitDelay (1000000/BaudRate)
#define HalfBitDelay (500000/BaudRate)
#else
#define BitDelay (500000/BaudRate)
#define HalfBitDelay (250000/BaudRate)
#endif
#if (PIC_CLK == 4000000)
#define DelayReceivebit DelayUs(BitDelay-7)\
DelayUs(HalfBitDelay-7)
#if (BaudRate <= 19200)
#define DelayStartBit DelayUs(BitDelay-7)
#define DelaySendBit NDelayUs(BitDelay-18)
#elif (BaudRate == 28800)
#define DelayStartBit DelayUs(BitDelay-6)
#define DelaySendBit NDelayUs(BitDelay-18)
#elif (BaudRate == 38400)
#define DelayStartBit DelayUs(BitDelay-7)\
dly2u
#define DelaySendBit DelayUs(BitDelay-19)\
dly1u
#endif
#elif (PIC_CLK == 8000000)
#define DelayReceivebit DelayUs(BitDelay-7)\
DelayUs(HalfBitDelay-2)
#define DelayStartBit DelayUs(BitDelay-4)
#if (BaudRate <= 38400)
#define DelaySendBit NDelayUs(BitDelay-10)
#else //(BaudRate == 57600)
#define DelaySendBit NDelayUs(BitDelay-9)
#endif
#elif (PIC_CLK == 10000000)
#define DelayReceivebit DelayUs(BitDelay-7)\
DelayUs(HalfBitDelay)
#if (BaudRate <= 38400)
#define DelayStartBit DelayUs(BitDelay-4)
#define DelaySendBit NDelayUs(BitDelay-8)
#else //(BaudRate == 57600)
#define DelayStartBit DelayUs(BitDelay-3)
#define DelaySendBit NDelayUs(BitDelay-7)
#endif
#elif (PIC_CLK == 16000000) || (PIC_CLK == 20000000)
#if (PIC_CLK == 16000000)
#define DelayReceivebit DelayUs(BitDelay)\
DelayUs(BitDelay)\
DelayUs(BitDelay-5)
#else //(PIC_CLK == 20000000)
#define DelayReceivebit DelayUs(BitDelay)\
DelayUs(BitDelay)\
DelayUs(BitDelay-4)
#endif
#if (BaudRate <= 38400)
#define DelayStartBit DelayUs(BitDelay)\
DelayUs(BitDelay-2)
#define DelaySendBit NDelayUs(BitDelay)\
NDelayUs(BitDelay-4)
#else //(BaudRate == 57600)
#define DelayStartBit DelayUs(BitDelay)\
DelayUs(BitDelay-1)
#define DelaySendBit NDelayUs(BitDelay)\
NDelayUs(BitDelay-3)
#endif
#endif
/*
void InitSoftUart(void)
{
TxPin = 1;
}
*/
#else
#error Faltan definir parametros
#endif
#define InitSoftUart TxPin = 1
unsigned char getch_s(void)
{
unsigned char contador = 7;
unsigned char letra = 0;
while (RxPin == 1);
DelayReceivebit;
do
{
if (RxPin == 1) letra += 128;
letra = letra >> 1;
contador--;
DelaySendBit;
}
while (contador > 0);
DelaySendBit;
return letra;
}
void putch_s (unsigned char data)
{
unsigned char contador = 8;
TxPin = 0;
DelayStartBit;
do
{
TxPin = data;
DelaySendBit;
data = data >> 1;
contador--;
}
while (contador > 0);
TxPin = 1;
DelayStartBit; //tiempo de espera del bit de stop
}
void putst_s (const char *word)
{
while (*word != 0)
{
putch_s(*word);
word++;
}
}
char * getst_s (char * st)
{
char * st1;
char caracter;
st1 = st;
do
{
caracter = getch_s();
if (caracter != '\r')
{
*st1 = caracter;
st1++;
}
*st1 = '\0';
}
while (caracter != '\r');
return st;
}/*
lowlevel delay routines
Designed by Shane Tolmie of www.microchipC.com corporation. Freely distributable.
Questions and comments to webmaster@microchipC.com.
Completely re-written by Matthew Swabey and Paul Hoy of Southampton University, July 2005.
Questions and comments to mas@ecs.soton.ac.uk
Freely distributable, as above. Please add any other clock frequencies you want.
This uses no memory resources, and is precise.
Hi-Tech C and
Example C:
#define PIC_CLK 8000000
#include "delay.h"
void main(void)
{
TRISC = 0x00;
while(1)
{
PORTC = 0x00;
DelayUs(x);
PORTC = 0xFF;
}
}
*/
//#include "delay.h"
#define PIC_CLK 8000000
#ifndef __DELAY_H
#define __DELAY_H
#if (PIC_CLK == 4000000)
#define dly125n please remove; for 32Mhz+ only
#define dly250n please remove; for 16Mhz+ only
#define dly500n please remove; for 8Mhz+ only
#define dly1u asm("nop")
#define dly2u dly1u;dly1u
#elif (PIC_CLK == 8000000)
#define dly125n please remove; for 32Mhz+ only
#define dly250n please remove; for 16Mhz+ only
#define dly500n asm("nop")
#define dly1u dly500n;dly500n
#define dly2u dly1u;dly1u
#elif (PIC_CLK == 10000000)
#define dly400n asm("nop")
#elif (PIC_CLK == 16000000)
#define dly125n please remove; for 32Mhz+ only
#define dly250n asm("nop")
#define dly500n dly250n;dly250n
#define dly1u dly500n;dly500n
#define dly2u dly1u;dly1u
#elif (PIC_CLK == 20000000)
#define dly200n asm("nop")
#define dly400n dly200n;dly200n
#define dly1u dly400n;dly400n;dly200n
#define dly2u dly1u;dly1u
#elif (PIC_CLK == 32000000)
#define dly125n asm("nop")
#define dly250n dly125n;dly125n
#define dly500n dly250n;dly250n
#define dly1u dly500n;dly500n
#define dly2u dly1u;dly1u
#else
#error please define PIC_CLK correctly
#endif
/* ======================================== */
/* Delay Routines for less than 255us */
/* These give a precise delay. */
/* DelayUs(10) is 10us exactly! */
/* Only multiples of 2 available at slower */
/* speeds (16Mhz or less) */
#if PIC_CLK == 4000000
#define DelayUs(x)\
asm("\tMOVLW "___mkstr(x>>2));\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 2");
#elif PIC_CLK == 8000000
#define DelayUs(x)\
asm("\tMOVLW "___mkstr(x>>1));\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 2");
#elif PIC_CLK == 10000000
#define DelayUs(x)\
asm("\tMOVLW "___mkstr(x>>1));\
asm("\tNOP");\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 3");
#elif PIC_CLK == 16000000
#define DelayUs(x)\
asm("\tMOVLW "___mkstr(x));\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 2");
#elif PIC_CLK == 20000000
#define DelayUs(x)\
asm("\tMOVLW "___mkstr(x));\
asm("\tNOP");\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 3");
#elif PIC_CLK == 32000000
#define DelayUs(x)\
asm("\tMOVLW "___mkstr(x));\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 6");
#else
#error please define PIC_CLK correctly
#endif
/* ======================================== */
/* NDelay Routines for less than 255us */
/* These give a precise delay to the Next */
/* Instructions ACTIVATION, so NDelayUs(10) */
/* is 10us - 1 instruction! */
#if PIC_CLK == 4000000
#define NDelayUs(x)\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tMOVLW "___mkstr((x>>2)-1) );\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 2");
#elif PIC_CLK == 8000000
#define NDelayUs(x)\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tMOVLW "___mkstr((x>>1)-1) );\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 2");
#elif PIC_CLK == 10000000
#define NDelayUs(x)\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tMOVLW "___mkstr((x>>1)-1) );\
asm("\tNOP");\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 3");
#elif PIC_CLK == 16000000
#define NDelayUs(x)\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tMOVLW "___mkstr(x-1));\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 2");
#elif PIC_CLK == 20000000
#define NDelayUs(x)\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tMOVLW "___mkstr(x-1));\
asm("\tNOP");\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 3");
#elif PIC_CLK == 32000000
#define NDelayUs(x)\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tMOVLW "___mkstr(x-1));\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tNOP");\
asm("\tADDLW 0xFF");\
asm("\tBTFSS _STATUS, 2");\
asm("\tGOTO $ - 6");
#else
#error please define PIC_CLK correctly
#endif
#endif
// PIC16F819 Configuration Bit Settings
#include <xc.h>
// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTRC oscillator; CLKO function on RA6/OSC2/CLKO pin and port I/O function on RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#include <xc.h>
#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#define _XTAL_FREQ 8000000
#include "flex_lcd.h"
// CONFIG1
#pragma config FOSC = INTRC_CLKOUT// Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
void main(void)
{
unsigned char i, j;
unsigned char buffer1[20];
ANSEL=0;
ANSELH=0;
Lcd_Init();
Lcd_Cmd(LCD_CLEAR);
Lcd_Cmd(LCD_CURSOR_OFF);
__delay_ms(100);
for(i=10; i>0; i--)
{
//sprintf(buffer1,"%3d",i); //Right aligned text
sprintf(buffer1,"Cuenta %03d",i); //Right aligned text and adding zeros if necessary
//sprintf(buffer1,"%d ",i); //Left aligned text
Lcd_Out2(1, 1, buffer1);
__delay_ms(100);
}
Lcd_Out(2, 1, "Gabriel");
__delay_ms(600);
Lcd_Cmd(LCD_BLINK_CURSOR_ON);
__delay_ms(1000);
Lcd_Cmd(LCD_BLINK_CURSOR_ON);
Lcd_Cmd(LCD_UNDERLINE_ON);
__delay_ms(1000);
Lcd_Cmd(LCD_CURSOR_OFF);
__delay_ms(1000);
Lcd_Cmd(LCD_CLEAR);
Lcd_Out(1, 4, "Gracias");
Lcd_Out(2, 4, "Thank u");
while(1);
}//******************************************
// Libreria para control de LCD *
//#define LCD_RD7 PORTBbits.RB7 // D7
#define LCD_RD7 LATDbits.LATD7 // D7
//#define TRISRD7 TRISBbits.TRISB7
#define TRISRD7 TRISDbits.TRISD7
//#define LCD_RD6 PORTBbits.RB6 // D6
#define LCD_RD6 LATDbits.LATD6 // D6
//#define TRISRD6 TRISBbits.TRISB6
#define TRISRD6 TRISDbits.TRISD6
//#define LCD_RD5 PORTBbits.RB5 // D5
#define LCD_RD5 LATDbits.LATD5 // D5
//#define TRISRD5 TRISBbits.TRISB5
#define TRISRD5 TRISDbits.TRISD5
//#define LCD_RD4 PORTBbits.RB4 // D4
#define LCD_RD4 LATDbits.LATD4 // D4
//#define TRISRD4 TRISBbits.TRISB4
#define TRISRD4 TRISDbits.TRISD4
//#define LCD_EN PORTBbits.RB3 // EN
#define LCD_EN LATEbits.LATE2 // EN
//#define TRISEN TRISBbits.TRISB3
#define TRISEN TRISEbits.TRISE2
//#define LCD_RS PORTBbits.RB2 // RS
#define LCD_RS LATEbits.LATE1 // RS
//#define TRISRS TRISBbits.TRISB2
#define TRISRS TRISEbits.TRISE1
//comandos disponibles
#define LCD_FIRST_ROW 128
#define LCD_SECOND_ROW 192
#define LCD_THIRD_ROW 148
#define LCD_FOURTH_ROW 212
#define LCD_CLEAR 1
#define LCD_RETURN_HOME 2
#define LCD_CURSOR_OFF 12
#define LCD_UNDERLINE_ON 14
#define LCD_BLINK_CURSOR_ON 15
#define LCD_MOVE_CURSOR_LEFT 16
#define LCD_MOVE_CURSOR_RIGHT 20
#define LCD_TURN_OFF 0
#define LCD_TURN_ON 8
#define LCD_SHIFT_LEFT 24
#define LCD_SHIFT_RIGHT 28
void Lcd_Init(void);
void Lcd_Out(unsigned char y, unsigned char x, const char *buffer);
void Lcd_Out2(unsigned char y, unsigned char x, char *buffer);
void Lcd_Chr_CP(char data);
void Lcd_Cmd(unsigned char data);
void Lcd_Init(void){
unsigned char data;
TRISRD7 = 0;
TRISRD6 = 0;
TRISRD5 = 0;
TRISRD4 = 0;
TRISEN = 0;
TRISRS = 0;
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 0;
LCD_RD4 = 0;
LCD_EN = 0;
LCD_RS = 0;
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
__delay_us(5500);
for(data = 1; data < 4; data ++)
{
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 1; LCD_EN = 0;
LCD_RS = 0; LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 1;
LCD_EN = 1; LCD_RS = 0;
__delay_us(5);
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 1; LCD_EN = 0;
LCD_RS = 0;
__delay_us(5500);
}
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 0; LCD_EN = 0; LCD_RS = 0;
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 0; LCD_EN = 1; LCD_RS = 0;
__delay_us(5);
LCD_RD7 = 0; LCD_RD6 = 0; LCD_RD5 = 1; LCD_RD4 = 0; LCD_EN = 0; LCD_RS = 0;
__delay_us(5500);
data = 40; Lcd_Cmd(data);
data = 16; Lcd_Cmd(data);
data = 1; Lcd_Cmd(data);
data = 15; Lcd_Cmd(data);
}
void Lcd_Out(unsigned char y, unsigned char x, const char *buffer)
{
unsigned char data;
switch (y)
{
case 1: data = 128 + x; break;
case 2: data = 192 + x; break;
case 3: data = 148 + x; break;
case 4: data = 212 + x; break;
default: break;
}
Lcd_Cmd(data);
while(*buffer) // Write data to LCD up to null
{
Lcd_Chr_CP(*buffer);
buffer++; // Increment buffer
}
return;
}
void Lcd_Out2(unsigned char y, unsigned char x, char *buffer)
{
unsigned char data;
switch (y)
{
case 1: data = 128 + x; break;
case 2: data = 192 + x; break;
case 3: data = 148 + x; break;
case 4: data = 212 + x; break;
default: break;
}
Lcd_Cmd(data);
while(*buffer) // Write data to LCD up to null
{
Lcd_Chr_CP(*buffer);
buffer++; // Increment buffer
}
return;
}
void Lcd_Chr_CP(char data){
LCD_EN = 0; LCD_RS = 1;
LCD_RD7 = (data & 0b10000000)>>7; LCD_RD6 = (data & 0b01000000)>>6;
LCD_RD5 = (data & 0b00100000)>>5; LCD_RD4 = (data & 0b00010000)>>4;
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
LCD_RD7 = (data & 0b00001000)>>3; LCD_RD6 = (data & 0b00000100)>>2;
LCD_RD5 = (data & 0b00000010)>>1; LCD_RD4 = (data & 0b00000001);
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
__delay_us(5); __delay_us(5500);
}
void Lcd_Cmd(unsigned char data){
LCD_EN = 0; LCD_RS = 0;
LCD_RD7 = (data & 0b10000000)>>7; LCD_RD6 = (data & 0b01000000)>>6;
LCD_RD5 = (data & 0b00100000)>>5; LCD_RD4 = (data & 0b00010000)>>4;
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
LCD_RD7 = (data & 0b00001000)>>3; LCD_RD6 = (data & 0b00000100)>>2;
LCD_RD5 = (data & 0b00000010)>>1; LCD_RD4 = (data & 0b00000001);
_delay(10);
LCD_EN = 1; __delay_us(5); LCD_EN = 0;
__delay_us(5500);//Delay_5us();
}
#endif
lcd_pic16.c:145: warning: function declared implicit int
lcd_pic16.c:150: warning: function declared implicit int
lcd_pic16.c:192: error: undefined identifier "PORTB"
lcd_pic16.c:193: error: undefined identifier "TRISB"
lcd_pic16.c:199: error: undefined identifier "TRISBbits"
lcd_pic16.c:199: error: struct/union required
lcd_pic16.c:200: error: struct/union required
lcd_pic16.c:201: error: struct/union required
lcd_pic16.c:202: error: undefined identifier "PORTBbits"
lcd_pic16.c:202: error: struct/union required
lcd_pic16.c:203: error: struct/union required
lcd_pic16.c:204: error: struct/union required
lcd_pic16.c:278: error: undefined identifier "TRISB"
lcd_pic16.c:279: error: undefined identifier "PORTB"
lcd_pic16.c:286: error: undefined identifier "PORTBbits"
lcd_pic16.c:286: error: struct/union required
lcd_pic16.c:287: error: struct/union required
lcd_pic16.c:289: error: struct/union required
lcd_pic16.c:291: error: struct/union required
lcd_pic16.c:300: error: struct/union required
lcd_pic16.c:302: error: struct/union required
lcd_pic16.c:336: error: undefined identifier "TRISB"
lcd_pic16.c:337: error: undefined identifier "PORTB"
lcd_pic16.c:337: advisory: too many errors (21)Hola Rseliman,
He probado tu libreria de LCD tal y como la subistes y me da este error:Código: [Seleccionar]lcd_pic16.c:145: warning: function declared implicit int
lcd_pic16.c:150: warning: function declared implicit int
lcd_pic16.c:192: error: undefined identifier "PORTB"
lcd_pic16.c:193: error: undefined identifier "TRISB"
lcd_pic16.c:199: error: undefined identifier "TRISBbits"
lcd_pic16.c:199: error: struct/union required
lcd_pic16.c:200: error: struct/union required
lcd_pic16.c:201: error: struct/union required
lcd_pic16.c:202: error: undefined identifier "PORTBbits"
lcd_pic16.c:202: error: struct/union required
lcd_pic16.c:203: error: struct/union required
lcd_pic16.c:204: error: struct/union required
lcd_pic16.c:278: error: undefined identifier "TRISB"
lcd_pic16.c:279: error: undefined identifier "PORTB"
lcd_pic16.c:286: error: undefined identifier "PORTBbits"
lcd_pic16.c:286: error: struct/union required
lcd_pic16.c:287: error: struct/union required
lcd_pic16.c:289: error: struct/union required
lcd_pic16.c:291: error: struct/union required
lcd_pic16.c:300: error: struct/union required
lcd_pic16.c:302: error: struct/union required
lcd_pic16.c:336: error: undefined identifier "TRISB"
lcd_pic16.c:337: error: undefined identifier "PORTB"
lcd_pic16.c:337: advisory: too many errors (21)
Es como si no los #define no hicieran su trabajo ¿Puede que sea alguna configuracion del MPLABX?
Gracias.
Edito: Con la libreria del compañero gab163 me da el mismo error..
#include <xc.h>
#define _XTAL_FREQ 8000000
#include <stdio.h>
#include <stdlib.h>
#include "lcd_pic16.c"
#include "delay.h"
// PIC16F819 Configuration Bit Setting
// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTRC oscillator; CLKO function on RA6/OSC2/CLKO pin and port I/O function on RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has PGM function, Low-Voltage Programming enabled)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
//#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable
//variables globales
unsigned char buffer [14];
// unsigned int contador=0;
//funciones prototipo
void init(void);
void main(void)
{
OSCCONbits.IRCF2 = 1; //
OSCCONbits.IRCF1 = 1; // defino oscilador interno en 4 mhz
OSCCONbits.IRCF0 = 0; //
init();
SetDDRamAddr(0x00);
putrsXLCD("Ramiro Seliman");
putsXLCD(buffer);
SetDDRamAddr(0x40);
putrsXLCD("Victoria E.R");
}
void init(void)
{
ADCON0bits.ADON = 0;
TRISB=0; //todo el PORTB como salidas digitales
PORTB=0;
OpenXLCD(FOUR_BIT & LINES_5X7 );
}
* For 8-bit operation uncomment the #define BIT8
*/
// #define BIT8
/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
#define UPPER
/* When in 6-10-bit interface comment the #define BUSY_LCD and conected PIN
* R/W to GND in LCD
*/
//#define BUSY_LCD
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTB
#define TRIS_DATA_PORT TRISB
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN PORTBbits.RB0 /* PORT for RW */
#define TRIS_RW TRISBbits.TRISB0 /* TRIS for RW */
#define RS_PIN PORTBbits.RB1 /* PORT for RS */
#define TRIS_RS TRISBbits.TRISB1 /* TRIS for RS */
#define E_PIN PORTBbits.RB2 /* PORT for D */
#define TRIS_E TRISBbits.TRISB2 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00000100 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00000101 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00000110 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00000111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */
#ifdef _OMNI_CODE_
#define PARAM_SCLASS
#else
#define PARAM_SCLASS auto
#endif
/* CLS_Line2
* Clear Screen Line 2
*/
void CLS_Line2(void);
/* CLS_Line1
* Clear Screen Line 1
*/
void CLS_Line1(void);
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in to the LCD
*/
void putrsXLCD(const char *);
// Rutinas de tiempo auxiliares para la libreria XLCD
void DelayFor18TCY(void)
{
__delay_us(18);
}
void DelayPORXLCD(void)
{
__delay_ms(20); //Delay de 15 ms
}
void DelayXLCD(void)
{
__delay_ms(20); //Delay de 20 ms
}
void CLS_Line2(void)
{
SetDDRamAddr(0x40);
putrsXLCD(" ");
}
void CLS_Line1(void)
{
SetDDRamAddr(0x00);
putrsXLCD(" ");
}
/********************************************************************
* Function Name: OpenXLCD *
* Return Value: void *
* Parameters: lcdtype: sets the type of LCD (lines) *
* Description: This routine configures the LCD. Based on *
* the Hitachi HD44780 LCD controller. The *
* routine will configure the I/O pins of the *
* microcontroller, setup the LCD for 4- or *
* 8-bit mode and clear the display. The user *
* must provide three delay routines: *
* DelayFor18TCY() provides a 18 Tcy delay *
* DelayPORXLCD() provides at least 15ms delay *
* DelayXLCD() provides at least 5ms delay *
********************************************************************/
void OpenXLCD(unsigned char lcdtype)
{
// The data bits must be either a 8-bit port or the upper or
// lower 4-bits of a port. These pins are made into inputs
#ifdef BIT8 // 8-bit mode, use whole port
DATA_PORT = 0;
TRIS_DATA_PORT = 0x00;
#else // 4-bit mode
#ifdef UPPER // Upper 4-bits of the port
DATA_PORT &= 0x0f;
TRIS_DATA_PORT &= 0x0F;
#else // Lower 4-bits of the port
DATA_PORT &= 0xf0;
TRIS_DATA_PORT &= 0xF0;
#endif
#endif
TRIS_RW = 0; // All control signals made outputs
TRIS_RS = 0;
TRIS_E = 0;
RW_PIN = 0; // R/W pin made low
RS_PIN = 0; // Register select pin made low
E_PIN = 0; // Clock pin made low
// Delay for 15ms to allow for LCD Power on reset
DelayPORXLCD();
//-------------------reset procedure through software----------------------
WriteCmdXLCD(0x30);
__delay_ms(5);
WriteCmdXLCD(0x30);
__delay_ms(1);
WriteCmdXLCD(0x32);
while( BusyXLCD() );
//------------------------------------------------------------------------------------------
// Set data interface width, # lines, font
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(lcdtype); // Function set cmd
// Turn the display on then off
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DOFF&CURSOR_OFF&BLINK_OFF); // Display OFF/Blink OFF
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(DON&CURSOR_ON&BLINK_ON); // Display ON/Blink ON
// Clear display
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x01); // Clear display
// Set entry mode inc, no shift
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(SHIFT_CUR_RIGHT); // Entry Mode
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(0x06); // Incremente
while(BusyXLCD()); // Wait if LCD busy
SetDDRamAddr(0x80); // Set Display data ram address to 0
while(BusyXLCD()); // Wait if LCD busy
WriteCmdXLCD(CURSOR_OFF); // Cursor OFF
return;
}
/********************************************************************
* Function Name: WriteDataXLCD *
* Return Value: void *
* Parameters: data: data byte to be written to LCD *
* Description: This routine writes a data byte to the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is written to the character generator RAM or*
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
void WriteDataXLCD(char data)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = data; // Write data to port
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data into LCD
DelayFor18TCY();
E_PIN = 0;
RS_PIN = 0; // Reset control bits
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= data&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= ((data>>4)&0x0f);
#endif
RS_PIN = 1; // Set control bits
RW_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= ((data<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= (data&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock nibble into LCD
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: WriteCmdXLCD *
* Return Value: void *
* Parameters: cmd: command to send to LCD *
* Description: This routine writes a command to the Hitachi*
* HD44780 LCD controller. The user must check *
* to see if the LCD controller is busy before *
* calling this routine. *
********************************************************************/
void WriteCmdXLCD(unsigned char cmd)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Data port output
DATA_PORT = cmd; // Write command to data port
RW_PIN = 0; // Set the control signals
RS_PIN = 0; // for sending a command
DelayFor18TCY();
E_PIN = 1; // Clock the command in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Data port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f;
DATA_PORT &= 0x0f;
DATA_PORT |= cmd&0xf0;
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0;
DATA_PORT &= 0xf0;
DATA_PORT |= (cmd>>4)&0x0f;
#endif
RW_PIN = 0; // Set control signals for command
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f;
DATA_PORT |= (cmd<<4)&0xf0;
#else // Lower nibble interface
DATA_PORT &= 0xf0;
DATA_PORT |= cmd&0x0f;
#endif
DelayFor18TCY();
E_PIN = 1; // Clock command in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Make data nibble input
TRIS_DATA_PORT |= 0xf0;
#else
TRIS_DATA_PORT |= 0x0f;
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetDDRamAddr *
* Return Value: void *
* Parameters: CGaddr: display data address *
* Description: This routine sets the display data address *
* of the Hitachi HD44780 LCD controller. The *
* user must check to see if the LCD controller*
* is busy before calling this routine. *
********************************************************************/
void SetDDRamAddr(unsigned char DDaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make port output
DATA_PORT = DDaddr | 0b10000000; // Write cmd and address to port
RW_PIN = 0; // Set the control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make port input
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make port output
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((DDaddr | 0b10000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make port output
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control bits
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((DDaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (DDaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock the cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make port input
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make port input
#endif
#endif
return;
}
/********************************************************************
* Function Name: SetCGRamAddr *
* Return Value: void *
* Parameters: CGaddr: character generator ram address *
* Description: This routine sets the character generator *
* address of the Hitachi HD44780 LCD *
* controller. The user must check to see if *
* the LCD controller is busy before calling *
* this routine. *
********************************************************************/
void SetCGRamAddr(unsigned char CGaddr)
{
#ifdef BIT8 // 8-bit interface
TRIS_DATA_PORT = 0; // Make data port ouput
DATA_PORT = CGaddr | 0b01000000; // Write cmd and address to port
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
DelayFor18TCY();
TRIS_DATA_PORT = 0xff; // Make data port inputs
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT &= 0x0f; // Make nibble input
DATA_PORT &= 0x0f; // and write upper nibble
DATA_PORT |= ((CGaddr | 0b01000000) & 0xf0);
#else // Lower nibble interface
TRIS_DATA_PORT &= 0xf0; // Make nibble input
DATA_PORT &= 0xf0; // and write upper nibble
DATA_PORT |= (((CGaddr |0b01000000)>>4) & 0x0f);
#endif
RW_PIN = 0; // Set control signals
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
DATA_PORT &= 0x0f; // Write lower nibble
DATA_PORT |= ((CGaddr<<4)&0xf0);
#else // Lower nibble interface
DATA_PORT &= 0xf0; // Write lower nibble
DATA_PORT |= (CGaddr&0x0f);
#endif
DelayFor18TCY();
E_PIN = 1; // Clock cmd and address in
DelayFor18TCY();
E_PIN = 0;
#ifdef UPPER // Upper nibble interface
TRIS_DATA_PORT |= 0xf0; // Make inputs
#else // Lower nibble interface
TRIS_DATA_PORT |= 0x0f; // Make inputs
#endif
#endif
return;
}
/********************************************************************
* Function Name: ReadDataXLCD *
* Return Value: char: data byte from LCD controller *
* Parameters: void *
* Description: This routine reads a data byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The data *
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
********************************************************************/
char ReadDataXLCD(void)
{
char data;
#ifdef BIT8 // 8-bit interface
RS_PIN = 1; // Set the control bits
RW_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
data = DATA_PORT; // Read the data
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#else // 4-bit interface
RW_PIN = 1;
RS_PIN = 1;
DelayFor18TCY();
E_PIN = 1; // Clock the data out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // read the upper nibble of data
#endif
E_PIN = 0; // Reset the clock line
DelayFor18TCY();
E_PIN = 1; // Clock the next nibble out of the LCD
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the lower nibble of data
#endif
E_PIN = 0;
RS_PIN = 0; // Reset the control bits
RW_PIN = 0;
#endif
return(data); // Return the data byte
}
/*********************************************************************
* Function Name: ReadAddrXLCD *
* Return Value: char: address from LCD controller *
* Parameters: void *
* Description: This routine reads an address byte from the *
* Hitachi HD44780 LCD controller. The user *
* must check to see if the LCD controller is *
* busy before calling this routine. The address*
* is read from the character generator RAM or *
* the display data RAM depending on what the *
* previous SetxxRamAddr routine was called. *
*********************************************************************/
unsigned char ReadAddrXLCD(void)
{
char data; // Holds the data retrieved from the LCD
#ifdef BIT8 // 8-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
data = DATA_PORT; // Save the data in the register
E_PIN = 0;
RW_PIN = 0; // Reset the control bits
#else // 4-bit interface
RW_PIN = 1; // Set control bits for the read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock data out of the LCD controller
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data = DATA_PORT&0xf0; // Read the nibble into the upper nibble of data
#else // Lower nibble interface
data = (DATA_PORT<<4)&0xf0; // Read the nibble into the upper nibble of data
#endif
E_PIN = 0; // Reset the clock
DelayFor18TCY();
E_PIN = 1; // Clock out the lower nibble
DelayFor18TCY();
#ifdef UPPER // Upper nibble interface
data |= (DATA_PORT>>4)&0x0f; // Read the nibble into the lower nibble of data
#else // Lower nibble interface
data |= DATA_PORT&0x0f; // Read the nibble into the lower nibble of data
#endif
E_PIN = 0;
RW_PIN = 0; // Reset the control lines
#endif
return (data&0x7f); // Return the address, Mask off the busy bit
}
/********************************************************************
* Function Name: putsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putsXLCD(char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/********************************************************************
* Function Name: putrsXLCD
* Return Value: void
* Parameters: buffer: pointer to string
* Description: This routine writes a string of bytes to the
* Hitachi HD44780 LCD controller. The user
* must check to see if the LCD controller is
* busy before calling this routine. The data
* is written to the character generator RAM or
* the display data RAM depending on what the
* previous SetxxRamAddr routine was called.
********************************************************************/
void putrsXLCD(const char *buffer)
{
while(*buffer) // Write data to LCD up to null
{
while(BusyXLCD()); // Wait while LCD is busy
WriteDataXLCD(*buffer); // Write character to LCD
buffer++; // Increment buffer
}
return;
}
/********************************************************************
* Function Name: BusyXLCD *
* Return Value: char: busy status of LCD controller *
* Parameters: void *
* Description: This routine reads the busy status of the *
* Hitachi HD44780 LCD controller. *
********************************************************************/
unsigned char BusyXLCD(void)
{
#ifdef BUSY_LCD
RW_PIN = 1; // Set the control bits for read
RS_PIN = 0;
DelayFor18TCY();
E_PIN = 1; // Clock in the command
DelayFor18TCY();
#ifdef BIT8 // 8-bit interface
if(DATA_PORT&0x80) // Read bit 7 (busy bit)
{ // If high
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Bit 7 low
{
E_PIN = 0; // Reset clock line
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#else // 4-bit interface
#ifdef UPPER // Upper nibble interface
if(DATA_PORT&0x80)
#else // Lower nibble interface
if(DATA_PORT&0x08)
#endif
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 1; // Return TRUE
}
else // Busy bit is low
{
E_PIN = 0; // Reset clock line
DelayFor18TCY();
E_PIN = 1; // Clock out other nibble
DelayFor18TCY();
E_PIN = 0;
RW_PIN = 0; // Reset control line
return 0; // Return FALSE
}
#endif
#else
__delay_ms(5);
return 0;
#endif
}
lcd_pic_16.c:127: warning: function declared implicit int
lcd_pic_16.c:132: warning: function declared implicit int
lcd_pic_16.c:174: error: undefined identifier "PORTB"
lcd_pic_16.c:175: error: undefined identifier "TRISB"
lcd_pic_16.c:181: error: undefined identifier "TRISBbits"
lcd_pic_16.c:181: error: struct/union required
lcd_pic_16.c:182: error: struct/union required
lcd_pic_16.c:183: error: struct/union required
lcd_pic_16.c:184: error: undefined identifier "PORTBbits"
lcd_pic_16.c:184: error: struct/union required
lcd_pic_16.c:185: error: struct/union required
lcd_pic_16.c:186: error: struct/union required
lcd_pic_16.c:260: error: undefined identifier "TRISB"
lcd_pic_16.c:261: error: undefined identifier "PORTB"
lcd_pic_16.c:268: error: undefined identifier "PORTBbits"
lcd_pic_16.c:268: error: struct/union required
lcd_pic_16.c:269: error: struct/union required
lcd_pic_16.c:271: error: struct/union required
lcd_pic_16.c:273: error: struct/union required
lcd_pic_16.c:282: error: struct/union required
lcd_pic_16.c:284: error: struct/union required
lcd_pic_16.c:318: error: undefined identifier "TRISB"
lcd_pic_16.c:319: error: undefined identifier "PORTB"
lcd_pic_16.c:319: advisory: too many errors (21)
Que versión tienes de xc8? Limbo)xc8 v1.12
Fijate que yo pase el zippara que lo bajes y habras directamente con mplabx ...y tambien para la simulacion con proteus ...Ya ya, tus archivos no me compilan tampoco.. por eso creo que es algo del compilador pero no logro descubrir que es..
CitarQue versión tienes de xc8? Limbo)xc8 v1.12CitarFijate que yo pase el zippara que lo bajes y habras directamente con mplabx ...y tambien para la simulacion con proteus ...Ya ya, tus archivos no me compilan tampoco.. por eso creo que es algo del compilador pero no logro descubrir que es..
Prueba incluir delay.h antes de incluir la librería del LCDYa probe todo eso, porque sé que hay liso aveces con el orden de las librerias, pero nada, lo he vuelto a probar lo que dices y nada.
:: warning: Omniscient Code Generation not available in Free mode
:0: error: undefined symbols:
_WriteCmdXLCD(dist/default/production\pru18.X.production.obj) _putrsXLCD(dist/default/production\pru18.X.production.obj) _OpenXLCD(dist/default/production\pru18.X.production.obj) _BusyXLCD(dist/default/production\pru18.X.production.obj)
(908) exit status = 1Solo he cambiado la extension de la libreria y me da este error... ¿Alguna sugerencia?¿Porque al cambiar la extension em da solo un error?
Si no dejas un tiempo entre escritura estará actualizando tan rápido que parecería estar parpadeando intenta poner un delay y pruebaNo, no, digo que el programa se repite indefinidamente sin haber bucle en ningun sitio..
CitarSi no dejas un tiempo entre escritura estará actualizando tan rápido que parecería estar parpadeando intenta poner un delay y pruebaNo, no, digo que el programa se repite indefinidamente sin haber bucle en ningun sitio..
Si pongo un bucle while al final del main. me muestra elemnsaje sin parpadeo porque solo lo escribe una vez, me explic?Es un bucle infinito del programa entero.. Hay alguna configuracion del pic o del mplab que haga esto sin necesidad de un bucle?
Si tu programa es un bucle infinito en sí mimosMi programa no es un bucle que yo defina,¿ o quieres decir que TODO programa en mplabx es un bucle? Yo siempre, tanto en C como en asembler hacia un bucle infinito para que el programa no se acabara, sino no se veia el resultado del programa, me explico?
Las extensiones h se usan para los header, o sea para las definicion de las funciones por ejemploYa ya, pero esa no es la cuestion, la cuestion es porque me funciona con la extension .h y con la .c no..
Ahhhh otra cosa ...si estas usando Mplabx ....en el arbol que aparece al costado del IDE ...no definas las funcines en souce ni en header ....solamente el main en source ....me explico ???mmmm que ocurre sino hago eso? Tengo añadidos el archivo main y el archivo de libreria en source... ¿Donde añado las librerias sino?
mmmm que ocurre sino hago eso? Tengo añadidos el archivo main y el archivo de libreria en source... ¿Donde añado las librerias sino?
Tengo un pequeño problema que creo que se debe a que la rutina de interrupción no salvaguarda bien los datos.
¿Como se salva el contexto en las interrupciones con XC8? ¿Es todo automático o hay que hacerlo a mano para ciertos registros?
Saludos.
Perdon AngelGris ....como yo veo la subrutina ...segun entiendo ...con lo poco que se , que en el main , deberias referirte al swuart.c y NO al swuart.h ...
O sea que primero debes incluir el swuart.c para que el mismo incluya los headers ..en el swuart.h ...
Perdon si me equivoco ...
Saludos
Saca el archivo de la libreria en source ...ahi solamente pone el main.c y si queres hacer mas legible el main ...separa los pragma en un archivo diferente ...configuratiob_bits.c ...que ese si lo agregas en el source junto con el main ....desp las librerias las agregas con los #include al rpincipio del main ...ahi te puese un ejemplo ....en el main.c al principio pones #include la libreria.c ...y al principio de la lñibreria pones el #include libreria.h que es donde estan los headers ...que son las definiciones de las funciones ....me explico ....si haces esto y a su ves los agregas en el source ...vas a tener conflictos ...y errores que no vas a saber de donde vienen .....te vuelvo a repetir yo logre compilar bien ..solamente teniendo en el arbol de la izquierda ..en el source ...el main y el config bits ....y nada masSolo tengo el main.c en el arbol de la izquierda, intento incluir la libreria en .c y me da errores, en cambio incluyo el MISMO codigo en un archivo .h y me va perfecto... no lo entiendo..
se podría abrir un hilo de recursos para XC8, y así tenerlos un poco mas ordenadosPienso yo que para eso esta este tema no?
Aquí dejo una librería en para manejo de UART por SoftWare
Hay que tener en cuenta que no todas las velocidades de comunicación serán posibles en todas las frecuencias de trabajo del microcontrolador. Por ejemplo, con 4MHz no se puede comunicar a una velocidad mayor a 19200
En el header de la librería están definidos los tiempos y hay una "especie de compensación" según la frecuencia a la que esté trabajando.
Lo simulé en ISIS con un 16F876A y va bien.
Si tienes un max232 puedes probar comunicación entre el PIC y la PC... también puedes intentar una comunicación a menor velocidad. Postea tu programa y el header de la librería como lo estés utilizando, tal vez hay algún problema.
Si tienes un max232 puedes probar comunicación entre el PIC y la PC... también puedes intentar una comunicación a menor velocidad. Postea tu programa y el header de la librería como lo estés utilizando, tal vez hay algún problema.
#define _XTAL_FREQ 8000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <htc.h>
// #include "i2c.h"
// #include "BMP085.h"
#include "swuart.h"
char mensaje[10] = "Ramiro";
long temperature;
void init ();
void main(void)
{
__delay_ms(1000);
unsigned char *punterostring;
punterostring = mensaje;
swinit_uart(); //inicialiso el UART
__delay_ms(10);
swputch('T');
swputch('E');
swputch('M');
swputch('P'); //mando la palabra Hola letra por letra
swputch('\r'); //salto de linea
swputs(mensaje); //mando la cadena almacenada en mensaje
swputch('\r'); //salto de linea
swgets(punterostring); //recibo una cadena terminada con '\r'
swputch('\r'); //salto de linea
swputs(punterostring); //mando la cadena apuntada por punterostring
//(recibida anteriormente)
//temperature = bmp085ReadTemp();
//itoa( mensaje, temperature, 10 );
while(1);
}
void init(void)
{
OSCCONbits.IRCF2 = 1; //
OSCCONbits.IRCF1 = 1; // defino oscilador interno en 8 mhz
OSCCONbits.IRCF0 = 1; //
ADCON0bits.ADON = 0; //
ADCON1bits.PCFG3 = 0; //
ADCON1bits.PCFG2 = 1; // pongo todas las entradas digitales porta
ADCON1bits.PCFG1 = 1; //
ADCON1bits.PCFG0 = 1; //
ADCON1bits.ADCS2 = 0; //
TRISA=0;
PORTA=0;
// TRISB =1;
// PORTB =0;
// BMP085_Calibration();
}#ifndef SWUART_H
#define SWUART_H
#ifndef _XC_H_
#include <xc.h>
#endif
/*******************************************************************************
* Parametros configurables por el usuario *
*******************************************************************************/
/*
* El valor de _XTAL_FREQ debe coincidir con el valor definido
* en el programa principal
*/
/*
* En el caso que solo se desee transmitir se debe definir TXONLY
* En el caso que solo se desee recibir se debe definir RXONLY
* En el caso de querer transmitir y recibir se debe definir TXRX
*/
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 8000000
#endif
#define TXPIN PORTBbits.RB0
#define RXPIN PORTBbits.RB2
#define TXDIR TRISBbits.TRISB0
#define RXDIR TRISBbits.TRISB2
#define SWUARTBAUD 9600
#define TXRX
/*******************************************************************************
* Parametros internos para los tiempos de cada bit *
*******************************************************************************/
#define _BitOutDelay (1000000UL/SWUARTBAUD)
#define StartDelay (1500000UL/SWUARTBAUD)
#if (_XTAL_FREQ <= 4000000)
#define BitOutDelay (_BitOutDelay - 24)
#define BitInDelay (_BitOutDelay - 24)
#elif (_XTAL_FREQ <= 6000000) && (_XTAL_FREQ > 4000000)
#define BitOutDelay (_BitOutDelay - 16)
#define BitInDelay (_BitOutDelay - 16)
#elif (_XTAL_FREQ <= 8000000) && (_XTAL_FREQ > 6000000)
#define BitOutDelay (_BitOutDelay - 12)
#define BitInDelay (_BitOutDelay -12)
#elif (_XTAL_FREQ <= 10000000) && (_XTAL_FREQ > 8000000)
#define BitOutDelay (_BitOutDelay - 10)
#define BitInDelay (_BitOutDelay -9)
#elif (_XTAL_FREQ <= 12000000) && (_XTAL_FREQ > 10000000)
#define BitOutDelay (_BitOutDelay - 8)
#define BitInDelay (_BitOutDelay - 7)
#elif (_XTAL_FREQ <= 16000000) && (_XTAL_FREQ > 12000000)
#define BitOutDelay (_BitOutDelay - 6)
#define BitInDelay (_BitOutDelay - 5)
#elif (_XTAL_FREQ <= 20000000) && (_XTAL_FREQ > 16000000)
#define BitOutDelay (_BitOutDelay - 5)
#define BitInDelay (_BitOutDelay - 4)
#elif (_XTAL_FREQ <= 26000000) && (_XTAL_FREQ > 20000000)
#define BitOutDelay (_BitOutDelay - 3)
#define BitInDelay (_BitOutDelay - 3)
#elif (_XTAL_FREQ <= 48000000) && (_XTAL_FREQ > 26000000)
#define BitOutDelay (_BitOutDelay - 2)
#define BitInDelay (_BitOutDelay - 2)
#endif
/*******************************************************************************
* Definicion de funciones *
*******************************************************************************/
/*
* La funcion swgets recibe una cadena que termine con '\r' (decimal 13)
* la cadena es devuelta a travez del puntero que se le pasa como parametro
*/
void swinit_uart(void);
void swputch(unsigned char);
void swputs(unsigned char *);
unsigned char swgetch(void);
void swgets(unsigned char *);
#endif /* SWUART_H */#ifndef SWUART_H
#include "swuart.h"
#endif
#if !defined(TXPIN) || !defined(RXPIN) || !defined(TXDIR) || !defined(RXDIR)
#error No estan definidos los pines
#else
#ifndef SWUARTBAUD
#error Falta definir la velocidad
#endif
void swinit_uart(void)
{
#if defined TXONLY
TXDIR = 0;
#elif defined RXONLY
RXDIR = 1;
#elif defined TXRX
TXDIR = 0;
RXDIR = 1;
#endif
}
void swputch(unsigned char _dato)
{
unsigned char _bits2 = 8;
TXPIN = 0;
__delay_us(BitOutDelay);
do
{
TXPIN = _dato & 1;
__delay_us(BitOutDelay);
_dato = _dato >> 1;
_bits2--;
}
while (_bits2 > 0);
TXPIN = 1;
__delay_us(_BitOutDelay);
}
void swputs(unsigned char *_st)
{
while (*_st != 0)
{
swputch(*_st);
_st++;
}
}
unsigned char swgetch(void)
{
unsigned char _datain = 0;
unsigned char _bits2 = 8;
while (RXPIN == 1);
__delay_us(StartDelay);
do
{
_datain = _datain >> 1;
if (RXPIN == 1) _datain |= 0b10000000;
__delay_us(BitInDelay);
_bits2--;
}
while (_bits2 > 0);
__delay_us(BitOutDelay/2);
return _datain;
}
void swgets(unsigned char *st)
{
unsigned char *word;
unsigned char character;
word = st;
do
{
character = swgetch();
if (character != '\r')
{
*word = character;
word++;
}
}
while (character != '\r');
*word = 0;
}
#endif // PIC16F819 Configuration Bit Settings
#include <xc.h>
// CONFIG
#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTRC oscillator; CLKO function on RA6/OSC2/CLKO pin and port I/O function on RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
Logre que funcione ...es la segunda vez que cometo el mismo error ...la programacion del oscilador !!!!!
OSCCONbits.IRCF2 = 1; //
OSCCONbits.IRCF1 = 1; // defino oscilador interno en 8 mhz
OSCCONbits.IRCF0 = 1; //
estaban fuera del main ...y evidentemente a Proteus no le interesa ....
Saludos
Hola yamilongiano. Para encender todo el puerto debés hacer referencia a todo el puerto con el identificador PORTB
así:
PORTB = b00010001; // Fijate que la sintaxis del valor del entero es diferente al assembler b'00010001'
gracias si funciono.
Hola yamilongiano. Para encender todo el puerto debés hacer referencia a todo el puerto con el identificador PORTB
así:
PORTB = b00010001; // Fijate que la sintaxis del valor del entero es diferente al assembler b'00010001'
gracias si funciono.
Ten cuidado una cosa es LATB y otra muy diferente es PORTB, la primera es colocar datos en el puerto B y la segunda es leer datos del puertoB, oviamente se debe estar configurado el puertoB como salida o sea TRISB = 0; o TRISBbits.TRISB0 = 0, para solo encender el bit 0 del puertoB.
Hola amigos en esta ocasion les traigo dos videos. El primero muestra como instalar MPLABX en Linux Mint 14 y el segundo muestra como instalar los compiladores XC8, XC16 Y XC32.
Espero que los Disfruten :-/
3.4.1 ANSELH REGISTER
The ANSELH register (Register 3-4) is used to
configure the Input mode of an I/O pin to analog.
Setting the appropriate ANSELH bit high will cause all
digital reads on the pin to be read as ‘0’ and allow
analog functions on the pin to operate correctly.
The state of the ANSELH bits has no affect on digital
output functions. A pin with TRIS clear and ANSELH
set will still operate as a digital output, but the Input
mode will be analog. This can cause unexpected
behavior when executing read-modify-write
instructions on the affected port.
#include <xc.h>
#define _XTAL_FREQ 4000000
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = ON // Internal External Switchover bit (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
void main(void)
{
ANSELH = 0; //si comentan esto RB5 nunca prende.
PORTB = 0;
TRISB = 0;
while (1)
{
RB5 = 1;
RB7 = 1;
__delay_ms(2000);
RB5 = 0;
RB7 = 0;
__delay_ms(1000);
}
}
Gracias Jukinch.. Voy a estar quemando neurona haciendo este codigo.. y poco a poco lo ire subiendo... Gracias..
Estas respuestas son mas rápidas que la justicia aquí en colombia jejejejej
Exitos a todos..
///Generacion de onda cuadrada 10Khz con duty-cycle 50%
//Cofiguración de Bits
#pragma config PLLDIV = 1 //No importa por que vamos a trabajar con el oscilador interno
#pragma config CPUDIV = OSC1_PLL2 //No importa por que vamos a trabajar con el oscilador interno
#pragma config USBDIV = 1
#pragma config FOSC = INTOSC_EC //Configurado para trabajar oscilador interno, si se deja por default trabajará a 1MHZ de clock
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 8192
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = OFF
#pragma config CCP2MX = OFF
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config ICPRT = OFF
#pragma config XINST = OFF
#pragma config DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF,CP3 = OFF
#pragma config CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
#pragma config EBTRB = OFF
#pragma config EBTR3 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR0 = OFF
#include <p18f4550.h>
//Declarando funciones de interrupciones
void Interrupt_isr_Tmr0(void);
void main(void){
//Configuracion
INTCON = 0b00100000; //Habilito el TMR0 overflow Interrupt
INTCON2 = 0b10000100; //Resistencia pull-up son off
RCONbits.IPEN = 1; //Habilito interrupciones por prioridad
TMR0H=0xFF;
TMR0L=0XFA; //Cargo el timer0 para trabajar a 16bits para que se me desborde cada 50us para obtener una frecuencia de 10KHz
T0CON=0b10000011; //Los calculos son realizado de la siguiente manera:
INTCONbits.GIEH=1; //Timer_Frecuencia = Fos/4 ==> 8Mhz/4 = 2Mhz.
TRISB = 0X00; //utilizando un prescales de 16 2Mhz/16 = 125Khz
PORTB = 0X00; //(125Khz)(50us) = 6, como estoy trabajando a 16bits
//la cuenta va desde 0x0000-0xFFFF (0-65535)
while(1); //65535-6 = 65530 Ó 0xFFFA, que es lo que cargo en el timer
}
#pragma code Interrupt_vector_TMR0 = 0x08
void Interrupt_vector_TMR0(void)
{
_asm goto Interrupt_isr_Tmr0
_endasm
}
//Rutina de interrupción
#pragma code
#pragma interrupt Interrupt_isr_Tmr0
void Interrupt_isr_Tmr0(void)
{
if(INTCONbits.TMR0IF ==1){ //Preguntamos por la bandera
INTCONbits.TMR0IF=0; //Borramos la bandera
LATBbits.LATB1=!LATBbits.LATB1;
}
}
Quiero hacer esto:No saben tampoco como? :mrgreen:
unsigned char pines[3] = {RD0, RB1, RC2};
Pero no me deja. Dice que solo admite constantes. Bueno mi idea es controlar varios pines de una forma mas didactica. Entonces pense en punteros, pero como no soy muy bueno en este tema, no logro dar que me compile:
unsigned char *pines;
pines = &RD0;
Y me da ilegal operation on bit variable y ilegal conversion
Alguien sabe como hacerle?
Gracias.
Lo que intento hacer es poder controlar el estado de varios pines de diferentes puertos del PIC.
Lo mejor que se me ocurre es un array de los pines que quiero controlar: unsigned char pines_a_controlar[5] = {RA0, RB3, RC4, RD4, RD6};
De esta forma, setearia al pin RA0 poniendo: pines_a_controlar[0] = 1;
Pero esto no compila.
Estoy mirando los links que has propuesto, estan interesantes. Graias por tu tiempo.
#include <xc.h> /* definiciones 12F683 */
#define _XTAL_FREQ 4000000
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#pragma config FOSC = INTOSCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF
#pragma config CP = OFF, CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
void toggle_bit(int pin){
GPIO ^= (1<<pin); /* cambia estado de pin en GPIO */
}
void main (void){
CMCON0 |= 0b00000111; /* desactiva comparadores */
ANSEL &= 0b11110000; /* puerto como E/S digitales */
GPIO = 0b000000; /* inicia con LEDs apagados */
TRISIO = 0b111000; /* GP1, GP2 y GP3 como salidas */
OPTION_REG &= 0b01111111; /* habilita "pull-ups" internos */
int pin = 0;
while (1){
for (pin = 0; pin < 3; pin++){
toggle_bit(pin);
__delay_ms(200);
}
}
}int n=0;
while (1)
{
for(n=0;n<8;n++)
{
LATD =(LATD |= 1<<n); // pone en 1 el bit n del puerto D
myMsDelay(100);
LATD &= (~(1<<n)); // pone en 0 el bit n del puerto D
}
for(n=6;n>=1;n--)
{
LATD=(LATD |= 1<<n); // pone en 1 el bit n del puerto D
myMsDelay(100);
LATD &= (~(1<<n)); // pone en 0 el bit n del puerto D
}
}Operadores a nivel de bit (bitwise operators)
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
El operador AND "&" compara dos bits; si los dos son 1 el resultado es 1, en otro caso el resultado será 0.
Ejemplo:
c1 = 0x45 --> 01000101
c2 = 0x71 --> 01110001
---------------------------
c1 & c2 = 0x41 --> 01000001
-----------------------------------------------------------------------------------------------------------------------------
El operador OR "|" compara dos bits; si cualquiera de los dos bits es 1, entonces el resultado es 1; en otro caso será 0. Ejemplo:
i1 = 0x47 --> 01000111
i2 = 0x53 --> 01010011
---------------------------
i1 | i2 = 0x57 --> 01010111
-----------------------------------------------------------------------------------------------------------------------------
El operador exclusivo (XOR) "^", da por resultado uno cuando los dos operandos tienen distinto valor.
Cuando los dos operandos son distintos da 1.-
ej: 1 y 0 =1
0 y 1 =1
Cuando los dos operandos son iguales da 0.-
0 y 0 =0
1 y 1 =0
Ejemplo:
i1 = 0x47 --> 01000111
i2 = 0x53 --> 01010011
---------------------------
i1 ^ i2 = 0x14 --> 00010100
-----------------------------------------------------------------------------------------------------------------------------
El operador de complemento a 1 "~" cambia cada dígito del operando por su opuesto:
si el bit es 1 se cambia por 0 y viceversa
c = 0x45 --> 01000101
----------------------
~c = 0xBA --> 10111010
-----------------------------------------------------------------------------------------------------------------------------
Los operadores de desplazamiento a nivel de bit "<<" y ">>" Desplazan a la izquierda o a la derecha un número especificado de bits.
En un desplazamiento a la izquierda los bits que sobran por el lado izquierdo se descartan y se rellenan los nuevos espacios con ceros. De manera análoga pasa con los desplazamientos a la derecha. Veamos un ejemplo:
c = 0x1C 00011100
c << 1 c = 0x38 00111000
c >> 2 c = 0x07 00000111
Como en binario se trabaja en base dos cada posición de desplazamiento implica dividir o multiplicar por 2
>> divide por 2.
<< multiplica por 2
c = 0x1C 00011100
c << 1 c = 0x38 00111000 multiplica por 2
c >> 2 c = 0x07 00000111 divide 2 veces por 2 (divide por 4)
Dependiendo el compilador El operador shift >> tiene diferente comportamiento
--------------------------------------------------------------------------------
depende del tipo de dato al que se le va a aplicar. Más precisamente si la variable fue creada con signo o sin signo.
EJEMPLO:
creamos dos variables
unsigned char A=100;
signed char B=-100;
Valor de A= 100 // valor decimal
Valor de A en binario: 01100100
Valor de A en binario luego de aplicarle shift >> 2:
Valor en binario: 00011001 // en este caso el bit más significativo se indica con un cero.
// y los bits que se desplacen hacia la derecha del bit más significativo
// se completan con ceros 0.
Valor de B= -100 // valor decimal
Valor de B en binario: 10011100
Valor de B en binario luego de aplicarle shift >> 2:
Valor de B en binario: 11100111 // en este caso el bit más significativo se mantiene para indicar el signo negativo
// y los bits que se desplacen hacia la derecha del bit más significativo
// se completan con unos 1.
-----------------------------------------------------------------------------------------------------------------------------
ejemplos de precedencia de los operandos:
puerto &= ~(1<<6) primero se desplaza un 1 hacia la izquierda 6 posiciones y luego el operando ~ lo convierte en cero. Es resultado se combina mediante el operando & con el contenido del byte del puerto. Aplicándose así una máscara que pone en cero el bit 6 dejando pasar los demás bits. De esta manera se logra un equivalente en assembler de bitclr en la posición del bit 6.
#define bit_set(bit,puerto) (puerto |= 1<<bit)
#define bit_clr(bit,puerto) (puerto &= ~(1<<bit))
// ejemplo en código
bit_set(0,PORTB); // pone a 1 el bit 0 del puerto B.
bit_clr(0,PORTB); // pone a 0 el bit 0 del puerto B.
-----------------------------------------------------------------------------------------------------------------------------
Código binario en complemento a dos:
En este sistema, los números positivos se representan reservando el bit más significativo (que debe ser cero) para el signo. Para los números negativos, se utiliza un sistema distinto, denominado complemento a dos, en el que se cambian los bits que serían 0 por 1 y viceversa, y al resultado se le suma uno.
Este sistema sigue reservando el bit más significativo para el signo, que sigue siendo 1 en los negativos. Por ejemplo, la representación de 33 y -33 sería:
+33 0010 0001
se invierte todo
-33 1101 1110
se le suma 1
+ 0000 0001
resultado
1101 1111 numero -33 en complemento a dos
El hardware necesario para implementar operaciones aritméticas con números representados de este modo es mucho más sencillo que el del complemento a uno, por lo que es el sistema más ampliamente utilizado.
-----------------------------------------------------------------------------------------------------------------------------
PARA ROTAR UN BYTE
C language does not specify a rotate operator; however, it does allow shifts. The compiler will detect expressions that implement rotate operations using shift and logical operators and compile them efficiently.
EJEMPLO:
c = (c << 1) | (c >> 7);
Hola amigo queria saber si tu libreria i2c puede manejar el ds1307, y tambien quería saber si esta libreria lo sacaste de algun lugar o lo hiciste tu.
Hola amigo queria saber si tu libreria i2c puede manejar el ds1307, y tambien quería saber si esta libreria lo sacaste de algun lugar o lo hiciste tu.
¿A cuál librería te refieres? Yo subí una de I2C por software, por ello la pregunta. En el caso de mi librería, trabaja a una velocidad aproximada de 70Khz y la velocidad máxima para el modo standard es de 100KHz así que supongo que funcionaría, a no ser que necesite una mayor velocidad.
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include <spi.h>
#include "5110lcd.h"
#define SCE_5110 LATBbits.LATB3
#define RESET_5110 LATBbits.LATB2
#define DC_5110 LATBbits.LATB4
const char font[] = {0x00, 0x00, 0x00, 0x00, 0x00, // 20 space
0x00, 0x00, 0x5f, 0x00, 0x00, // 21 !
0x00, 0x07, 0x00, 0x07, 0x00, // 22 "
0x14, 0x7f, 0x14, 0x7f, 0x14, // 23 #
0x24, 0x2a, 0x7f, 0x2a, 0x12, // 24 $
0x23, 0x13, 0x08, 0x64, 0x62, // 25 %
0x36, 0x49, 0x55, 0x22, 0x50, // 26 &
0x00, 0x05, 0x03, 0x00, 0x00, // 27 '
0x00, 0x1c, 0x22, 0x41, 0x00, // 28 (
0x00, 0x41, 0x22, 0x1c, 0x00, // 29 )
0x14, 0x08, 0x3e, 0x08, 0x14, // 2a *
0x08, 0x08, 0x3e, 0x08, 0x08, // 2b +
0x00, 0x50, 0x30, 0x00, 0x00, // 2c ,
0x08, 0x08, 0x08, 0x08, 0x08, // 2d -
0x00, 0x60, 0x60, 0x00, 0x00, // 2e .
0x20, 0x10, 0x08, 0x04, 0x02, // 2f /
0x3e, 0x51, 0x49, 0x45, 0x3e, // 30 0
0x00, 0x42, 0x7f, 0x40, 0x00, // 31 1
0x42, 0x61, 0x51, 0x49, 0x46, // 32 2
0x21, 0x41, 0x45, 0x4b, 0x31, // 33 3
0x18, 0x14, 0x12, 0x7f, 0x10, // 34 4
0x27, 0x45, 0x45, 0x45, 0x39, // 35 5
0x3c, 0x4a, 0x49, 0x49, 0x30, // 36 6
0x01, 0x71, 0x09, 0x05, 0x03, // 37 7
0x36, 0x49, 0x49, 0x49, 0x36, // 38 8
0x06, 0x49, 0x49, 0x29, 0x1e, // 39 9
0x00, 0x36, 0x36, 0x00, 0x00, // 3a :
0x00, 0x56, 0x36, 0x00, 0x00, // 3b ;
0x08, 0x14, 0x22, 0x41, 0x00, // 3c <
0x14, 0x14, 0x14, 0x14, 0x14, // 3d =
0x00, 0x41, 0x22, 0x14, 0x08, // 3e >
0x02, 0x01, 0x51, 0x09, 0x06, // 3f ?
0x32, 0x49, 0x79, 0x41, 0x3e, // 40 @
0x7e, 0x11, 0x11, 0x11, 0x7e, // 41 A
0x7f, 0x49, 0x49, 0x49, 0x36, // 42 B
0x3e, 0x41, 0x41, 0x41, 0x22, // 43 C
0x7f, 0x41, 0x41, 0x22, 0x1c, // 44 D
0x7f, 0x49, 0x49, 0x49, 0x41, // 45 E
0x7f, 0x09, 0x09, 0x09, 0x01, // 46 F
0x3e, 0x41, 0x49, 0x49, 0x7a, // 47 G
0x7f, 0x08, 0x08, 0x08, 0x7f, // 48 H
0x00, 0x41, 0x7f, 0x41, 0x00, // 49 I
0x20, 0x40, 0x41, 0x3f, 0x01, // 4a J
0x7f, 0x08, 0x14, 0x22, 0x41, // 4b K
0x7f, 0x40, 0x40, 0x40, 0x40, // 4c L
0x7f, 0x02, 0x0c, 0x02, 0x7f, // 4d M
0x7f, 0x04, 0x08, 0x10, 0x7f, // 4e N
0x3e, 0x41, 0x41, 0x41, 0x3e, // 4f O
0x7f, 0x09, 0x09, 0x09, 0x06, // 50 P
0x3e, 0x41, 0x51, 0x21, 0x5e, // 51 Q
0x7f, 0x09, 0x19, 0x29, 0x46, // 52 R
0x46, 0x49, 0x49, 0x49, 0x31, // 53 S
0x01, 0x01, 0x7f, 0x01, 0x01, // 54 T
0x3f, 0x40, 0x40, 0x40, 0x3f, // 55 U
0x1f, 0x20, 0x40, 0x20, 0x1f, // 56 V
0x3f, 0x40, 0x38, 0x40, 0x3f, // 57 W
0x63, 0x14, 0x08, 0x14, 0x63, // 58 X
0x07, 0x08, 0x70, 0x08, 0x07, // 59 Y
0x61, 0x51, 0x49, 0x45, 0x43, // 5a Z
0x00, 0x7f, 0x41, 0x41, 0x00, // 5b [
0x02, 0x04, 0x08, 0x10, 0x20, // 5c 55
0x00, 0x41, 0x41, 0x7f, 0x00, // 5d ]
0x04, 0x02, 0x01, 0x02, 0x04, // 5e ^
0x40, 0x40, 0x40, 0x40, 0x40, // 5f _
0x00, 0x01, 0x02, 0x04, 0x00, // 60 `
0x20, 0x54, 0x54, 0x54, 0x78, // 61 a
0x7f, 0x48, 0x44, 0x44, 0x38, // 62 b
0x38, 0x44, 0x44, 0x44, 0x20, // 63 c
0x38, 0x44, 0x44, 0x48, 0x7f, // 64 d
0x38, 0x54, 0x54, 0x54, 0x18, // 65 e
0x08, 0x7e, 0x09, 0x01, 0x02, // 66 f
0x0c, 0x52, 0x52, 0x52, 0x3e, // 67 g
0x7f, 0x08, 0x04, 0x04, 0x78, // 68 h
0x00, 0x44, 0x7d, 0x40, 0x00, // 69 i
0x20, 0x40, 0x44, 0x3d, 0x00, // 6a j
0x7f, 0x10, 0x28, 0x44, 0x00, // 6b k
0x00, 0x41, 0x7f, 0x40, 0x00, // 6c l
0x7c, 0x04, 0x18, 0x04, 0x78, // 6d m
0x7c, 0x08, 0x04, 0x04, 0x78, // 6e n
0x38, 0x44, 0x44, 0x44, 0x38, // 6f o
0x7c, 0x14, 0x14, 0x14, 0x08, // 70 p
0x08, 0x14, 0x14, 0x18, 0x7c, // 71 q
0x7c, 0x08, 0x04, 0x04, 0x08, // 72 r
0x48, 0x54, 0x54, 0x54, 0x20, // 73 s
0x04, 0x3f, 0x44, 0x40, 0x20, // 74 t
0x3c, 0x40, 0x40, 0x20, 0x7c, // 75 u
0x1c, 0x20, 0x40, 0x20, 0x1c, // 76 v
0x3c, 0x40, 0x30, 0x40, 0x3c, // 77 w
0x44, 0x28, 0x10, 0x28, 0x44, // 78 x
0x0c, 0x50, 0x50, 0x50, 0x3c, // 79 y
0x44, 0x64, 0x54, 0x4c, 0x44, // 7a z
0x00, 0x08, 0x36, 0x41, 0x00, // 7b {
0x00, 0x00, 0x7f, 0x00, 0x00, // 7c |
0x00, 0x41, 0x36, 0x08, 0x00, // 7d }
0x10, 0x08, 0x08, 0x10, 0x08, // 7e ~
0x78, 0x46, 0x41, 0x46, 0x78};
void LCD5110_init(void)
{
Delay10KTCYx(20);
SCE_5110 = 0; // Enable the 5110 device (Active Low)
RESET_5110 = 0; // Reset the device. Again, active low
Delay10KTCYx(20); // Delay 20ms to make sure its ok!
RESET_5110 = 1;
OpenSPI(SPI_FOSC_16, MODE_00, SMPEND );
LCD5110_send(0x20 + 0x01, 0); // Extended instructions enabled
LCD5110_send(0x80 + 0x40, 0); // Set contrast 0 - 127
LCD5110_send(0x04 + 0x02, 0); // Temperature control
LCD5110_send(0x10 + 0x03, 0); // Set bias system
LCD5110_send(0x20 + 0x00, 0); // Return to basic instruction set, power on, set horizontal addressing
LCD5110_send(0x08 + 0x04, 0); // Display control set to normal mode
}
void LCD5110_send(unsigned char data, unsigned char dc)
{
DC_5110 = dc; // Set the appropriate status for command=0 or data=1
putcSPI (data);
}
void LCD5110_cls(unsigned char b_w)
{
unsigned int i;
unsigned char bg;
if (b_w == 0) // set the background color
{
bg = 0x00;
}
else if (b_w == 1)
{
bg = 0xFF;
}
LCD5110_send(0x40, 0); // set Y address
LCD5110_send(0x80, 0); // set X address
for (i = 0; i < 504; i++)
{
LCD5110_send(bg, 1); // Clear everything
}
}
void LCD5110_sendchar(unsigned char character)
{
unsigned char column = 0;
character = character - 0x20; // 0x20 is the first element of the array
for (column = 0; column < 5; column++) // Pass through each column
{
LCD5110_send(font[(int) character * 5 + column], 1);
}
LCD5110_send(0x00, 1); // Send a small space
}
void LCD5110_sendstring(const char *str)
{
while (*str) // pass through each character
{
LCD5110_sendchar(*str); // and send it
str++;
}
}
void LCD5110_init(void);
void LCD5110_send(unsigned char data, unsigned char dc);
void LCD5110_cls(unsigned char b_w);
void LCD5110_sendchar(unsigned char character);
void LCD5110_sendstring(const char *str);
Hola rodrigo.
Probaste poner la línea del include del pic al comienzo?
#include <pic18f2550.h>
Hubo algunas veces que agregándola se me solucionaron los problemas.
No debería ser así porque xc.h se encarga de ello pero con probar no se pierde nada.
Con estas dos directivas se me fueron todos los unable to resolve identifiers :-/
#define __18CXX // con esta solucioné los de la libreria de los delays
#define __18F4550 // y con esta los de las funciones de la usart y de los adc
Pareciera que el IDE no define correctamente el pic seleccionado en el proyecto. :5]
agregúe al principio de mi archivo main.c estos dos defines
Creo que el problema está en que si no se los define a mano el preprocesador no expande el código correspondiente a nuestro pic dentro del archivo pconfig.h:Código: [Seleccionar]#ifdef __18F4550
/*############################################################*/
/* Configuration for device = 'PIC18F4550' */
/*############################################################*/
/* ADC */
#define ADC_V5
/* ECC */
/*No configuration chosen for this peripheral*/
/* CC */
#define CC_V2
/* EPWM */
#define PWM_V5
/* PWM */
#define PWM_V5
/* PCPWM */
/*No configuration chosen for this peripheral*/
/* USART */
#define EAUSART_V5
/* SPI */
#define SPI_V1
/* I2C */
#define I2C_V1
/* TIMERS */
#define TMR_V2
/* EEPROM */
#define EEP_V2
/* PORT_B */
#define PTB_V1
/* ANCOMP */
#define ANCOM_V3
/* MWIRE */
#define MWIRE_V1
/* CTMU */
/*No configuration chosen for this peripheral*/
/* PPS */
/*No configuration chosen for this peripheral*/
/* RTCC */
/*No configuration chosen for this peripheral*/
/* DPSLP */
/*No configuration chosen for this peripheral*/
/* PMP */
/*No configuration chosen for this peripheral*/
/* FLASH */
#define FLASH_V1_2
#endif
Y por ello dentro de los headers de los periféricos se saltean los prototipos de las funciones.
Es necesario que estén definidas las versiones de cada uno de ellos por ejemplo en mi 4550 #define ADC_V5 . De lo contrario se saltean los prototipos de las funciones.
Como por ejemplo la de OpenADC en el header adc.hCódigo: [Seleccionar]#elif defined (ADC_V3) || defined (ADC_V4) || defined (ADC_V5) || defined (ADC_V6) ||\
defined (ADC_V7) || defined (ADC_V7_1)|| defined (ADC_V12) || defined (ADC_V13)\
|| defined (ADC_V13_1) || defined (ADC_V13_2) || defined (ADC_V13_3) || \
defined (ADC_V14) || defined (ADC_V14_1) || defined (ADC_V14_2) || defined (ADC_V14_3)
void OpenADC ( unsigned char ,
unsigned char ,
unsigned char );
#define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
//Funciones para delay's. No son muy precisas por lo que vi en el osciloscopio
//REVISAR
#pragma intrinsic(_delay)
extern void _delay(unsigned long);
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#include <stdio.h>
#include <stdlib.h>
#include <xc.h> // Librería XC8. Este include termina incluyendo al 16F883.h
//#include <delays.h> // Para utilizar demoras en nuestro código debemos incluir la librería delays.h.
//Includes locales, configuracion de fusibles y del IO
#include "configuracion_de_fuses.c"
#include "configuracion_hard.c"
unsigned char cont = 0; //Contador para destello de LED
/*------------------------DECLARACION DE FUNCIONES---------------------------*/
void conf_oscilador (void); // Configuracion del oscilador
void conf_puertos (void); // Configuracion de puertos I/O
void conf_timer0 (void); // Configuracion registros TIMER0
void conf_timer1 (void); // Configuracion registros TIMER1
void conf_pwm (void);
/********** Funcion para la ISR (Rutina de Servicio de Interrupcion) **********/
void interrupt interrupciones (void) {
//Verifico que interrupcion se disparó
if (TMR0IE && TMR0IF){ // se verifica si la interrupcion es por TMR0
//Destello de LED cada 20 * 65,535 mS -> 1,3Seg
if(++cont == 20){
cont=0;
LED_tst ^= 1;
}
TMR0IF = 0; // Pongo en 0 el Flag de interrupcion del TMR0
}
/* el resto de las interrupciones utilizadas se deben analizar a coninuacion*/
}
/*************************** Programa Principal ******************************/
void main(void) {
conf_oscilador ();
conf_puertos ();
conf_timer0 ();
conf_pwm();
//conf_timer1 ();
INTCONbits.TMR0IE = 1; //Habilito interrupcion por TMR0
INTCONbits.PEIE = 1; //Habilito las interrupciones de los perifericos
INTCONbits.GIE = 1; //Habilito Interrupcion Global
PORTC=0b00000000;
int i=0;
/*-------------------------- Bucle infinito ------------------------------*/
do{
CCP1CONbits.P1M=0b01; //Motor en Forward
CCPR1L=0; // DC en 0
for(i=0; i<255; i+=5){ // Voy incrementando el DC de a 5
CCPR1L = CCPR1L++;
__delay_ms (50);
}
CCPR1L=0; // DC en 0
CCP1CONbits.P1M=0b11; // Motor en Backward
for(i=0; i<255; i+=5){ // Voy incrementando el DC de a 5
CCPR1L = CCPR1L++;
__delay_ms (50);
}
}while(1);
}
/*------------------------------FUNCIONES------------------------------------*/
/* Funcion para la configuracion del oscilador del pic16f88 */
void conf_oscilador (void) {
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 0; // IRCF <2:0> = 110 setea Fosc 4MHz
OSCCONbits.SCS = 0; /* SCS = 0 Modo del oscilador definido por
* FOSC <2:0> en #pragma config FOSC = INTOSCIO */
}
/* Funcion para la configuracion de los puertos entrada salida del pic 16f88 */
void conf_puertos (void) {
ANSEL=0x00; //Todos entrada/salida digitales - Puerto A.
ANSELH=0x00; //Todos entrada/salida digitales - Puerto B.
TRISA=0b00101010; //RA0, 2 y 4 Salidas. RA1, 3 y 5 Entradas-
TRISB=0x00; //Todos como SALIDAS.
TRISC=0x0F; //RC0-3 Entrada. RC4-7 Salida
PORTC=0;
PORTB=0;
}
/* Funcion para la configuracion del modulo Timer0 como temporizador */
void conf_timer0 (void) {
// Configuración del timer 0. Con Osc de 4MHz la frecuencia de entrada del TMR
// es 1MHz, con el prescaler en 256 tenemos una cuenta cada 256uSeg. Al ser
// de 8 bits tenemos interrupcion cada 65,535 mSeg.
TMR0 = 0;
OPTION_REGbits.PS0 = 1;
OPTION_REGbits.PS1 = 1;
OPTION_REGbits.PS2 = 1; //Prescaler en 256
OPTION_REGbits.PSA = 0; //Prescaler al TMR0 y no al WDT
OPTION_REGbits.T0CS = 0; //Clock Source es el Ciclo de Instruccion
}
/* Funcion para la configuracion del modulo Timer1 como temporizador */
void conf_timer1 (void) {
// Configuración del timer 1. Con Osc de 4MHz la frecuencia de entrada del TMR
// es 1MHz, con el prescaler en 1 tenemos una cuenta cada 1uSeg. Al ser
// de 16 bits tenemos interrupcion cada 65,535 mSeg.
// El timer 1 se usa como base de tiempos de CCP2
TMR1 = 0;
T1CONbits.T1CKPS = 0x00; //Prescaler en 2 -> XX00
T1CONbits.TMR1ON = 0; //Enable Timer1
}
/* Funcion para la configuracion del modulo Timer1 como temporizador */
void conf_timer2 (void) {
// Configuración del timer 1. Con Osc de 4MHz la frecuencia de entrada del TMR
// es 1MHz, con el prescaler en 1 tenemos una cuenta cada 1uSeg. Al ser
// de 16 bits tenemos interrupcion cada 65,535 mSeg.
// El timer 1 se usa como base de tiempos de CCP2
TMR1 = 0;
T1CONbits.T1CKPS = 0x00; //Prescaler en 2 -> XX00
T1CONbits.TMR1ON = 0; //Enable Timer1
}
void conf_pwm(void){
// CONFIGURANDO PWM - Pagina 133 datasheet
TRISCbits.TRISC2=1; //Configuro como entrada los pines del PWM
TRISB |= 0b00010110;
PR2 = 0x65; // Frecuencia
CCP1CONbits.CCP1M = 0b1100; // Activamos el modo PWM.
CCP1CONbits.P1M = 0b01; // Full Bridge Forward
CCP1CONbits.DC1B = 0b00; // LSB del DC=0
CCPR1=0x00; // MSB del DC=0
PIR1bits.TMR2IF=0; // Borro posible bandera de Int del TMR2
T2CONbits.T2CKPS = 0b01; // Prescaler del timer 2 en 1:4
T2CONbits.TMR2ON = 1; // Arranca el PWM
while(PIR1bits.TMR2IF==0); // Espero a primera interrupcion del TMR2
TRISCbits.TRISC2=0; // Configuro como Salida los pines del PWM
TRISB &= ~(0b00010110); // para que comience a funcionar
}
// PIC16F883 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
/*
* File: 5110lcd.h
* Author: Ramiro
*
* Created on 22 de septiembre de 2013, 20:03
*/
void gotoxy(int x , int y );
void LCD5110_init(void);
void LCD5110_send(unsigned char data, unsigned char dc);
void LCD5110_cls(unsigned char b_w);
void LCD5110_sendchar(unsigned char character);
void LCD5110_sendstring(const char *str);
/*
* File: 5110lcd.c
* Author: Ramiro Seliman 2013
*
* Created on 22 de septiembre de 2013, 20:32
*/
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include <spi.h>
#include "5110lcd.h"
// define the pins
#define SCE_5110 LATBbits.LATB3
#define RESET_5110 LATBbits.LATB2
#define DC_5110 LATBbits.LATB4
const char font[] = {0x00, 0x00, 0x00, 0x00, 0x00, // 20 space
0x00, 0x00, 0x5f, 0x00, 0x00, // 21 !
0x00, 0x07, 0x00, 0x07, 0x00, // 22 "
0x14, 0x7f, 0x14, 0x7f, 0x14, // 23 #
0x24, 0x2a, 0x7f, 0x2a, 0x12, // 24 $
0x23, 0x13, 0x08, 0x64, 0x62, // 25 %
0x36, 0x49, 0x55, 0x22, 0x50, // 26 &
0x00, 0x05, 0x03, 0x00, 0x00, // 27 '
0x00, 0x1c, 0x22, 0x41, 0x00, // 28 (
0x00, 0x41, 0x22, 0x1c, 0x00, // 29 )
0x14, 0x08, 0x3e, 0x08, 0x14, // 2a *
0x08, 0x08, 0x3e, 0x08, 0x08, // 2b +
0x00, 0x50, 0x30, 0x00, 0x00, // 2c ,
0x08, 0x08, 0x08, 0x08, 0x08, // 2d -
0x00, 0x60, 0x60, 0x00, 0x00, // 2e .
0x20, 0x10, 0x08, 0x04, 0x02, // 2f /
0x3e, 0x51, 0x49, 0x45, 0x3e, // 30 0
0x00, 0x42, 0x7f, 0x40, 0x00, // 31 1
0x42, 0x61, 0x51, 0x49, 0x46, // 32 2
0x21, 0x41, 0x45, 0x4b, 0x31, // 33 3
0x18, 0x14, 0x12, 0x7f, 0x10, // 34 4
0x27, 0x45, 0x45, 0x45, 0x39, // 35 5
0x3c, 0x4a, 0x49, 0x49, 0x30, // 36 6
0x01, 0x71, 0x09, 0x05, 0x03, // 37 7
0x36, 0x49, 0x49, 0x49, 0x36, // 38 8
0x06, 0x49, 0x49, 0x29, 0x1e, // 39 9
0x00, 0x36, 0x36, 0x00, 0x00, // 3a :
0x00, 0x56, 0x36, 0x00, 0x00, // 3b ;
0x08, 0x14, 0x22, 0x41, 0x00, // 3c <
0x14, 0x14, 0x14, 0x14, 0x14, // 3d =
0x00, 0x41, 0x22, 0x14, 0x08, // 3e >
0x02, 0x01, 0x51, 0x09, 0x06, // 3f ?
0x32, 0x49, 0x79, 0x41, 0x3e, // 40 @
0x7e, 0x11, 0x11, 0x11, 0x7e, // 41 A
0x7f, 0x49, 0x49, 0x49, 0x36, // 42 B
0x3e, 0x41, 0x41, 0x41, 0x22, // 43 C
0x7f, 0x41, 0x41, 0x22, 0x1c, // 44 D
0x7f, 0x49, 0x49, 0x49, 0x41, // 45 E
0x7f, 0x09, 0x09, 0x09, 0x01, // 46 F
0x3e, 0x41, 0x49, 0x49, 0x7a, // 47 G
0x7f, 0x08, 0x08, 0x08, 0x7f, // 48 H
0x00, 0x41, 0x7f, 0x41, 0x00, // 49 I
0x20, 0x40, 0x41, 0x3f, 0x01, // 4a J
0x7f, 0x08, 0x14, 0x22, 0x41, // 4b K
0x7f, 0x40, 0x40, 0x40, 0x40, // 4c L
0x7f, 0x02, 0x0c, 0x02, 0x7f, // 4d M
0x7f, 0x04, 0x08, 0x10, 0x7f, // 4e N
0x3e, 0x41, 0x41, 0x41, 0x3e, // 4f O
0x7f, 0x09, 0x09, 0x09, 0x06, // 50 P
0x3e, 0x41, 0x51, 0x21, 0x5e, // 51 Q
0x7f, 0x09, 0x19, 0x29, 0x46, // 52 R
0x46, 0x49, 0x49, 0x49, 0x31, // 53 S
0x01, 0x01, 0x7f, 0x01, 0x01, // 54 T
0x3f, 0x40, 0x40, 0x40, 0x3f, // 55 U
0x1f, 0x20, 0x40, 0x20, 0x1f, // 56 V
0x3f, 0x40, 0x38, 0x40, 0x3f, // 57 W
0x63, 0x14, 0x08, 0x14, 0x63, // 58 X
0x07, 0x08, 0x70, 0x08, 0x07, // 59 Y
0x61, 0x51, 0x49, 0x45, 0x43, // 5a Z
0x00, 0x7f, 0x41, 0x41, 0x00, // 5b [
0x02, 0x04, 0x08, 0x10, 0x20, // 5c 55
0x00, 0x41, 0x41, 0x7f, 0x00, // 5d ]
0x04, 0x02, 0x01, 0x02, 0x04, // 5e ^
0x40, 0x40, 0x40, 0x40, 0x40, // 5f _
0x00, 0x01, 0x02, 0x04, 0x00, // 60 `
0x20, 0x54, 0x54, 0x54, 0x78, // 61 a
0x7f, 0x48, 0x44, 0x44, 0x38, // 62 b
0x38, 0x44, 0x44, 0x44, 0x20, // 63 c
0x38, 0x44, 0x44, 0x48, 0x7f, // 64 d
0x38, 0x54, 0x54, 0x54, 0x18, // 65 e
0x08, 0x7e, 0x09, 0x01, 0x02, // 66 f
0x0c, 0x52, 0x52, 0x52, 0x3e, // 67 g
0x7f, 0x08, 0x04, 0x04, 0x78, // 68 h
0x00, 0x44, 0x7d, 0x40, 0x00, // 69 i
0x20, 0x40, 0x44, 0x3d, 0x00, // 6a j
0x7f, 0x10, 0x28, 0x44, 0x00, // 6b k
0x00, 0x41, 0x7f, 0x40, 0x00, // 6c l
0x7c, 0x04, 0x18, 0x04, 0x78, // 6d m
0x7c, 0x08, 0x04, 0x04, 0x78, // 6e n
0x38, 0x44, 0x44, 0x44, 0x38, // 6f o
0x7c, 0x14, 0x14, 0x14, 0x08, // 70 p
0x08, 0x14, 0x14, 0x18, 0x7c, // 71 q
0x7c, 0x08, 0x04, 0x04, 0x08, // 72 r
0x48, 0x54, 0x54, 0x54, 0x20, // 73 s
0x04, 0x3f, 0x44, 0x40, 0x20, // 74 t
0x3c, 0x40, 0x40, 0x20, 0x7c, // 75 u
0x1c, 0x20, 0x40, 0x20, 0x1c, // 76 v
0x3c, 0x40, 0x30, 0x40, 0x3c, // 77 w
0x44, 0x28, 0x10, 0x28, 0x44, // 78 x
0x0c, 0x50, 0x50, 0x50, 0x3c, // 79 y
0x44, 0x64, 0x54, 0x4c, 0x44, // 7a z
0x00, 0x08, 0x36, 0x41, 0x00, // 7b {
0x00, 0x00, 0x7f, 0x00, 0x00, // 7c |
0x00, 0x41, 0x36, 0x08, 0x00, // 7d }
0x10, 0x08, 0x08, 0x10, 0x08, // 7e ~
0x78, 0x46, 0x41, 0x46, 0x78};
void LCD5110_init(void)
{
OpenSPI(SPI_FOSC_64, MODE_00, SMPEND );
Delay10KTCYx(20);
SCE_5110 = 0; // Enable the 5110 device (Active Low)
RESET_5110 = 0; // Reset the device. Again, active low
Delay10KTCYx(20); // Delay 20ms to make sure its ok!
RESET_5110 = 1;
LCD5110_send(0x21, 0); // Extended instructions enabled
LCD5110_send(0xC0, 0); // Set VOLTAJE 5V
LCD5110_send(0x07, 0); // Temperature control
LCD5110_send(0x13, 0); // Set bias system
LCD5110_send(0x20, 0); // Display control set to BASIC mode
LCD5110_send(0x0C, 0); // Display modo NORMAL
}
void gotoxy(int x , int y )
{
LCD5110_send((0x80 | x) , 0); //X address
LCD5110_send((0x40 | y) , 0); //Y address
}
void LCD5110_send(unsigned char data, unsigned char dc)
{
DC_5110 = dc; // Set the appropriate status for command=0 or data=1
putcSPI (data);
}
void LCD5110_cls(unsigned char b_w)
{
unsigned int i;
unsigned char bg;
if (b_w == 0) // set the background color
{
bg = 0x00;
}
else if (b_w == 1)
{
bg = 0xFF;
}
LCD5110_send(0x40, 0); // set Y address
LCD5110_send(0x80, 0); // set X address
for (i = 0; i < 504; i++)
{
LCD5110_send(bg, 1); // Clear everything
}
}
void LCD5110_sendchar(unsigned char character)
{
unsigned char column = 0;
character = character - 0x20; // 0x20 is the first element of the array
for (column = 0; column < 5; column++) // Pass through each column
{
LCD5110_send(font[(int) character * 5 + column], 1);
}
LCD5110_send(0x00, 1); // Send a small space
}
void LCD5110_sendstring(const char *str)
{
// LCD5110_send((0x40 | y) , 0); //Y address
// LCD5110_send((0x80 | x) , 0); //X address
while (*str) // pass through each character
{
LCD5110_sendchar(*str); // and send it
str++;
}
}
/*
* File: main.c
* Author: Ramiro Seliman 2013
*
* Created on 5 de septiembre de 2013, 14:24
*/
#include <xc.h>
#include <delays.h>
#include <stdio.h>
#include <stdlib.h>
#include "system.h"
#include <PIC18F2550.h>
#include <spi.h>
#include "5110lcd.h"
#define _XTAL_FREQ 8000000
void main(void) {
ConfigureOscillator();
_delay(500);
// BMP085_Calibration();
LATB = 0x00 ;
PORTB = 0x00 ;
TRISB = 0x00;
TRISA = 0x00 ;
LATC = 0x00 ;
PORTC = 0x00 ;
TRISC = 0x00 ;
LCD5110_init();
LCD5110_cls(0);
gotoxy(1,0); // coordenada x , coordenada y
LCD5110_sendstring("Hola Mundo!"); //envio string
while (1)
{
};
return;
}
// PIC18F2550 Configuration Bit Settings
// CONFIG1L
#pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
// CONFIG1H
#pragma config FOSC = INTOSC_HS // Oscillator Selection bits (Internal oscillator, HS oscillator used by USB (INTHS))
#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 disabled)
#pragma config BOR = OFF // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting)
#pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = OFF // 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 analog input channels on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = OFF // 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 bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
/*
* File: system.h
* Author: Ramiro
*
* Created on 23 de septiembre de 2013, 15:03
*/
#ifndef SYSTEM_H
#define SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_H */
#define _XTAL_FREQ 8000000
void ConfigureOscillator(void);/*
* File: system.c
* Author: Ramiro
*
* Created on 23 de septiembre de 2013, 15:08
*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "system.h"
void ConfigureOscillator(void)
{
ADCON1 = 0x0f ; //todos los bits como digitales
CMCONbits.CM0 = 1;
CMCONbits.CM1 = 1; // deshabilito los comparadores
CMCONbits.CM2 = 1;
OSCCONbits.IRCF2 = 1; //
OSCCONbits.IRCF1 = 1; // defino oscilador interno en 8 mhz
OSCCONbits.IRCF0 = 1; //
}
void LCD5110_sendstring(int x, int y, const char *str)
{
if (y == 1 ) y == 0 ;
{
x = (6*x)+y ;
}
LCD5110_send((0x80 | x) , 0); //X address
LCD5110_send((0x40 | y) , 0); //Y address
while (*str) // pass through each character
{
LCD5110_sendchar(*str); // and send it
str++;
} LCD5110_sendstring(4, 0, "Ramiro");
LCD5110_sendstring(3,0, "Seliman");
Gracias por el dato AngelGris, se me paso por alto dicho bit pero sigue sin entrar en la interrupcion, me volvere a leer el datasheet y os cuento.
De todas formas voy a hacer un programa que sea una simple interrupcion, parpadeo de un led, nada mas para probar.
Saludos y Gracias de nuevo.
quizás debieras abrir un hilo nuevo por ese tema particular...
no obstante ello, muy interesantes los modulos!!!! tienes el precio de ellos?
en cuanto a la aplicacion me suena a uav, puede ser?
en cuanto a la solución no estoy seguro de como implementarlo....
saludos!
quizás debieras abrir un hilo nuevo por ese tema particular...
no obstante ello, muy interesantes los modulos!!!! tienes el precio de ellos?
en cuanto a la aplicacion me suena a uav, puede ser?
en cuanto a la solución no estoy seguro de como implementarlo....
saludos!
Hola como estas ?? gracias por responder ....si tenes razon deberia abrir un hilo nuevo ...en cuanto a la aplicacion ...les va a parecer raro lo que hago ya que no muchos se dedican a esto pero bueno ...se los comento igual ...hago coheteria civil (diseño y construyo cohetes ) ...y el sistema que estoy desarrollando es un sistema de telemetria para un vector de mediano porte ....
Gracias
Saludos
interesante, interesante!!!!! de pibe siempre veia en la lupin los temas de coheteria y he visto en unos foros las cosas tremendas que hacen!!!! se puede ver en algun sitio lo que estas haciendo?
saludos!
quizás debieras abrir un hilo nuevo por ese tema particular...
no obstante ello, muy interesantes los modulos!!!! tienes el precio de ellos?
en cuanto a la aplicacion me suena a uav, puede ser?
en cuanto a la solución no estoy seguro de como implementarlo....
saludos!
Hola Ramiro, intenté entrar al canal de youtube y salió un mensaje diciendo que el canal no existe. Algo está pasando con dicho sitio porque a mí se me borraron algunos videos.
¿Podrías comentarme eso de NMEA? Ya que no tengo idea :oops:
Ramiro, pero que buenos trabajos!!!!! me estare poniendo en contacto por privado para ver si podemos armar algún vinculo, yo tmb soy profesor en una est aca en ramallo...
saludos!!!
Hola! Lo que necesitas ahora es comunicar el GPS y el bmp085 con el 18F2550, y utilizando el APC220 enviar los datos a una PC?
Saludos!
y si metes los datos del gps al 2550 y alli armas la trama completa?
si no tiene 2 uart, la que recive los datos del gps la puedes hacer por software....
otra podría ser poner unas llaves electrónicas (no se si el 4066 sirve para eso) y que el micro elija si pasan los datos del gps o los mismos del micro. hay unos integrados digitales que no recuerdo como se llaman, transeiver, codificadores, no recuerdo, pero posee 2 entradas por cada línea de salida y con un pin de control se elije que dato pasa a la salida...
Me interesa el código del bmp, estoy por utilizar uno igual, está disponible?
Salludos!
/*
* File: bmp085.c
* Author: Ramiro
*
* Created on 21 de septiembre de 2013, 13:09
*/
#define _XTAL_FREQ 8000000
#include "xc.h"
#include <math.h>
#include "bmp085.h"
// * Defines ************************************************************
#define BMP085_R 0xEF
#define BMP085_W 0xEE
#define OSS 3 // Oversampling Setting
// * Globals Variables **************************************************
const unsigned char OSS_conversion_time[] = {5, 8, 14, 26};
signed char BMP_err;
long ac1;
long ac2;
long ac3;
long b1;
long b2;
long mb;
long mc;
long md;
unsigned long ac4;
unsigned long ac5;
unsigned long ac6;
/************************************************************************
*
*
************************************************************************/
void delay_ms(unsigned short ms)
{
for(; ms > 0; ms--)
{
Delay100TCYx(20);
}
}
/************************************************************************
*
*
************************************************************************/
void BMP085_Calibration(void)
{
ac1 = (signed short) bmp085ReadShort(0xAA);
ac2 = (signed short) bmp085ReadShort(0xAC);
ac3 = (signed short) bmp085ReadShort(0xAE);
ac4 = bmp085ReadShort(0xB0);
ac5 = bmp085ReadShort(0xB2);
ac6 = bmp085ReadShort(0xB4);
b1 = (signed short) bmp085ReadShort(0xB6);
b2 = (signed short) bmp085ReadShort(0xB8);
mb = (signed short) bmp085ReadShort(0xBA);
mc = (signed short) bmp085ReadShort(0xBC);
md = (signed short) bmp085ReadShort(0xBE);
}
/************************************************************************
*
*
************************************************************************/
void BMP085_Known_Calibration(void)
{
ac1 = 408;
ac2 = -72;
ac3 = -14383;
ac4 = 32741;
ac5 = 32757;
ac6 = 23153;
b1 = 6190;
b2 = 4;
mb = -32768;
mc = -8711;
md = 2868;
}
/************************************************************************
*
************************************************************************/
void BMP_process_error()
{
#ifdef ERROR_HANDLING
if(BMP_err != 0)
{
flag |= BMP_ERROR;
printf((const far rom char*) "BMP_err: %d\r\n", BMP_err);
BMP_err = 0;
}
#endif
}
/************************************************************************
*
*
************************************************************************/
unsigned short bmp085ReadShort(unsigned char address)
{
unsigned short msb, lsb;
unsigned short data;
StartI2C();
BMP_err |= WriteI2C(BMP085_W); // Write 0xEE
BMP_err |= WriteI2C(address); // Write register address
RestartI2C();
BMP_err |= WriteI2C(BMP085_R); // Write 0xEF
msb = ReadI2C(); // Get MSB result
BMP_err |= AckI2C();
lsb = ReadI2C(); // Get LSB result
NotAckI2C();
StopI2C();
delay_ms(10);
data = msb << 8;
data |= lsb;
BMP_process_error();
return data;
}
/************************************************************************
*
*
************************************************************************/
unsigned long bmp085ReadThreeBytes(unsigned char address)
{
unsigned short msb, lsb, xlsb;
unsigned long data;
StartI2C();
BMP_err |= WriteI2C(BMP085_W); // Write 0xEE
BMP_err |= WriteI2C(address); // Write register address
RestartI2C();
BMP_err |= WriteI2C(BMP085_R); // Write 0xEF
msb = ReadI2C(); // Get MSB result
AckI2C();
lsb = ReadI2C(); // Get LSB result
NotAckI2C();
StopI2C();
delay_ms(10);
data = msb;
data <<= 8;
data |= lsb;
data <<= 8;
data |= xlsb;
BMP_process_error();
return data;
}
/************************************************************************
*
*
************************************************************************/
long bmp085ReadTemp(void)
{
StartI2C();
WriteI2C(BMP085_W); // Write 0xEE
WriteI2C(0xF4); // Write register address
WriteI2C(0x2E); // Write register data for temp
StopI2C();
delay_ms(10); // Max time is 4.5ms
return (signed short) bmp085ReadShort(0xF6);
}
/************************************************************************
*
*
************************************************************************/
long bmp085ReadPressure(void)
{
StartI2C();
WriteI2C(BMP085_W); // Write 0xEE
WriteI2C(0xF4); // Write register address
WriteI2C(0x34 | (OSS << 6)); // Write register data for temp
StopI2C();
delay_ms(OSS_conversion_time[OSS]); // Max time is 4.5ms
if(OSS) {
return bmp085ReadThreeBytes(0xF6);
} else {
return ((long) bmp085ReadShort(0xF6)) << 8;
}
}
/************************************************************************
*
*
************************************************************************/
#define SHIFT(shift) (((long) 1) << (shift))
void bmp085Convert(long *temperature, long *pressure, unsigned char readings)
{
long ut;
long up;
long x1, x2, b5, b6, x3, b3, p;
unsigned long b4, b7;
unsigned char i;
ut = 0;
up = 0;
for(i = 0; i < readings; i++)
{
ut += bmp085ReadTemp();
up += bmp085ReadPressure();
}
ut = ut / readings;
up = up / readings;
up = up >> (8-OSS);
x1 = (ut - ac6) * ac5 / SHIFT(15);
x2 = (mc * SHIFT(11)) / (x1 + md);
b5 = x1 + x2;
*temperature = (b5 + 8) / SHIFT(4);
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 / SHIFT(12))) / SHIFT(11);
x2 = ac2 * b6 / SHIFT(11);
x3 = x1 + x2;
b3 = ((((ac1 * 4) + x3) << OSS) + 2) / SHIFT(2);
x1 = ac3 * b6 / SHIFT(13);
x2 = (b1 * (b6 * b6 / SHIFT(12))) / SHIFT(16);
x3 = ((x1 + x2) + 2) / SHIFT(2);
b4 = (ac4 * (unsigned long) (x3 + 32768)) / SHIFT(15);
b7 = ((unsigned long) up - b3) * (50000 >> OSS);
p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
x1 = p / SHIFT(8);
x1 *= x1;
x1 = (x1 * 3038) / SHIFT(16);
x2 = (-7357 * p) / SHIFT(16);
x2 = x2 / SHIFT(16);
*pressure = p + (x1 + x2 + 3791) / SHIFT(4);
}Ramiro, las funciones writei2c y las demas referentes al i2c donde estan las definiciones? son de alguna plib de microchip?
me llego la imu para empezar a jugar y probablemente comience con este sensor hasta que le agarre la mano al i2c, que nunca he usado...
saludos!
Ramiro, las funciones writei2c y las demas referentes al i2c donde estan las definiciones? son de alguna plib de microchip?
me llego la imu para empezar a jugar y probablemente comience con este sensor hasta que le agarre la mano al i2c, que nunca he usado...
saludos!
Ramiro, tendras el bmp085.h a mano?
Saludos!
Ramiro, tendras el bmp085.h a mano?
Saludos!
Te lo paso cuando llegue a casa disculpame !!!
Abrazo
/*
* File: bmp085.h
* Author: Ramiro
*
* Created on 21 de septiembre de 2013, 13:12
*/
#ifndef BMP085_H
#define BMP085_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* BMP085_H */
void delay_ms(unsigned short ms);
void BMP085_Calibration(void);
long bmp085ReadTemp(void);
long bmp085ReadPressure(void);
unsigned short bmp085ReadShort(unsigned char address);
void bmp085Convert(long *temperature, long *pressure, unsigned char readings);
void BMP_process_error();
Gracias compañero por el aporte..
Veo que estas mas familiarizado que yo en esto.
Preguntas:
1. declare bien los puertos?
2. como hago para "invocar" el valor almacenado en la variable contador?
Hola a todos, soy nuevo en el foro, ni siquiera sabía que ahora hay que decir que tiempo es el que se va estar dentro del Foro jejeje... He leído las respuestas y preguntas que muchos de ustedes han realizado a través de este tema, y Woao, no se, mi duda en algunos puntos se han aclarado, por ejemplo en los "Fuses" que no sabía que había que declararlos, yo vengo de Proton IDE y tengo ya más de 3 años que no agarro un PIC para programar, y simplemente por el uso de Software libre quise intentarlo usando las herramientas necesarias que existen para Ubuntu, cosa que MPLAB me suena bastante interesante y amigable, como bien dicen, se parece mucho a NetBeans para Java. En fin, lo único que busco es hacer un pequeño contador que muestre en 3 displays 7 segmentos, pero como quiero un PIC pequeño, procuro utilizar un Decodificador para ahorrarme unas patas del microcontrolador. Entonces mi gran duda es, por que cuando trato de activar un pin del microcontrolador a través de una variable, asignándole su respectiva posición, el compilador me da error?. Intento realizar algo como así:
char numeros[10] = {0,1,2,3,4,5,6,7,8,9};
char numero, i ;
numero = numeros ;
PORTBbits.RB0 = numero.0 ;
PORTBbits.RB1 = numero.1 ;
PORTBbits.RB2 = numero.2 ;
PORTBbits.RB3 = numero.3 ;
Esto debido a que numero debe ir cambiando ya que solo utilizo un solo decodificador y 3 displays, debido que la cifra más grande a mostrar posee 3 unidades, desde 0 a 250. No tengo todo el programa terminado, pero simplemente quería saber si el compilador no me daba error cuando trataba de modificar un bit del puerto del microcontrolador, pero no puedo hacerlo desde una variable, si me pudieran orientar mejor?, porque no recuerdo sinceramente si desde PROTON en Basic se podía realizar dicha modificaciones. O es que a juro necesito decirle que el valor es 0 o 1 para poder modificar el valor del pin del microcontrolador?... Gracias...
Me estoy iniciando con el CX8 y quería ver las ejecuciones paso a paso de algunos programitas sencillos que copie de este gran curso y no encuentro los archivos .cof, nose si el cx8 los genera o no?? o como se hace para generarlos. :huh:
Si trabajo con el mplabx, y he buscado deseperadamente los benditos archivos cof y no los encuentro en ninguna carpeta del proyecto no se si deba ajustarle algo al mplabx para wue se generen al compilar el proyecto
Si en esta carpeta proyecto/dist/default/production siempre lo encuentro pero cuando compilo con CCS ahora que compilo CX8 solo me aparecen 10 archivos con las siguientes extensiones: .cmf .elf .hex .hxl .lst .map .obj .rlf .sdb .sym . Ningún .cof creo que hay que ajustar algo voy a buscar documentación del CX8.
/*
* File: Secuenciador de 8 leds
* Author: Abel
* Simula el funcionamiento de las luces del auto fantastico
* Created on 25 de marzo de 2014, 12:27 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <xc.h> // Librería XC8
#define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// FUNCION PRINCIPAL
void main()
{
TRISB = 0; // Configuro puerto B como salidas
PORTB = 0; // borramos el puerto B
while (1) // Bucle infinito
{ //El primer bucle for deplaza la luz del bit 0 al bit 7 de portb
for (PORTB=1; PORTB<128; PORTB=PORTB*2)
{ // se visualiza por 200 milisegundos.
__delay_ms(200);
} //El segundo bucle for desplaza la luz del bit 7 al bit 0 de portb
for (PORTB=128; PORTB>1; PORTB=PORTB/2)
{ // se visualiza por 200 milisegundos.
__delay_ms(200);
}
}
}
Estoy haciendo un programa en XC8 y me estoy volviendo loco para conseguir un vector de reset.
Lo que quiero es hacer el programa compatible con un bootloader. Para eso en las 4 primeras direcciones de memoria debe haber un goto a la rutina que inicia el programa.
No consigo que haya un goto en la dirección de memoria 0
¿Cómo demonios se hace eso en XC8?
PD: Lo he intentado con la opción --CODEPAGE y ni caso
Saludos.
hay algun include en xc8 que me permita usar las definiciones uint8_t, int16_t, etc?
saludos
Hola soy nuevo en MPLAB X y XC8 y trato de hacer un programa como practica para aprender a utilizar un PIC16F84A. El programa es para un velocímetro digital que muestre la velocidad en 3 Diplays de 7 segmentos y la señal del sensor quiero ingresarla por el pin del RA4 como contador.
Creo que el funcionamiento se debe parecer al de un frecuencímetro ya que he la cantidad de pulsos que ingresan serán numéricamente igual a la velocidad. Para esto, el periodo de tiempo debe ser de 555 ms .
¿Es correcto suponer que mientras espero que ocurra la interrupción para este período, se pueden contar los pulsos que ingresan por RA4 y procesarlos para separarlos en unidades, decenas y centenas y por medio de multiplexión los muestro en los displays?
Utilizaré 4 pines y un decodificador para los displays y tres pines para controlarlos, todos estos del puerto B.
Me gustaría saber si esta idea es correcta, si voy por el camino correcto.
Gracias por su ayuda!!!!
Hola a todos, me estoy iniciando en el MPLABX y XC8, tengo algo de experiencia en MPLAB y C18, tengo algunas dudas.
¿XC8 trae librerías de manejo de periféricos como el compilador C18 pero para los pic inferiores a PIC18, ósea los PIC10/12/16?.
¿Los proyectos hechos con C18 y librerías valdrían a pelo sin modificar nada para XC8?
gracias
Pues vaya, me costará un poco adaptarme, creo que seguiré con C18 ya que si quisiera utilizar un conjunto de librerías como las de TCPIP sería un verdadero infierno adaptarlas.
saludos
Hola. Revisando diferentes aportaciones me surgieron varias preguntas las cuales son:
¿el RA4 y el TMR0 en el 16F84A, son mutuamente excluyentes, es decir, si uso RA4 como entrada de una señal cuadrada para contar sus pulsos, ya no podré usar TMR0 para generar interrupciones al mismo tiempo?
¿Puedo usar alguna otra entrada del puerto A como entrada de una señal cuadrada para contar los pulsos mientras espero una interrupción del TMR0?
ojalá alguien pueda sacarme de estas dudas. Gracias de antemano.
Pues vaya, me costará un poco adaptarme, creo que seguiré con C18 ya que si quisiera utilizar un conjunto de librerías como las de TCPIP sería un verdadero infierno adaptarlas.
saludos
Tal vez deberías ver algún readme de la última edición de las librerías. Yo probé la de USB y ya contempla al compilador XC8, muy posiblemente para TCP/IP también pueda compilar con XC8.
Gracias AngelGris. con ese dato se que puedo usar el F84A que ya tengo. Usando el RB0 para generar interrupción y TMR0 para contar el tiempo entre pulsos. ´¿Estaría midiendo el tiempo entre pulsos? yo quiero realizar el otro método, el contar los pulsos en un periodo fijo de tiempo. Probablemente contando las interrupciones en RB0. El tiempo que necesito es de 0.555077 us y debido a que el TMR0 solo cuenta hasta 256 usaré un valor de TMR0 de 39 para tener un perodo de 0.0555... y hacerlo dar 10 vueltas con un while y asi completarlo, entondes despues leer la cuenta de interrupciones de RB0 y mandarlas a displays despues de separarlas en unidades,, decenas y centenas.
Hoy me he pasado de FREESCALE a MICROCHIP
Hoy me he pasado de FRRESCALE a MICROCHIP :-/, estoy usando MPLAB X ide 2.10, instalo los compiladores pero no aparecen cuando creo un nuevo proyecto, mientras instalaba los compiladores por ejemplo xc8-v1.32-windows-installer.exe sobre win8.1-OS genero un error que decía algo de MPLABXC8.dll pienso que aquí radica el problema aunque la intsalcion si ternina, deseo su colaboración para iniciarme en el mundo de MICROCHIP pues estoy "quieto" hasta solucionar esto :(
Gracias
Mensaje que genera mientras se instala el compilador
/!\ Problem running post-install step. Installation may not complete correctly
Error running C:\Windows\systems32\regsvr32/s "C:\Program Files\Microchip\v1.32\bin\MPLABXC9.dll": Program ended with an error exit code
Supongo que estas usando el simulador del MPLABX, buscas en las propiedades del proyecto, ahí te aparece las opciones para el simulador, buscas
Instruction execution frequency (Fcyc) y colocas el valor de cristal dividido entre cuatro, es decir los MIPS (la frecuencia real a la que se ejecutan las instrucciones)
Saludos.
Es normal. El timer sigue contando pulsos, mientras que el CCP mantiene el valor capturado del timer sin cambios.Hola Picuino podria ser lo que comentas, ya que el valor de la parte baja del TMR1 siempre es superior al CCPR1L. Los valores de los registros los veo a traves de la simulacion.
¿Cómo ves los valores de los registros? ¿Qué frecuencia tiene la señal del timer?
Saludos.
Para medir la duración de pulso de ese sensor, lo mejor es poner como señal de reloj al propio reloj del sistema con un preescaler para reducir su frecuencia a unos 200kHz.:shock: :shock: :shock: :shock: :shock: Te cuento, yo la electrónica no se si por suerte o desgracia la tengo como un hobby, y como tengo un montón de proyectos sin terminar por quedarme estancado y no saber solucionarlo, he decidido coger un pic en este caso un 16f876A
La captura del valor del timer puedes hacerla por soft sin el módulo de captura porque ese sensor tiene un incertidumbre grande, de +-10us.
En cuanto a tu programa, es bastante difícil de entender porque no se pueden ver los bits individuales que activas en la configuración.
Luego subo un programa Python interesante que he programado para solucionarlo.
Saludos.
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTC
#define TRIS_DATA_PORT TRISC
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN LATBbits.LATC6 /* PORT for RW */
#define TRIS_RW TRISBbits.TRISC6 /* TRIS for RW */
#define RS_PIN LATBbits.LATC5 /* PORT for RS */
#define TRIS_RS TRISBbits.TRISC5 /* TRIS for RS */
#define E_PIN LATBbits.LATC4 /* PORT for E */
#define TRIS_E TRISBbits.TRISC4 /* TRIS for E */#define DATA_PORT PORTB
#define TRIS_DATA_PORT TRISBLo que no entiendo es la parte de control que pone por ejemplo: RS_PIN LATBbits.LATC5 que es LATB o LATC.Lo siento pero sigo sin saber donde modificar para usar un determinado bit de un determinado puerto.
Gracias
#define RS_PIN LATBbits.LATC5 /* PORT for RS */
#define TRIS_RS TRISBbits.TRISC5 /* TRIS for RS */esta mezclando LATBbits con LATC5 y TRISBbits con LATC5 y eso es lo que no entendia pero sera que hay un error.#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "my_xlcd.h"
#include <plib/delays.h>
#pragma config PLLDIV = 5 // PLL Prescaler Selection bits (Divide by 5 (20 MHz oscillator input))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 2 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes from the 96 MHz PLL divided by 2)
#pragma config FOSC = HSPLL_HS // Oscillator Selection bits (HS oscillator, PLL enabled (HSPLL))
#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)
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting)
#pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled)
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
#pragma config CCP2MX = ON // 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 Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
#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))
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
#define _XTAL_FREQ 48000000
//Retardos requeridos por la librería XLCD
void DelayFor18TCY(void);
void DelayPORXLCD(void);
void DelayXLCD(void);
void main(void)
{
ADCON1 = 0b1111;
//Configurando LCD 4 bits mutilínea
OpenXLCD(FOUR_BIT & LINES_5X7);
//Esperar hasta que el display esté disponible.
while(BusyXLCD());
//Mover cursor a la derecha...
WriteCmdXLCD(0x06);
//Desactivando el cursor.
WriteCmdXLCD(0x0C);
while(1)
{
//Primera línea
SetDDRamAddr(0x00);
putrsXLCD("HOLA");
//Segunda línea
SetDDRamAddr(0x40);
putrsXLCD("MUNDO");
}
}
void DelayFor18TCY(void)
{
Delay10TCYx(120);
return;
}
void DelayPORXLCD(void)
{
Delay1KTCYx(180);
return;
}
void DelayXLCD(void)
{
Delay1KTCYx(60);
return;
}my_xlcd.h#ifndef __XLCD_H
#define __XLCD_H
#include "p18cxxx.h"
/* PIC18 XLCD peripheral routines.
*
* Notes:
* - These libraries routines are written to support the
* Hitachi HD44780 LCD controller.
* - The user must define the following items:
* - The LCD interface type (4- or 8-bits)
* - If 4-bit mode
* - whether using the upper or lower nibble
* - The data port
* - The tris register for data port
* - The control signal ports and pins
* - The control signal port tris and pins
* - The user must provide three delay routines:
* - DelayFor18TCY() provides a 18 Tcy delay
* - DelayPORXLCD() provides at least 15ms delay
* - DelayXLCD() provides at least 5ms delay
*/
/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
/* #define BIT8 */
/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
/* #define UPPER */
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTB
#define TRIS_DATA_PORT TRISB
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN LATBbits.LATB2 /* PORT for RW */
#define TRIS_RW TRISBbits.TRISB2 /* TRIS for RW */
#define RS_PIN LATBbits.LATB0 /* PORT for RS */
#define TRIS_RS TRISBbits.TRISB0 /* TRIS for RS */
#define E_PIN LATBbits.LATB1 /* PORT for E */
#define TRIS_E TRISBbits.TRISB1 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00000100 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00000101 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00000110 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00000111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */
#ifdef _OMNI_CODE_
#define PARAM_SCLASS
#else
#define PARAM_SCLASS auto
#endif
#ifndef MEM_MODEL
#ifdef _OMNI_CODE_
#define MEM_MODEL
#else
#define MEM_MODEL far /* Change this to near for small memory model */
#endif
#endif
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in ROM to the LCD
*/
void putrsXLCD(const char *);
/* User defines these routines according to the oscillator frequency */
extern void DelayFor18TCY(void);
extern void DelayPORXLCD(void);
extern void DelayXLCD(void);
#endif
#ifndef __XLCD_H
#define __XLCD_H
#include "p18f2550.h"
/* PIC18 XLCD peripheral routines.
*
* Notes:
* - These libraries routines are written to support the
* Hitachi HD44780 LCD controller.
* - The user must define the following items:
* - The LCD interface type (4- or 8-bits)
* - If 4-bit mode
* - whether using the upper or lower nibble
* - The data port
* - The tris register for data port
* - The control signal ports and pins
* - The control signal port tris and pins
* - The user must provide three delay routines:
* - DelayFor18TCY() provides a 18 Tcy delay
* - DelayPORXLCD() provides at least 15ms delay
* - DelayXLCD() provides at least 5ms delay
*/
/* Interface type 8-bit or 4-bit
* For 8-bit operation uncomment the #define BIT8
*/
/* #define BIT8 */
/* When in 4-bit interface define if the data is in the upper
* or lower nibble. For lower nibble, comment the #define UPPER
*/
//#define UPPER
/* DATA_PORT defines the port to which the LCD data lines are connected */
#define DATA_PORT PORTB
#define TRIS_DATA_PORT TRISB
/* CTRL_PORT defines the port where the control lines are connected.
* These are just samples, change to match your application.
*/
#define RW_PIN LATBbits.LATB1 /* PORT for RW */
#define TRIS_RW TRISBbits.TRISB1 /* TRIS for RW */
#define RS_PIN LATBbits.LATB2 /* PORT for RS */
#define TRIS_RS TRISBbits.TRISB2 /* TRIS for RS */
#define E_PIN LATBbits.LATB3 /* PORT for D */
#define TRIS_E TRISBbits.TRISB3 /* TRIS for E */
/* Display ON/OFF Control defines */
#define DON 0b00001111 /* Display on */
#define DOFF 0b00001011 /* Display off */
#define CURSOR_ON 0b00001111 /* Cursor on */
#define CURSOR_OFF 0b00001101 /* Cursor off */
#define BLINK_ON 0b00001111 /* Cursor Blink */
#define BLINK_OFF 0b00001110 /* Cursor No Blink */
/* Cursor or Display Shift defines */
#define SHIFT_CUR_LEFT 0b00000100 /* Cursor shifts to the left */
#define SHIFT_CUR_RIGHT 0b00000101 /* Cursor shifts to the right */
#define SHIFT_DISP_LEFT 0b00000110 /* Display shifts to the left */
#define SHIFT_DISP_RIGHT 0b00000111 /* Display shifts to the right */
/* Function Set defines */
#define FOUR_BIT 0b00101100 /* 4-bit Interface */
#define EIGHT_BIT 0b00111100 /* 8-bit Interface */
#define LINE_5X7 0b00110000 /* 5x7 characters, single line */
#define LINE_5X10 0b00110100 /* 5x10 characters */
#define LINES_5X7 0b00111000 /* 5x7 characters, multiple line */
#ifdef _OMNI_CODE_
#define PARAM_SCLASS
#else
#define PARAM_SCLASS auto
#endif
#ifndef MEM_MODEL
#ifdef _OMNI_CODE_
#define MEM_MODEL
#else
#define MEM_MODEL far /* Change this to near for small memory model */
#endif
#endif
/* OpenXLCD
* Configures I/O pins for external LCD
*/
void OpenXLCD(PARAM_SCLASS unsigned char);
/* SetCGRamAddr
* Sets the character generator address
*/
void SetCGRamAddr(PARAM_SCLASS unsigned char);
/* SetDDRamAddr
* Sets the display data address
*/
void SetDDRamAddr(PARAM_SCLASS unsigned char);
/* BusyXLCD
* Returns the busy status of the LCD
*/
unsigned char BusyXLCD(void);
/* ReadAddrXLCD
* Reads the current address
*/
unsigned char ReadAddrXLCD(void);
/* ReadDataXLCD
* Reads a byte of data
*/
char ReadDataXLCD(void);
/* WriteCmdXLCD
* Writes a command to the LCD
*/
void WriteCmdXLCD(PARAM_SCLASS unsigned char);
/* WriteDataXLCD
* Writes a data byte to the LCD
*/
void WriteDataXLCD(PARAM_SCLASS char);
/* putcXLCD
* A putc is a write
*/
#define putcXLCD WriteDataXLCD
/* putsXLCD
* Writes a string of characters to the LCD
*/
void putsXLCD(PARAM_SCLASS char *);
/* putrsXLCD
* Writes a string of characters in ROM to the LCD
*/
void putrsXLCD(const char *);
/* User defines these routines according to the oscillator frequency */
extern void DelayFor18TCY(void);
extern void DelayPORXLCD(void);
extern void DelayXLCD(void);
#endifHe probado dejando comentado //#define UPPER y sin comentar y no funciona #include <xc.h> //PIC hardware mapping
#include <plib/delays.h>
#include "my_xlcd.h"
#include <stdlib.h>
#include <stdio.h>
#define _XTAL_FREQ 48000000 //Used by the XC8 delay_ms(x) macro
// CONFIG1L
#pragma config PLLDIV = 5 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
// CONFIG1H
#pragma config FOSC = HSPLL_HS // Oscillator Selection bits (XT oscillator (XT))
#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 = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting)
#pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = ON // 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 Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin 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 bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
/* Retardos requeridos por la libreria XLCD */
void DelayFor18TCY(void);
void DelayPORXLCD(void);
void DelayXLCD(void);
//*********************************************************
/* FUNCIONES DE RETARDOS REQUERIDOS POR LA LIBRERIA LCD */
//*********************************************************
void DelayFor18TCY(void)
{
Delay10KTCYx(120); /* Retardo de 18 TCY */
return;
}
void DelayPORXLCD(void)
{
Delay1KTCYx(180); /* Retardo de 15ms */
return;
}
void DelayXLCD(void)
{
Delay1KTCYx(60); /* Retardo de 5ms */
return;
}
//*********************************************************
/* FUNCION PRINCIPAL */
//*********************************************************
int main ()
{
/* Set RB<4:0> as digital I/O pins (required if config bit PBADEN is set */
ADCON1 = 0x0E;
/* Configure external LCD */
OpenXLCD( FOUR_BIT & LINES_5X7 );
/* Esperamos a que el display este disponible */
while(BusyXLCD());
WriteCmdXLCD( BLINK_ON );
WriteCmdXLCD( SHIFT_DISP_LEFT );
while(1)
{
//Primera línea
SetDDRamAddr(0x00);
putrsXLCD("HOLA");
//Segunda línea
SetDDRamAddr(0x40);
putrsXLCD("MUNDO");
}
}Por favor nadie sabe lo que puede estar pasando.
Miquel_S
Antes de tirar la Pcb a la basura es necesario tener el pin RW conectado al micro o puedo ponerlo directo a masa como es el caso.
Aquí lo dejo no me funciona ni simulado ni montado en Pcb, si alguien es tan amable de ayudarme lo agradeceré sino no pasa nada ya estoy acostumbrado a no terminar ninguno, despues de un par de años a día de hoy solo se encender un led.
Killerjc, tu caso es diferente.. Que programa usas? Que compilador? El MPLABX utilizando el XC8 debería de encontrarte la librería XLCD y sus funciones, están en la ruta que e puesto antes, si no están ahí es porque algo tienes mal instalado o estas utilizando un compilador o programa diferente.
/* DECLARACION DE FUNCIONES */
void Menu_Inicio(void);
void Menu_Principal(void);
/* FUNCIONES DE TEMPORIZACION */
void DelayFor18TCY(void)
{
Delay10TCYx(2);
}
void DelayPORXLCD(void)
{
Delay1KTCYx(15);
}
void DelayXLCD(void)
{
Delay1KTCYx(2);
}
/* Envia comando al LCD */
void comandXLCD(unsigned char a)
{
BusyXLCD();
WriteCmdXLCD(a);
}
/* Ubica cursor en ( x = Posicion en linea , y = N de linea ) */
void gotoxyXLCD(unsigned char x, unsigned char y)
{
unsigned char direccion;
if(y != 1)
direccion = 0x40;
else
direccion = 0;
direccion += x-1;
comandXLCD(0x80 | direccion);
}
void main(void)
{
ADCON1 = 0b00001111;
TRISA = 0x01;
OpenXLCD(FOUR_BIT & LINES_5X7); // Iniciamos Lcd
comandXLCD(0x06); // Nos aseguramos incremento de direccion, display fijo
comandXLCD(0x0C); // Encendemos Lcd
Menu_Inicio(); // Llamamos a la funcion del menu de inicio.
Menu_Principal(); // Llamamos a la funcion del menu principal.
while(1)
{
if(PORTAbits.RA0){
Menu_Principal(); // Retorna al menu principal
}
Delay1KTCYx(15);
}
}
/* FUNCIONES PARA EL USO DEL MENU CICLICO */
/* Funcion menu de inicio */
void Menu_Inicio(void){
putrsXLCD("Robot Minisumo");
gotoxyXLCD(6,2);
putrsXLCD("PANCHO");
Delay10KTCYx(0);
}
/* Funcion menu principal */
void Menu_Principal(void){
WriteCmdXLCD(CLEAR);
gotoxyXLCD(2,1);
putrsXLCD("MENU1");
gotoxyXLCD(2,2);
putrsXLCD("MENU2");
gotoxyXLCD(10,1);
putrsXLCD("MENU3");
gotoxyXLCD(10,2);
putrsXLCD("MENU4");
}
En la función Menu_Principal donde dice gotoxyXLCD(2,1); por mucho que cambie el valor de x siempre empieza en la posición 1 y no se porque ya que los demás si funcionan correctamente.hola una consulta,como realizo pausas extensas(de horas) en xc8 ,es decir lo que quiero hacer es presionar un botón y que cambie el estado de un pin luego de un tiempo(1hora) determinado vuelva a cero.
Esta funcion no se si es eficiente para realizar lo que quiero hacer
void pausa(unsigned int tiempo)
{
unsigned int __tiempo;
for (__tiempo = tiempo; __tiempo > 0; __tiempo--)
{
__delay_ms(1000);
}
}
saludos :-/
[pre]#include <p24FJ64GB002.h>
#include <stdio.h>
#include <stdlib.h>
#include <libpic30.h>
//config2
//#pragma config POSCMOD = HS // Primary Oscillator Select (HS Oscillator mode selected)
#pragma config PLL96MHZ = ON // 96MHz PLL Startup Select (96 MHz PLL Startup is enabled automatically on start-up)
#pragma config PLLDIV = DIV5 // USB 96 MHz PLL Prescaler Select (Oscillator input divided by 5 (20 MHz input))
//config1
#pragma config FWDTEN = OFF // Watchdog Timer (Watchdog Timer is disabled)
#pragma config GWRP = OFF // General Segment Write Protect (Writes to program memory are allowed)
#pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled)
#pragma config JTAGEN = ON // JTAG Port Enable (JTAG port is enabled)
#define _XTAL_FREQ 20000000
#define __delay_ms(x) __delay32((unsigned long)((x)*(_XTAL_FREQ/10000.0)))
#define __delay_us(x) __delay32((unsigned long)((x)*(_XTAL_FREQ/10000000.0)))
#define LED PORTAbits.RA1
#define ra0 PORTAbits.RA0
#include "xclcd.h"
void main(void)
{
unsigned char alfa[17] = "Peque";
const unsigned char letra[8] = {0b00000000,
0b00001110,
0b00000000,
0b00010110,
0b00011001,
0b00010001,
0b00010001};
unsigned char veces;
PORTA = 0;
TRISA = 0;
// PORTB = 0;
// TRISB = 0;
lcd_init();
__delay_ms(1500);
lcd_createchar(1,letra);
__delay_ms(1500);
lcd_setdisplay(DISPLAY_OFF);
__delay_ms(1500);
lcd_puts("Pequeno");
__delay_ms(1500);
lcd_gotoxy(1,2);
__delay_ms(1500);
lcd_puts(alfa);
__delay_ms(1500);
lcd_putch(1);
__delay_ms(1500);
lcd_putch('o');
__delay_ms(1500);
lcd_setdisplay(CURSOR_ON);
__delay_ms(1500);
lcd_puts("hola");
__delay_ms(1500);
lcd_gotoxy(1,2);
__delay_ms(1500);
lcd_setdisplay(CURSOR_ON);
__delay_ms(1500);
lcd_puts("fino");
while(1)
{
LED=1;
__delay_ms(500);
LED=0;
__delay_ms(500);
}
}[/pre]#ifndef XCLCD_H
#define XCLCD_H
#ifndef _XC_H_
#include <p24FJ64GB002.h>
#endif
/******************************************************************************
* Parametros configurables por el usuario *
******************************************************************************/
/*
* El valor de _XTAL_FREQ debe coincidir con el valor definido
* en el programa principal
*/
/*
* LCDEN define el pin EN para el lcd
* LCDRS define el pin RS para el lcd
* LCDRW define el pin RW para el lcd
* LCDDATA define el puerto de datos
*/
/*
* Si se utiliza un pic con resgistros LAT
* se pueden definir los pines utilizando LAT<x>bits.LAT<x><y>
* siendo <x> la letra del puerto correspondiente y <y> el bit
* Tambien se puede definir de la misma manera el puerto de datos
*/
/*
* LCDTRISEN define el bit TRIS para el pin EN
* LCDTRISRS define el bit TRIS para el pin RS
* LCDTRISRW define el bit TRIS para el pin RW
* LCDTRIS define el TRIS correspondiente al puerto de datos
*/
/*
* PROTOCOL4BIT define si se utiliza protocolo de 4 bits
* PROTOCOL8BIT define si se utiliza protocolo de 8 bits
*/
/*
* En caso de utilizar protocolo de 4 bits
* UPPER define si se utiliza el nibble alto del puerto
* LOWER define si se utiliza el nibble bajo del puerto
*/
/*
* En caso de utilizar el pin RW, hay que definir
* USE_RW
*/
#ifndef _XTAL_FREQ
#define _XTAL_FREQ 20000000
#endif
#define LCDEN PORTBbits.RB13
#define LCDRS PORTBbits.RB15
#define LCDRW PORTBbits.RB14
#define LCDTRISEN TRISBbits.TRISB13
#define LCDTRISRS TRISBbits.TRISB15
#define LCDTRISRW TRISBbits.TRISB14
#define LCDDATA PORTB
#define LCDTRIS TRISB
#define LCDLAT LATB
#define PROTOCOL4BIT
#define LOWER
#define USE_RW
/******************************************************************************
* Definicion de valores para lcd_setdisplay *
******************************************************************************/
/*
* Los valores se pueden combinar utilizando el operador |
*/
#define DISPLAY_OFF 0b00001000
#define DISPLAY_ON 0b00001100
#define CURSOR_OFF 0b00001100
#define CURSOR_ON 0b00001110
#define BLINK_OFF 0b00001100
#define BLINK_ON 0b00001101
/******************************************************************************
* Definicion de valores para lcd_shift *
******************************************************************************/
/*
* Los valores se pueden combinar utilizando el operador |
*/
#define SHIFT_DISPLAY 0b00011000
#define SHIFT_CURSOR 0b00010000
#define SHIFT_LEFT 0b00010000
#define SHIFT_RIGHT 0b00010100
/******************************************************************************
* Definicion de valores para lcd_entrymode *
******************************************************************************/
/*
* Los valores se pueden combinar utilizando el operador |
*/
#define INCREMENT 0b00000110
#define DECREMENT 0b00000100
#define SHIFT_ON 0b00000101
#define SHIFT_OFF 0b00000100
/******************************************************************************
* Definicion de funciones *
******************************************************************************/
void lcd_init(void);
void lcd_put(unsigned char, unsigned char);
void lcd_puts(const unsigned char*);
void lcd_gotoxy(unsigned char, unsigned char);
int lcd_busy(void);
void lcd_putini(unsigned char);
void lcd_createchar(unsigned char, const unsigned char*);
void lcd_setdisplay(unsigned char);
void lcd_shift(unsigned char);
void lcd_entrymode(unsigned char);
#define lcd_putch(x) lcd_put(x,1)
#define lcd_clear() lcd_put(0x01,0)
#define lcd_home() lcd_put(0x02,0)
#define lcd_off() lcd_put(0x08,0)
#define lcd_on() lcd_put(0x0C,0)
#endif /* XCLCD_H */
#include <p24FJ64GB002.h>
#include "xclcd.h"
#define _XTAL_FREQ 20000000
#define __delay_ms(x) __delay32((unsigned long)((x)*(_XTAL_FREQ/10000.0)))
#define __delay_us(x) __delay32((unsigned long)((x)*(_XTAL_FREQ/10000000.0)))
#if !defined(LCDEN) || !defined(LCDRS)
#error Faltan definir los pines de control
#elif !defined(LCDTRISEN) || !defined(LCDTRISRS)
#error Falta definir la direccion de los pines de control
#elif !defined(LCDDATA) || !defined(LCDTRIS)
#error Falta definir el puerto y/o el tris de datos
#elif !defined(PROTOCOL4BIT) && !defined(PROTOCOL8BIT)
#error Falta definir el protocolo
#elif defined(PROTOCOL4BIT) && !defined(UPPER) && !defined(LOWER)
#error Falta definir el nibble
#else
void lcd_putini(unsigned char data)
{
unsigned char lasttris;
lasttris = LCDTRIS;
#if defined(PROTOCOL8BIT)
LCDTRIS = 0;
LCDDATA = data;
#elif defined(PROTOCOL4BIT)
#if defined(UPPER)
LCDTRIS &= 0x0F;
LCDDATA = (LCDDATA & 0x0F) | data;
#elif defined(LOWER)
LCDTRIS &= 0xF0;
data = data >> 4;
LCDDATA = (LCDDATA & 0xF0) | data;
#endif
#endif
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
LCDTRIS = lasttris;
}
void lcd_put(unsigned char data, unsigned char reg)
{
unsigned char lasttris;
lasttris = LCDTRIS;
#if defined (USE_RW)
while(lcd_busy() == 1);
#else
__delay_ms(2);
#endif
LCDRS = reg;
LCDRW = 0;
#if defined(PROTOCOL8BIT)
LCDTRIS = 0;
LCDDATA = data;
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
#elif defined(PROTOCOL4BIT)
#if defined(UPPER)
LCDTRIS &= 0x0F;
LCDDATA = (LCDDATA & 0x0F) | (data & 0xF0);
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
__delay_us(1);
LCDDATA = (LCDDATA & 0x0F) | (data << 4);
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
#elif defined(LOWER)
LCDTRIS &= 0xF0;
LCDDATA = (LCDDATA & 0xF0) | (data >> 4);
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
__delay_us(1);
LCDDATA = (LCDDATA & 0xF0) | (data & 0x0F);
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
#endif
#endif
LCDTRIS = lasttris;
}
void lcd_init(void)
{
unsigned char veces;
LCDEN = 0;
LCDRS = 0;
LCDRW = 0;
LCDTRISRS = 0;
LCDTRISRW = 0;
LCDTRISEN = 0;
__delay_ms(15);
for (veces = 3; veces > 0; veces--)
{
lcd_putini(0x30);
__delay_ms(5);
}
#if defined(PROTOCOL8BIT)
lcd_put(0x38,0); // Dos lineas, caracter 5x8
#elif defined(PROTOCOL4BIT)
lcd_putini(0x20); // Protocolo de 4 bits
lcd_put(0x28,0); // Dos lineas, caracter 5x8
#endif
lcd_put(0x08,0); // Apagar display, cursor, blink
lcd_put(0x01,0); // Borrar display
lcd_put(0x06,0); // Incrementa posicion, sin shift
}
int lcd_busy(void)
{
unsigned char lasttris;
unsigned char busy;
lasttris = LCDTRIS;
LCDRS = 0;
LCDRW = 1;
#if defined(PROTOCOL8BIT)
LCDTRIS = 0xFF;
LCDEN = 1;
__delay_us(1);
busy = LCDDATA;
LCDEN = 0;
#elif defined(PROTOCOL4BIT)
#if defined(UPPER)
LCDTRIS = (LCDTRIS & 0x0F) | 0xF0;
LCDEN = 1;
__delay_us(1);
busy = LCDDATA;
LCDEN = 0;
__delay_us(1);
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
#elif defined(LOWER)
LCDTRIS = (LCDTRIS & 0xF0) | 0x0F;
LCDEN = 1;
__delay_us(1);
busy = LCDDATA << 4;
LCDEN = 0;
__delay_us(1);
LCDEN = 1;
__delay_us(1);
LCDEN = 0;
#endif
#endif
LCDTRIS = lasttris;
if ((busy & 0x80) == 0x80) return 1;
else
return 0;
}
void lcd_gotoxy(unsigned char x, unsigned char y)
{
x--;
y--;
if (y == 0) lcd_put((0x80 + x),0);
else
lcd_put((0xC0 + x),0);
}
void lcd_puts(const unsigned char *st)
{
while (*st != 0)
{
lcd_put(*st,1);
st++;
}
}
void lcd_createchar(unsigned char asciicode, const unsigned char* ascii)
{
unsigned char line;
unsigned char caracter;
for (line = 0; line < 7; line++)
{
caracter = (((asciicode & 0x07) << 3) | (0x40 + line));
lcd_put(caracter,0);
lcd_put(*ascii,1);
ascii++;
}
caracter = ((asciicode & 0x07) << 3) | 0x47;
lcd_put(caracter,0);
lcd_put(0,1);
lcd_clear();
}
void lcd_setdisplay(unsigned char state)
{
lcd_put(state,0);
}
void lcd_shift(unsigned char state)
{
lcd_put(state,0);
}
void lcd_entrymode(unsigned char state)
{
lcd_put(state,0);
}
#endif
#define TRISB TRISB
extern volatile unsigned int TRISB __attribute__((__sfr__));
typedef struct tagTRISBBITS {
unsigned TRISB0:1;
unsigned TRISB1:1;
unsigned TRISB2:1;
unsigned TRISB3:1;
unsigned TRISB4:1;
unsigned TRISB5:1;
unsigned :1;
unsigned TRISB7:1;
unsigned TRISB8:1;
unsigned TRISB9:1;
unsigned TRISB10:1;
unsigned TRISB11:1;
unsigned :1;
unsigned TRISB13:1;
unsigned TRISB14:1;
unsigned TRISB15:1;
} TRISBBITS; TRISB = 0x0001;
PORTB = 0;
void lcd_init(void)
{
unsigned char veces;
// Set inicial de valores de los pines y configuracion de los mismo
LCDEN = 0;
LCDRS = 0;
LCDRW = 0;
LCDTRISRS = 0;
LCDTRISRW = 0;
LCDTRISEN = 0;
// Comienzo de inicio del modulo
__delay_ms(15);
for (veces = 3; veces > 0; veces--)
{
lcd_putini(0x30);
__delay_ms(5);
}
#if defined(PROTOCOL8BIT)
lcd_put(0x38,0); // Dos lineas, caracter 5x8
#elif defined(PROTOCOL4BIT)
lcd_putini(0x20); // Protocolo de 4 bits
lcd_put(0x28,0); // Dos lineas, caracter 5x8
#endif
lcd_put(0x08,0); // Apagar display, cursor, blink
lcd_put(0x01,0); // Borrar display
lcd_put(0x06,0); // Incrementa posicion, sin shift
}
10.2 Configuring Analog Port Pins
The AD1PCFG and TRIS registers control the operation of the A/D port pins. Setting a port pin as an analog input also requires that the corresponding TRIS bit be set. If the TRIS bit is cleared (output), the digital output level (VOH or VOL) will be converted.
When reading the PORT register, all pins configured as analog input channels will read as cleared (a low level). Pins configured as digital inputs will not convert an analog input. Analog levels on any pin that is defined as a digital input (including the ANx pins) may cause the
input buffer to consume current that exceeds the device specifications
#pragma config POSCMOD = HS // Primary Oscillator Select (HS Oscillator mode selected)
#pragma config FCKSM = CSDCMD
#pragma config FNOSC = PRIPLL // Initial Oscillator Select (Primary Oscillator with PLL module (XTPLL, HSPLL, ECPLL))
#pragma config PLL96MHZ = ON // 96MHz PLL Startup Select (96 MHz PLL Startup is enabled automatically on start-up)
#pragma config PLLDIV = DIV5 // USB 96 MHz PLL Prescaler Select (Oscillator input divided by 5 (20 MHz input))
#pragma config IESO = OFF // Internal External Switchover (IESO mode (Two-Speed Start-up) disabled)
modificacion del delay para que mostrara la lcd el mensaje#define _XTAL_FREQ 20000000
#define __delay_ms(x) __delay32((unsigned long)((x)*(_XTAL_FREQ/800.0)))
#define __delay_us(x) __delay32((unsigned long)((x)*(_XTAL_FREQ/800000.0)))
/opt/microchip/xc8/v1.34/include/plib/timers.h:31: error: (141) can't open include file "pconfig.h": No such file or directory
Tiene pinta de ser un fallo de haber borrado un fichero, y el makefile te lo esta pidiendo.Hola juaperser1 el fichero no ha sido borrado se encuentra en la carpeta include/plib, lo que no se el porque no lo abre, he probado de incluirlo en el código pero sigue sin abrirlo.
Por otro lado:Citar/opt/microchip/xc8/v1.34/include/plib/timers.h:31: error: (141) can't open include file "pconfig.h": No such file or directory
En las versiones de XC32 como la v1.34 ya no sirven las plib, hace mucho que no uso xc8 ¿pasa lo mismo en xc8?
Microchip MPLAB XC8 C Compiler (--- Mode) V1.33
Part Support Version: 1.33 (A)
Copyright (C) 2014 Microchip Technology Inc.
License type: Node Configuration
:: advisory: (1233) Employing 18F2550 errata work-arounds:
:: advisory: (1234) * Corrupted fast interrupt shadow registers
Memory Summary:
Program space used 84h ( 132) of 8000h bytes ( 0.4%)
Data space used 9h ( 9) of 800h bytes ( 0.4%)
Configuration bits used 7h ( 7) of 7h words (100.0%)
EEPROM space used 0h ( 0) of 100h bytes ( 0.0%)
ID Location space used 8h ( 8) of 8h bytes (100.0%)
Data stack space used 0h ( 0) of 7A0h bytes ( 0.0%)
make[2]: Leaving directory 'F:/CCS/MPLABx/Prueba/Prueba.X'
make[1]: Leaving directory 'F:/CCS/MPLABx/Prueba/Prueba.X'
BUILD SUCCESSFUL (total time: 1s)
Loading symbols from F:/CCS/MPLABx/Prueba/Prueba.X/dist/default/production/Prueba.X.production.elf...
Loading code from F:/CCS/MPLABx/Prueba/Prueba.X/dist/default/production/Prueba.X.production.hex...
Loading completedSigo con el mismo error, de todos modos veo que estas usando una versión diferente, no se si probar a actualizar a la versión 1.35.
Saludos!
Al final he podido compilar con la versión v1.33
Interrupciones de alta y baja prioridad.
En este programa vamos a utilizar las interrupciones externas del pic18F4550 en los pines RB0, RB1 y RB2
configurando lso flancos de subida para INT0, INT1, e INT2.
En el 4550 la INT0 es siempre de alta prioridad. No se puede setear como de baja prioridad
Las INT1 e INT2 las configuramos en baja prioridad.
Cada vez que se produzca una interrupción en INT0 cambiará el estado del pin RA0
Cada vez que se produzca una interrupción en INT1 cambiará el estado del pin RA1
Cada vez que se produzca una interrupción en INT2 cambiará el estado del pin RA2
Saludos.
JukinchCódigo: C
File: main.c Author: JUKINCH Created on 31 de mayo de 2013, 14:49 PRUEBA DE INTERRUPCIONES en baja y alta prioridad EN INT0 (RB0) INT1 (RB1) E INT2 (RB2) pic: 18f4550 crystal: NO CPU: 8Mhz (valor establecido dentro de main cambiando los bits IRCF2, IRCF1 e IRCF0 del registro OSCCON) en RA6 sale la frecuencia de Fosc/4 -------> 8Mhz/4 = 2Mhz FUSES: los bits de configuración se establecen en el archivo "configuracion_de_fuses.c" CONEXIONES entrenadora FELIXLS: 1 módulo conectado en IDC(RB0) en modo botón 1 módulo conectado en IDC(RA0) en modo leds los cambios se pueden hacer en el archivo configuracion_hard.c */ /*Includes globales*/ #include <xc.h> #include <delays.h> /* Para utilizar demoras en nuestro código*/ /*Includes locales*/ #include "configuracion_de_fuses.c" #include "configuracion_hard.c" volatile int myVolatileVariable=0;//variable para utilizar con las interrupciones //******************************************************// // Rutina de Interrupcion de Alta Prioridad //******************************************************// // void interrupt interrupcionDeAlta(void)//prototipo de la interrupción de alta prioridad { if(INTCONbits.INT0IF) //pregunta por bandera de interrupción en rb0 { LED0 = ~LED0; // invierto estado del led myVolatileVariable++; INTCONbits.INT0IF = 0; //limpia bandera y salimos } } // //******************************************************// // Rutina de Interrupcion de baja prioridad //******************************************************// // void interrupt low_priority interrupcionDeBaja(void)//prototipo de la interrupción de baja prioridad { if(INTCON3bits.INT1IF) //pregunta por bandera de interrupción { LED1 = ~LED1; // invierto estado del led myVolatileVariable++; INTCON3bits.INT1IF = 0; //limpia bandera y salimos } if(INTCON3bits.INT2IF) //pregunta por bandera de interrupción { LED2 = ~LED2; // invierto estado del led myVolatileVariable++; INTCON3bits.INT2IF = 0; //limpia bandera y salimos } } //******************************************************// // Programa Principal //******************************************************// void main(void) { ADCON0 = 0X00,ADCON1 = 0X0F,CMCON = 0X07; //puerto A con todos los pines digitales PINLED0=0; // Configuración de pines como salida para los leds PINLED1=0; PINLED2=0; PINBOTON0=1; // Configuración de pines como entrada para los botones PINBOTON1=1; PINBOTON2=1; LATA = 0X00; // todo el puerto A a cero. RCONbits.IPEN = 1; // Activa modo alta y baja prioridad INTCONbits.GIEL = 1;// permitimos interrupciones de baja prioridad (Global Interrupt Enable Low) INTCONbits.GIEH = 1;// permitimos interrupciones de alta prioridad (Global Interrupt Enable High) INTCON2bits.INTEDG0 = 1;//configura interrupcion por flanco de subida para la interrupcion en RB0 INTCON2bits.INTEDG1 = 1;//configura interrupcion por flanco de subida para la interrupcion en RB1 INTCON2bits.INTEDG2 = 1;//configura interrupcion por flanco de subida para la interrupcion en RB2 INTCONbits.INT0IE=1; // activa la interrupción externa por flanco del pin RB0 // La Int0 es siempre de alta prioridad. No se puede setear como de baja prioridad INTCON3bits.INT1IE=1; // activa la interrupción externa por flanco del pin RB1 INTCON3bits.INT1IP=0; // selecciona la interrupción de baja prioridad del pin RB1 INTCON3bits.INT2IE=1; // activa la interrupción externa por flanco del pin RB2 INTCON3bits.INT2IP=0; // selecciona la interrupción de baja prioridad del pin RB2 //******************************************************* //******************************************************* while (1); } //******************************************************* //*******************************************************
Tal ves te falta configurar las entradas RB4:0 Como digitales, en especial si tus fuses estan puestos para que puedan ser digital o analogicos esos
ADCON1 = 0X0F
Tambien intenta primero activar las interrupciones del modulo y como punto final activar las interrupciones globales, no activar la interrrupcion global y lluego configurar el modulo
y lo otro que me dices seria solo dejar las las interrupciones del modulo osea estas:
RCONbits.IPEN = 1; // Activa modo alta y baja prioridad
INTCONbits.GIEL = 1;// permitimos interrupciones de baja prioridad (Global Interrupt Enable Low)
INTCON2bits.INTEDG2 = 1;//configura interrupcion por flanco de subida para la interrupcion en RB2
INTCON3bits.INT2IE=1; // activa la interrupción externa por flanco del pin RB2
INTCON3bits.INT2IP=0; // selecciona la interrupción de baja prioridad del pin RB2 RCONbits.IPEN = 1; // Activa modo alta y baja prioridad
INTCON2bits.INTEDG2 = 1;//configura interrupcion por flanco de subida para la interrupcion en RB2
INTCON3bits.INT2IE=1; // activa la interrupción externa por flanco del pin RB2
INTCON3bits.INT2IP=0; // selecciona la interrupción de baja prioridad del pin RB2
INTCONbits.GIEL = 1;// permitimos interrupciones de baja prioridad (Global Interrupt Enable Low)A ver si me explico mejor. Si lo tenes como analogico no va a pasar de 0 a 1 o de 1 a 0 el pin, siempre va a leer 0. Por eso no entra a la interrupcion.
Ponelo como digital y va a poder realizarse eso. asi que si no usas el ADC directamente ponelo a todos como digitales con el registro ADCON1.
Podrias pasar de nuevo el codigo?.
Mas que eso es como si se llamara continuamente a una funcion y nunca se volviera, interrupcion dentro de otra interrupcion, muchas veces seguidas, lo cual es absurdo ya que al entrar se deshabilitan las mismas.
Y es C, con lo cual el tema de CALL - RETURN se manejan solos. Te piedo el codigo para probarlo yo en mi PC y ver cual es el problema.
Podrias pasar de nuevo el codigo?.
Mas que eso es como si se llamara continuamente a una funcion y nunca se volviera, interrupcion dentro de otra interrupcion, muchas veces seguidas, lo cual es absurdo ya que al entrar se deshabilitan las mismas.
Y es C, con lo cual el tema de CALL - RETURN se manejan solos. Te piedo el codigo para probarlo yo en mi PC y ver cual es el problema.
Bueno.. Ahi mire el programa y lo probe, solo probe la parte del sprintf, y todo lo del micro, nada de ADC/LCD, estos son los problemas que encontre, aunque voy a ir con tu problema primero:
- La interrupcion esta como "alta velocidad" ( le falta el low_priority), pero vos tenes definida la interrupcion como baja prioridad. Ademas tenes habilitada las 2 interrupciones, las de alta y las de baja cuando solo usarias la de baja:Código: C
INTCONbits.GIEL = 1;// permitimos interrupciones de baja prioridad (Global Interrupt Enable Low) INTCONbits.GIEH=1; //alto en ultima compuerta
En si el problema es el siguiente. la interrupcion de alta prioridad se encuentra en 0x0008 y la de baja en 0x0018, MPLAB no se por que pone todo el codigo a partir de la direccion 0x800 tal ves esperando un bootloader. Entonces cuando ocurre una interrupcion, catalogada como baja prioridad va a 0x0018, PERO tu call a la funcion de interrupcion se da en 0x0008, de esta forma primero que nada estas ejecutando NOP hasta que vuelve a las instrucciones de reset ( va de 0x0018 a 0x0800 ejecutando NOPs), lo feo es que si se habia ejecutado un CALL por ejemplo ( como para comparar los flotantes ) y se produce la interrupcion, ese CALL, nunca ejecuta un RETURN. LLenando el STACK poco a poco ya que jamas se saca nada, y eso termina en el STACK OVERFLOW que tenes.
- Mas problemas con tu programa:
- Comparacion:Código: C
presion1 = presion1_anterior;
Eso no tiene sentido por que siempre asignaria un 0 a presion1 y jamas daria igualdad entre lo anterior y presion1 e imagino que quisiste hacerlo al reves, es decir:Código: C
presion1_anterior = presion1;
- Repeticion de codigo... es terrible la cantidad de codigo que se repite y algunas condiciones que tampoco tienen sentido.
Podrias haber realizado con un for, todo eso, para cada una de las entradas, pero hiciste una por 1, tambien comprobas cosas que habias comprobado antes, como es el ejemplo de ver que es menos de 30 y luego en el else comparar si es mayor o igual, si ya hiciste antes esa comparacion, ¿por que nuevamente?. La otra tambien es la de preguntar siempre si es igual o no que el valor anterior. Un solo if fuera y esta listo.
Tu programa:Código: C
float presion[5], presion_anterior[5] = 0; // para que solo escriba en pantalla si cambia la presion char T[17], terminacion; // cadena de 16 caracteres incluyendo el final \0 int i;Código: C
while (1) { for(i=0;i<5;i++) { presion[i]=(((float)ADC_get(i)/203.7221)-0.5)/0.01333333333; if(presion[i] != presion_anterior[i]) { terminacion = 0x3C; if (presion[i]<30) { LATBbits.LATB5=1; if(!i) LATAbits.LATA4=1; //Solo para canal0 } else if (presion[i] <=40) { LATBbits.LATB6=1; LATBbits.LATB5=0; LATBbits.LATB7=0; terminacion = 0x2D; } else { LATBbits.LATB7=1; } if (i==4) LCD_gotoxy(9,0); else LCD_gotoxy(0,i); LCD_puts(T); presion_anterior[i] = presion[i]; } } }
Incluso si tenes que hacer una salida por cada uno seguiria asi el ejemplo. nomas que usaria otra funcion mas aparte de eso.
Creo que la reduccion es poca, ya que lo que mas ocupa son otras cosas como lo de float y sprintf pero tenes:
Program space used 1642h ( 5698) of 8000h bytes ( 17.4%)
versus un 20%+ ocupado como lo tenias en tu programa. Y tal ves no sea necesario calcular todo, solo cuando sea necesario ademas, tenes que darte cuenta que la coma flotante para que se produzca una igualdad es bastante complejo. Por gusto probe con enteros :)Código: C
int presion[5], presion_anterior[5]; // para que solo escriba en pantalla si cambia la presion float resultado; char T[17], terminacion; // cadena de 16 caracteres incluyendo el final \0 short int i;Código: C
for(i=0;i<5;i++) { presion[i]=ADC_get(i); if(presion[i] != presion_anterior[i]) { presion_anterior[i] = presion[i]; terminacion = 0x3C; if (presion[i]<183) { LATBbits.LATB5=1; if(!i) LATAbits.LATA4=1; //Solo para canal0 } else if (presion[i] <=210) { LATBbits.LATB6=1; LATBbits.LATB5=0; LATBbits.LATB7=0; terminacion = 0x2D; } else { LATBbits.LATB7=1; } resultado=(((float)presion[i]/203.7221)-0.5)/0.01333333333; if (i==4) LCD_gotoxy(9,0); else LCD_gotoxy(0,i); LCD_puts(T); } }
Una curiosidad que encontre.
Tiempos:
Comparacion, activar saidas, etc: 89 a 120 ciclos
Calculo: 1960 a 2000 ciclos ( Solo la linea con la matematica )
Pasarlo a texto: 11600 a 13800 ciclos ( Solo la linea del sprintf )
-------------------------
Una mejora para el calculo, simplificandolo:Código: C
resultado=((float)(test/2.71629)-37.5);
Ocupa 900 ciclos menos aproximadamente.
Floats de 24 bits, no de 32! Pero suficiente para la precision que estas buscando.
presion1 = presion1_anterior;
aqui lo que trato de hacer es que no escriba en pantalla continuamente, es decir, que no realize el printf a menos que la presion cambie, osea el valor de la entrada analogica, esto es lo que trato de hacer, tu me diras si si esta bien o se puede hacer de otra manera, ademas tienes razon en que son coma flotante y es dificil que se cumpla la igualdad, mas bien creo que ese codigo esta de mas...
en mi programa, el que te pase, todas las presiones tienen los mismos intervalos pero era solo para probarlas, en realidad cada presion tiene intervalos diferentes porque medire diferentes gases, con los gases diferentes ya no podria aplicar el codigo con el for o si???
TMR1IF=0;
TMR1 = (lo que le quieras poner, en tu caso 0) ;TMR1IF=0;
TMR1H = 0;
TMR1L=0;hola miguel, antes de nada decirte que te falta en tu programa un bucle principal, un while (1); si no lo tienes se ejecutara una vez y se acabo, por lo tanto debes agregarlo.Hola Juan José ante todo gracias, lo del bucle infinito lo se, se que sin el solo se ejecuta una vez pero es que ni siquiera llega a una vez, en la simulación me he dado cuenta que los registros del Timer TMR1H y TMR1L solo se incrementa el low el high siempre esta a 0.
por otro lado cada vez que salta la interrupción debes recargar los registros y limpiar el flag de interrupcion.
es decir cada vez que se desborde debes reiniciarloCódigo: [Seleccionar]TMR1IF=0;
TMR1 = (lo que le quieras poner, en tu caso 0) ;
oCódigo: [Seleccionar]TMR1IF=0;
TMR1H = 0;
TMR1L=0;
y ya de paso habilita su interrupción, si no me equivoco, eran los registros PIE1, TMR1IE
por cierto los fuses los has colocado en algún lado?
un saludo
#define _XTAL_FREQ 20000000
#include <xc.h>
#include <pic18f2550.h>
#include "config.h"
void main(void)
{
TRISBbits.RB0 = 0; //Configuramos RB0 como salida
LATB0 = 0; //Empezamos con el led apagado
//CONFIGURAMOS TIMER1
INTCONbits.GIE = 0; //Desabilitamos todas las interrupciones
T1CONbits.RD16 = 1; //16 bit
T1CONbits.T1RUN = 0;
T1CONbits.T1CKPS1 = 0; //Seleccionamos
T1CONbits.T1CKPS0 = 0; //prescaler 1:1
T1CONbits.T1OSCEN = 0; // Timer 1 Osc Enable: 0 = off, 1 = on
T1CONbits.T1SYNC = 0;
T1CONbits.TMR1CS = 0; //Internal clock (Fosc/4)
TMR1H = 0x00;
TMR1L = 0x00;
PIR1bits.TMR1IF = 0; //Reset the interrupt flag
T1CONbits.TMR1ON = 1; //Enable Timer1
while(1)
{
if(PIR1bits.TMR1IF)
{
LATB0 =~ LATB0;
TMR1IF=0;
TMR1H = 0;
TMR1L=0;
}
}
}¿El bit TMR1IE debe estar habilitado?
INTCONbits.GIE = 0; //Desabilitamos todas las interrupcionesHOLA KILLERJC, primero que todo gracias por tus respuestas y consejos, estuve toda la semana arreglando el codigo y entendiendo todo lo que me explicabas...Citarpresion1 = presion1_anterior;
aqui lo que trato de hacer es que no escriba en pantalla continuamente, es decir, que no realize el printf a menos que la presion cambie, osea el valor de la entrada analogica, esto es lo que trato de hacer, tu me diras si si esta bien o se puede hacer de otra manera, ademas tienes razon en que son coma flotante y es dificil que se cumpla la igualdad, mas bien creo que ese codigo esta de mas...
2 cosas ahi:
Estas haciendo:
presion1 <- presion1_anterior
en ves de al reves, eso intente hacerte notar, como presion1_anterior inicializa a 0 y vos jamas lo cambias ( ya que tu asignacion estaba al reves, era lo mismo que poner:
presion1 = 0;
Con respecto a los flotantes, siempre que los uses, trata de jamas usar igualdades, siempre menor a o mayor a, es algo que me traje de python pero creo que se aplica aca tambien. Las representaciones binarias no son exactas y bueno puede parecer que son iguales pero que dentro en la representacion no lo son.Citaren mi programa, el que te pase, todas las presiones tienen los mismos intervalos pero era solo para probarlas, en realidad cada presion tiene intervalos diferentes porque medire diferentes gases, con los gases diferentes ya no podria aplicar el codigo con el for o si???
Si podes hacerlo. Suponete que fijamos 2 valores por cada "presion", podes utilizar un array de esta forma:Código: C
const int limites_presion[5][2] = {{10,20},{30,40},{50,60},{700,1000},{80,200}};
El const, te lo pone en flash, pero si ves que esta muy llena tu flash se lo sacas para que quede almacenado en la RAM. y reemplazas los valores de los if:Código: C
if (presion[i]<30) else if (presion[i] <=40)
porCódigo: C
if (presion[i] < limites_presion[i][0]) else if (presion[i] <= limites_presion[i][1])
Con respecto a las salidas ya se complica un poco mas.
Voy a suponer por un momento que cada condicion.. es decir: Minimo, Medio, Maximo de cada presion son distintos.
Voy a intentar hacer un codigo facil para que te sea facil verlo. OJO! hay muchas formas mas de hacerlo, esto es solo para que veas una forma y se pueda ver facilmente. todo va a depender de que tan complejas sean tus funciones.Código: C
for(i=0;i<5;i++) { presion[i]=ADC_get(i); if(presion[i] != presion_anterior[i]) { presion_anterior[i] = presion[i]; terminacion = 0x3C; salida = i*3; if (presion[i] > limite_presion[i][0] && presion[i] <= limite_presion[i][1]) { salida++ terminacion = 0x2D; } else { salida+=2; } Cambiar_salida(salida); resultado=(((float)presion[i]/203.7221)-0.5)/0.01333333333; if (i==4) LCD_gotoxy(9,0); else LCD_gotoxy(0,i); LCD_puts(T); } } void Cambiar_salida(short valor_salida) { switch(valor_salida) { // i = 0 case 0: //Valor minimo (presion[0] < limite_presion[0][0]) break; case 1: //Valor medio (limite_presion[0][0] < presion[0] <= limite_presion[0][1]) break; case 2: //Valor maximo (presion[0] > limite_presion[0][1]) break; // i = 1 case 3: //Valor minimo (presion[i] < limite_presion[i][0]) break; case 4: //Valor medio (limite_presion[i][0] < presion[i] <= limite_presion[i][1]) break; case 5: //Valor maximo (presion[i] > limite_presion[i][1]) break; // i = 2 case 6: //Valor minimo (presion[i] < limite_presion[i][0]) break; case 7: //Valor medio (limite_presion[i][0] < presion[i] <= limite_presion[i][1]) break; case 8: //Valor maximo (presion[i] > limite_presion[i][1]) break; // i = 3 case 9: //Valor minimo (presion[i] < limite_presion[i][0]) break; case 10: //Valor medio (limite_presion[i][0] < presion[i] <= limite_presion[i][1]) break; case 11: //Valor maximo (presion[i] > limite_presion[i][1]) break; // i = 4 case 12: //Valor minimo (presion[i] < limite_presion[i][0]) break; case 13: //Valor medio (limite_presion[i][0] < presion[i] <= limite_presion[i][1]) break; case 14: //Valor maximo (presion[i] > limite_presion[i][1]) break; default: // Aca entra si existe un error. Deberia desactivar todo. } }
Hola después de muchas pruebas con el timer consigo las temporizaciones según la formula del Timer1, pero sigo con fallos en la simulación con el IDE, por lo cual puedo asegurar que el MPLAB X IDE v3.10 me esta fallando mas que una escopeta de feria :5]Código: [Seleccionar]#define _XTAL_FREQ 20000000
#include <xc.h>
#include <pic18f2550.h>
#include "config.h"
void main(void)
{
TRISBbits.RB0 = 0; //Configuramos RB0 como salida
LATB0 = 0; //Empezamos con el led apagado
//CONFIGURAMOS TIMER1
INTCONbits.GIE = 0; //Desabilitamos todas las interrupciones
T1CONbits.RD16 = 1; //16 bit
T1CONbits.T1RUN = 0;
T1CONbits.T1CKPS1 = 0; //Seleccionamos
T1CONbits.T1CKPS0 = 0; //prescaler 1:1
T1CONbits.T1OSCEN = 0; // Timer 1 Osc Enable: 0 = off, 1 = on
T1CONbits.T1SYNC = 0;
T1CONbits.TMR1CS = 0; //Internal clock (Fosc/4)
TMR1H = 0x00;
TMR1L = 0x00;
PIR1bits.TMR1IF = 0; //Reset the interrupt flag
T1CONbits.TMR1ON = 1; //Enable Timer1
while(1)
{
if(PIR1bits.TMR1IF)
{
LATB0 =~ LATB0;
TMR1IF=0;
TMR1H = 0;
TMR1L=0;
}
}
}
prueba eso, eso te debe dar una señal cuadrada y si debe cargar la parte superior del registro.Citar¿El bit TMR1IE debe estar habilitado?
creo que no, ya que no recurres a ninguna interrupcion, por eso esta linera tampoco es necesaria:Código: [Seleccionar]INTCONbits.GIE = 0; //Desabilitamos todas las interrupciones
un saludo
EDITO cambia de posición las lineas de carga y encendido del timer como he puesto yo
Hola después de muchas pruebas con el timer consigo las temporizaciones según la formula del Timer1, pero sigo con fallos en la simulación con el IDE, por lo cual puedo asegurar que el MPLAB X IDE v3.10 me esta fallando mas que una escopeta de feria :5]
Miquel_S
Gracias KILLERJC voy a seguir probando y ya os contare, de momento necesito hacer una temporizacion de 5 seg para que se ejecute antes del inicio del programa.CitarHola después de muchas pruebas con el timer consigo las temporizaciones según la formula del Timer1, pero sigo con fallos en la simulación con el IDE, por lo cual puedo asegurar que el MPLAB X IDE v3.10 me esta fallando mas que una escopeta de feria :5]
Miquel_S
Hasta ahora el unico fallo que tuve con el MPLAB X es de que se me corrompiera un proyecto y no me compilara, pase el codigo entero a otro proyecto y funcionando. Fue el unico, en simulacion no tuve problemas, incluso cuando hice los codigos para los PIC18 y dsPIC
Y sigo liado, estoy intentando una temporización de 5 segundos y no consigo que me funcione la interrupción en RB0 y no veo el porque ¿Podéis ayudarme?Código: COtro favor, alguien puede simularlo que a mi no me corre como debería la simulación y no sabré que tiempo a transcurrido cuando pongo a nivel alto RB1.
#define _XTAL_FREQ 20000000 #include <xc.h> //#include "config.h" #include <delays.h> /* * */ // CONFIG1L #pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly)) #pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2]) #pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale) // CONFIG1H #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator (HS)) #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 = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled)) #pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting) #pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled) // CONFIG2H #pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit)) #pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768) // CONFIG3H #pragma config CCP2MX = ON // 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 Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation) #pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin 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 enabled) #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 bit (Block 0 (000800-001FFFh) is not code-protected) #pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected) #pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected) #pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected) // CONFIG5H #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected) #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected) // CONFIG6L #pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected) #pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected) #pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected) #pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected) // CONFIG6H #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected) #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected) #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected) // CONFIG7L #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks) #pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks) // CONFIG7H #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks) unsigned char i=0; //Variable usada en la temporizacion void main(void) { TRISBbits.RB0 = 1; //Configuramos RB0 como entrada TRISBbits.RB1 = 0; //Configuramos RB3 como salida LATB1 = 0; //Robot parado //Configuramos INT0 INTCONbits.INT0IE = 1; //Habilitamos interrupcion en RB0 INTCON2bits.INTEDG0 = 1; //Flanco ascendente INTCONbits.GIE = 1; //Habilitamos todas las interrupciones while(1){ //Iniciamos secuencia if(INTCONbits.INT0IF == 1){ //Temporizamos 5seg antes del inicio del robot for(i=0; i<=10; i++){ Delay10KTCYx(226); INTCONbits.INT0IF = 0; //Borramos flag de interrupcion en RB0 INTCONbits.INT0IE = 0; //Desabilitamos interrupcion en RB0 INTCONbits.GIE = 0; //Desabilitamos interrupciones LATB1 = 1; //Inicia escaneo } }else{ LATB1 = 0; //Robot parado } } }
Gracias y perdón por las molestias.
Hola Miguel, ¿exactamente que es lo que deseas hacer?Gracias Juan José por la intención y para nada me lo tomo a mal pero aunque sea con ayuda de ustedes tengo que intentar hacerlo yo mismo que si no no aprendo.
No me gusta ese delay y como esta quedando el código (no quiero Criticarte ni nada por el estilo, no te lo tomes a mal), si me dices que quieres hacer, puedo escribirte un codigo que haga lo que quieres.
Y ya lo modificas tu como quieras.
Te lo haría mañana, hoy ya no puedo, dime que micro estas usando, compilador, etc
Un saludo.
tengo que intentar hacerlo yo mismo que si no no aprendo
Gracias, tengo un compañero de mi hijo que se ha propuesto hacerse un minisumo y me pregunto si me gustaria echarle una mano con ello y eso es lo que intento, la temporización de 5 segundos es el tiempo de espera antes de que el robot empiece a moverse.Hola Miguel, ¿exactamente que es lo que deseas hacer?Gracias Juan José por la intención y para nada me lo tomo a mal pero aunque sea con ayuda de ustedes tengo que intentar hacerlo yo mismo que si no no aprendo.
No me gusta ese delay y como esta quedando el código (no quiero Criticarte ni nada por el estilo, no te lo tomes a mal), si me dices que quieres hacer, puedo escribirte un codigo que haga lo que quieres.
Y ya lo modificas tu como quieras.
Te lo haría mañana, hoy ya no puedo, dime que micro estas usando, compilador, etc
Un saludo.
Nuevamente gracias a todos.
Delay10KTCYx(226);Hola Juan José te dejo como funciona dicha instrucción, no entiendo que quieres decir con que Cuando pulsas, se hace la espera, y se pone LATA3 a 1, lo malo es que inmediatamente después se pondrá a 0 al salir del bucle while y el robot se parara tan pronto como empiece a moverse ¿No puede estar todo el código dentro de dicho bucle? con el código que he dejado en el post anterior y colocando un led en el lugar del motor una vez transcurrido el tiempo de espera dicho led se enciende y no vuelve a apagarse hasta que no quitas la alimentación al circuito.
Esta instrucción no la había visto nunca, pero supongo que tu la conoces y la has calculado bien, pero veo mas intuitiva delay_ms().
Gracias a los dos, a seguir estudiando y buscar la manera de hacerlo para que funcione correctamente, en un principio el arranque, pero si eso ya se me complica no quiero ni pensar el la estrategia del combate.
Saludos!
te recomiendo que pienses en tu sistema como una maquina de estados y no de una forma secuencial. Es como están pensados muchisimos programas, y por ejemplo si utilizas las harmony para generar el código, te crea automaticamente una maquina de estados.Estoy empezando a mirar lo de las maquinas de estado y se ve una cosa interesante, había oído sobre ellas pero nunca hacer uso de ellas, lo de las harmony podéis aconsejarme algún software para probar.
Hola estoy intentando lo de la maquina de estados finitos y no me termina de funcionar como debería, con este código:Código: Cme pasa que si antes de alimentar el circuito mantengo pulsado el switch de inicio y después lo alimento, hasta que no lo dejo de pulsar los motores permanecen parados, pero si doy corriente al circuito sin mantener el pulsador los motores se alimentan al momento como si entrara en el if pero sin contar los 5 segundos, y lo siento pero no veo el error.
#define _XTAL_FREQ 20000000 #include <xc.h> #include "config.h" #include <delays.h> #define pulsador_ini PORTAbits.RA2 //pulsador_ini conectado en RA2 #define motor_izq PORTAbits.RA3 //motor izquierdo conectado en RA3 #define motor_dcho PORTAbits.RA4 //motor derecho conectado en RA4 /* ENUMERAMOS LOS TIPOS DE ESTADOS */ enum eEstados{ Detenido }estado; /* FUNCION PRINCIPAL */ void main(void) { unsigned char i=0; //Variable usada en la temporizacion de 5 segundos /* CONFIGURACION DE PINES */ ADCON1bits.PCFG3 = 1; //Configuramos ADCON1bits.PCFG2 = 1; //RA0:RA1 analogicos ADCON1bits.PCFG1 = 0; //el resto de pines ADCON1bits.PCFG0 = 1; //digitales TRISAbits.RA2 = 1; //Configuramos RA2 como entrada TRISAbits.RA3 = 0; //Configuramos RA3 como salida TRISAbits.RA4 = 0; //Configuramos RA4 como salida estado = Detenido; //Empezamos con el robot parado while(1) { switch(estado) { case Detenido: if(pulsador_ini) { for(i=0; i<=10; i++) { Delay10KTCYx(226); } motor_izq = 1; motor_dcho = 1; }else{ motor_izq = 0; motor_dcho = 0; } break; default: Detenido; break; } } }
Gracias.
#define _XTAL_FREQ 20000000
#include <xc.h>
#include "config.h"
#include <delays.h>
#define pulsador_ini PORTAbits.RA2 //pulsador_ini conectado en RA2
#define motor_izq LATAbits.LA3 //motor izquierdo conectado en RA3
#define motor_dcho LATAbits.LA4 //motor derecho conectado en RA4
/* DECLARACION DE FUNCIONES */
void pausa_5seg(void);
/* ENUMERAMOS LOS TIPOS DE ESTADOS */
enum eEstados{
Detenido,Inicio,Espera
}estado;
/* FUNCION PRINCIPAL */
void main(void)
{
/* CONFIGURACION DE PINES */
estado = Detenido; //Empezamos con el robot parado
ADCON1bits.PCFG3 = 1; //Configuramos
ADCON1bits.PCFG2 = 1; //RA0:RA1 analogicos
ADCON1bits.PCFG1 = 0; //el resto de pines
ADCON1bits.PCFG0 = 1; //digitales
TRISAbits.RA2 = 1; //Configuramos RA2 como entrada
TRISAbits.RA3 = 0; //Configuramos RA3 como salida
TRISAbits.RA4 = 0; //Configuramos RA4 como salida
while(1)
{
switch(estado)
{
case Detenido:
{
motor_izq = 0;
motor_dcho = 0;
if(pulsador_ini == 1)
{
estado = Espera;
}
}
break;
case Espera:
{
pausa_5seg();
estado=Inicio;
}
break;
case Inicio:
{
motor_izq = 1;
motor_dcho = 1;
}
break;
}
}
}
void pausa_5seg(void){
unsigned char i = 0;
for(i=0; i<=10; i++){
Delay10KTCYx(226);
}
}Gracias Juan José me has abierto los ojos, ahora tengo mas claro como implementar la maquina de estados. Perdón una pregunta ¿Si usamos la instrucción switch debemos seguir el mismo orden que seguiríamos en el diagrama de la maquina de estados, o sea un estado detrás de otro?
Volví !!! Totalmente alejado del XC8 retome un poco el tema. Estuve leyendo y googleando y estoy medio perdido con el tema de librerías. De forma oficial Microchip lanzo algún paquete con LCD, I2C, SPI, 1-Wire, Modbus, USB????
Por el momento estoy jugando con un RTC DS1307 y un sensor DS18B20, y no encuentro mucha información. Estoy buscando mal, o hay que laburar para implementar estos dispositivos?
Saludos y buen año!!!
De forma oficial Microchip lanzo algún paquete con LCD, I2C, SPI, 1-Wire, Modbus, USB????
Buenas, soy un novato en esto y necesito su ayuda en una práctica simulada en proteus. tengo que hacer que el pic me genere una frecuencia de 25KHz como salida en un pin. Tengo que usar un pic16f887.
Me he informado en paginas web y veo que es un largo proceso y no manejo muy bien lo de los registros del pic y esas cosas. el pic que tengo.
Alguien podria ayudarme?
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <pic16f88.h>
#pragma config FOSC = HS // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
void main ()
{
while (1)
{
TRISB &= ~(1 << 3); /*limpiar bit RB3/CCP1 en TRISB, hacer PORTB3/CCP1 como salida*/
CCP1CON = 0x2C; /*activar PWM */
PR2 = 0x7C; /*124 (DECIMAL)*/
T2CON = 0X06; /*prescale 16 */
CCPR1L = 0X3E;
}
}Empecemos primero por la forma del programa, Voy a escribir masomenos como estan formados todos los main.c:Código: C
// Aca los #include // Aca los FUSES // Prototipos de funciones y variables void main(void) { // Aca la configuracion de cada modulo que se vaya a usar while(1) // Loop infinito, el unico loop infinito que hay en todo el programa. { //Aca el programa en cuestion } } // Otras funciones si es que es el caso
Ahora vamos adentro de la funcion main y veamos como quedaria el codigo:
El CCP del PIC16F88 utiliza el timer 2, si observas al final de la parte de PWM ahi estan TODOS los regsotrs y bits que estan involucrados con el PWM, algunos registros solo tiene 1 bit como es PIE1 por ejemplo que corresponde al PWM. Voy a usar valores obtenidos de una calculadora online. Igual lo explico en el comentario, si tenes alguna duda podes ver el diagrama del PWM, observa que solo basta configurar el PWM y darle arranque al TMR2, luego de ahi no tenes que hacer mas nada.Código: C
void main(void) { //Aca configuracion de modulos // Puertos TRISB = 0; // Todas salidas por ahora nomas, la salida PWM puede estar en RB0 o RB3 segun el fuse que se elija. PORTB = 0; // Apagamos todos // CCP CCP1CON = 0x1C; // En PWM, y los ultimos 2 bits ( de los 10 del duty ) es 01 PR2 = 0x7C; // Periodo va estar dado por PR2, y como este el timer2 configurado, 0x7C = 124, pero se crea virtualmente 2 bits mas, resultado periodo igual a 496 T2CON = 0x07; // T2CON, postscaler = 1, prescaler = 16, TMR2 ON. Periodo : (PR2+1)*4*Tosc*(Prescaler) = (124+1)*4*Tosc*16 = 8000 * 0.250us = 2ms CCPR1L = 0x3E; // Valor real de duty que con los 2 bits del CCP1CON es 0xF9 = 249, virtualmente el PWM hace llegar al timer hasta 496, un duty de 50% 496 * 0.5 = 248 while(1) { } }
2 cosas mas, usa FOSC = XT para 4Mhz o menos y HS para cuando tenes mas de 4Mhz, y... no hace falta que agregues tantos includes, con el de xc.h se agrega el del pic16f88 por si solo. es decir solo necesitas este include:Código: C
#include <xc.h>
Aunque a veces da problemas igual..
Y el MPLAB X tiene una forma facil de generar codigo para crearte los fuses
#include <xc.h>
#define _XTAL_FREQ 10000
#pragma config WDTE = OFF
#pragma config FOSC = XT
#pragma config CCPMX = RB0
void prender ()
{
PORTBbits.RB1 = 1;
}
void main()
{
TRISB = 0b00000001;
PORTB = 0b00000001;
while (PORTBbits.RB0 == 1)
{
prender();
}
}
main.cCódigo: C
#include <xc.h> #include "prender.h" #pragma config WDTE = OFF #pragma config FOSC = XT #pragma config CCPMX = RB0 void main() { TRISB = 0b00000001; PORTB = 0b00000001; while (PORTBbits.RB0 == 1) { Luz(); } }
prender.hCódigo: C
#ifndef PRENDER_H #define PRENDER_H void luz(void); #endif // PRENDER_H
prender.cCódigo: C
#include <xc.h> #include "prender.h" void Luz(void) { PORTBbits.RB1 = 1; }
Primero que nada no poner codigo en los .h, aunque se puede hacer.
Pusiste la parte del .h dentro de la seccion para C++, cosa que no se usa en XC8, podras observar que yo no lo puse en mi .h. Si sacaras tu codigo afuera funcionaria, pero violaria lo de antes.
Otra cosa mas, es que inclui en el prender.c a xc.h nuevamente, para poder usar el "PORTBbits"
user.h
void LCDWrite(unsigned char data_or_command, unsigned char data);
void gotoXY(int x, int y);
void LCDBitmap(char my_array[]);
void LCDCharacter(char character);
void LCDString(char *characters);
void LCDClear(void);
void LCDInit(void) ;
void LCDNumero(long num );
const unsigned char ramiro[];
void InitApp(void); /* I/O and Peripheral Initialization */
user.c
/*
* File: user.c
* Author: Ramiro
*
* Created on 20 de junio de 2016, 9:44
*/
/******************************************************************************/
/* Files to Include */
/******************************************************************************/
#if defined(__XC)
#include <xc.h> /* XC8 General Include File */
#elif defined(HI_TECH_C)
#include <htc.h> /* HiTech General Include File */
#endif
#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h>
#include <pic16f628a.h> /* For true/false definition */
#include "user.h"
/******************************************************************************/
/* User Functions */
/******************************************************************************/
#define LCD_CLK PORTBbits.RB5
#define LCD_DIN PORTBbits.RB4
#define LCD_DC PORTBbits.RB3
#define LCD_CE PORTBbits.RB2
#define LCD_RST PORTBbits.RB7
//The DC pin tells the LCD if we are sending a command or data
#define LCD_COMMAND 0
#define LCD_DATA 1
//You may find a different size screen, but this one is 84 by 48 pixels
#define LCD_X 84
#define LCD_Y 48
//------------------------------------------------------------------------------
// File generated by LCD Assistant
// http://en.radzio.dxp.pl/bitmap_converter/
//------------------------------------------------------------------------------
const unsigned char ramiro[] = {
0x80, 0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0x7C, 0x7E, 0x3E, 0x3E, 0x3E, 0x1F, 0x1F, 0x1F, 0x1F, 0x9F,
0x9F, 0x9F, 0x1F, 0x1F, 0x9F, 0x9F, 0x9F, 0x1F, 0x1F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x1F,
0x1F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x1F, 0x1F, 0x1F, 0x9F, 0x9F, 0x1F, 0x1F, 0x9F, 0x9F,
0x9F, 0x9F, 0x9F, 0x9F, 0x1F, 0x1F, 0x1F, 0x1F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x1F, 0x1F, 0x1F,
0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x1F, 0x1F, 0x1F, 0x3E, 0x3E, 0x3E, 0x7E, 0x7C, 0xFC, 0xF8,
0xF8, 0xF0, 0xE0, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x7F, 0x0F, 0x7C, 0x7C, 0x0F, 0x7F, 0x7F, 0x00, 0x00, 0x7F, 0x7F, 0x6D,
0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x7F, 0x3F, 0x00, 0x00, 0x7F, 0x7F,
0x00, 0x00, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x7F, 0x3F, 0x00, 0x00, 0x3F, 0x7F, 0x61, 0x61, 0x61,
0x7F, 0x3F, 0x00, 0x00, 0x7F, 0x7F, 0x0D, 0x0D, 0x3D, 0x7F, 0x67, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18,
0xF8, 0xF0, 0x00, 0x00, 0xF8, 0xF8, 0xD8, 0xD8, 0xD8, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0xF0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFE, 0xFC, 0xF8,
0xF8, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x87, 0x8F, 0x8F, 0x8F, 0x0F, 0x0F, 0x0F, 0x8F,
0x8F, 0x07, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x87,
0x87, 0x86, 0x06, 0x06, 0x07, 0x83, 0x80, 0x80, 0x07, 0x07, 0x06, 0x06, 0x86, 0x86, 0x00, 0x00,
0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x07, 0x0F, 0x0F, 0x8F, 0x8F,
0x0F, 0x0F, 0x0F, 0x0F, 0x87, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x61, 0x61, 0x61, 0x7F,
0x3F, 0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x67, 0x67, 0x6D, 0x6D, 0x7D, 0x39, 0x10, 0x01, 0x01,
0x01, 0x7F, 0x7F, 0x01, 0x01, 0x01, 0x40, 0x78, 0x7E, 0x37, 0x33, 0x3F, 0x7E, 0x78, 0x40, 0x00,
0x7F, 0x7F, 0x07, 0x1E, 0x38, 0x7F, 0x7F, 0x00, 0x00, 0x3F, 0x7F, 0x61, 0x61, 0x61, 0x73, 0x33,
0x00, 0x00, 0x7F, 0x7F, 0x00, 0x40, 0x78, 0x7E, 0x37, 0x33, 0x3F, 0x7E, 0x78, 0x40, 0x00, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x3F, 0x3E, 0x7E, 0x7C, 0x7C, 0x7C,
0x7C, 0x7C, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7E,
0x3E, 0x3F, 0x3F, 0x1F, 0x0F, 0x0F, 0x07, 0x01,
};
/* <Initialize variables in user.h and insert code for user algorithms.> */
const unsigned char ASCII[][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 ?
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ?
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d ?
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c "\"
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f DEL
};
void setup(void) {
LCDInit(); //Init the LCD
}
void loop(void) {
LCDClear();
// LCDBitmap(SFEFlame);
// delay(1000);
// LCDClear();
// LCDBitmap(SFEFlameBubble);
/// delay(1000);
// LCDClear();
// LCDBitmap(awesome);
// delay(1000);
//LCDClear();
LCDString("Hello World!");
// delay(1000);
}
void gotoXY(int x, int y) {
LCDWrite(0, 0x80 | x); // Column.
LCDWrite(0, 0x40 | y); // Row. ?
}
//This takes a large array of bits and sends them to the LCD
void LCDBitmap(char my_array[]){
for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++)
LCDWrite(LCD_DATA, my_array[index]);
}
//This function takes in a character, looks it up in the font table/array
//And writes it to the screen
//Each character is 8 bits tall and 5 bits wide. We pad one blank column of
//pixels on each side of the character for readability.
void LCDCharacter(char character) {
LCDWrite(LCD_DATA, 0x00); //Blank vertical line padding
for (int index = 0 ; index < 5 ; index++)
LCDWrite(LCD_DATA, ASCII[character - 0x20][index]);
//0x20 is the ASCII character for Space (' '). The font table starts with this character
LCDWrite(LCD_DATA, 0x00); //Blank vertical line padding
}
//Given a string of characters, one by one is passed to the LCD
void LCDString(char *characters) {
while (*characters)
{
LCDCharacter(*characters);
*characters++;
}
}
//Clears the LCD by writing zeros to the entire screen
void LCDClear(void) {
for (int index = 0 ; index < (LCD_X * LCD_Y / 8) ; index++)
LCDWrite(LCD_DATA, 0x00);
gotoXY(0, 0); //After we clear the display, return to the home position
}
//This sends the magical commands to the PCD8544
void LCDInit(void) {
//Configure control pins
TRISBbits.TRISB3=0;
TRISBbits.TRISB4=0;
TRISBbits.TRISB5=0;
TRISBbits.TRISB6=0;
TRISBbits.TRISB7=0;
LCD_DIN=0;
LCD_CLK=0;
LCD_DC=0;
// pinMode(PIN_SCE, OUTPUT);
// pinMode(PIN_RESET, OUTPUT);
// pinMode(PIN_DC, OUTPUT);
// pinMode(PIN_SDIN, OUTPUT);
// pinMode(PIN_SCLK, OUTPUT);
//Reset the LCD to a known state
// digitalWrite(PIN_RESET, LOW);
LCD_RST=0;
// digitalWrite(PIN_RESET, HIGH);
LCD_RST=1;
LCDWrite(LCD_COMMAND, 0x21); //Tell LCD that extended commands follow
LCDWrite(LCD_COMMAND, 0xBB); //Set LCD Vop (Contrast): Try 0xB1(good @ 3.3V) or 0xBF if your display is too dark
LCDWrite(LCD_COMMAND, 0x04); //Set Temp coefficent
LCDWrite(LCD_COMMAND, 0x14); //LCD bias mode 1:48: Try 0x13 or 0x14
LCDWrite(LCD_COMMAND, 0x20); //We must send 0x20 before modifying the display control mode
LCDWrite(LCD_COMMAND, 0x0C); //Set display control, normal mode. 0x0D for inverse
}
//There are two memory banks in the LCD, data/RAM and commands. This
//function sets the DC pin high or low depending, and then sends
//the data byte
void LCDWrite(unsigned char data_or_command, unsigned char data) {
unsigned char i,d;
d=data;
if(data_or_command==0)LCD_DC=0;
else LCD_DC=1;
//data_or_command; //Tell the LCD that we are writing either to data or a command
//Send the data
LCD_CE=0;
// digitalWrite(PIN_SCE, LOW);
for(i=0;i<8;i++)
{
LCD_DIN=0;
if(d&0x80)LCD_DIN=1;
LCD_CLK=1;
d<<=1;
LCD_CLK=0;
}
// shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
LCD_CE=1;
// digitalWrite(PIN_SCE, HIGH);
}
void InitApp(void)
{
/* TODO Initialize User Ports/Peripherals/Project here */
/* Setup analog functionality and port direction */
/* Initialize peripherals */
// OPTION_REG=0x80;
/* Enable interrupts */
TMR0IE=1;
GIE=1;
}
system.h
/******************************************************************************/
/* System Level #define Macros */
/******************************************************************************/
/* TODO Define system operating frequency */
/* Microcontroller MIPs (FCY) */
#define SYS_FREQ 400000L
#define FCY SYS_FREQ/4
extern unsigned char spk_bit;
extern unsigned char led_bit;
extern unsigned char spk_enable,spk_enable2;
extern unsigned int led_counter;
/******************************************************************************/
/* System Function Prototypes */
/******************************************************************************/
/* Custom oscillator configuration funtions, reset source evaluation
functions, and other non-peripheral microcontroller initialization functions
go here. */
void ConfigureOscillator(void); /* Handles clock switching/osc initialization */
system.c
/*
* File: System.c
* Author: Ramiro
*
* Created on 20 de junio de 2016, 9:42
*/
/******************************************************************************/
/*Files to Include */
/******************************************************************************/
#if defined(__XC)
#include <xc.h> /* XC8 General Include File */
#elif defined(HI_TECH_C)
#include <htc.h> /* HiTech General Include File */
#endif
#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h> /* For true/false definition */
#include "system.h"
/* Refer to the device datasheet for information about available
oscillator configurations. */
void ConfigureOscillator(void)
{
/* TODO Add clock switching code if appropriate. */
/* Typical actions in this function are to tweak the oscillator tuning
register, select new clock sources, and to wait until new clock sources
are stable before resuming execution of the main project. */
}
main.c
#define _XTAL_FREQ 4000000
#include <xc.h>
#include <pic16f628a.h>
#include <stdio.h>
#include <stdlib.h>
#include "confbits.h"
#include <stdint.h> /* For uint8_t definition */
#include <stdbool.h> /* For true/false definition */
#include "user.h"
#include "system.h" /* System funct/params, like osc/peripheral config */
/* User funct/params, such as InitApp */
#define triger PORTBbits.RB0
#define echo PORTBbits.RB1
/******************************************************************************/
/* User Global Variable Declaration */
/******************************************************************************/
unsigned char led_bit,spk_bit,spk_enable,spk_enable2;
unsigned int led_counter,a;
char salida[20] ;
/* i.e. uint8_t <variable_name>; */
/******************************************************************************/
/* Main Program */
/******************************************************************************/
/************************/
void main(void)
{
// **********************inicializo el micro
// ******************** inicializacion cpu ***************************
PCONbits.OSCF;// reloj en 4 mhz
CMCON = 0X07 ; //apaga los comparadores y habilita los pines de I/O
TRISA = 0x00;
PORTA = 0X00;
TRISB = 0x00;
TRISBbits.TRISB1 = 1;
/* Configure the oscillator for the device */
ConfigureOscillator();
/* Initialize I/O and Peripherals for application */
InitApp();
led_counter=0;
spk_bit=0;
led_bit=0;
LCDInit();
LCDClear();
gotoXY(0,0);
LCDBitmap(ramiro);
__delay_ms(5000);
LCDClear();
while(1)
{
T1CONbits.TMR1CS = 0;
TMR1H = 0; //Sets the Initial Value of Timer
TMR1L = 0; //Sets the Initial Value of Timer
triger = 1; // disparo el triger del distanciometro
__delay_us(10); // espero 10 us
triger = 0; // apago el triger
while(!echo); //Waiting for Echo
T1CONbits.TMR1ON = 1; //Timer Starts
while(echo); //Waiting for Echo goes LOW
T1CONbits.TMR1ON = 0; //Timer Stops
a = (TMR1L | (TMR1H<<8)); //Reads Timer Value
a = a/58.82; //Converts Time to Distance
//Distance Calibration
itoa(salida,a,10);
if(a>=2 && a<=400) //Check whether the result is valid or not
{
LCDClear();
gotoXY(15,2);
LCDString("DISTANCIA");
gotoXY(25,4);
LCDString(salida);
LCDString(" cm");
}
else
{
LCDClear;
gotoXY(0,5);
LCDString("out of range");
}
__delay_ms(300);
// if(spk_bit==1)
// {
// if((spk_enable==1)&&(spk_enable2==1))
// TRISBbits.TRISB6=1;
// } else TRISBbits.TRISB6=0;
}
}
#include <xc.h>
#pragma config WDTE = OFF
#pragma config FOSC = XT
#pragma config CCPMX = RB0
void main()
{
TRISA = 0b00000111;
PORTA = 0b00000111;
TRISB = 0b00000000;
PORTB = 0b00000000;
ANSEL = 0b00000000;
while(1)
{
if (PORTAbits.RA0==1)
{
PORTBbits.RB0=1;
}
else if (PORTAbits.RA1==1)
{
PORTBbits.RB1=1;
}
else if (PORTAbits.RA2==1)
{
PORTBbits.RB2=1;
}
else
{
PORTB = 0b00000000;
}
}
}#include <xc.h>
#pragma config CCPMX = RB0
#pragma config WDTE = OFF
void main (void)
{
TRISA = 0b00000111;
PORTA = 0b00000111;
TRISB = 0b00000000;
PORTB = 0b00000000;
ANSEL = 0b00000000;
unsigned char input ;
while(1)
{
switch (input)
{
case :
}
}
}
int a;
switch(input) {
case a: /* oops!
cannot use variable as part of a case label */
input++;
}Hola gente, necesito las librerias perifericas de XC8. Las encontre en un archivo instalador de windows, pero yo utilizo Minux y no me deja extraerlas de ahi.
¿Alguien las tiene o sabe de donde descargarlas en un formato compatible Linux?.
Saludos.
Realmente en 8 bits nunca me maneje con una libreria, creo ni siquiera dan el codigo, distinto a XC16 en adelante que si te dan el codigo de los perifericos y ademas deberias tener un PDF.
Por que la mayoria de los modulos son 2/3 registros como maximo.
PD: Yo uso el MPLAB en Linux
Hola gente, necesito las librerias perifericas de XC8. Las encontre en un archivo instalador de windows, pero yo utilizo Minux y no me deja extraerlas de ahi.
¿Alguien las tiene o sabe de donde descargarlas en un formato compatible Linux?.
Saludos.
Hola AcoranTf, ¿A qué te refieres, a las de ADC, por ejemplo?
De ser así, las hay. Pero creo que sólo para las familias 18xxxxx
En Debian Jessie las tengo en "/opt/microchip/xc8/v1.33/sources/pic18/plib"
Asi como dice AngelGris, es justamente para PIC18, pero no se si estan todas las funciones a simple vista
.../Microchip/xc8/v1.xx/docs/MPLAB_XC8_Peripheral_Libraries.pdf
.../Microchip/xc8/v1.xx/include/plib/...
.../Microchip/xc8/v1.xx/sources/pic18/plib/...
De todas formas creo mas facil usar el datasheet del micro, y al final de cada modulo te aparece que registros son los necesarios. Incluso te sule poner un paso a paso sobre como configurar el modulo.
En las librerias vas a ver muchas mas cosas de las que necesitas, si es que realmente queres aprenderlo.
Yo también instalé la versión gratis. Ahora no estoy en casa, pero recuerdo que hay una carpeta por periférico. Me vienen a la mente, ADC, I2C, SPI, UART, CCPM, I2C por software.... a la noche me fijo en case y te paso el listado de las carpetas.
Yo también instalé la versión gratis. Ahora no estoy en casa, pero recuerdo que hay una carpeta por periférico. Me vienen a la mente, ADC, I2C, SPI, UART, CCPM, I2C por software.... a la noche me fijo en case y te paso el listado de las carpetas.
OK, eso no esta en mi instalacion, no se si lo habran cambiado. Voy a preparar una cuenta de FTP en mi servidor y te pasare los datos para que me envies todas esas carpetas comprimidas, si te parece bien.
Saludos.
Dale, no hay ningún problema
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* File: LCD 16x2 y LCD 20x4
* Author: Sebas
* Comments: Gama de pic 16f8XX
* Revision history: 1.0a
* Descripcion: LCD HD44780 o equivalente
* -Lcd_int();//Inicializacion del LCD
* -Lcd_printf();//Funcion para imprimir lo que queremos ver en el LCD
* -Lcd_clear();//Funcion para limpiar pantalla
* -Lcd_printf_String();//Funcion para imprimir un string
* -Lcd_gotoxy();//Funcion de la posicion de posicion en el LCD
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef LCD20x4
#define LCD20x4
#define PIN_RS PORTBbits.RB0
#define TRISBRS TRISBbits.TRISB0
#define PIN_EN PORTBbits.RB1
#define TRISBEN TRISBbits.TRISB1
#define LCD_D4 PORTBbits.RB4
#define LCD_D4_T TRISBbits.TRISB4
#define LCD_D5 PORTBbits.RB5
#define LCD_D5_T TRISBbits.TRISB5
#define LCD_D6 PORTBbits.RB6
#define LCD_D6_T TRISBbits.TRISB6
#define LCD_D7 PORTBbits.RB7
#define LCD_D7_T TRISBbits.TRISB7
/*Declaracion de funciones*/
void Lcd_int();
void Lcd_control_cmd(char);
void Lcd_port(char);
void Lcd_write_data_port(char);
void Lcd_printf(char*);
void Lcd_clear();
void Lcd_printf_String(char*);
void Lcd_gotoxy(char , char);
/*Funciones*/
void Lcd_int() //configuracion para inicializar el LCD
{
PIN_RS = 0;
PIN_EN = 0;
TRISBRS = 0;
TRISBEN = 0;
LCD_D4 = 0;
LCD_D4_T = 0;
LCD_D5 = 0;
LCD_D5_T = 0;
LCD_D6 = 0;
LCD_D6_T = 0;
LCD_D7 = 0;
LCD_D7_T = 0;
Lcd_port(0x00);
__delay_ms(20);
Lcd_control_cmd(0x03);
__delay_ms(5);
Lcd_control_cmd(0x03);
__delay_ms(11);
Lcd_control_cmd(0x03);
Lcd_control_cmd(0x02);
Lcd_control_cmd(0x02);
Lcd_control_cmd(0x08);
Lcd_control_cmd(0x00);
Lcd_control_cmd(0x0C);
Lcd_control_cmd(0x00);
Lcd_control_cmd(0x06);
}
void Lcd_control_cmd(char data) //pines de control para LCD
{
PIN_RS = 0;
Lcd_port(data);
PIN_EN = 1;
__delay_ms(4);
PIN_EN = 0;
}
void Lcd_port(char data) //
{
if(data & 1)
{
LCD_D4 = 1;
}
else
{
LCD_D4 = 0;
}
if(data & 2)
{
LCD_D5 = 1;
}
else
{
LCD_D5 = 0;
}
if(data & 4)
{
LCD_D6 = 1;
}
else
{
LCD_D6 = 0;
}
if(data & 8)
{
LCD_D7 = 1;
}
else
{
LCD_D7 = 0;
}
}
void Lcd_write_data_port(char data)//Modo de 4 bits LCD
{
char var;
char y;
var = (data & 0x0F);
y = (data & 0xF0);
PIN_RS = 1;
Lcd_port(y>>4);
PIN_EN = 1;
__delay_us(40);
PIN_EN = 0;
Lcd_port(var);
PIN_EN = 1;
__delay_us(40);
PIN_EN = 0;
}
void Lcd_printf(char *data)//Funcion para imprimir lo que queremos ver en el LCD
{
while (*data) // Mientras no sea Null
{
Lcd_write_data_port(*data); // Envio el dato al LCD
data++; // Incrementa el buffer de dato
}
}
void Lcd_gotoxy(char x, char y)//Funcion de la posicion de posicion en el LCD
{
char temp;
char dato1;
char dato2;
if(y == 1)
{
temp = 0x80 + x - 1;
dato1 = temp >> 4;
dato2 = temp & 0x0F;
Lcd_control_cmd(dato1);
Lcd_control_cmd(dato2);
}
if(y == 2)
{
temp = 0xC0 + x - 1;
dato1 = temp >> 4;
dato2 = temp & 0x0F;
Lcd_control_cmd(dato1);
Lcd_control_cmd(dato2);
}
if(y == 3)
{
temp = 0x94 + x - 1;
dato1 = temp >> 4;
dato2 = temp & 0x0F;
Lcd_control_cmd(dato1);
Lcd_control_cmd(dato2);
}
if(y == 4)
{
temp = 0xD4 + x - 1;
dato1 = temp >> 4;
dato2 = temp & 0x0F;
Lcd_control_cmd(dato1);
Lcd_control_cmd(dato2);
}
}
void Lcd_clear()//Funcion para limpiar pantalla
{
Lcd_control_cmd(0);
Lcd_control_cmd(1);
}
void Lcd_printf_String(char *data)//Funcion imprime string
{
int i;
for(i=0;data[i]!='\0';i++)
Lcd_write_data_port(data[i]);
}
/*
* Guardar caracteres especiales. en la CGRAM
*/
void lcd_put_caracter(char adress, char caracter[]) {
int i;
Lcd_control_cmd(0x40 + (adress * 8));
for (i = 0; i < 8; i++) {
Lcd_write_data_port(caracter[i]);
}
}
void Lcd_Shift_Right()
{
Lcd_control_cmd(0);
Lcd_control_cmd(1);
Lcd_control_cmd(0x0C);
}
void Lcd_Shift_Left()
{
Lcd_control_cmd(0);
Lcd_control_cmd(1);
Lcd_control_cmd(0x08);
}
#endif
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* File: ADC *
* Author: Sebas *
* Comments: Gama de pic 16f8XX *
* Revision history: 1.0a *
* Descripcion: ADC de resolucion 10bits *
* -ADC_Setup();//Elegir E/analagicas y REF interna o externar *
* -ADC_Selec_Fosc();//Seleccion de reloj *
* -ADC_Result_Format_Select();//Justificacion del formato *
* -ADC_ON_OFF();//Activa o desactiva el ADC *
* -ADC_READ();//Obtiene y calcula el valor del ADC y canal *
* Esta descripta las opciones para elegir en los *
* #define AN_All_VDD_VSS (ejmplo) *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef ADC_H
#define ADC_H
#define AN_All_VDD_VSS 1
#define AN_ALL_VREFPOS_VSS 2
#define AN4_AN3_AN2_AN1_AN0_VDD_VSS 3
#define AN4_AN3_AN2_AN1_AN0_VREFPOS_VSS 4
#define AN3_AN1_AN0_VDD_VSS 5
#define AN1_AN0_VRESFPOS_VSS 6
#define ALL_SHUT_DOWN_AN 7
#define AN_ALL_VREFPOS_VREFNEG 8
#define AN5_AN4_AN3_AN2_AN1_AN0_VDD_VSS 9
#define AN5_AN4_AN2_AN1_AN0_VREFPOS_VSS 10
#define AN5_AN4_VREFPOS_VREFNEG_AN1_AN0 11
#define AN4_VREFPOS_VRESNEG_AN1_AN0 12
#define VREFPOS_VREFNEG_AN1_AN0 13
#define AN0_VDD_VSS 14
#define AN0_VRREFPOS_VREFNEG 15
#define FOSC2 1
#define FOSC8 2
#define FOSC32 3
#define FRC 4
#define FOSC4 5
#define FOSC16 6
#define FOSC64 7
#define FRC2 8
#define RIGHT 1
#define LETF 0
#define ON 1
#define OFF 2
/*Declaracion de funciones*/
void ADC_Setup(char);
unsigned int ADC_READ(unsigned char);
void ADC_Selec_Fosc(char);
void ADC_Result_Format_Select(char);
void ADC_ON_OFF(char);
void ADC_Setup(char set)
{
if(set == 1)//Referencia Ref+:Vdd y Ref-:Vss
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 0;
}
if(set == 2)//Referencia Ref+:Vdd y Ref-:Vss
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 1;
}
if(set == 3)//Analogicos de AN4 a AN0 con VDD y VSS referencia interna
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG2 = 0;
}
if(set == 4)//Analogicos de AN4 a AN0 con Ref externa +(AN3) y VSS referencia interna
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG3 = 1;
}
if(set == 5)//Analogicos de AN3, AN1 y AN0 con ref interna VDD y VSS
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 0;
}
if(set == 6)//Analogicos de AN1 y AN0 con Ref externa +(AN3) y VSS referencia interna
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 1;
}
if(set == 7)//Apaga todas las entradas analogicas
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG3 = 0;
}
if(set == 8)//Todas analogias pero AN3 es ref positivo y AN2 ref negativa
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 0;
}
if(set == 9)//AN5 a AN0 con referencia VDD y VSS
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 1;
}
if(set == 10)//AN5, AN4, AN2, AN1 y AN0 Ref positovo en AN3 y VSS
{
ADCON1bits.PCFG0 = 0;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 1;
}
if(set == 11)//AN5, AN4, AN1 y AN0 Ref positovo en AN3 y AN2 Ref negativo
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 0;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG3 = 1;
}
if(set == 12)//AAN4, AN1 y AN0 Ref positovo en AN3 y AN2 Ref negativo
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 0;
}
if(set == 13)//AN1 y AN0, Ref positovo en AN3 y AN2 Ref negativo
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 0;
ADCON1bits.PCFG3 = 1;
}
if(set == 14)//AN0, Referencia VDD y VSS
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG3 = 0;
}
if(set == 15)//AN0, Ref positovo en AN3 y AN2 Ref negativo
{
ADCON1bits.PCFG0 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG3 = 1;
}
}
void ADC_Selec_Fosc(char set2)
{
if (set2 == 1)
{
ADCON1bits.ADCS2 = 0;
ADCON0bits.ADCS1 = 0;
ADCON0bits.ADCS0 = 0;
}
if (set2 == 2)
{
ADCON1bits.ADCS2 = 0;
ADCON0bits.ADCS1 = 0;
ADCON0bits.ADCS0 = 1;
}
if (set2 == 3)
{
ADCON1bits.ADCS2 = 0;
ADCON0bits.ADCS1 = 1;
ADCON0bits.ADCS0 = 0;
}
if (set2 == 4)
{
ADCON1bits.ADCS2 = 0;
ADCON0bits.ADCS1 = 1;
ADCON0bits.ADCS0 = 1;
}
if (set2 == 5)
{
ADCON1bits.ADCS2 = 1;
ADCON0bits.ADCS1 = 0;
ADCON0bits.ADCS0 = 0;
}
if (set2 == 6)
{
ADCON1bits.ADCS2 = 1;
ADCON0bits.ADCS1 = 0;
ADCON0bits.ADCS0 = 1;
}
if (set2 == 7)
{
ADCON1bits.ADCS2 = 1;
ADCON0bits.ADCS1 = 1;
ADCON0bits.ADCS0 = 0;
}
if (set2 == 8)
{
ADCON1bits.ADCS2 = 1;
ADCON0bits.ADCS1 = 1;
ADCON0bits.ADCS0 = 1;
}
}
void ADC_Result_Format_Select(char set3)
{
if (set3 == 0) //justificado a la izquierda
{
ADCON1bits.ADFM = 0;
}
if(set3 == 1)//justifiacado a la derecha
{
ADCON1bits.ADFM = 1;
}
}
void ADC_ON_OFF(char set4)// //Activamos el ADC
{
if(set4 == 1)
{
ADCON0bits.ADON = 1;
}
if (set4 == 2)
{
ADCON0bits.ADON = 0;
}
}
unsigned int ADC_READ(unsigned char ch)
{
if(ch == 0)
{
ADCON0bits.CHS = 0;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 1)
{
ADCON0bits.CHS = 1;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 2)
{
ADCON0bits.CHS = 2;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 3)
{
ADCON0bits.CHS = 3;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 4)
{
ADCON0bits.CHS = 4;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 5)
{
ADCON0bits.CHS = 5;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 6)
{
ADCON0bits.CHS = 6;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
if(ch == 7)
{
ADCON0bits.CHS = 7;
__delay_us(30);
ADCON0bits.GO_nDONE = 1;
while(ADCON0bits.GO_nDONE);
return ((ADRESH<<8)+ADRESL);
}
}
#endif
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define _XTAL_FREQ 4000000
#include"lcd4x20.h"
#include"ADC.h"
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
void main(void)
{
int adc,adc2;
float a,b;
char s[20];
char s2[20];
TRISA=0b0000011;
//Inicializacion de ADC
ADC_Setup(AN_ALL_VREFPOS_VSS);
ADC_Selec_Fosc(FOSC2);
ADC_Result_Format_Select(RIGHT);
ADC_ON_OFF(ON);
//Incializacion del LCD
Lcd_int();
Lcd_clear();
while(1)
{
adc= ADC_READ0();
sprintf(s,"ADC:%04d",adc);
Lcd_gotoxy(1,1);
Lcd_printf_String(s);
adc2= ADC_READ(1);
sprintf(s,"ADC:%04d",adc2);
Lcd_gotoxy(1,2);
Lcd_printf_String(s);
}
}
Holas, les consulto por el tema de la memoria eeprom que en esta misma seccion estan las rutina de escritura y lectura, el problema que tengo es que lo logro guardar datos que sean mayores a 255 y necesito por ejemplo guardar valores de 0 a 999 pero no me estoy dando cuenta para modificar esas funciones.
Gracias
Hola amigos, a continuación voy a publicar el mini curso que estoy armando de a poco en el foro uControl. Bienvenidas sugerencias, correcciones y aportes aquí mismo, por Twitter (http://www.twitter.com/lmtreser) o como sea!
Mini curso "Programación de micros en C desde 0"
Introducción
Hola, hoy empiezo este mini curso de programación de microcontroladores PIC en lenguaje C desde 0. La idea es aprender paso a paso, realizar algunos proyectos simples y sumar conocimientos.
Voy a trabajar sobre el sistema operativo Ubuntu, con software libre o gratuito. Para todos aquellos que utilizan Windows no van a tener inconvenientes porque los paquetes de software son multiplataforma. Voy a utilizar como entorno de desarrollo MPLAB X en conjunto con el compilador XC8. No me voy a detener en la instalación y configuración del IDE y del compilador ya que existen muchos tutoriales sobre esto (por ejemplo (http://www.automatismos-mdq.com.ar/blog/2011/04/instalar-mplab-x-en-ubuntu.html)). El microcontrolador por ahora es un PIC16F648A salvo indicación contraria!
El curso lo voy realizando sobre la marcha, en parte leyendo libros, en parte dudas consultadas a los expertos en el foro y en parte en experiencias propias. Por este motivo lo verán formarse "online" y a medida que el tiempo me lo permita ire sumando contenido. Les recomiendo que lean el tutorial sobre XC8 que escribió Suky (http://www.micros-designs.com.ar/tutorial-xc8-introduccion/) que es un buen punto de partida y el "Tutorial MPLAB C18 Desde Cero" (http://www.ucontrol.com.ar/forosmf/tutoriales-guias-y-cursos-en-ucontrol/tutorial-mplab-c18-desde-0/). También es de mucha utilidad tener a mano los ejemplos de Microchip para consulta: Microchip Code Examples (12F & 16F) (http://www.mediafire.com/?ajiish29dzjd09u).
Indice:
1.1. Estructura de un programa en C (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338215#msg338215)
1.2. ¡Hola Mundo! en C (o como hacer destellar un LED) (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338216#msg338216)
1.3. Leer un pulsador (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338217#msg338217)
1.4. Utilizando PWM (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338218#msg338218)
1.5. Uso de funciones (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338219#msg338219)
1.6. Variables y tipos de datos (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338220#msg338220)
1.7. Usando una interrupción por timer0 (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338221#msg338221)
1.8. Interrupciones de alta y baja prioridad (http://www.todopic.com.ar/foros/index.php?topic=40649.msg340202#msg340202)
Ejemplos y rutinas útiles:
2.1. Ejemplo de uso PIC18F4550, delays y USART (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339587#msg339587)
2.2. Escribir y leer una memoria EEPROM (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338370#msg338370)
2.3. Rutina para generar pausas extensas (http://www.todopic.com.ar/foros/index.php?topic=40649.msg338510#msg338510)
2.4. PIC16F819 controlando un modulo LCD 2x16 - 4 bits (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339676#msg339676)
2.5. Conversores ADC/PWM (uso de la función ITOA) (http://www.todopic.com.ar/foros/index.php?topic=40649.msg340679#msg340679)
2.6. Uso de I2C por software (http://www.todopic.com.ar/foros/index.php?topic=40649.msg340651#msg340651)
Bugs, errores, herramientas:
3.1. Corrección del bug "maldita linea roja" (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339853#msg339853)
3.2. Dolor de cabeza con el uso de la librería del LCD xlcd.h (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339865#msg339865)
3.3. Integrar Proteus VSM para hacer debug en los proyectos de MPLABX con el plugin Proteus VSM viewer (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339909#msg339909)
3.4. View Includes Hierarchy (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339910#msg339910)
3.5. View macro expansion (http://www.todopic.com.ar/foros/index.php?topic=40649.msg339911#msg339911)
3.6. Generador de código para los "Bits de configuración" (http://www.todopic.com.ar/foros/index.php?topic=40649.msg340566#msg340566)
Buenas gracias por la ayuda.
pusssssssss. mas que un guion bajo. Ya lo encontre. Antes era ""void interrupt ISR (void)"" ahora supongo que por la nueva versión de xc8 es ""void __interrrupt() ISR()""
esto es a lo que me refiero si todos te enseñan de una manera como es que esto cambia tanto, ¿esto no es algo estándar?? cada vez que actualizan es como aprender de 0
Gracias. PD: lo encontré en la misma página de microchip.