x == y : x (igual a) y
x != y : x (es diferente a) y
x > y : x (es mayor que) y
x < y : x (es menor que) y
x <= y : x (es menor o igual que) y
x >= y : x (es mayor o igual que) y
x && y : AND logico
x || y : OR logico
ah que bien tio!!! jjejej :mrgreen: yo tambien sufri al inicio para hacerlo arrancar me lei como 10 veces el datasheet del C18 el user's guide son varios detalles no? cada vez que creo un proyecto tengo que poner el linker, adjuntar el codigo fuente, luego tengo que ir a projects y rutear unas carpetas H y LIB que se me borran no se porque cada vez que hago un proyecto nuevo :shock: jeje pero ya me acostumbre :mrgreen:
hola maunix, seria algo asi:
#include <c:\archivosdeprograma\microchip\c18\h>
:-/
Algo como guardar tu workspace ;)
Hola de nuevo, :) :)
Estoy intentando probar el programita de micro_cadaver de hacer parpadear un led, como veis mis pasos son lentos aunque espero que firmes :P.Y cuando le doy a "build all" me da error y pone lo siguiente:
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "D:\PROGRAMAS\MCC18\bin\mcc18.exe" -p=18F4620 "parpadeo.c" -fo="parpadeo.o" -Oa -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:1:Error [1027] unable to locate 'p18f4620.h'
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:2:Error [1027] unable to locate 'delays.h'
C:\Documents and Settings\Rafa\Escritorio\Pruebas con C18\Nueva carpeta\parpadeo.c:3:Error [1027] unable to locate 'stdio.h'
Creo que el problema es que no reconoce la localizacion de los archivos, pero lo he provado de muchas formas distintas y siempre es el mismo resultado.¿Alguien sabe el porque de mi error?
bueno ... le pido publicamente a kedutpic (JUAN VEGA COD:666XXX666) :D que vaya implementando un circuito para probar la EUSART del pic18f2550, la siguiente entrega sera esa, pero pa el 18f2525 :-) que es casi lo mismo, los mismo pines etc etc, jiji asi que vayan repasando, de paso yo tambien :-/
Y de nuevo mil gracias publicas a mis compatriotas Henry y Curio pues despues de una caotica lucha tratando de configurar
y demas trabas logre compilar los ejemploq e Henry(uCADAVER) esta posteando , a decirles a los foreros Henry que si simulan en proteus ponerle el voltaje de 5 voltios en el pic 18f2525 en el MCLR si no no arranca chaufa y mil gracias de nuevo :-/
¿Sabe alguien como seria el protoco SPI en C18?Yo la verdad es que no tengo mucha idea de este protocolo y menos en C18 :oops: :oops:
RUTINA PARA UN LCD 16X2 CON BUS DE DATOS A 4BITS
El siguiente codigo lo vengo modificando de el siguiente hilo http://www.todopic.com.ar/foros/index.php?topic=17005.0
donde la amiga :g) Mulderson amablemente compartio. La modificación que hice solo es para que se acomode al hardware que uso y le agregue una rutina para escribir strings (cadenas de caracteres) en el LCD, ubicados en la memoria de programa y en la memoria de datos.
#include <p18f2550.h>
#include <delays.h> // Rutinas de retardo
#include "F:\PIC\C18\LCD4b2x16.h"
#pragma config PLLDIV =1,CPUDIV = OSC1_PLL2,USBDIV =1 //CONFIG1L
#pragma config FOSC = XT_XT, FCMEN = OFF,IESO = OFF//CONFIG1H
#pragma config PWRT = ON,BOR = OFF,BORV =0,VREGEN = OFF //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = ON//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = ON,CP1 = ON,CP2 = ON,CP3 = ON//CONFIG5L ; PROTECCION DE LECTURA DESDE 0000-7FFFh
#pragma config CPB = OFF,CPD = OFF//CONFIG5H ; CPB: ON HABILITADO CODIGO DE PROTECCION ,CPD :ON HABILITADO PROTECCION CONTRA LECCTURA EEPROM
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON,WRT3 = ON//CONFIG6L ; PROTECCION DE ESCRITURA DESDE 0000-7FFFh
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H ; WRBT = ON HABILITADO CODIGO DE PROTECCION DE ESCRITURA ,WRCT=ON PROTECCION A LOS REGISTROS (3000000-30000FFH),WRTD= ON PROTECCION DE ESCRITURA DE LOS DATOS EN LA EEPROM
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L ; PROTECCION DESDE TABLAS LEIDAS EJECUTADAS EN OTROS BLOQUES
#pragma config EBTRB = OFF//CONFIG7H
//******************************************************//
//******************************************************////******************************************************//
//******************************************************//
//
//
// Programa Principal
//
//
//******************************************************//
//******************************************************//
char mensaje[]="Henry";
void main(void)
{
ADCON1 = 0X0F; PUERTO B DIGITAL
UCON = 0X00;
TRISA = 0X00;
TRISB = 0XF0;
TRISC = 0X00;
PORTA = 0X00;
PORTB = 0X00;
PORTC = 0X00;
Inicializa_LCD();
Comando_LCD(CURSOR_OFF & BLINK_ON);
Dato_LCD('#');//un dato
Datos_LCD(" VIVA EL PERU ");//una cadena desde la memoria de programa
Dato_String_LCD(mensaje);//una cadena desde la memoria de datos
//con este comando pasamos a la linea 2 del LCD
Comando_LCD(DDRAM_LINEA_2);
Datos_LCD("micro_cadaver");
while(1);
}jajaj si duermo, poquito, pero luego todo el dia estoy volando.... entiendase por distraido o fuera de la realidad, además este clima me encanta (el invierno y el otoño), a ver si luego del DS1307 hacemos un panelcito de leds en C18 mostrando la hora :mrgreen:
// Cristal 10MHz
#include <p18f452.h>
#include <stdio.h>
#include <delays.h>
#pragma config OSC=HS
#pragma config WDT = OFF
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config LVP=OFF
int i;
void main(){
TRISB =0; //Puerto b como salidas
PORTB =0;
while (1){
Delay10KTCYx(250); //Retardo de 1 seg; con 189 si da 1 seg
PORTB = !PORTB; //Cambia estado del puerto
}
}
...
ahora en el proteus pues ... tambien veo 1.33seg.
Hay cosas que suceden en el proteus que no entiendo tampoco, debe ser algun problemilla bug con el compilador, aunque en la realidad si se cumplen los tiempos, asi como en el MPLABSIM.
...
He hecho unas pruebitas para no quedarme con la duda.
Compile el ejemplo de los 5ms en C18, lo simule en proteus y lo medi en un osciloscopio, luego hice lo mismo pero con CCS y los resultados que obtuve fueron estos:
Programa con 5ms de retardo:
C18:
Proteus: 7.96ms
Osciloscopio: 8ms :?
CCS:
Proteus: 5ms
Osciloscopio: 5ms
Conclusión: EL compilador perfecto no existe :x
#define lcd_type 2
#define lcd_line_two 0x40
#define tris_write 0x00
#define tris_read 0xF0
//Interfaz 4 bits, datos en nibble superior.
#define LCD_E PORTDbits.RD0
#define LCD_RS PORTDbits.RD1
#define LCD_RW PORTDbits.RD2
#define LCD_TRIS TRISD
#define LCD_PORT PORTD
char const INIT[4]={0x20|(lcd_type<<2),0x0c,1,6};
extern void Delay1u();
extern void Delayms(char n);
char lcd_read_byte();
void lcd_send_nibble(char n);
void lcd_CmdData(char opt,char n);
void lcd_init();
void lcd_gotoxy(char x,char y);
void lcd_putc(char c);
char lcd_read_byte()
{
char lo,hi;
LCD_TRIS=tris_read;
LCD_RW=1;
Nop();
LCD_E=1;
Nop();
hi=LCD_PORT&0xF0;
LCD_E=0;
Nop();
LCD_E=1;
Delay1u();
Delay1u();
lo=(LCD_PORT>>4)&0x0F;
LCD_E=0;
LCD_TRIS=tris_write;
return(hi|lo);
}
void lcd_send_nibble(char n)
{
LCD_PORT&=0x0F;
LCD_PORT|=((n&0x0F)<<4);
Nop();
Delay1u();
LCD_E=1;
Delay1u();
LCD_E=0;
}
void lcd_CmdData(char opt,char n)
{
LCD_RS=0;
while((lcd_read_byte()|0x7F)==0xFF);
LCD_RS=opt;
Nop();
LCD_RW=0;
Delay1u();
LCD_E=0;
lcd_send_nibble(n>>4);
lcd_send_nibble(n);
}
void lcd_init()
{
char i;
LCD_TRIS=tris_write;
LCD_RS=0;
LCD_RW=0;
LCD_E=0;
Delayms(5);
for(i=1;i<=3;++i)
{
lcd_send_nibble(3);
Delayms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_CmdData(0,INIT[i]);
}
void lcd_gotoxy(char x,char y)
{
char addr;
if(y==1)
{
addr=0x00;
}
else
{
addr=0x40;
}
addr+=x-1;
lcd_CmdData(0,0x80|addr);
}
void lcd_putc(char c)
{
switch (c){
case '\f' :lcd_CmdData(0,1);
Delayms(2);
break;
case '\n' :lcd_gotoxy(1,2);
break;
case '\b' :lcd_CmdData(0,0x10);
break;
default :lcd_CmdData(1,c);
}
}
void _user_putc(char c)
{
lcd_putc(c);
}
...dibujando por las columnas y habilitando por las filas
...
pero estariamos mas cerca a desarrollar rutinas de control retroalimentadas por ejemplo ,
#pragma config LVP = OFF
#pragma config WDT = OFF
#pragma config OSC = XT
Es el complemento.
El operador logico NOT es !.
para preguntar por 0
if(PORTAbits.RA0==0)
{
codigo
}
pd1: que ya no funciona el link? a ver.... h**p://www.box.net/shared/51111xhblr si funciona, naturalmente amigo teneis que cambiar los * * por t t de tal manera que diga http :mrgreen: es un truquito para que no lo bajen bots de descargas :-)
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
ADC_CH2 & ADC_INT_OFF, //Config ADCON0
12); //Config ADCON1
ADCON1=0x0B;
Como podran ver en el datasheet del 18F4550 al ejecutar la instruccion ADCON1=0x0B lo que hago es configurar los voltajes de referencia internos a Vss y Vdd, ademas de configurar los pines analogicos que se van a emplear, esto se tendria que hacer mediante la instruccion OpenADC pero es aqui donde tuve los problemas, lo que pasa es q la libreria adc.h para el PIC 18f4550 utiliza solo numeros enteros entre 0 y 15, que al utilizarlos no contemplan la configuracion de los voltajes de referencia para el conversor ADC, pues lo pone por defecto como las entradas a los pines AN2 y AN3, y del modo que queria hacerlo esto no me funcionaba, es por eso que añado la intruccion ADCON1=0x0B luego de utilizar la instruccion OpenADC de este modo si funciono asi que aqui esta lo que hice.. Espero les sirva :-)
...Saludos... :-/
#include <p18f4520.h>
#include <delays.h>
#include <usart.h>
/* Para saber como configurar los Fusibles se debe mirar
en MPLAB -> HELP -> TOPICS -> Configuration Settings ->
y buscar el microcontrolador en nuestro caso es el 18F4520 */
#pragma config OSC = HSPLL, FCMEN = OFF, IESO = OFF // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 3 // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768 // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF, DEBUG = ON // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF // CONFIG5L
#pragma config CPB = OFF, CPD = OFF // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF // CONFIG7L
#pragma config EBTRB = OFF // CONFIG7H
//************************************************************
unsigned char recepcion;
void main(void)
{
TRISA = 0X00;
TRISB = 0X00;
TRISD = 0X00;
PORTA = 0X00;
PORTB = 0X00;
PORTD = 0X00;
/*********************************************************************
*/
Nop();
// configuramos el EUSART para 9600 baudios
/*
/* USART_TX_INT_OFF = Interrupcion de Tx apagada
/* USART_RX_INT_OFF = Interrupcion de Rx apagada
/* USART_ASYNCH_MODE = se trabajara en modo asincrono
/* USART_EIGHT_BIT = se trabajara con 8 bits
/* USART_CONT_RX = la transmision sera continua
/* USART_BRGH_HIGH = transmision y recepcion a alta velocidad
*/
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_SINGLE_RX &
USART_BRGH_HIGH,
1040); //1040 para 40mhz y 9600baudios - Manual del PIC18F4520 - DS39631D-page 208
//BAUDCONbits.BRG16=1;
baudUSART (BAUD_IDLE_CLK_HIGH &
BAUD_16_BIT_RATE &
BAUD_WAKEUP_ON &
BAUD_AUTO_OFF);
Nop();
for (;;)
{
while(!DataRdyUSART());
recepcion = ReadUSART();
while(BusyUSART());
putcUSART('1');
}
while(1);
}
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_SINGLE_RX &
USART_BRGH_LOW,
63); //64 - 1040 pa 40mhz y 9600baudios USART_SINGLE_RX por USART_CONT_RX
//BAUDCONbits.BRG16=1;
/*
baudUSART (BAUD_IDLE_CLK_HIGH &
BAUD_16_BIT_RATE &
BAUD_WAKEUP_ON &
BAUD_AUTO_OFF);
*/le baje de USART_BRGH_HIGH a USART_BRGH_LOWvoid write_eeprom(unsigned int, unsigned char);
unsigned char read_eeprom(unsigned int);
void write_eeprom(unsigned int eeprom_addr, unsigned char eeprom_data)
{
EECON1bits.EEPGD = 0; /* Ensure EEPGD is clear for EEDATA access */
EECON1bits.CFGS=0; /* Select Data EEPROM */
EECON1bits.WREN = 1; /* Ensure WREN is set to enable EEDATA writes */
EEADR = eeprom_addr;
EEDATA = eeprom_data; /* Set EEDATA to the value to write */
EECON2 = 0x55; /* Write 0x55 to EECON2 */
EECON2 = 0xaa; /* Write 0xAA to EECON2 */
EECON1bits.WR = 1; /* Initiate write cycle by setting the WR bit */
while (!PIR2bits.EEIF); /* Wait for the EEIF flag to be set */
PIR2bits.EEIF = 0; /* Clear the EEIF flag */
EECON1bits.WREN = 0; /* Ensure WREN is set to enable EEDATA writes */
}
unsigned char read_eeprom(unsigned int eeprom_addr)
{
EEADR = eeprom_addr;
EECON1bits.EEPGD = 0; /* Ensure EEPGD is clear for EEDATA access */
EECON1bits.RD = 1; /* Trigger a read by setting the RD bit */
return EEDATA; /* Read the result from EEDATA register */
}
hola León, es un gusto saber que al menos algo que hice le puede servir a demás personas, incluso gente que nunca llegare a conocer en persona.
mi cometido era intentar retomar el tutorial pero por cuestiones de trabajo me he alejado del c18, y estoy programando con el c30 para pic24xxx, pero bueno derepente alguien toma la posta.
saludos :-/
Una pregunta, micro_cadaver, acaso es muy distinto el C30, con el el C18? o solo es cuestion ver el hard que trae el PIC24 y aprender el uso de sus librerias, etc. (asi como lo he estado haciendo con el C18)?
while(BusyUSART()); //esperamos caracter del virtual terminal
while(!DataRdyUSART());
Comando_LCD(0XCC);
recepcion = getcUSART();
Dato_LCD(recepcion); //envia caracter68.
putcUSART(recepcion);
Comando_LCD(0XC3);//posicion en el LCD
Dato_LCD(recepcion); }#include<p18f4550.h>
#include<delays.h>
#include<usart.h>
#include<xlcd.h>
void DelayFor18TCY(){Delay10TCYx(3);} //FUNCIONES PARA LCD
void DelayPORXLCD(){Delay10KTCYx(3);} //FUNCIONES PARA LCD
void DelayXLCD(){Delay10KTCYx(3);} //FUNCIONES PARA LCD
unsigned char recepcion;
void main(){
ADCON1=15;TRISC = 0;
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,25);
//OpenADC(ADC_FOSC_2 & ADC_RIGHT_JUST & ADC_2_TAD,ADC_CH0 & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,14);
OpenXLCD(FOUR_BIT & LINES_5X7);
WriteCmdXLCD(1);
Delay10KTCYx(10);
putrsXLCD("RECEPCION USART");
Delay10KTCYx(250);
while(1){
while(BusyUSART()){}
while(!DataRdyUSART()){}
recepcion = ReadUSART();
WriteDataXLCD(recepcion);
putcUSART(recepcion);
WriteCmdXLCD(192); //POSICION LCD
WriteDataXLCD(recepcion);
}
}
Te refieres a la interrupcion por recepcion serial???
Si es asi avisame y posteo un ejemplo en C18, hasta luego
#include<p18f4550.h>
#include<delays.h>
#include<usart.h> //Libreria para configurar modulo USART
void int_recepcion(); //Funcion a llamar en la interrupcion
int recepcion;
#pragma code int_alta = 0x08 //INTERRUPCION POR RECEPCION
void int_alta(){
_asm
goto int_recepcion
_endasm
}
#pragma code
#pragma interrupt int_recepcion
void int_recepcion(){ //EN ESTE PUNTO SE ACABA DE RECIBIR UN DATO, EL BUFFER ESTA LLENO
recepcion = ReadUSART(); //LEEMOS EL CONTENIDO DEL BUFFER PARA LIMPIARLO AUTOMATICAMENTE
PIR1bits.RCIF = 0; //APAGAMOS LA BANDERA PARA PERMITIR UNA FUTURA INTERRUPCION
}
void main(){
TRISC = 192; //PUERTO DE TRANSMISION
INTCONbits.GIE=1; RCONbits.IPEN = 1;//HABILITAR INTERRUPCIONES Y PRIORIDAD
INTCONbits.PEIE = 1; //INTERRUPCIONES POR PERIFERICOS (usart)
IPR1bits.RCIP=1; //PRIORIDAD INT RECEPCION
OpenUSART(USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,25); //CONFIGURA MODULO USART
PIE1bits.RCIE = 1; //HABILITA INT RECEPCION
while(1){
//ACA PUEDES OPERAR LA VARIABLE GLOBAL 'recepcion' QUE SE ALTERA POR MEDIO DE LA INTERRUPCION...
mostrar(); //POR EJEMPLO LLAMAR UNA FUNCION QUE ME MUESTRE EL DATO RECIBIDO EN UNA LCD... O ALGO ASI
}
}
BYTE inputstr[]="vacio";
#pragma code Interrupcion = 0X12
void VectorInterrupcion(void){
_asm goto ISRRecepcion _endasm
}
#pragma code
// Rutina de Interrupcion.-
#pragma interrupt ISRRecepcion
void ISRRecepcion(void){
if(PIR1bits.RC1IF==1){
gets1USART(inputstr, 9);
Kbhit=1; // Indicamos que se ha recibido un dato.-
PIR1bits.RC1IF=0; // Borramos bandera.-
}
}
/*=========================================================================
Title:
Description:
Author: Luis Carlos Osorio Jayk
===========================================================================*/
/*===========================================================================
HEADER FILES
===========================================================================*/
#include <p18f452.h>
#include "myVars.h"
#include <delays.h>
#include <i2c.h>
#include "myI2C.h"
/*===========================================================================
CONFIGURATION BITS
===========================================================================*/
#pragma config WDT = OFF // Turn OFF Watch Dog
#pragma config WDTPS = 128 //
#pragma config OSC = XT // Oscilator selection: HS {Using 20MHz Crystal}
#pragma config PWRT = ON // Turn ON Power Up Time Delay
#pragma config LVP = OFF // Turn OFF Low Voltage Progamming
#pragma config WRTC = ON //
#pragma config WRTD = ON //
#pragma config EBTR0 = ON //
#pragma config EBTR1 = ON //
#pragma config EBTR2 = ON //
#pragma config EBTR3 = ON //
#pragma config EBTRB = ON //
#pragma config DEBUG = OFF //
#pragma config STVR = OFF //
#pragma config CP0 = ON //
#pragma config CP1 = ON //
#pragma config CP2 = ON //
#pragma config CP3 = ON //
#pragma config CPB = ON //
#pragma config CPD = ON //
#pragma config CCP2MUX = OFF //
#pragma config BOR = OFF //
#pragma config BORV = 25 //
/*===========================================================================
USER DATA
===========================================================================*/
#define LedRed PORTBbits.RB0
#define LedGreen PORTBbits.RB1
unsigned char arrayrd[20];
unsigned char *parrayrd = &arrayrd[0];
unsigned char arraywr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
unsigned char *parraywr = &arraywr[0];
//charBitVar var; // A 8bits variable with bit acces. e.g: var.bit0~var.bit7
//intBitVar leds;
/* A 16bit variable with bit and nibble acces.
e.g: leds.bit0~leds.bit15 and leds.nibble0~leds.nibble3*/
/*===========================================================================
User Functions
===========================================================================*/
/*===========================================================================
INTERRUPTION SERVICE ROUTINES
===========================================================================*/
/*High Priority Iterruption Service*/
/*---------------------------------*/
#pragma interrupt high_ISR
void high_ISR (void)
{
// Do...
}
/*Low Priority Interruption Service*/
/*---------------------------------*/
#pragma interruptlow low_ISR
void low_ISR (void)
{
// Do...
}
/*===========================================================================
INTERRUPTION CODE LOCATION
===========================================================================*/
/*High Priority Section*/
/*---------------------*/
#pragma code highPriorityVector = 0x08
void jumpHighPriority (void)
{
_asm
goto high_ISR
_endasm
}
#pragma code // End this code section
/*Low Priority Section*/
/*--------------------*/
#pragma code lowPriorityVector = 0x18
void jumpLowPriority (void)
{
_asm
goto low_ISR
_endasm
}
#pragma code // End this code section
/*===========================================================================
Main Program
===========================================================================*/
void main()
{
/*Configuration*/
/*-------------*/
//RCONbits.IPEN = 1; // Enable Interrupt Priority.
//INTCONbits.GIEH = 1; // Enable High Priority Interruptions.
//INTCONbits.GIEL = 1; // Enable Low Priority Interruptions.
/*TRISCbits.TRISC3 = 1;
TRISCbits.TRISC4 = 1;*/
TRISC = 0x18;
LATC = 0x00;
TRISB = 0; // PORTB pins -> All as Outputs.
OpenI2C(MASTER, SLEW_OFF);
SSPADD = 0x18;
/*SSPSTAT = 0x80;
SSPADD = 0x18;
SSPCON1 = 0x28;
SSPCON2 = 0x00;*/
EscribeDato_i2c_eeprom(0xA0,0x00,0x00,'@');
Ack_i2c_eeprom(0xA0);
while(1)
{
}
} /* End Main Prgram */
/*=========================================================================*/
/*=========================================================================*/
#include <p18f2525.h>
#include <delays.h>
#include <i2c.h>
#include "memoria_externa.h"
#pragma config OSC = XT,FCMEN = OFF,IESO = OFF //CONFIG1H
#pragma config PWRT = ON,BOREN = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = PORTC//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = ON,CP1 = ON,CP2 = ON//CONFIG5L
#pragma config CPB = ON,CPD = ON//CONFIG5H
#pragma config WRT0 = ON,WRT1 = ON,WRT2 = ON//CONFIG6L
#pragma config WRTB = ON,WRTC = ON,WRTD = ON//CONFIG6H
#pragma config EBTR0 = ON,EBTR1 = ON,EBTR2 = ON//CONFIG7L
#pragma config EBTRB = ON//CONFIG7H
int caracter;
unsigned char henry[]="*micro_cadaver*",
cadena[16];
void main(void)
{
TRISA = 0X00;
TRISB = 0X00;
TRISC = 0X18;
LATA = 0X00;
LATB = 0X00;
LATC = 0X00;
Delay1KTCYx(100);
//*******************************************************
// configuración del modulo i2c
//*******************************************************
OpenI2C(MASTER,SLEW_OFF);//inicializo modulo
SSPADD = 9;//100KHz para 4MHz
//*******************************************************
EscribeDato_i2c_eeprom(0XA0,0X00,0X00,'M');
EscribeDato_i2c_eeprom(0XA0,0X00,0X01,'E');
EscribeDato_i2c_eeprom(0XA0,0X00,0X02,'N');
EscribeDato_i2c_eeprom(0XA0,0X00,0X03,'S');
EscribeDato_i2c_eeprom(0XA0,0X00,0X04,'A');
EscribeDato_i2c_eeprom(0XA0,0X00,0X05,'J');
EscribeDato_i2c_eeprom(0XA0,0X00,0X06,'E');
Ack_i2c_eeprom(0XA0);
caracter=LeeDato_i2c_eeprom(0XA0,0X00,0X00);
Delay1KTCYx(500);
EscribeDatos_i2c_eeprom(0XA0,0X00,0X10,"|||PERU|||");
Ack_i2c_eeprom(0XA0);
EscribeCadena_i2c_eeprom(0XA0,0X00,0X00,henry);
Ack_i2c_eeprom(0XA0);
LeeDatos_i2c_eeprom(0XA0,0X00,0X10,cadena,10);
LeeDatos_i2c_eeprom(0XA0,0X00,0X00,cadena,15);
while(1);
//*******************************************************
//*******************************************************
}
Hola otra vez.
Disculpen mi desespero pero bueno...sigo intentado una y otra y otra vez.
He logrado entre comillas "resolverlo" colocando un retardo de mínimo 5000 ciclos de reloj, para un cristal de 4 MHz pues serían unos 5ms.
Pero para la aplicación que quiero desarrollar, 5ms es una eternidad. Requiero leer al menos 6 bytes de la memoria, en un lapso máximo de 1 ms.
HEEEEEEEEEEEEEEEEEEEEEEEEEEELP :sad: :8}
#include "p18f4520.h"
#include <stdlib.h>
#include <stdio.h>
#include <delays.h>
#pragma config OSC = HSPLL, FCMEN = OFF, IESO = OFF // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 3 // CONFIG2L
#pragma config WDT = OFF, WDTPS = 32768 // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF, DEBUG = ON // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF // CONFIG5L
#pragma config CPB = OFF, CPD = OFF // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF // CONFIG7L
#pragma config EBTRB = OFF // CONFIG7H
// control line pins
#define LCD_RS PORTBbits.RB7
#define LCD_WR PORTBbits.RB6
#define LCD_RD PORTBbits.RB5
#define LCD_CS PORTBbits.RB4
#define LCD_RES PORTBbits.RB3
/*************************************************/
void Write_Command(unsigned char command)
{
PORTC = command;
LCD_RS = 0;
LCD_WR = 0;
LCD_WR = 1;
}
/*************************************************/
void Write_Data(unsigned char data1)
{
PORTC = data1;
LCD_WR = 0;
LCD_WR = 1;
}
/*************************************************/
void Command_Write(unsigned char REG,unsigned char VALUE)
{
Write_Command(REG);
LCD_RS = 1;
Write_Data(VALUE);
}
/*************************************************/
void SendData(unsigned long color)
{
LCD_RS = 1;
Write_Data((color)>>16); //red
Write_Data((color)>>8); //green
Write_Data(color);
}
/*************************************************/
void Init_SSD1963(void)
{
LCD_CS = 0;
LCD_RD = 1;
LCD_WR = 0;
LCD_RES = 0;
Delay10KTCYx(2);
LCD_RES = 1;
Delay10KTCYx(10);
Write_Command(0x01); //Software Reset
Write_Command(0x01);
Write_Command(0x01);
Command_Write(0xe0,0x01); //START PLL
Command_Write(0xe0,0x03); //LOCK PLL
Write_Command(0xb0); //SET LCD MODE SET TFT 18Bits MODE
LCD_RS = 1;
Write_Data(0x0c); //SET TFT MODE & hsync+Vsync+DEN MODE
Write_Data(0x80); //SET TFT MODE & hsync+Vsync+DEN MODE
Write_Data(0x01); //SET horizontal size=320-1 HightByte
Write_Data(0x3f); //SET horizontal size=320-1 LowByte
Write_Data(0x00); //SET vertical size=240-1 HightByte
Write_Data(0xef); //SET vertical size=240-1 LowByte
Write_Data(0x00); //SET even/odd line RGB seq.=RGB
Command_Write(0xf0,0x00); //SET pixel data I/F format=8bit
Command_Write(0x3a,0x60); // SET R G B format = 6 6 6
Write_Command(0xe6); //SET PCLK freq=6.4MHz ; pixel clock frequency
LCD_RS = 1;
Write_Data(0x00);
Write_Data(0xe7);
Write_Data(0x4f);
Write_Command(0xb4); //SET HBP,
LCD_RS = 1;
Write_Data(0x01); //SET HSYNC Total 440
Write_Data(0xb8);
Write_Data(0x00); //SET HBP 68
Write_Data(0x44);
Write_Data(0x0f); //SET VBP 16=15+1
Write_Data(0x00); //SET Hsync pulse start position
Write_Data(0x00);
Write_Data(0x00); //SET Hsync pulse subpixel start position
Write_Command(0xb6); //SET VBP,
LCD_RS = 1;
Write_Data(0x01); //SET Vsync total 265=264+1
Write_Data(0x08);
Write_Data(0x00); //SET VBP=19
Write_Data(0x13);
Write_Data(0x07); //SET Vsync pulse 8=7+1
Write_Data(0x00); //SET Vsync pulse start position
Write_Data(0x00);
Write_Command(0x2a); //SET column address
LCD_RS = 1;
Write_Data(0x00); //SET start column address=0
Write_Data(0x00);
Write_Data(0x01); //SET end column address=319
Write_Data(0x3f);
Write_Command(0x2b); //SET page address
LCD_RS = 1;
Write_Data(0x00); //SET start page address=0
Write_Data(0x00);
Write_Data(0x00); //SET end page address=239
Write_Data(0xef);
Write_Command(0x13); //SET normal mode
Write_Command(0x29); //SET display on
}
/*************************************************/
void WindowSet(unsigned int s_x,unsigned int e_x,unsigned int s_y,unsigned int e_y)
{
Write_Command(0x2a); //SET page address
LCD_RS = 1;
Write_Data((s_x)>>8); //SET start page address=0
Write_Data(s_x);
Write_Data((e_x)>>8); //SET end page address=319
Write_Data(e_x);
Write_Command(0x2b); //SET column address
LCD_RS = 1;
Write_Data((s_y)>>8); //SET start column address=0
Write_Data(s_y);
Write_Data((e_y)>>8); //SET end column address=239
Write_Data(e_y);
}
/*************************************************/
void FULL_ON(unsigned long dat)
{
unsigned x,y;
WindowSet(0x0000,0x013f,0x0000,0x00ef);
Write_Command(0x2c);
for(x=0;x<240;x++)
{
for(y= 0;y<320;y++)
{
SendData(dat);
}
}
}
/*************************************************/
void QUADS(void)
{
unsigned i,j;
WindowSet(0x0000,0x013f,0x0000,0x00ef);
Write_Command(0x2c);
for(j= 0 ;j<120;j++)
{
for(i=0;i<160;i++)
{
SendData(0x0000FF); //blue
}
for(i=0;i<160;i++)
{
SendData(0xFF0000); //red
}
}
for(j= 0 ;j<120;j++)
{
for(i=0;i<160;i++)
{
SendData(0xFFFF00); //yellow
}
for(i=0;i<160;i++)
{
SendData(0x00FF00); //green
}
}
}
/*************************************************/
void main(void)
{
TRISA = 0b00000000;
PORTA = 0b00000000;
TRISB = 0b00000000;
PORTB = 0b00000000;
TRISC = 0b00000000;
PORTC = 0b00000000;
Delay10KTCYx(50);
Delay10KTCYx(50);
Init_SSD1963(); // Initialize the display
while(1)
{
Delay10KTCYx(50);
Delay10KTCYx(50);
QUADS();
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
FULL_ON(0xff0000); //red
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
FULL_ON(0x00ff00); //green
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
FULL_ON(0x0000ff); //blue
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
Delay10KTCYx(50);
}
Existen algunas funciones propias del C18, como en el caso del CCS, un output_bit por ejemplo, o un output_high? En caso de existir donde puedo encontrar su ayuda correspondiente?
ok, me tendré que conformar entonces jeje.
Entonces no creo que haya una forma, al menos sencilla, de pasar librería de CCS a C18.
Seguiré estudiando el C18, que con la costumbre al CCS, cuesta un poco... :(
saludos, gracias por responder suky.
Entonces no creo que haya una forma, al menos sencilla, de pasar librería de CCS a C18.
Hola, amigos;
Disculpen la ignorancia, pero recién acabo de comenzar con C18 y me gustaría adentrarme de manera de poder gestionarlo favorablemente.
Mi duda es la siguiente; cómo se setea la frecuencia del Xtal con la que trabajará el micro? Estuve viendo en el MPLAB 8.46, pero no encontré dicha opción.
Alguien podrá ayudarme?
Muchas gracias!!
Saludos.
Hola, amigos;
Disculpen la ignorancia, pero recién acabo de comenzar con C18 y me gustaría adentrarme de manera de poder gestionarlo favorablemente.
Mi duda es la siguiente; cómo se setea la frecuencia del Xtal con la que trabajará el micro? Estuve viendo en el MPLAB 8.46, pero no encontré dicha opción.
Alguien podrá ayudarme?
Muchas gracias!!
Saludos.
te refieres a esto?
#define FCY 20000000UL
por ejemplo ahi se setea que el cristal del chip sera de 20MHZ.
Hola a todos...
alguien me podria ayudar a saber como calcular la resolucion del ADC si utilizo 10 bits y otra cosa si alguien sabe utilizar bien el PWM como calculo al Duty Cycle, o si tienen algun programa sencillo que me sirva de ejemplo, estoy usando el pic18f4550 y programo en C18
muchas gracias.
Buenos dias a todos
soy un novato en pics... he iniciado hace poco a estudiarlo y provando el pic 18f2550 y usando el compilador c18. Quiero leer un dato que recibo en serial (db9+max232), quiero realizar esta lectura tramite interrupt. Leyendo las librerias, tengo una duda, tengo que usar la uart o la usart? :shock: disculpen mi ignorancia
les agradezco de antemano por la ayuda :)
/*
Nombre del Programa: reloj.c
Compilador: c18
Fecha:
Autor: Terodáctilo y Jukinch
Descripción: uso de rtc con placa entrenadora
------------------------------------------------------------
CONEXIONES:
lcd conectado en PUERTO D
bus de datos en el nible alto conector idc rb 4 a 7
DATA7 PUERTO D.7
DATA6 PUERTO D.6
DATA5 PUERTO D.5
DATA4 PUERTO D.4
bus de control en el nible bajo conector idc rb 0 a 3
E_PIN PUERTO D.3
RS_PIN PUERTO D.2
RW_PIN PUERTO D.1
------------------------------------------------------------
MODULO I2C conector idc rb 0 a 3
en RB0 está el SDA SERIAL CLOCK
en RB1 está el SCL SERIAL DATA
------------------------------------------------------------
PULSADOR DE control RC0 en conector idc rC 0 a 3
LED DE CONTROL RC1 en conector idc rC 0 a 3
------------------------------------------------------------
*/
/*Includes*/
#include "p18F4550.h"
#include "xlcd.h"
#include "delays.h"
#include <stdlib.h> //Libreria para conversiones.
#include <i2c.h> //Libreria para bus i2c
/* Bits de configuración*/
#pragma config FOSC = XTPLL_XT,FCMEN = OFF,IESO = OFF,PLLDIV = 1, CPUDIV = OSC1_PLL2
#pragma config PWRT = ON,BOR = OFF,BORV = 0
#pragma config WDT = OFF,WDTPS = 32768
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF,CCP2MX = OFF
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF
#pragma config CPB = OFF,CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF
#pragma config EBTRB = OFF
/*declaración de DEFINICIONES*/
#define CLOCK 4000000
#define TCY 1/CLOCK
#define BITRATE 100000
#define teclaDebugger PORTCbits.RC0 // tecla para avanzar en programa para controlar errores
/*declaración de variables*/
unsigned char hour=0;
unsigned char minutes=0;
unsigned char seconds=0;
unsigned char day=0;
unsigned char month=0;
unsigned char year=0;
unsigned char texto=0;
/*declaración de funciones*/
void DelayFor18TCY(void);
void DelayPORXLCD(void);
void DelayXLCD(void);
void EsperaBotonDebugger(void);
/*****Programa principal******/
/********************************************************************/
void main (void)
{
/*****configuro los puertos******/
TRISBbits.TRISB7=7; // B0=salida
TRISBbits.TRISB6=6; // B0=salida
TRISBbits.TRISB5=5; // B0=salida
TRISBbits.TRISB4=4; // B0=salida
TRISBbits.TRISB3=3; // B0=salida
TRISBbits.TRISB2=2; // B0=salida
TRISBbits.TRISB0=1; // B0=ENTRADA SDA SERIAL CLOCK
TRISBbits.TRISB1=1; // B1=ENTRADA SCL SERIAL DATA
TRISD=0b00000000; // Puerto D7:0 como salidas
LATD=0b00000000; //todas las salidas abajo
TRISCbits.TRISC0=1; // C0=ENTRADA // botón para hacer control del programa
TRISCbits.TRISC1=0; // C1=salida // led para control del programa
/***** preparo lcd para escribir ******/
Delay10KTCYx(10000); //Retardo para esperar que pase cualquier transitorio
OpenXLCD(FOUR_BIT&LINES_5X7); //inicializamos LCD con varias lineas y caracteres 5x7
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("PRUEBA RTC");
while(BusyXLCD()){}
WriteCmdXLCD(0xC0); //Nos posicionamos en la posición 8
while(BusyXLCD()){}
putrsXLCD("PULSE RC.0");
EsperaBotonDebugger();
Delay10KTCYx(100000); //Retardo para esperar que pase cualquier transitorio
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("PULSE para init");
EsperaBotonDebugger();
/***** rutina de inicialización de rtc ***************************************/
OpenI2C(MASTER,SLEW_OFF); // inicializo el i2c en modo maestro y 100khz
ADCON0 = 0X00;
ADCON1 = 0X0F;
CMCON = 0X07;
SSPADD =9; // ((CLOCK/BITRATE)/4)-1 = 9 for 100kHz @ 20MHz
IdleI2C();
StartI2C();
WriteI2C(0b11010000); // escribe la dirección del rtc (11010000= hex D0)
// y le dice que se va a escribir con el bit0 en 0
IdleI2C();
WriteI2C(0b00000000); // pone el puntero del rtc en dirección 00h
StartI2C();
WriteI2C(0b00000000); // GRABAMOS EN EL PRIMER REGISTRO 00 SEGUNDOS
// Y HABILITAMOS EL OSCILADOR con el octavo bit apagado
IdleI2C();
WriteI2C(0b00000010); // GRABAMOS EN EL SEGUNDO REGISTRO 23 MINUTOS
IdleI2C();
WriteI2C(0b00010000); // GRABAMOS EN EL TERCER REGISTRO configura reloj formato 24 hs
IdleI2C();
WriteI2C(0b00000110); // GRABAMOS EN EL CUARTO REGISTRO EL NOMBRE DE DIA DE LA SEMANA
IdleI2C();
WriteI2C(0b00011000); // GRABAMOS EN EL QUINTO REGISTRO EL NUMERO DE DIA DEL MES
IdleI2C();
WriteI2C(0b00000110); // GRABAMOS EN EL SEXTO REGISTRO EL MES
IdleI2C();
WriteI2C(0b00010000); // GRABAMOS EN EL SÉPTIMO REGISTRO EL AÑO
IdleI2C();
WriteI2C(0b00010000); // GRABAMOS EL OCTAVO Y ULTIMO REGISTRO
// Configura la salida del oscilador de onda cuadrada en 1hz
IdleI2C();
StopI2C();
Delay10KTCYx(100000); //Retardo para esperar que pase cualquier transitorio
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("YA INICIALIZO");
EsperaBotonDebugger();
// ********************************** rutina de init rtc *********************
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("i2c cargado");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
Delay10KTCYx(100000); //Retardo para ver lo escrito en lcd
EsperaBotonDebugger();
while(1)
{
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("Lectura i2c");
EsperaBotonDebugger();
IdleI2C();
StartI2C();
WriteI2C(0b11010001); // escribe dirección del rtc y le dice que se va a leer
WriteI2C(0x00); // pone el puntero del rtc en dirección 00h
seconds=ReadI2C();
AckI2C();
minutes=ReadI2C();
AckI2C();
hour=ReadI2C();
AckI2C();
minutes=ReadI2C();
AckI2C();
seconds=ReadI2C();
AckI2C();
day=ReadI2C();
AckI2C();
month=ReadI2C();
AckI2C();
year=ReadI2C();
NotAckI2C();
StopI2C();
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("termino lectura");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
EsperaBotonDebugger();
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("comienza display");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
EsperaBotonDebugger();
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
EsperaBotonDebugger();
// btoa(hour,texto); // convierto 8 bits a caracter ascii
while(BusyXLCD()){}
putsXLCD(texto);
while(BusyXLCD()){}
EsperaBotonDebugger();
putrsXLCD(":");
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
btoa(minutes,texto); // convierto 8 bits a caracter ascii
while(BusyXLCD()){}
putsXLCD(texto);
while(BusyXLCD()){}
EsperaBotonDebugger();
putrsXLCD(":");
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
btoa(seconds,texto); // convierto 8 bits a caracter ascii
while(BusyXLCD()){}
putsXLCD(texto);
while(BusyXLCD()){}
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
Delay10KTCYx(500); //Retardo para poder refrescar pantalla
WriteCmdXLCD(0x01); // Borra pantalla y vuelve al origen.-
while(BusyXLCD()){} //Preguntamos al RW si el display esta ocupado
WriteCmdXLCD(0x80); // Nos posicionamos en la la posicion x=0 Y=0
while(BusyXLCD()){}
putrsXLCD("termino display");
WriteCmdXLCD(CURSOR_OFF & BLINK_OFF);
EsperaBotonDebugger();
}
}// final de main
/*Funciones*/
void DelayFor18TCY(void)
{
Delay1KTCYx(1); //Retardo de 1mSeg
}
void DelayPORXLCD(void)
{
Delay1KTCYx(180); //Delay 15 mSeg
}
void DelayXLCD(void)
{
Delay1KTCYx(60);
}
void EsperaBotonDebugger(void)
{
while (PORTCbits.RC0==0)
{
}
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
LATCbits.LATC1=1; // ENCIENDO LED C1
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
LATCbits.LATC1=0; // APAGO LED C1
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
LATCbits.LATC1=1; // ENCIENDO LED C1
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
LATCbits.LATC1=0; // APAGO LED C1
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
LATCbits.LATC1=1; // ENCIENDO LED C1
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
LATCbits.LATC1=0; // APAGO LED C1
Delay10KTCYx(10000); //Retardo para ver lo escrito en lcd
}
Sería bueno que se agregue al índice del tema la librería esta también.
Sería bueno que se agregue al índice del tema la librería esta también.
Hecho! Espero a micro_cadaver no le moleste :oops: Si hay alguna otra librería, avisan ;-)
Saludos!
Bueno, aquí les dejo una librería realizada a partir de flex_lcd utilizada en CCS en donde se puede definir cualquier pin para su utilización. Se tiene 2 archivos, flex_lcd_c18.h y flex_lcd_c18.c, ambos debemos colocarlos en la carpeta del proyecto y agregarlos al proyecto.
Respecto a que archivo agregar, en los compiladores de Microchip (Ansi C) se llama al archivo cabecera (*.h), él cual indica que funciones se implementan y algunas definiciones. Y en la estructura del proyecto se debe agregar ambos archivos para que sean compilados.Entonces al agregar el .c de la lib del LCD al proyecto ya es parte del código y no hace falta q haya un #include "flex_lcd_c18.c" e incluyendo el .h de la librería es suficiente?
Respecto a que archivo agregar, en los compiladores de Microchip (Ansi C) se llama al archivo cabecera (*.h), él cual indica que funciones se implementan y algunas definiciones. Y en la estructura del proyecto se debe agregar ambos archivos para que sean compilados.Entonces al agregar el .c de la lib del LCD al proyecto ya es parte del código y no hace falta q haya un #include "flex_lcd_c18.c" e incluyendo el .h de la librería es suficiente?
Hola! Bueno a peticion de microcadaver :mrgreen: subo un ejemplo utilizando la libreria adc.h, se trata de un voltimetro implementado con un 18F4550 con un cristal de 20Mhz, el funcionamiento es sencillo utiliza el ADC para captar el voltaje en el pin AN3 y luego muestra el valor captado (previamente escalado a la resolucion del ADC) en un LCD de 2x16, la libreria del LCD la saque de otro hilo y esta basada en la libreria XLCD.h de microchip, pueden reemplazarla por la libreria de manejo de LCD que utilizen o si me la piden con gusto se las paso :-)
#include<p18f4550.h>
#include<delays.h>
#include<stdlib.h>
#include<adc.h>
#include "lcd.h"
#pragma config PLLDIV = 5//CONFIG1L
#pragma config FCMEN = OFF,IESO = OFF,FOSC=HS //CONFIG1H
#pragma config PWRT = OFF,BORV = 0 //CONFIG2L
#pragma config WDT = OFF,WDTPS = 32768 //CONFIG2H
#pragma config MCLRE = ON,LPT1OSC = OFF,PBADEN = OFF, CCP2MX = OFF//CONFIG3H
#pragma config STVREN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF//CONFIG4L
#pragma config CP0 = OFF,CP1 = OFF,CP2 = OFF//CONFIG5L
#pragma config CPB = OFF,CPD = OFF//CONFIG5H
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF//CONFIG6L
#pragma config WRTB = OFF,WRTC = OFF,WRTD = OFF//CONFIG6H
#pragma config EBTR0 = OFF,EBTR1 = OFF,EBTR2 = OFF//CONFIG7L
#pragma config EBTRB = OFF//CONFIG7H
unsigned float v = 0;
char s[3]={""};
void main(void)
{
OpenXLCD(FOUR_BIT & LINES_5X7);
WriteCmdXLCD(BLINK_ON);
WriteCmdXLCD(CLEAR);
TRISAbits.TRISA2 = 1;
LATA=0x00;
OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, //Config ADCON2
ADC_CH2 & ADC_INT_OFF, //Config ADCON0
12); //Config ADCON1
ADCON1=0x0B;
for( ; ; )
{
s[0] = 0;
s[1] = 0;
s[2] = 0;
SetChanADC(ADC_CH3);
Delay10TCYx(5); //Delay de 50Ci
ConvertADC();
while(BusyADC());
v = ReadADC();
v = v * 488 / 1000;
ultoa(v,s); //conversion de un entero a una cadena
WriteCmdXLCD(CLEAR);//visualizacion de resultado en LCD (2x16)
putrsXLCD("V1 = ");
if(s[1]==0 && s[2]==0)
{
s[2]=s[0];
s[1]='0';
s[0]='0';
}
if(s[2]==0)
{
s[2]=s[1];
s[1]=s[0];
s[0]='0';
}
putcXLCD(s[0]);
putcXLCD('.');
putcXLCD(s[1]);
putcXLCD(s[2]);
Delay10KTCYx(50); //Delay de 100ms
}
}
Como podran ver en el datasheet del 18F4550 al ejecutar la instruccion ADCON1=0x0B lo que hago es configurar los voltajes de referencia internos a Vss y Vdd, ademas de configurar los pines analogicos que se van a emplear, esto se tendria que hacer mediante la instruccion OpenADC pero es aqui donde tuve los problemas, lo que pasa es q la libreria adc.h para el PIC 18f4550 utiliza solo numeros enteros entre 0 y 15, que al utilizarlos no contemplan la configuracion de los voltajes de referencia para el conversor ADC, pues lo pone por defecto como las entradas a los pines AN2 y AN3, y del modo que queria hacerlo esto no me funcionaba, es por eso que añado la intruccion ADCON1=0x0B luego de utilizar la instruccion OpenADC de este modo si funciono asi que aqui esta lo que hice.. Espero les sirva :-)
...Saludos... :-/
Estoy intentando hacer un proyecto en el cual necesito hacer conversiones por medio de interrupción y me gustaría si me pudierais verificar este código. Os lo paso y me dicís que opinas al respecto.
Hola compañeros!!!
En primer lugar daros las gracias por la info que habéis posteado en el foro de todopic en especial a microcadaver. Yo era un programador de CCS pero me ha dado tanto por.... los bugsss que al final he pasado al C18 ya que pienso que si microchip da este lenguaje, será por algo.
Había mandado un privado a nuestro compañero microcadaver, pero hablando con otro del foro, Azicuetano, me dijo que lo postease directamente.
#pragma config XINST = OFF
//ON:Instruction set extension and Indexed Addressing mode enabled
Una ayuda con las interrupciones.
Situacion:
Tengo la interrupcion de tx y rx del eusart ambas con alta prioridad activas, me llega la interrupcion de trasmision TXIF y salta a la interrupcion, ejecuto mi programa de la interrupcion(de TXIF) y antesitos de salir :D :D de esta interrupcion se activa la bandera de RCIF(indicando que me llego un dato), despues de salir de la interrupcion volveria a entrar(a la interrupcion) por la activacion de la bandera de RCIF ?¡
Saludos.
Tengo un problema con la definicion y declaracion de variables en los .c y .h, tengo entendido que:No, no es así, sería de la siguiente manera:
fileA.h:
extern char variable;
fileA.c:
#include "fileA.h"
char variable;
fileB.c
#include "fileA.h"
variable=50;
hasta ahi todo bien, pero si quiero usar la misma variable en otro archivo .c no puedo hacerlo...
como se hace? es todo un rollo esto de los .c y .h, alguien conoce una guia para saber q se hace y que no con estos archivos?
Lo q nose hacer es crear una variable en un archivo C, y este se incluya en un archivo B y el archivo B se incluya en el archivo A, por tanto A tendrá las variables de B y C. como hacer?
gracias.
ok muchas gracias por la pronta respuesta.
que es lo que se coloca en los .h entonces?
como hago para tener la misma varible en 3 o más .c??
como harías tu para tener una variable global para tres o mas archivos .c?
y para definir constantes, sería la misma idea?
typedef unsigned char UINT8
typedef unsigned int UINT16#include "definiciones.h"
UINT8 myVar8;
UINT16 myVar16;#include "definiciones.h"
extern UINT8 myVar8;
extern UINT16 myVar16;#include "definiciones.h"
extern UINT8 myVar8;
extern UINT16 myVar16;Gracias,
En caso de las funciones, si voy a usarlas en distintos .c, tambien se debe hacer lo mismo con extern?
donde defino y donde declaro las funciones??
Saludos
He probado esto en un 18F14K50 y funciona:Si funciona, lo pude ver en el .hex, lo que me extraña es q grabo la posición0 con el dato 0x01, tengo las funciones de lectura y escritura como las desarrollaron anteriormente en un otro post (http://www.todopic.com.ar/foros/index.php?topic=17017.msg190008#msg190008) acá en el mismo hilo. Salvo q en la addres,como el pic q uso usa 10bits para direccionar hago:Código: C
#pragma romdata EEDATA=0xF00000 rom const char buff[]={0xAA,0x55,0x33}; #pragma romdata
Eso! Eso! Falta el ; :mrgreen:
jukinch 20s más rápido :undecided: :laugh:
Saludos!
Hola Suky, gracias por tu pronta respuesta, no estoy seguro de entender lo que propones pero lo intentare, entiendo lo de explorar la bandera, pero seria escribiendo otro #pragma code en la misma direccion.
Gracias.
Hola suky, tengo una pregunta, como se convierte 2 variables de 8 bits a una de 16bits?
Esto lo quisiera para convertir los 2 datos leídos del ADC, y colocarlos a una solo variable INT.
muchas gracias, un saludo
O con punteros;Los punteros son la clave; generan 4 lineas de ASM, lo estaba haciendo con una multiplicacion y una suma, q genera algo de 14 instrucciones ASM.Código: C
unsigned char myVar; *((char *)&myVar)=0x16; *((char *)&myVar+1)=0x56;
Nuevamente gracias Suky, todo esto que explicas esta en el datasheet o de donde lo sacas, porque yo nunca encuentro la info que busco en C18 :(
Saludos.
Otra pregunta tonta :oops:
En esta parte de codigo:
SetChanADC(0);
No deberia de poner:
SetChanADC(ADC_CH0);
Lo pregunto porque de la primera manera da error de compilacion.
Miquel_S
...mientras que el hitech es para los micros de gama media y baja(16f y 12f)
Entonces son 2 cosas diferentes ?? Cual es el tan famoso ?? O sea que este tutorial no es para hi-tech ??
O sea que por cada Gama de pic que quiera programar debo aprender un C ? No es todo lo mismo ? Perdón por tantas preguntas
Ok gracias che y nada de hi-tech ?? Estuve viendo y no hay compilador para 16F o sea como un C16 o si ??
//Librerías varias
#include <adc.h>
#include <math.h>
#include <stdio.h>
#if defined ADC_FUNC
/***********************************************************************************/
//Lectura completa del ADC, toma la conersion, espera y lee los registros
int Read_ADC (void){
ConvertADC(); //conversion
while(BusyADC()); //espero a que termine
return ReadADC(); //tomo el valor y lo retorno
}
/***********************************************************************************/
#endif
#if defined FLOAT2STR
/***********************************************************************************/
void float2str(char *buffer, float f){
float fenteros;
float fdecimales;
int entero, decimal;
fenteros = floor(f);
fdecimales = f - fenteros;
entero = (int)fenteros;
decimal = (int)1000 * fdecimales;
sprintf(buffer, "%d.%03i", entero, decimal);
}
/***********************************************************************************/
#endif#ifndef mylibs
#define mylibs
#define ADC_FUNC
#define FLOAT2STR
/***********************************************************************************/
int Read_ADC (void);
void float2str(char *buffer, float f);
/***********************************************************************************/
/***********************************************************************************/
//Frecuencia del cristal externo (no divido internamente) en [Hz]
//Baudios para el USART
#define XTAL 4000000
#define baud 9600
/***********************************************************************************/
/***********************************************************************************/
//Macro para el calculo de baudios automatico
//Hay que colocar el define BAUDIOS en la funcioón OpenUSART
//donde pide el valor de "spbrg" y SPEED_MODE donde pide modo
//high o low speed:
//Ejemplo a 9600 baudios:
//OpenUSART(USART_ASYNCH_MODE & USART_EIGHT_BIT & SPEED_MODE, BAUDIOS);
#if((((XTAL/baud)/16)-1)<255 && (((XTAL/baud)/16)-1)>0)
#define SPEED_MODE USART_BRGH_HIGH
#define BAUDIOS (unsigned int)(((XTAL/baud)/16)-1)
#elif((((XTAL/baud)/64)-1)<255 && (((XTAL/baud)/64)-1)>0)
#define SPEED_MODE USART_BRGH_LOW
#define BAUDIOS (unsigned int)(((XTAL/baud)/64)-1)
#else
#error No se pudo establecer un rate correcto: baudio = baud
#endif
/***********************************************************************************/
#endifClean: Deleting intermediary and output files.
Clean: Deleted file "C:\Disco local Andrés (C)\Electrónica\Pruebas C18\Prueba 1\Main.o".
Clean: Deleted file "C:\Disco local Andrés (C)\Electrónica\Pruebas C18\Prueba 1\mylibs.o".
Clean: Done.
Executing: "C:\MCC18\bin\mcc18.exe" -p=18F4520 "..\..\Escuela Cena\Prueba 1\Main.c" -fo="Main.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\Main.c:26:Warning [2066] type qualifier mismatch in assignment
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\Main.c:32:Warning [2066] type qualifier mismatch in assignment
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\Main.c:37:Warning [2066] type qualifier mismatch in assignment
Executing: "C:\MCC18\bin\mcc18.exe" -p=18F4520 "..\..\Escuela Cena\Prueba 1\mylibs.c" -fo="mylibs.o" -D__DEBUG -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
C:\Disco local Andrés (C)\Electrónica\Escuela Cena\Prueba 1\mylibs.c:31:Error [1020] unexpected input following '#endif'
Halting build on first failure as requested.
----------------------------------------------------------------------
Debug build of project `C:\Disco local Andrés (C)\Electrónica\Pruebas C18\Prueba 1\Prueba ADC.mcp' failed.
Language tool versions: mpasmwin.exe v5.30.01, mplink.exe v4.30.01, mcc18.exe v3.30
Preprocessor symbol `__DEBUG' is defined.
Sat Jul 30 14:34:48 2011
----------------------------------------------------------------------
BUILD FAILED
#include <p18f4520.h>
#include <adc.h>
#include <usart.h>
#include <stdio.h>
#include <math.h>
#include <delays.h>
#include <timers.h>
#include <pwm.h>
#include "mylibs.h"
#pragma config WDT = OFF //WDT apagado
int result;
char string[20];
void main (void){
TRISA = 0xFF; TRISB = 0b00000001; PORTB = 0x00; TRISC = 0x00;
OpenADC(ADC_FOSC_RC & ADC_RIGHT_JUST,ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS, ADC_1ANA);
SetChanADC(ADC_CH0);
OpenUSART(USART_ASYNCH_MODE & USART_EIGHT_BIT & SPEED_MODE, BAUDIOS);
OpenTimer2(TIMER_INT_OFF & T2_PS_1_16 & T2_POST_1_1);
OpenPWM1(10);
SetDCPWM1(5);
printf("Prueba de C18 con PIC18F4520\n\r");
while(1){
if(PORTBbits.RB0 == 1){
result = Read_ADC();
float2str(string,(float)result*5.0/1024.0);
printf("ADC = %u VOLT = %s\n\r",result,string);
Delay10KTCYx(20);
}
else{
if(DataRdyUSART()){
printf("Recibido = %c\n\r",ReadUSART());
}
}
}
}
Pero si divides la frecuencia de Fosc por 4, los cálculos de delay debes hacerlo con 5MHz ;-)
Saludos!
Hay que configurar el xLCD.h y agregar los archivos fuentes de la librería para que sean compilados y se hagan efectivos los cambios, lo hiciste?
Aaa! Mplab ide x! Ahí a remarla solito :tongue: No se como trabajará ese. En todo caso los archivos fuentes están en ..\MCC18\src\pmc_common\XLCD
Saludos!
Nadie sabe por que no funciona el codigo que coloqué arriba ?
#ifndef LCD_USE_3PINES
/* ** Pines tolerables a 5V para usar RW ** */
#define LCD_DATA_PIN_7 LATAbits.LATA3
#define LCD_DATA_PIN_6 LATAbits.LATA2
#define LCD_DATA_PIN_5 LATAbits.LATA1
#define LCD_DATA_PIN_4 LATAbits.LATA0
#define LCD_READ_PIN_7 PORTAbits.RA3
#define LCD_READ_PIN_6 PORTAbits.RA2
#define LCD_READ_PIN_5 PORTAbits.RA1
#define LCD_READ_PIN_4 PORTAbits.RA0
#define LCD_TRIS_DATA_PIN_7 TRISAbits.TRISA3
#define LCD_TRIS_DATA_PIN_6 TRISAbits.TRISA2
#define LCD_TRIS_DATA_PIN_5 TRISAbits.TRISA1
#define LCD_TRIS_DATA_PIN_4 TRISAbits.TRISA0
#define LCD_E_PIN LATCbits.LATC0
#define LCD_RS_PIN LATAbits.LATA4
#ifdef LCD_USE_RW
#define LCD_RW_PIN LATAbits.LATA5
#endif
#define LCD_TRIS_E TRISCbits.TRISC0
#define LCD_TRIS_RS TRISAbits.TRISA4
#ifdef LCD_USE_RW
#define LCD_TRIS_RW TRISAbits.TRISA5
#endif void main(void){
ADCON1=0x0F;
TRISC=0xF0;
LATC=0x00;
LedLCDOn;
test();
vInitLCD();
stdout=_H_USER;
printf("\fProbando LCD\nSegunda linea");
LedLCDOn;
for(;;){
}
}Hola!sobre el tema del oscilador te recomiendo leas el datasheet del pic que uses.
Para utilizar el módulo dedicado a SPI existe librería, <spi.h> la cual tiene funciones para configurar y trabajar con el módulo. Información de como se usa en C:\MCC18\doc\periph-lib, el spi.h en C:\MCC18\h, y los archivos fuente en C:\MCC18\src\pmc_common\SPI
Saludos!
#define microcontrolador1
//#define microcontrolador2
#define teclaDebugger PORTCbits.RC5 // tecla para avanzar en programa para controlar errores
// recordar configurar el tris del puerto correspondiente como entrada
#define ledDebugger LATBbits.LATB4 // led para controlar estado del programa
// recordar configurar el tris del puerto correspondiente como salida
#ifdef microcontrolador1
#define nopulsoboton 0
#else
#define nopulsoboton 1
#endif
//#define nopulsoboton 0
/****************** espera se pulse boton de debugger ************************************/
void EsperaBotonDebugger(void)
{
LATBbits.LATB4=1;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB4=0;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB5=1;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB5=0;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB6=1;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB6=0;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB7=1;
Delay10KTCYx(200); //Retardo para ver lo escrito en lcd
LATBbits.LATB7=0;
while (teclaDebugger==nopulsoboton)
{
}
Delay10KTCYx(10); //Retardo para ver lo escrito en lcd
ledDebugger=1; // ENCIENDO LED
Delay10KTCYx(10); //Retardo para ver lo escrito en lcd
ledDebugger =0; // APAGO LED
Delay10KTCYx(10); //Retardo para ver lo escrito en lcd
ledDebugger =1; // ENCIENDO LED
Delay10KTCYx(10); //Retardo para ver lo escrito en lcd
ledDebugger=0; // APAGO LED
}
/****************** fin espera se pulse boton de debugger ************************************/
#include <p18f4550.h>
#include <delays.h>
//////////////////Configuaracion de bits//////////////////////////
#pragma config PLLDIV = 1 //En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config CPUDIV = OSC1_PLL2 ////En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config USBDIV = 1 /////En este caso no importa por que vamos a utilizar Oscilador Interno
#pragma config FOSC = INTOSCIO_EC //Configurando oscilador interno
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = OFF
#pragma config BORV = 0
#pragma config VREGEN = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 16384
#pragma config MCLRE = OFF
#pragma config LPT1OSC = OFF
#pragma config PBADEN = ON
#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
#pragma config CPD = OFF
#pragma config WRT0 = OFF,WRT1 = OFF,WRT2 = OFF,WRT3 = OFF
#pragma config WRTB = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF,EBTR2 = OFF,EBTR3 = OFF
#define bandera INTCONbits.TMR0IF
void Interrupt_isr_TMR0(void);
//-------------------------------------------------------
void main (void)
{
//------------Configuracion de puertos--------------------------
TRISB=0x00;
LATB=0x00;
ADCON1=0x0F; //Todos los pines digitales.
//----------------Configuracion de oscilador interno------------------
OSCCON=0b01110110; //Oscilador Interno a 8Mhz
//--------------------------------------------------------
RCONbits.IPEN=1; //Habilito prioridad de interrupcion.
INTCONbits.GIE_GIEH=1; //Habilito todas las interrupciones de alta prioridad
INTCONbits.TMR0IE=1; //Habilito Interrupcion TMR0 por desbordamiento
bandera=0; //Pongo a cero la bandera de desbordamiento.
//-------------------------------------------------------------
//------------Configurando el Timer0--------------------------
T0CON=0b11001000; //Configurado a 8 bits sin prescales
TMR0L=00;
while(1){}
}
#pragma code HighVector = 0x08
void high_ISR(void){
_asm goto Interrupt_isr_TMR0 _endasm
}
//Rutina de Interrupciones de alta prioridad
#pragma code
#pragma interrupt Interrupt_isr_TMR0
void Interrupt_isr_TMR0 (void){
TMR0L=206; // 256-206= 50 paso: Como se sabe que cada paso es de 500ns 500ns*50=25us el desbordamiento.
if(bandera==1){
bandera=0;
LATBbits.LATB0=!LATBbits.LATB0;
}
}
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include <i2c.h>
#include <delays.h>
#include <string.h>
#include <stdlib.h> //Libreria para conversiones a string
#include <stdio.h>
#pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)
#pragma config CPUDIV = OSC1_PLL2
#pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
#pragma config FOSC = HSPLL_HS
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config BOR = ON
#pragma config BORV = 3
#pragma config VREGEN = ON //USB Voltage Regulator
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config MCLRE = ON
#pragma config LPT1OSC = OFF
#pragma config PBADEN = OFF
// #pragma config CCP2MX = ON
#pragma config STVREN = ON
#pragma config LVP = OFF
// #pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming
#pragma config XINST = OFF // Extended Instruction Set
#pragma config CP0 = OFF
#pragma config CP1 = OFF
// #pragma config CP2 = OFF
// #pragma config CP3 = OFF
#pragma config CPB = OFF
// #pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
// #pragma config WRT2 = OFF
// #pragma config WRT3 = OFF
#pragma config WRTB = ON // Boot Block Write Protection
#pragma config WRTC = OFF
// #pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
// #pragma config EBTR2 = OFF
// #pragma config EBTR3 = OFF
#pragma config EBTRB = OFF
/** V A R I A B L E S ********************************************************/
#pragma udata
unsigned char ENVIO_I2C[10];
#pragma udata
unsigned char DATO;
/** P R I V A T E P R O T O T Y P E S ***************************************/
void YourHighPriorityISRCode();
void YourLowPriorityISRCode();
unsigned char escribirI2C(unsigned char DIRECCION);
unsigned char leerI2C(unsigned char slave_addr, unsigned char direcc);
/** V E C T O R R E M A P P I N G *******************************************/
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void High_ISR (void) {
_asm goto YourHighPriorityISRCode _endasm
}
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void Low_ISR (void){
_asm goto YourLowPriorityISRCode _endasm
}
#pragma code
#pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode(){
#if defined(USB_INTERRUPT)
USBDeviceTasks();
#endif
}
#pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode(){
}
/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
* Function: void main(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Main program entry point.
*
* Note: None
*****************************************************************************/
/** L E D ***********************************************************/
void main(void)
{
TRISD=0x00;
CloseI2C();
//Iniciamos I2C
OpenI2C(MASTER, SLEW_ON); //MASTER, 400KHZ
SSPADD = 119; // I2C_clock = FOSC/(4 * (SSPADD + 1)) => FOSC = 20MHz y Scl=100KHz //119
// escribirI2C(0xA2);
//ESPERO UN TIEMPO GRANDE ANTES DE LLER
// Delay10KTCYx(200);
DATO = leerI2C(0xA2, 0x40);
while(1){
PORTD = DATO;
}
}
unsigned char leerI2C(unsigned char slave_addr, unsigned char direcc) {
//slave_addr => Direccion de Escritura del dispositivo I2C
unsigned char reg,reg2;
IdleI2C(); // Esperar a que el periferico esté disponible
StartI2C(); // Generar condicion Start
while (SSPCON2bits.SEN); // Espera a que se inicie la condicion START en los pines SDA y SCL
WriteI2C(slave_addr); // Slave address to SSPBUF (Dummy Write)
WriteI2C(direcc); // Word address to SSPBUF
RestartI2C(); // Generar condicion Restart
while (SSPCON2bits.RSEN); // Espera a que se inicie la condicion RESTART en los pines SDA y SCL
WriteI2C(slave_addr | 0x01); // Slave address to SSPBUF (Read)
// while(!DataRdyI2C());
reg = ReadI2C(); // Leer dato de Memoria I2C
while (SSPSTATbits.BF == 1)
NotAckI2C(); // Generar condicion NACK
while (SSPCON2bits.ACKEN); // Espera a que se inicie la condicion NACK en los pines SDA y SCL
StopI2C(); // Generar condicion STOP
while (SSPCON2bits.PEN); // Espera a que se inicie la condicion STOP en los pines SDA y SCL
Delay1KTCYx(25);
return (reg);
}#include <p18f4620.h>
#include <delays.h>
#include <usart.h>
#include <stdio.h>
#include <string.h>
#include <i2c.h>
#pragma config OSC=HSPLL
#pragma config IESO=OFF
#pragma config PWRT=ON
#pragma config WDT=OFF
#pragma config MCLRE=ON
#pragma config XINST=OFF
#pragma config DEBUG=ON
#pragma config FCMEN = OFF
#pragma config LVP=OFF
#pragma config BOREN=OFF
/** V A R I A B L E S ********************************************************/
unsigned int ADDR,DATO,KBIT,i,j,k,L;
#pragma udata
unsigned char ENVIO_I2C[10];
#pragma udata
/** P R I V A T E P R O T O T Y P E S ***************************************/
void low_isr(void);
void high_isr(void);
unsigned char escribirI2C ( unsigned char slave_addr);
unsigned char leerI2C ( unsigned char slave_addr, unsigned char direcc);
/** V E C T O R R E M A P P I N G *******************************************/
//Vector de interrupcion de baja prioridad
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
_asm GOTO low_isr _endasm
}
#pragma code /* Regresa al lugar de donde dio el salto */
#pragma interruptlow low_isr
void low_isr (void)
{
//En esta secccion se coloca las lineas de codigo
//con grado de baja prioridad
}
//Vector de interrupcion de alta prioridad
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}
#pragma code /* Regresa al lugar de donde dio el salto */
#pragma interrupt high_isr
void high_isr (void)
{
//VERIFICA SI SALTO INTERRUPCION, SI EL SSPBUF ESA COMPLETO (BF) Y SI SE TRATA DE LA DIRECCION(D_A)
if (PIR1bits.SSPIF == 1 && SSPSTATbits.BF == 1 && SSPSTATbits.D_A == 0){
ADDR = SSPBUF; //LEO LA DIRECCION
PIR1bits.SSPIF = 0; //BAJO BANDERA
SSPSTATbits.BF = 0; //BAJO DATO DE SSPBUF LLENO
}
//Esto comprueba si una interrupción ha sido recibido, SSPBUF es realmente completo de nuevo,
//y SSPBUF contiene datos (no una dirección). Si todos los cheques que puede leer el byte de datos:
if (PIR1bits.SSPIF == 1 && SSPSTATbits.BF == 1 && SSPSTATbits.D_A == 1){
DATO = SSPBUF;
//Ahora que tenemos nuestros datos tenemos que hacer un poco de limpieza adicional:
PIR1bits.SSPIF = 0; // interrupción clara
SSPSTATbits.D_A = 0; // establecer D_A poco a 0 para que podamos comprobar si el byte posterior es más datos.
}
if (PIR1bits.SSPIF == 1 && SSPSTATbits.BF == 0 && SSPSTATbits.D_A == 0){
WriteI2C(0xA2);
}
PIR1bits.SSPIF = 0; // interrupción clara
}
/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
* Function: void main(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Main program entry point.
*
* Note: None
*****************************************************************************/
/************************************************************************************************/
/*************************************************************************************************************/
//PROGRAMA PRINCIPAL
void main(void)
{
TRISD=0x00;
ADCON1 = 0xFF; //DESHABILITA ENTRADAS ANALOGICAS
RCONbits.IPEN = 1; // habilitamos Prioridades
IPR1bits.SSPIP = 1; //PRIORIDAD ALTA AL I2C
// Configuracion de las interrupciones.
PIE1bits.SSPIE = 1; // Habilita la interrupcion del modulo SSP
INTCONbits.PEIE = 1; // Habilita las interrupciones de los perifericos
INTCONbits.GIE = 1; // Habilita las interrupciones globales!
PIR1bits.SSPIF = 0; // BORRO LA BANDERA DE LA INTERRUPCION
//Iniciamos I2C
OpenI2C(SLAVE_7,SLEW_ON);//MASTER, 400KHZ
SSPADD = 0xA2;
//CONDICIONES INICIALES
i = j = KBIT = 0;
k = 1;
while(1){
}
}
unsigned char escribirI2C(unsigned char DIRECCION) {
//slave_addr => Direccion de Escritura del dispositivo I2C
IdleI2C(); // Esperar a que el periferico esté disponible
StartI2C(); // Generar condicion Start
while (SSPCON2bits.SEN); // Espera a que se inicie la condicion START en los pines SDA y SCL
WriteI2C(DIRECCION); // Slave address to SSPBUF (Write)
//WriteI2C(30); // Write Data to SSPBUF
StopI2C(); // Generar condicion Stop
while (SSPCON2bits.PEN); // Espera a que se inicie la condicion STOP en los pines SDA y SCL
//while (EEAckPolling(slave_addr_w)); //Espera que se complete escritura.
}