TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: nordestenica en 25 de Agosto de 2005, 03:31:00
-
me e conprado una entrenadora mas concretamente esta
http://www.primetec.pt/loja/catalogo/product_info.php?products_id=111
lo que passa es que con los exemplos em asm que trae la lcd funciona perfectamente pero quando quiero trabajar em ccs no consigo que arranque e probado casi todos los exemplos que ai para lcd escritos em ccs e ningum me funciona a excepcion de este lo curioso es que la lcd se inicializa e se queda parpadeando el primero caracter pero esso se debe a esto printf ( LCD_PutChar, " 01/20/03 " ); si cambio esto 01/20/03 por otra cosa ya sea numeros o letras la lcd ya no inicializa alguien que tenga unas luzes de asm e me pueda ayudar a adaptar el codido em asm para poder preparar algun otro codigo em ccs
este codigo funciona pero solo inicializa la lcd
#case
#include <16F628.H>
#fuses INTRC_IO, NOPROTECT, PUT, NOWDT, BROWNOUT, NOLVP, NOCPD
/* LCD STUFF */
#define LCD_D0 PIN_B4
#define LCD_D1 PIN_B5
#define LCD_D2 PIN_B6
#define LCD_D3 PIN_B7
#define LCD_EN PIN_A0
#define LCD_RS PIN_A1
#define FIRST_LINE 0x00
#define SECOND_LINE 0x40
#define CLEAR_DISP 0x01
#use delay ( clock=4000000 )
#use standard_io ( A )
#use standard_io ( B )
void LCD_Init ( void );
void LCD_SetPosition ( unsigned int cX );
void LCD_PutChar ( unsigned int cX );
void LCD_PutCmd ( unsigned int cX );
void LCD_PulseEnable ( void );
void LCD_SetData ( unsigned int cX );
/******************************************************************************/
void main ( void )
{
char cX;
// initilize screen
LCD_Init();
LCD_PutCmd ( CLEAR_DISP );
LCD_SetPosition ( FIRST_LINE );
printf ( LCD_PutChar, "DARKROOM SYSTEM " );
LCD_SetPosition ( SECOND_LINE );
printf ( LCD_PutChar, " v1.1 " );
delay_ms ( 1000 );
LCD_SetPosition ( FIRST_LINE );
printf ( LCD_PutChar, " Jon Fick " );
LCD_SetPosition ( SECOND_LINE );
printf ( LCD_PutChar, " 01/20/03 " );
delay_ms ( 500 );
LCD_PutCmd ( CLEAR_DISP );
}
/******************************************************************************/
void LCD_Init ( void )
{
LCD_SetData ( 0x00 );
delay_ms ( 200 ); /* wait enough time after Vdd rise */
output_low ( LCD_RS );
LCD_SetData ( 0x03 ); /* init with specific nibbles to start 4-bit mode */
LCD_PulseEnable();
LCD_PulseEnable();
LCD_PulseEnable();
LCD_SetData ( 0x02 ); /* set 4-bit interface */
LCD_PulseEnable(); /* send dual nibbles hereafter, MSN first */
LCD_PutCmd ( 0x2C ); /* function set (all lines, 5x7 characters) */
LCD_PutCmd ( 0x0C ); /* display ON, cursor off, no blink */
LCD_PutCmd ( 0x01 ); /* clear display */
LCD_PutCmd ( 0x06 ); /* entry mode set, increment */
}
void LCD_SetPosition ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) | 0x08 );
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) );
LCD_PulseEnable();
}
void LCD_PutChar ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
output_high ( LCD_RS );
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
output_low ( LCD_RS );
}
void LCD_PutCmd ( unsigned int cX )
{
/* this subroutine works specifically for 4-bit Port A */
LCD_SetData ( swap ( cX ) ); /* send high nibble */
LCD_PulseEnable();
LCD_SetData ( swap ( cX ) ); /* send low nibble */
LCD_PulseEnable();
}
void LCD_PulseEnable ( void )
{
output_high ( LCD_EN );
delay_us ( 10 );
output_low ( LCD_EN );
delay_ms ( 5 );
}
void LCD_SetData ( unsigned int cX )
{
output_bit ( LCD_D0, cX & 0x01 );
output_bit ( LCD_D1, cX & 0x02 );
output_bit ( LCD_D2, cX & 0x04 );
output_bit ( LCD_D3, cX & 0x08 );
}
este codigo em asm viene como exemplo com la entrenadora e funciona perfectamente :
codigo :
list p=16f628A ;configura o tipo de CPU usado
radix hex ;pre-definicao do tipo de valores numericos usados
include "p16f628a.inc" ;inclui ficheiro das definicoes do PIC16F628A
__config _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_ON & _MCLRE_ON & _INTOSC_OSC_NOCLKOUT & _PWRTE_ON & _WDT_OFF
;---------------------------
temp equ 0x20 ;define endereco 0x20 com o nome de TEMP
;---------------------------
org 0x0000
goto principal ;salta para inicio do programa
tabela
addwf PCL, F ;tabela com frase para escrever no LCD
dt "", 0
principal
;configura toda a porta A como entrada/saida DIGITAL
movlw 0x07 ;carrega W como valor de 0x07
movwf CMCON ;move de W para CMCON
clrf PORTA ;desliga buffers de saida antes de configurar
clrf PORTB ;desliga buffers de saida antes de configurar
;
;configura portas A e B como entradas/saidas
bsf STATUS,5 ;activa bit 5 do registo STATUS, Banco 1
movlw 0x00 ;carrega W com 0x00
movwf TRISA ;move de W para TRISA
movlw 0x00 ;carrega W com 0x00
movwf TRISB ;move de W para TRISB
clrf OPTION_REG ;limpa registo OPTION
bcf STATUS, 5 ;desactiva bit 5 do registo STATUS, Banco 0
;
inicio
call setup ;inicializa e limpa LCD
call lcd101 ;posiciona cursor na 1a linha, 3a posicao
clrf temp ;limpa registo de contagem
repete
movf temp, w ;carrega registo Temp para W
call tabela ;chama tabela
iorlw 0
btfss STATUS, 2 ;testa se chegou ao fim da mesma
goto out ;envia byte para LCD
goto $ ;ciclo infinito, fica nesta posicao
out
call lcdout ;envia dados para o LCD
incf temp, f ;incrementa para nova posicao
goto repete ;salta para carregamento de Temp para W
;---------------------------
include "usar_lcd.asm" ;inclui ficheiro de uso e configuracao do LCD
;---------------------------
end
aqui el driver em asm :
;*************************************************************
;
; Rotina de configuracao, e uso, de LCD com controlador
; HD44780 da Hitachi.
;
; Configurada para correr com oscilador de 4MHz.
; Definicoes incluidas no programa.
; Ambas as portas de dados e comandos podem ser definidas,
; bem como os bits de RS e E.
;
; Declarar registo de OPTION e INTCON.
; Dentro do banco 1, limpar o registo OPTION.
; O registo INTCON eh apenas usado pela rotina de LCD. Ignorar.
;
; Rotinas usadas pelo programa:
;
; * lcdout -> transfere para o LCD, o byte que se encontra
; no acumulador
;
; * setup -> configura o LCD, usando modo de 4-bits
;
; * del_lcd -> limpa o LCD, e retorna ao inicio
;
; * lcd101 -> posiciona cursor na 1a linha, 1a posicao
; Restantes rotinas sao iguais, apenas muda
; a linha e a posicao
;
;*************************************************************
;*************************************************************
; definicoes
;*************************************************************
e equ 1 ;linha E do LCD
rs equ 0 ;linha RS do LCD
porta_comando equ PORTA ;porta de comandos
porta_dados equ PORTB ;porta de dados
loopa equ 0x60
loopb equ 0x61
store equ 0x62
rsline equ 0x63
clkcnt equ 0x64
;*************************************************************
; rotinas de actualizacao do LCD
;*************************************************************
del_lcd movlw 0x01 ;limpa LCD e retorna ao inicio
goto lcdcmd
lcd208 movlw b"11000111" ;posiciona 2a linha, 8a posicao
goto lcdcmd
lcd204 movlw b"11001111" ;posiciona 2a linha, 4a posicao
goto lcdcmd
lcd202 movlw b"11000001" ;posiciona 2a linha, 2a posicao
goto lcdcmd
lcd201 movlw b"11000000" ;posiciona 2a linha, 1a posicao
goto lcdcmd
lcd104 movlw b"10000011" ;posiciona 1a linha, 4a posicao
goto lcdcmd
lcd101 movlw b"10000000" ;posiciona 1a linha, 1a posicao
lcdcmd bcf porta_comando, rs ;limpa pino RS - activa comandos do LCD
lcdout movwf store ;guarda dados em registo temporario
movlw d"10" ;atraso entre bytes enviados para o LCD
movwf loopa
delay decfsz loopa, f ;atraso
goto delay
call mandar ;manda 4bits altos
swapf store, f
call mandar ;manda 4bits baixos
bsf porta_comando, rs ;activa pino RS - activa dados para o LCD
return
mandar ;carrega e manda 4bits
movf store, w
andlw 0xf0 ;AND com 0xF0, 4bits altos da porta B
movwf porta_dados ;carrega o byte na porta B
bsf porta_comando, e
bcf porta_comando, e ;envia
return
;*************************************************************
; rotina de configuracao do LCD
;*************************************************************
setup call pausit ;rotina de atraso
clrf loopb ;limpa registo de loop
lcdset movf loopb, w ;carrega offset para o acumulador
call tablcd ;busca instrucao
call lcdcmd ;envia instrucao para o LCD
incf loopb, f ;incrementa loop
btfss loopb, 3 ;ultima instrucao enviada ??
goto lcdset ;nao
call pausit ;atraso
return ;fim da rotina de configuracao
;*************************************************************
; rotinas de atraso
;*************************************************************
pausit movlw d"60" ;configuracao de atraso
movwf clkcnt
bcf INTCON, 2 ;limpa flag de interrupcao
pause btfss INTCON, 2 ;temporizador chegou ao fim ??
goto pause ;nao
bcf INTCON, 2 ;sim
decfsz clkcnt, f ;decrementa loop, = 0 ??
goto pause ;nao
return ;sim, sai
;*************************************************************
; tabela para configuracao do LCD
;*************************************************************
tablcd addwf PCL,f ;adiciona offset ao Program Counter
retlw b"00110011" ;inicializa LCD - 1o byte
retlw b"00110011" ;2o byte (4x no total)
retlw b"00101100" ;configura para operacao 4-bit & 2 linhas
retlw b"00101100" ;configura para operacao 4-bit & 2 linhas
retlw b"00000110" ;incrementa endereco, a cada byte recebido
retlw b"00001100" ;display on, cursor off, pisca off
retlw b"00000001" ;limpa LCD
retlw b"00000010" ;volta a 1a posicao, cursor & ram a zero
;fim de tabela de configuracao
-
Lo importante no es el código en ASM, es saber como estan conectadas las lineas de la LCD, explica mas datos de estas, si esta en 8 o 4 bits, en que puertos, etc ...



