First of all, hey everyone! I'm kinda new to this business (although I have a couple of years worth of experience with programming in general), and I just found out about this forum, because I've encountered a problem with my microcontroller programming. I have a bit of experience with microcontrollers from one of college courses, but only in Assembly and this is a bit more complex than what I've learned there. I have a project where I need to program the microcontroller to write some text to the LCD, and for starters I just it to write a simple "Hello world", but I've ran headfirst into a wall right off the bat. I've gotten a header file online for working with the LCD, and I've managed to pick up what's it doing for the most part, but I can't seem to get the LCD to display any text at all, all it does is start up, I get a blinking cursor which I can move around by setting the ENABLE bit to 1 through my developing board (not sure if that's the correct term, English is not my native language) and that's it (even though it shouldn't be blinking or even be there at all based on the code). I'm using MPLAB with Hi-Tech C Compiler. Something seemed wrong with the interface length setup with the code being 0x28, because the datasheet clearly states that the 5th bit should be 1, so I've tried changing that, but to no avail. Here's the code and the datasheet for the LCD; any help would be greatly appreciated. Thanks in advance!
#delay.h
#lcd.h
#main.c
#delay.h
Rich (BB code):
#define MHZ *1000L /* number of kHz in a MHz */
#define KHZ *1 /* number of kHz in a kHz */
#if XTAL_FREQ == 20MHZ
#define DelayUs(x) { unsigned int _dcnt; \
_dcnt = (x)/3; \
while(--_dcnt != 0) \
continue; }
#elif XTAL_FREQ == 16MHZ
#define DelayUs(x) { unsigned int _dcnt; \
_dcnt = (x)/3.75; \
while(--_dcnt != 0) \
continue; }
#elif XTAL_FREQ == 8MHZ
#define DelayUs(x) { unsigned int _dcnt; \
_dcnt = (x)/7.5; \
while(--_dcnt != 0) \
continue; }
#elif XTAL_FREQ == 4MHZ
#define DelayUs(x) { unsigned int _dcnt; \
_dcnt = (x)/15; \
while(--_dcnt != 0) \
continue; }
#else
#error Please define XTAL_FREQ - 20MHZ/16MHZ/8MHZ/4MHZ
#endif
void DelayMs(unsigned int cnt){
do {
DelayUs(1000);
} while(--cnt);
}
Rich (BB code):
/*
* LCD interface example
* Uses routines from delay.c
*
* RD3 is connected to the LCD RS input (register select)
* RD2 is connected to the LCD RW bit (read/write)
* RD1 is connected to the LCD EN bit (enable)
* RD4-RD7 are connected to the LCD data bits 4-7 (high nibble)
*
* To use these routines, set up the port I/O (TRISD) then
* call lcd_init(), then other routines as required.
*
*/
#ifndef _XTAL_FREQ
// Unless specified elsewhere, 4MHz system frequency is assumed
#define _XTAL_FREQ 4000000
#endif
#include <htc.h>
#include "delay.h"
#define LCD_RS RD3
#define LCD_RW RD2
#define LCD_EN RD1
#define LCD_DATA PORTD
#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))
unsigned char lcd_line;
/* write a byte to the LCD in 4 bit mode */
void lcd_write(unsigned char rs_bit, unsigned char c)
{
LCD_RS = rs_bit;
DelayUs(50);
LCD_DATA = (c & 0xF0);// | (LCD_DATA & 0x0F);
LCD_STROBE();
LCD_DATA = ( ( c << 4 ) & 0xF0 );// | (LCD_DATA & 0x0F);
LCD_STROBE();
DelayUs(50);
}
/*
* Go to the specified position
*/
void lcd_goto(unsigned char pos_x,unsigned char pos_y)
{
pos_y--;
lcd_line = pos_x;
lcd_write(0, 0b00000010); //1.1: CURSOR RETURN
DelayMs(2);
if(pos_x == 1)
{
lcd_write(0, 0x80+pos_y);
}
else if(pos_x == 2)
{
lcd_write(0, 0xC0+pos_y);
}
else if(pos_x == 3)
{
lcd_write(0, 0x94+pos_y);
}
else if(pos_x == 4)
{
lcd_write(0, 0xD4+pos_y);
}
}
/*
* Clear and home the LCD
*/
void lcd_clear(void)
{
lcd_line=1;
lcd_write(0,0x1);
DelayMs(2);
}
/* write a string of chars to the LCD */
void lcd_puts(const char * s)
{
LCD_EN = 0;
int i = 0;
while(*s)
{
switch (*s)
{
case '\b': lcd_write(0,0x10); break; //backspace
case '\f': lcd_write(0,0x1); //clear display
DelayMs(2);
break;
case '\n': lcd_goto(lcd_line++,1); break; //newline
default : lcd_write(1,s); // write characters
break;
}
i++;
}
LCD_EN = 1;
}
/* write one character to the LCD */
void lcd_putch(unsigned char c)
{
lcd_write(1, c); // write characters
}
//Backspace
void lcd_back(void)
{
lcd_write(0,0x10);
}
/* initialise the LCD - put into 4 bit mode */
void lcd_init()
{
LCD_RS = 0;
LCD_EN = 0;
LCD_RW = 0;
DelayMs(15); // wait 15mSec after power applied,
LCD_DATA = (LCD_DATA & 0x0F) | ( ( 0x3 << 4 ) & 0xF0 ); //Reset
LCD_STROBE();
DelayMs(5);
LCD_STROBE();
DelayUs(200);
LCD_STROBE();
DelayUs(200);
LCD_DATA = (LCD_DATA & 0x0F) | ( ( 0x2 << 4 ) & 0xF0 ); // Four bit mode
LCD_STROBE();
lcd_write(0, 0b00101000); // Set interface length
lcd_write(0, 0b00001100); // Display On, Cursor Off, Cursor Blink Off
lcd_clear(); // Clear screen
lcd_write(0, 0x6); // Set entry Mode
}
#main.c
Rich (BB code):
#define XTAL_FREQ 4MHZ
#include <htc.h>
#include "lcd.h"
void
main(void)
{
TRISD = 0b00000000;
lcd_init();
lcd_goto(2, 5);
lcd_puts("Hello world!");
while (1);
}
Attachments
-
108.5 KB Views: 89