zanak:
yeah I have a 1k resistor, and when I run the code I can see some random caracters with a blinking cursor.
some caracters go off others change, and the cursor moves continuously.
Aha! Then you are VERY close. Find that last little detail and you're in business. Did you try single stepping through the init and the first letter or two? Just do a run-to the beginning of the init and then step-over each line. Takes too long to step-into everything, but if you have to then do that too. Just step-over the delays or you'll be there till next year and wear out that key on your keyboard. :grin:
zanak:
but I have some doubts about the FIOCLR problem.
Here's what mine looks like. Works fine.
void lcd_nybble(unsigned char nyb,unsigned char rs)
{
int i,dat;
if(rs)
FIO0SET |= RS; //set RS pin
else
FIO0CLR |= RS; //clear RS pin
dat = nyb; //get the nybble in an int
FIO0CLR = 0x001e0000; //clear D4-D7
FIO0PIN |= dat<<17; //OR the bits in there
strobe_e(); //latch data to LCD
}
One thing, is that you need to do is to stop using the |= operator with the FIO0SET and FIO0CLR registers. These registers are write only, so the or is not required (and not desired), and in many cases, it can actually cause problems.
This problem is regularly mentioned on the LPC2000 yahoo group, and has been shown to cause behaviour that is unexpected.
manton:
One thing, is that you need to do is to stop using the |= operator with the FIO0SET and FIO0CLR registers. These registers are write only, so the or is not required (and not desired), and in many cases, it can actually cause problems.
This problem is regularly mentioned on the LPC2000 yahoo group, and has been shown to cause behaviour that is unexpected.
Oh ya! Good point! I never thought of that. Now I gotta go fix all my code. :D Luckily it all works good, so I haven't yet been bit by the unexpected behaviour thing.
manton:
One thing, is that you need to do is to stop using the |= operator with the FIO0SET and FIO0CLR registers. These registers are write only, so the or is not required (and not desired), and in many cases, it can actually cause problems.
This problem is regularly mentioned on the LPC2000 yahoo group, and has been shown to cause behaviour that is unexpected.
Mike
yeah exact ! I changed all the OR operation, and now it works fine in simulation, but I still having the same problem, and even the random characters are no longer displayed !!
zanak:
I changed all the OR operation, and now it works fine in simulation, but I still having the same problem, and even the random characters are no longer displayed !!
Here is working delay code for 20x4 with the FIO0SET/FIO0CLR thing fixed:
#include "LPC214x.h"
#include "lcd4bit.h"
#include <stdio.h>
char row[]=" ";
int main(void)
{
SCS = 0x00000001; //enable fast gpio
clkinit();
PINSEL0 = 0x00000000;
FIO0DIR = 0x107e0000;
FIO0CLR = 0x107e0000;
lcd_init();
while(1){
lcd_line1();
sprintf(row,"bleh",0);
lcd_string("LPC2148 LCD");
delay_ms(1000);
lcd_line2();
lcd_string("It works!");
lcd_line3();
lcd_string("Line 3 here.");
lcd_line4();
lcd_string("Here is line 4!");
delay_ms(1000);
}
}
void lcd_string(char *senpoint)
{
while(*senpoint != '\0')
{
lcd_char(*senpoint);
senpoint++;
}
}
void lcd_line1(void)
{
lcd_cmd(0x80);
}
void lcd_line2(void)
{
lcd_cmd(0xc0);
}
void lcd_line3(void)
{
lcd_cmd(0x94);
}
void lcd_line4(void)
{
lcd_cmd(0xd4);
}
void lcd_cmd(unsigned char letter)
{
unsigned char temp;
temp=letter;
temp=temp>>4;
lcd_nybble(temp,0);
temp=letter;
temp=temp&0x0f;
lcd_nybble(temp,0);
}
void lcd_char(unsigned char letter)
{
unsigned char temp;
temp=letter;
temp=temp>>4;
lcd_nybble(temp,1);
temp=letter;
temp=temp&0x0f;
lcd_nybble(temp,1);
}
void lcd_nybble(unsigned char nyb,unsigned char rs)
{
int i,dat;
if(rs)
FIO0SET = RS; //set RS pin
else
FIO0CLR = RS; //clear RS pin
dat = nyb; //get the nybble in an int
FIO0CLR = 0x001e0000; //clear D4-D7
FIO0PIN |= dat<<17; //OR the bits in there
strobe_e(); //latch data to LCD
}
void lcd_init(void)
{
delay_ms(500); //settle time delay
lcd_nybble(0x03,0); //reset LCD
delay_ms(5);
strobe_e();
delay_us(160);
strobe_e();
delay_us(160);
lcd_nybble(0x02,0);
delay_us(160);
lcd_cmd(0x28); //set 4-bit mode and 2 lines
delay_us(160);
lcd_cmd(0x10); //cursor move & shift left
delay_us(160);
lcd_cmd(0x06); //entry mode = increment
delay_us(160);
lcd_cmd(0x0e); //display on - cursor blink on
delay_us(160);
lcd_cmd(0x01); //clear display
delay_ms(40);
}
void strobe_e(void)
{
FIO0SET = E;
delay_us(1);
FIO0CLR = E;
delay_us(160);
}
void delay_ms(int x)
{
int a,b;
for(a=0;a<x;a++){
for(b=0;b<3500;b++);
}
}
void delay_us(int x)
{
int a,b;
for(a=0;a<x;a++){
for(b=0;b<4;b++);
}
}
void clkinit(void)
{
PLLCFG=0x24; //set multiplier and divider values
PLLFEED=0xAA;
PLLFEED=0x55;
PLLCON=0x01; //enable PLL
PLLFEED=0xAA;
PLLFEED=0x55;
while(!(PLLSTAT & PLOCK)); //wait for PLL to lock to set frequency
PLLCON=0x3; //connect PLL as clock source
PLLFEED=0xAA;
PLLFEED=0x55;
MAMCR=0x02; //enable MAM
MAMTIM=0x04; //set number of clocks used for flash memory fetch
VPBDIV=0x01; //set peripheral clock (pclk) to system clock (cclk)
}
void IRQ_Routine (void) {
while (1) ;
}
void FIQ_Routine (void) {
while (1) ;
}
void SWI_Routine (void) {
while (1) ;
}
void UNDEF_Routine (void) {
while (1) ;
}
thank you very much, I just tried the code , still not working …
I’ve replaced the D7-D4 with LEDs, to see if the output change, and yes the LEDs blinks randomly. I tried the code without delays (using RW) but it don’t work, so I can conclude that the problem is not delays … (I guess!)
I think that the problem is power … the system is powered trough the onboard +5v. Olimex says that the board is able to deliver up to 800mA
zanak:
I think that the problem is power … the system is powered trough the onboard +5v. Olimex says that the board is able to deliver up to 800mA
the board is powered using ONLY USB.
800mA should be plenty, but I thought [[USB](http://en.wikipedia.org/wiki/USB) wouldn't deliver more than 100mA (or is it 500mA?) without the code asking for more.
Try powering it from a separate power supply. Can’t hurt to find out if that’s the problem.
The USB specification provides a 5 V supply on a single wire from which connected USB devices may draw power. The specification provides for no more than 5.25 V and no less than 4.75 V (5 V±5%) between the positive and negative bus power lines.
A unit load is defined as 100mA in USB 2.0, and was raised to 150mA in USB 3.0. A maximum of 5 unit loads can be drawn from a port in USB 2.0, and was raised to 6 in USB 3.0. There are two types of devices: low-power and high-power. Low-power devices draw at most 1 unit load, with minimum operating voltage of 4.4V in USB 2.0, and 4V in USB 3.0. High-power devices draw the maximum number of unit loads supported by the standard. All devices default as low-power but the device’s software may request high-power as long as the power is available on the providing bus.
A bus-powered hub is initialized at 1 unit load and transitions to maximum unit loads after hub configuration is obtained. Any device connected to the hub will draw 1 unit load regardless of the current draw of devices connected to other ports of the hub (i.e 1 device connected on a 4 port hub will only draw 1 unit load despite the fact that all unit loads are being supplied to the hub).
A self-powered hub will supply maximum supported unit loads to any device connected to it. A battery powered hub may supply maximum unit loads to port. In addition, the VBUS will supply 1 unit load upstream for communication if parts of the Hub are powered down.