P.D.: La entrenadora es muy bonita, no le falta de nada, pero joder
con el precio.
-
si es interesante pero yo la compre en miau.pt algo parecido a ebay e me a quedado en 75€ hehe
bueno esta conectada em modo 4 bits
la conexion es :
Os jumpers 21, 22 e 23, de nome CTRL, permitem escolher a que barramentos ligam os
sinais de controlo: 21 (R/W → RB3 ou GND), 22 (RS → RB2 ou RA1) e 23 (E → RB1 ou
RA0). Os 4 jumpers DATA permitem escolher a que barramentos ligam as linhas de dados:
portB (RB4-RB7) ou portC (RC0-RC3)
yo la tengo configurada asi e me funciona perfectamente com el exemplo em asm
LCD_D7 pin_b7
LCD_D6 pin_b6
LCD_D5 pin_b5
LCD_D4 pin_b4
LCD_EN pin_a0
LCD_RS pin_a1
segun pone el el tuturial de la entrenadora es compativel con el hd44780 de hitachi
-
Te voy a hacer una oferta que no podrás rechazar. Te pago ahora mismo 80€ por ella
-
hehe gracias pero no esta en venta me estoi quemando los neuronios con elha pero vale la pena ya que soy el mas cabeçota del foro asi que na de nada
-
Amigo nordes... no pude pegar el archivo (no, se) revise su privado...
es una libreria que adapte de este gran foro si le funciona pegela acá.
saludos..
maxluis.
-
ola maxluis antes de nada gracias por intentar ayudarme la question es que e intentado probar el driver pero me da un error te pego el codigo la lcd es uma wm-1602m de wintek que segum parece es compatible com la hitachi
///////////////////////////////////////////////////////////////////////////
//// LCDNORDESTENICA.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<<<RA0
// D1 rs <<<RA1
// D2 rw <<<ra3
// D4 D4 <<<RB4
// D5 D5 <<<RB5
// D6 D6 <<<<RB6
// D7 D7 <<<<RB7
//
// 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
//#device PIC16F876
struct lcd_pin_map { // ESTRUCTURA PARA LA DATA
int otro : 4;
int data : 4;
} lcd;
#byte lcd = 6 // pone la estructura sobre el puerto B
/*esto seria para usar las patillas de control del lcd en
el puerto a */
struct lcd_cont_pin_map{
BOOLEAN enable;//PINA0
BOOLEAN rs;//PINA1
BOOLEAN unuse;
BOOLEAN un;
BOOLEAN unus;
BOOLEAN unused;
//Ultimos 4 pines porta libres
}lcd_cont;
#byte lcd_cont = 5 // Control sobre puerto a
//AMIGO NORDESTECNICA EN TU MAIN QUE TE QUEDEN COMO SALIDAS AL MENOS RA0 Y RA1
//set_tris_a(0b000000);
//lcd_init();
#define set_tris_lcd(x) set_tris_b(x)
#define set_tris_lcd_cont(x) set_tris_a(x)
#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_pin_map const LCD_WRITE = {0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd_cont.rw = 1; //aqui me da un error pone esto ( elemente is not a member ) delay_cycles(1);
lcd_cont.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd_cont.enable = 0;
delay_cycles(1);
lcd_cont.enable = 1;
delay_us(1);
low = lcd.data;
lcd_cont.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd_cont.enable = 1;
delay_us(2);
lcd_cont.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd_cont.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd_cont.rs = address;
delay_cycles(1);
lcd_cont.rw = 0;
delay_cycles(1);
lcd_cont.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd_cont.rs = 0;
lcd_cont.rw = 0;
lcd_cont.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);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd_cont.rs=1;
value = lcd_read_byte();
lcd_cont.rs=0;
return(value);
}
-
Y es realidad lo que pone...
En tu estructura Lcd_Cont no has declarado al pin rw, posiblemente porque no lo utilizas, en ese caso no lo llamas y listo.

-
hehe ya funciona e probado casi todos los exemplos me e quedado casi sin neuronios pero al final e vencido

queren saber porque no funcionava pues el senhor que a escrito el manual de la entrenadora se a equivocado e a cambiado las lineas de rs e enable o sea en la entrenadora enable va a A1 e rs a A0 pero en el manual estan cambiadas por esso no conseguia poner em marcha la dichosa lcd
-
Por fin !!

Te iba a preguntar algo nordestenica, ¿tu entrenadora para que micro es? Me ha llamado mucho la atención.
-
perdona por el retraso pero aqui va es para las famílias 12C/Fxxx, 16C/Fxxx e 18C/Fxxx aunque el que mas me gusta no esta contemplado que es el 16f877 pero bueno estoi en este momentos montando un adaptador para este
-
Aja, pues si que viene completita
Yo aver si me monto una para el 18f4550