TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: pentax30 en 29 de Marzo de 2005, 09:44:00
-
BUENAS A TODOS:
Dispongo de la Micro pic trainer de Mirosystems Enginering i quiero conectar el lcd con bus de 4 bits para poder utilizar la patillas RB4.....7 como entradas de interrupcion, agradeceria si alguien me puede dar una paequeña ayuda en donde puedo encontrar una rutina que utilice el portB i el portA para comunicar com el LCD 4 bits.
Gracias por la ayuda prestada.
-
Hola pentax, lo que kieres es una rutina para LCD de CCS que trabaje con el MicroPIc Trainer, no? Si es asi, dimelo y te envio la que usaba yo con mi Trainer y que iba bastante bien.
Luego lo de utilizar RB4..RB7 como entradas de interrupcion se hace simplemente reprogramando el PIC y jumpeando correctamente el MicroPIc Trainer.
Un saludo.
-
Hola pentax30, aki te dejo la libreria modificada que uso yo para que funcione perfectamente en ccs con el micropictrainer, espero que te sirva de ayuda, un saludo.
///////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// f Clear display ////
////
Go to start of second line ////
//// Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
#define use_portb_lcd TRUE
struct lcd_control_pin_map { // This structure is overlayed
BOOLEAN rs; // on to an I/O port to gain
BOOLEAN rw; // access to the LCD pins.
BOOLEAN enable; // The bits are allocated from
// BOOLEAN unused; // low order up. ENABLE will
// int data : 4; // be pin B0.
} lcd_control;
struct lcd_data_pin_map {
BOOLEAN nc1;
BOOLEAN nc2;
BOOLEAN nc3;
BOOLEAN nc4;
int data : 4;
} lcd_data;
#if defined(__PCH__)
#if defined use_portb_lcd
#byte lcd = 0xF81 // This puts the entire structure
#else
#byte lcd = 0xF83 // This puts the entire structure
#endif
#else
#if defined use_portb_lcd
#byte lcd_data = 6 // on to port B (at address 6)
#byte lcd_control = 5
#else
#byte lcd = 8 // on to port D (at address 8)
#endif
#endif
#if defined use_portb_lcd
#define set_tris_lcd_data(x) set_tris_b(x)
#define set_tris_lcd_control(x) set_tris_a(x)
#else
#define set_tris_lcd(x) set_tris_d(x)
#endif
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_data_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_data_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
struct lcd_control_pin_map const LCD_CONTROL_WRITE = {0,0,0};
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd_data(LCD_READ);
lcd_control.rw = 1;
delay_cycles(1);
lcd_control.enable = 1;
delay_cycles(1);
high = lcd_data.data;
lcd_control.enable = 0;
delay_cycles(1);
lcd_control.enable = 1;
delay_us(1);
low = lcd_data.data;
lcd_control.enable = 0;
set_tris_lcd_data(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd_data.data = n;
delay_cycles(1);
lcd_control.enable = 1;
delay_us(2);
lcd_control.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd_control.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd_control.rs = address;
delay_cycles(1);
lcd_control.rw = 0;
delay_cycles(1);
lcd_control.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd_data(LCD_WRITE);
set_tris_lcd_control(LCD_CONTROL_WRITE);
lcd_control.rs = 0;
lcd_control.rw = 0;
lcd_control.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case "f" : lcd_send_byte(0,1);
delay_ms(2);
break;
case "
" : lcd_gotoxy(1,2); break;
case "" : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
-
hola Tornar
estube probando tu rutina i no ser que hago mal pero no consigo que funcione, he probado con varias rutinas mas i tampoco no ser si es que soy gafe o que simplemente soi un patoso.
Te mando quen me sea posible el programa y le echas un vistazo.
GRACIAS
-
Haz lo siguiente, coge el archivo de arriba y le guardas en c:Archivos de programaPICCDriversLCD_MPT.C (suponiendo que tienes el PICC instalado en archivos de programa), y luego ejecuta el siguiente codigo.
#include <16f84a.h>
#fuses NOWDT, HS, NOPROTECT
#use delay(clock=20000000)
#include <LCD_MPT.c>
void main()
{
lcd_init();
printf(lcd_putc,"Prueba"
;
delay_ms(1000);
}
lo compilas, y en el archivo .HEX que te genere, le kitas la ultima linea que pondra algo asi como ;PIC16F84A, y ya solo te keda grabar dicho archivo a la trainer con el programa PIC Programmer de la pagina web de MSE.
Un saludo, y no dudes en preguntar cualkier cosa, que yo tambien tuve problemas cuando empece con la MicroPicTrainer
-
hola tornar
me parece que el texo de arriba no esta completo la parte que falta es igual que la de la libreria original?
gracias
Esta tarde probaré lo que me has pasado haber si funciona.
-
cierto pentax, al parecer los foros de miarroba no permiten exceder un numero de lineas en los mensajes. Prueba a copiar el resto de codigo de la libreria normal, a partir de donde falta, pq los cambios estan hechos principalmente en el inicio de la libreria, el resto es igual.
-
Hola mira que si usas lcd de la marca powertip algunos no tienen la mismarutina de inicializacion o varian los timing de las mismas por eso puede ser que no te funcionen.
Aqui te envio una para powertip solo tienes que modificar las direcciones para trabajar con el puerto B
Espero que te sirba.
Eduardo
-
buenas
Hola Tornar
He probado el programa que me has pasado tu com el 16f84 i he de decir que funciona perfectamente ahora voy a probar de realizar un pequenyo programa con el que utilizo el PIC16F876 
Muchas gracias por echar-me este cable, tendre que volver ha escribir la mayoria de codigo paso a paso para asegurar que todo esta bien.
-
aki te dejo una q suelo usar... no se de donde la saké asiq no puedo citar la fuente

es totalmente configurable y no tiene pata de R/W (hay q ponerla a masa)... x lo q no podrás leer del LCD (q pocas veces se hace
, está preparada para 4Mhz, si vas a usar un clock mayor tendrás que ajustar los tiempos 
//include LCD para CCS
// La ventaja de este codigo es que puedes trabajar si lo quieres con pines
// dispersos es decir no estas sujeto a la mitad de un puerto
// Registros de Puertos A
#define PORTC 0xf82 // PortC
#define TRISC 0xf94 // TrisC
// Definición de Puertos Pantalla LCD 40x20 Hitachi 44780
#bit lcd_en = PORTC.0
#bit tris_lcd_en = TRISC.0
#bit lcd_rs = PORTC.1
#bit tris_lcd_rs = TRISC.1
#bit lcd_db4 = PORTC.4
#bit tris_lcd_db4 = TRISC.4
#bit lcd_db5 = PORTC.5
#bit tris_lcd_db5 = TRISC.5
#bit lcd_db6 = PORTC.6
#bit tris_lcd_db6 = TRISC.6
#bit lcd_db7 = PORTC.7
#bit tris_lcd_db7 = TRISC.7
// lcd_init() Inicialización del LCD (debe utilizarse al principio,
// antes de trabajar con el LCD).
//
// lcd_putc(c) Imprime un caracter en el LCD.
//
// lcd_gotoxy(x,y) Selecciona la nueva posicion de escritura en el LCD.
// (la esquina superior izquierda es 1,1)
//
// lcd_getc(x,y) Devuelve el caracter de la posicion x,y del LCD.
//
// void lcd_erase_line(x) Borra una cantidad de caracter hacia la derecha
// Conexion a la pantalla LCD 40x4
// RA0 <---> LCD DB4
// RA1 <---> LCD DB5
// RA2 <---> LCD DB6
// RA3 <---> LCD DB7
// RA5 <---> LCD ENABLE
// RA4 <---> LCD RS
//
#define LCD_DATO 1
#define LCD_INST 0
#define LCD_LINEA1 0x80 // Direccion de memoria para la 1 linea
#define LCD_LINEA2 0xc0 // Direccion de memoria para la 2 linea
#define LCD_LINEA3 0x94 // Direccion de memoria para la 3 linea
#define LCD_LINEA4 0xd4 // Direccion de memoria para la 4 linea
// 7 6 5 4 3 2 1 0
// Function Set 0b 0 0 1 B L F 0 0
// Bus size, B:0=4 bits, B:1=8 bits
// Line Number, L:0=1 Line, L:1=2 Lines
// Font size F:0=5x8, F:1=5x10
#define LCD_FUNCTION_SET 0b00101000 // Bus=4bit, Line=2 & Font=5x8
// 7 6 5 4 3 2 1 0
// Display/Cursor 0b 0 0 0 0 1 D U B
// Set Display on/off, D:0=off, D:1=on
// Underline cursor, U:0=off, U:1=on
// Blinking cursor, B:0=off, B:1=on
#define LCD_DISPLAY_CURSOR 0b00001100 // Display=on, Scroll=off, Blinkin=off
// 7 6 5 4 3 2 1 0
// Entry Mode 0b 0 0 0 0 0 1 M S
// Cursor direction, M:0=left, 1=right
// Display Scroll, S:0=no scroll, S:1=scroll
#define LCD_ENTRY_MODE 0b00000110 // Increment cursor, no disp shift
#define LCD_CLEAR_DISPLAY 0b00000001 // Clear Display
void lcd_set_write()
{
tris_lcd_db4 = 0; //
tris_lcd_db5 = 0; //
tris_lcd_db6 = 0; //
tris_lcd_db7 = 0; //---> Set PORTC RA0-RA3 mode output
}
void lcd_send_nibble(int8 n)
{
if (bit_test(n,0)) //
lcd_db4 = 1; //
else //
lcd_db4 = 0; //
if (bit_test(n,1)) //
lcd_db5 = 1; //
else //
lcd_db5 = 0; //
if (bit_test(n,2)) //
lcd_db6 = 1; //
else //
lcd_db6 = 0; //
if (bit_test(n,3)) //
lcd_db7 = 1; //
else //
lcd_db7 = 0; //---> Set data nibble
delay_cycles(1); // nop
lcd_en = 1; // Habilita LCD Enable __
delay_us(2); // Espera 2 uSeg. | |
lcd_en = 0; // Desabilita LCD Enable __| |__
}
void lcd_send_byte (int1 select, int8 n)
{
lcd_rs = 0; // Modo de instruccion
delay_us(10);
lcd_rs = select; // Escoje entre RS=0 : Instruccion & RS=1 : Data
delay_cycles(1); // nop // 5 original
lcd_en = 0; // Desabilita LCD Eneable
lcd_send_nibble(n >> 4); // Envia los datos superiores MSB
lcd_send_nibble(n); // Envia los datos inferiores LSB
}
void lcd_init()
{
int8 i, count=0;
lcd_set_write(); // Prepara el puerto DB4-DB7 como salida
tris_lcd_en = 0; //
tris_lcd_rs = 0; //---> Set PORTC RA0, RA1 & RA2 mode output
lcd_en = 0; //
lcd_rs = 0; //---> Clear LCD_EN, LCD_RW & LCD_RS
delay_ms(15);
// retry:
for(i=1; i<=3; ++i)
{
lcd_send_nibble(0b0011); // 8 bit mode 3 times
delay_ms(5);
}
lcd_send_nibble(0b0010); // 4 bit mode
lcd_send_byte(LCD_INST, LCD_FUNCTION_SET); // Function Set
lcd_send_byte(LCD_INST, LCD_DISPLAY_CURSOR); // Display Cursor
lcd_send_byte(LCD_INST, LCD_ENTRY_MODE); // Entry Mode
lcd_send_byte(LCD_INST, LCD_CLEAR_DISPLAY); // Clear Display
}
void lcd_gotoxy(int8 x, int8 y)
{
int8 const address[4]={LCD_LINEA1,LCD_LINEA2,LCD_LINEA3,LCD_LINEA4};
int8 pos;
pos=address[y-1]+(x-1);
lcd_send_byte (LCD_INST, pos);
}
void lcd_putc(char c)
{
switch (c)
{
case "f" : lcd_send_byte(0,1); //Limpia la pantalla
delay_ms(2);
break;
case "
" : lcd_gotoxy(1,2); //Coloca puntero en 1ª posicion de la 2ª línea
break;
case "" : lcd_send_byte(LCD_INST,0x10); //Retrocede una posición el cursor
break;
case " " : lcd_send_byte(LCD_INST,0x14); //Avanza una posición el cursor
break;
case "" : lcd_send_byte(LCD_INST,0x18); //Retrocede una posición la pantalla visible
break;
case "v" : lcd_send_byte(LCD_INST,0x1C); //Avanza una posición la pantalla visible
break;
default : lcd_send_byte(LCD_DATO,c); //Envía caracter a DDRAM,
break; //Si es una tira, los envía todos uno a uno
}
}
void lcd_clear()
{
lcd_send_byte(LCD_INST,0x01);
}
void lcd_home()
{
lcd_send_byte(LCD_INST,0x02);
}
void lcd_erase_line(int8 x)
{
int8 i;
for(i=1;i<=x;++i)
{
lcd_send_byte(LCD_DATO,32);
}
}
Saludos!
-
BUENO CHICOS
Parece que porfin la rutina funciona , el problema estaba en que se producia una interrupcion continuamente, , probe con eliminar las linias que hacian referencia a la interrupciion i funciono, lo unico que tengo que trabajar con los 4 bits altos del portB pues el LCD segun parece en formato de de 4 bits utiliza los bits altos del bus.
Quiero agradecer a todos vuestra ayuda prestada, ah J1M gracias por tu codigo lo tendré en cuenta para proximas aplicaciones pues es muy interesante, a TORNAR agradecerle la ayuda i el codigo del LCD.
GRACIAS A TODOS
Me gusta este foro es muy interesante