Moderadores: andre_luis, 51, guest2003, Renie
// Flex_LCD420.c
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
#define LCD_RS PIN_D1
#define LCD_RW PIN_D2
#define LCD_E PIN_D0
#define USE_RW_PIN 1
// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines(or more)
int8 lcd_line;
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Set mode: 4-bit, 2+ lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_RW_PIN
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_us(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
delay_us(1);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_RW_PIN
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_RW_PIN
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
lcd_line = 1;
output_low(LCD_RS);
#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif
output_low(LCD_E);
// Some LCDs require 15 ms minimum delay after
// power-up. Others require 30 ms. I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 50 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_RW_PIN
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
switch(y)
{
case 1:
address = LCD_LINE_1_ADDRESS;
break;
case 2:
address = LCD_LINE_2_ADDRESS;
break;
case 3:
address = LCD_LINE_3_ADDRESS;
break;
case 4:
address = LCD_LINE_4_ADDRESS;
break;
default:
address = LCD_LINE_1_ADDRESS;
break;
}
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
lcd_line = 1;
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1, ++lcd_line);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_RW_PIN
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(LCD_RS);
return(value);
}
#endif
jandom escreveu:OBRIGADO PELA AJUDA!
MAS ESTA ROTINA USA O R/W E NÃO TENHO PINO MAIS DISPONÍVEL NO PIC!
/*
* LCD interface example
* Uses routines from delay.c
* This code will interface to a standard LCD controller
* like the Hitachi HD44780. It uses it in 4 bit mode, with
* the hardware connected as follows (the standard 14 pin
* LCD connector is used):
*
* PORTB bits 4-7 are connected to the LCD data bits 4-7 (high nibble)
* PORTB bit 3 is connected to the LCD RS input (register select)
* PORTC bit 5 is connected to the LCD EN bit (enable)
*
* To use these routines, set up the port I/O (TRISB, TRISC) then
* call lcd_init(), then other routines as required.
*
*/
#include "lcd.h"
char lcdPosition;
void lcdDataIn(char c)
{
char d,e;
d=(c<<4);
d&=0xf0;
e=(LCD_DATA & 0x0f);
LCD_DATA=(d|e);
}
/* write a byte to the LCD in 4 bit mode */
void lcd_write(unsigned char c)
{
Delay_Us(40);
lcdDataIn(c >> 4);
LCD_STROBE();
lcdDataIn(c);
LCD_STROBE();
}
/*
* Clear and home the LCD
*/
void lcd_clear_lb(void)
{
LCD_RS = 0;
lcd_write(0x1);
Delay_Ms(2);
}
/* write one character to the LCD */
void lcd_putch(char c)
{
LCD_RS = 1; // write characters
lcd_write( c );
lcdPosition++;
/*if (lcdPosition==15) 16X2
lcd_goto(0x00);
if (lcdPosition==0x48)
lcd_goto(0x00);*/
if (lcdPosition==0x08)
lcd_goto(0x08); //16X1
if (lcdPosition==0x48)
lcd_goto(0x00);
}
/*
* Go to the specified position
*/
void lcd_goto(unsigned char pos)
{
char temp;
LCD_RS = 0;
temp=pos & 0b00001000; //tirar daqui
temp=temp<<3;
pos &= 0b00000111;
pos+=temp;
lcdPosition=pos; //até aqui
lcd_write(0x80+pos);
}
/* initialise the LCD - put into 4 bit mode */
void lcd_init_lb()
{
char init_value;
init_value = 0x3;
LCD_CTRL_CONTROL = LCD_CTRL_CFG;
LCD_DATA_CONTROL = LCD_DATA_CONFIG;
LCD_RS = 0;
LCD_EN = 0;
Delay_Ms(15); // wait 15mSec after power applied,
lcdDataIn(init_value);
LCD_STROBE();
Delay_Ms(5);
LCD_STROBE();
Delay_Us(200);
LCD_STROBE();
Delay_Us(200);
lcdDataIn(2);// Four bit mode
LCD_STROBE();
lcd_write(0x28); // Set interface length
lcd_write(0x0C); // Display On, Cursor Off, Cursor don't Blink
lcd_clear_lb(); // Clear screen
lcd_write(0x06); // Set entry Mode
lcd_goto(0);
}
/*
* LCD interface header file
* See lcd.c for more info
*/
#define LCD_RS PORTC.F5
#define LCD_EN PORTB.F3
#define LCD_DATA PORTB
#define LCD_DATA_CONTROL TRISB
#define LCD_DATA_CONFIG 0x07
#define LCD_CTRL_CONTROL TRISC
#define LCD_CTRL_CFG 0x5c
#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))
void lcdDataIn(char c);
/* write a byte to the LCD in 4 bit mode */
extern void lcd_write(unsigned char);
/* Clear and home the LCD */
extern void lcd_clear_lb(void);
/* Go to the specified position */
void lcd_goto(unsigned char pos);
/* intialize the LCD - call before anything else */
extern void lcd_init(void);
void lcd_putch(char c);
/* Set the cursor position */
#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)
/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}
lellis escreveu:faltou
- Código: Selecionar todos
/* write a string of chars, in ROM, to the LCD */
void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}
/* write a string of chars, in RAM, to the LCD */
void lcd_puts( char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante