He modificado una biblioteca lcd existente, solo funciona en DDRA por ejemplo si cambio:
Error de actualización solucionado:
Encontré que el error en el retraso del ensamblaje del código fue demasiado corto para los puertos B, C y D. Al cambiar el tiempo de retraso, pude usar todos los puertos.
Estoy usando un AVR ATMEGA16 . También he cableado los pines correctos a las líneas de bus de datos.
#define DDR DDRA
#define PORT PORTA
#define PIN PINA
#define RS_PIN 0
#define RW_PIN 1
#define E_PIN 2
a esto no pasa nada
#define DDR DDRC
#define PORT PORTC
#define PIN PINC
#define RS_PIN 0
#define RW_PIN 1
#define E_PIN 2
aquí está el enlace a library
y esto es lo que he cambiado. p.s no da ninguna advertencia o error
#include "lbl_lcd.h"
#include <avr/io.h>
/* One byte delay loop, one loop costs 3 cycles. */
void _lcd_delay_8(uint8_t t) {
asm volatile ( "\n"
"L_dl0%=: subi %0,1" "\n\t"
" brcc L_dl0%=" "\n\t"
:: "r" (t));
}
/* Two byte delay loop, one loop costs 4 cycles. */
void _lcd_delay_16(uint16_t t) {
asm volatile ( "\n"
"L_dl1%=: subi %A0,1" "\n\t"
" sbci %B0,0" "\n\t"
" brcc L_dl1%=" "\n\t"
:: "r" (t));
}
#define DDR DDRD
#define PORT PORTD
#define PIN PIND
#define RS_PIN 0
#define RW_PIN 1
#define E_PIN 2
uint8_t lcd_read_command(void) {
uint8_t command;
DDR|=1<<E_PIN|1<<RW_PIN|1<<RS_PIN; // control bus output
DDR&=~0xF0; // databus input
PORT|=1<<RW_PIN|0xF0; // R/!W= 1 (Read) and Pullup inputs
PORT&=~(1<<RS_PIN); // RS=0
_lcd_delay_us_small(2);
PORT|=1<<E_PIN; // E=1
_lcd_delay_us_small(1);
command=PIN&0xF0; // read high nibble
PORT&=~(1<<E_PIN); // E=0
_lcd_delay_us_small(2);
PORT|=1<<E_PIN; // E=1
_lcd_delay_us_small(1);
command|=PIN>>4; // read low nibble
PORT&=~(1<<E_PIN); // E=0
return command;
}
uint8_t lcd_read_data(void) {
uint8_t data;
DDR|=1<<E_PIN|1<<RW_PIN|1<<RS_PIN;
DDR&=~0xF0;
PORT|=1<<RW_PIN|1<<RS_PIN|0xF0; // R/!W= 1 (Read) RS=1 and Pullup inputs
_lcd_delay_us_small(2);
PORT|=1<<E_PIN;
_lcd_delay_us_small(1);
data=PIN&0xF0;
PORT&=~(1<<E_PIN);
_lcd_delay_us_small(2);
PORT|=1<<E_PIN;
_lcd_delay_us_small(1);
data|=PIN>>4;
PORT&=~(1<<E_PIN);
return data;
}
static void wait(void) {
while (lcd_read_command()&0x80);
}
static void pos_pulse_E(void) {
_lcd_delay_us_small(2);
PORT|=1<<E_PIN; // E=1
_lcd_delay_us_small(1);
PORT&=~(1<<E_PIN); // E=0
}
void lcd_write_command(uint8_t command) {
wait();
DDR|=1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0; // controlbus and databus output
PORT&=~(1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0);
PORT|=command&0xF0; // all control signals low RS=0 R/!W=0
pos_pulse_E();// write high nibble
PORT&=~(1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0);
PORT|=command<<4; // all control signals low RS=0 R/!W=0
pos_pulse_E();// write low nibble
}
void lcd_write_data(uint8_t data) {
wait();
DDR|=1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0;
PORT&=~(1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0);
PORT|=(data&0xF0)|1<<RS_PIN; // RS=1 other control signals 0 R/!W=0
pos_pulse_E();
PORT&=~(1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0);
PORT|=(data<<4)|1<<RS_PIN;
pos_pulse_E();
}
void lcd_init(void) {
DDR|=1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0;
_lcd_delay_us(15000);
PORT&=~(1<<E_PIN|1<<RW_PIN|1<<RS_PIN|0xF0);
PORT|=0x30; // all control signals low RS=0 R/!W=0
pos_pulse_E();
_lcd_delay_us(4100);
pos_pulse_E();
_lcd_delay_us(100);
pos_pulse_E();
_lcd_delay_us(100);
PORT&=~0x10;
pos_pulse_E();
_lcd_delay_us(100);
lcd_write_command(0x28);
lcd_write_command(0x06);
lcd_cls();
lcd_cursor(true, true);
}
void lcd_cls(void) {
lcd_write_command(0x01);
}
void lcd_home(void) {
lcd_write_command(0x02);
}
void lcd_cursor(bool cursorOn, bool cursorBlinks) {
lcd_write_command(0x0C+(cursorOn?0x02:0)+(cursorBlinks?0x01:0));
}
void lcd_goto(uint8_t row, uint8_t column) {
if (row<2 && column<16) {
lcd_write_command(0x80+row*0x40+column);
}
}
uint8_t lcd_get_row(void) {
wait();
return lcd_read_command()&1<<6 ? 1 : 0;
}
uint8_t lcd_get_column(void) {
wait();
return lcd_read_command()&0x3f;
}
void lcd_putc(char data) {
lcd_write_data(data);
}
void lcd_puts(char *s) {
while(*s) {
lcd_putc(*s++);
}
}
void lcd_puts_P(const char* PROGMEM s) {
char c;
while ((c = pgm_read_byte(s++)))
lcd_putc(c);
}