We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I am a newbie, and I am banging my head on the wall to get my system to work. I am lacking tools (scope mainly) but I am really keen to understand how to use the 8051 mcu. I hope more experienced programmers will take some time to help me out , I would really apreciate. What I know is working might help. I have an external EEPROM and RAM, and access to those peripheral is OK. A 4by4 keyboard, connected to P1 works fine, the same for LCD connected to P1, with program running from internal RAM of MCU or external RAM. My problems are : I am using a 2by16 LCD, and I have tested my routines for the LCD by using P1 for the data bus (LCD_BUS), and P3.2, P3.3 and P3.4 as the control lines RS, RW, EN. I do not have any problem at all with the data bus being P1. I also use a matrix keyboard (4 by 4), which I also tested on P1. I wrote the software to be able to change the bus definition by changing the port name, ie #define LCD_BUS P1 for the LCD and #define KEYBOARD P1. I want to use the keyboard on P1, and the LCD on P0. Because I have already a data bus on P0 (I use P0&P2 to access an external program in EEPROM and save data to NVRAM) it saves me one port, but I still use the same control lines (P3.2,P.3,P.4). Now my problem is the LCD does not work at all (probably not configured since I can see the top line with 5*7 black square, ..) I did the following to test the hardware : I tested with the soft running from mcu (/EA = VCC) and remove peripheral from bus (RAM and ROM), still the same. Since P0 is an open drain port, I added 3.3K resistors for the data lines, still the same, and I did change the define statement to use P0. I tried to connect the keyboard to P0, with pull up resistors (3.3K) and the keyboard does not work, and on P2 I have got the same problem ... (I did change the ort definition for the keyboard as well...) So I can have a displayon P1 running fine, the keyboard on P1 as well and that's all folks... I also tried to memory map the LCD, RS being connected to A0, RW to A1, LCD address is 0x8000 anda GAL 16V8A used as the decoder for the chip select /* Inputs: */ Pin 2 = PSEN; /* active low */ Pin 3 = RD; /* active low */ Pin 4 = WR; /* active low */ Pin 5 = A15; /* active high */ /* Outputs: */ Pin 16 = NOE_RAM; Pin 17 = CS_LCD; Pin 18 = CS_RAM; Pin 19 = OE_RAM; /* Logic: EQUATIONS */ OE_RAM = RD & PSEN; CS_LCD = RD & A15 # WR & A15; CS_RAM = !A15; (I use WinCUPL to program the GAL) in the C program I define the CS_ LCD as ADR_LCD : unsigned xdata ADR_LCD _at_ 0x8000; /* chip select for LCD */ #define DATA_BUS P0 to create the enable signal I use CS_LCD = 1; CS_LCD=0; to write a character to display void Data_Write(unsigned char character) { XBYTE[ADR_LCD+1] = character; // RS = 1, R/W = 0 CS_LCD = 1; CS_LCD=0; DATA_BUS = 0xFF; /* Data bus in read mode (HiZ) */ } to read a character to display unsigned char Read_Data(void) { unsigned char Read_bus; DATA_BUS = 0xFF; /* Data bus in read mode (HiZ) */ XBYTE[ADR_LCD+3]; /* RS = 1, R/W = 1 */ CS_LCD = 1; Read_bus = DATA_BUS; /* Read Data */ CS_LCD = 0; /* EN pulse */ return (Read_bus); } I also tried to use a NVRAM (DS1230) to be use to store code and data bu anding /PSEN and /RD as the /OE, /RD connected to /CE and /WR to /WE (equation with the GAL above), and program the NVRAM with a simple routine (loop forever that toggles P1.0 rougthly every second ) and I am sure you have guessed the result ? Does not work. Now I do not have an osilloscope (I know, need the budget...would help a lot). Last problem, I have tried to write low level routines to use with the I2C bus, such as a 24LC16B serial EEPROM and a DS1844 digital potentiometer. I do not think they are not working, but I have roblem with the high level routines and how to use the ack, no_ack signal... Could some point me to some web site with example ? Could someone tell me if I am miles away from the truth, should it be a bad wire connection that could give me so much trouble ? Thanks for any help
OK - LCD & keypad will work on P1, but neither LCD or keypad will work on P0. I see a few potential problems here. I would try to use P0 the same way you used P1. That is, skip using the XBYTE macro and manipulate P0 directly for the LCD. As long as make sure P2.7 (A15) remains high, your RAM & ROM should stay off the bus (assuming your chip select logic only enables RAM or ROM below 0x8000) Then write your code like this: //if P0, RD, WR, A15 are not yet defined // define them here #define P0 0x80 #define RD 0xB7 #define WR 0xB6 #define A15 0xA7 void Data_Write(unsigned char character) { A15 = 1;//this turns off RAM & ROM CS_LCD = 1;//if active hi or 0 if active low //assert anything else that the LCD //needs asserted here WR = 0; //assert write signal P0 = character; //put data on bus WR = 1; //deassert write signal CS_LCD = 0;//if active hi or 1 if active low //deassert everything asserted above here P0 = 0xFF; //maybe not needed - but doesn't hurt } unsigned char Read_Data(void) { unsigned char Read_bus; A15 = 1;//turns off RAM & ROM CS_LCD = 1;//if active hi or 0 if active low //assert anything else that the LCD //needs asserted here P0 = 0xFF;//prime data bus RD = 0;//assert read signal Read_bus = P0; //data is on bus, get it RD = 1;//deassert read signal CS_LCD = 0;//if active hi or 1 if active low //deassert anything asserted above here return (Read_bus); } With no scope or logic analyzer, you can debug your signals with a multimeter by inserting an endless loop in your code immediately after the instruction that you are interested in. Use while(1) ; for your endless loop. Essentially, your setup is "frozen" in the state it was in right before it went into the endless loop. You can then use a regular old multi-meter to see what signals are high and what signals are low. This works, but can be tedious since you have to constantly reprogram the code when you want to move the loop or take it out completely. You can use XBYTE if you want to. But, understand that the read or write takes place entirely "within" that instruction. In other words, you need to make sure that you assert everything that must be asserted and then do the XBYTE then deassert the LCD stuff. Or, if using the GAL to generate your chip selects - fix your CS_LCD equation. CS_LCD = !A15#(RD&WR);//CS_LCD active low CS_LCD = A15&(!RD#!WR);//CS_LCD active hi By the way, getting both the LCD and keypad working on P1 is pretty sophisticated for a Newbie. You are getting close! Good luck.