Hello
I have confused in the coding of the Serial Graphical LCD on NXP P89V664.
Can any one help ????
the code is
#include<reg52.H> #include<stdio.h> #include<intrins.h> // #define unsigned char unsigned char // 0~255 // #define unsigned int unsigned int // 0~65535 sbit _CS = P2^3; sbit _RST = P2^2; sbit A0 = P2^1; sbit SCK = P4^0; sbit DIN = P4^2; unsigned char ContrastLevel; // for contrast setting level //----------------------------------- // dispaly data (128x64) //----------------------------------- unsigned char code Logo[]={ ....0x15,0x06,0x00,0x00,0x10,0x1F,0x10,0x00,0x00,0x12,0x15,0x15,0x15,0x88,0xC0 }; //----------------------------------- // Delay Routine //----------------------------------- void delayms(unsigned int m) // 12MHz Xtal, close to ms value { unsigned int j; unsigned int i; for(i=0; i<m; i++) for(j=0; j<109; j++) _nop_(); } //----------------------------------- // IO Routine //----------------------------------- void lcd_cmd(unsigned char Command) //send command { SCK = 1; A0 = 0; _CS = 0; DIN = Command & 0x80; SCK= 0; SCK= 1; DIN = Command & 0x40; SCK= 0; SCK= 1; DIN = Command & 0x20; SCK= 0; SCK= 1; DIN = Command & 0x10; SCK= 0; SCK= 1; DIN = Command & 0x08; SCK= 0; SCK= 1; DIN = Command & 0x04; SCK= 0; SCK= 1; DIN = Command & 0x02; SCK= 0; SCK= 1; DIN = Command & 0x01; SCK= 0; SCK= 1; _CS = 1; } void lcd_data(unsigned char DData) //send data { SCK= 1; A0 = 1; _CS = 0; DIN = DData & 0x80; SCK= 0; SCK= 1; DIN = DData & 0x40; SCK= 0; SCK= 1; DIN = DData & 0x20; SCK= 0; SCK= 1; DIN = DData & 0x10; SCK= 0; SCK= 1; DIN = DData & 0x08; SCK= 0; SCK= 1; DIN = DData & 0x04; SCK= 0; SCK= 1; DIN = DData & 0x02; SCK= 0; SCK= 1; DIN = DData & 0x01; SCK= 0; SCK= 1; _CS = 1; } //----------------------------------- // Write a Screen //----------------------------------- void WriteScreen(unsigned char *DisplayData) // DisplayData should be 164x64/8 = 1312byte { unsigned char TempData; unsigned char i, j; for(i=0;i<8;i++) { lcd_cmd(0xb0 | i); // select page 0~7 lcd_cmd(0x10); // start form column 4 lcd_cmd(0x00); // (2byte command) for(j=0;j<128;j++) { TempData=(*(DisplayData+(i*128)+j)); lcd_data(TempData); } } } //----------------------------------- // Contrast control //----------------------------------- void LCD_Darker(void) { if (ContrastLevel<0x3F) { ContrastLevel++; } lcd_cmd(0x81); // E-Vol setting lcd_cmd(ContrastLevel); // (2byte command) } void LCD_Lighter(void) { if (ContrastLevel>0x00) { ContrastLevel--; } lcd_cmd(0x81); // E-Vol setting lcd_cmd(ContrastLevel); // (2byte command) } //----------------------------------- // Init LCD module //----------------------------------- void initLCDM(void) { _RST=1; // hardware reset LCD module _RST=0; delayms(1); _RST=1; delayms(800); ContrastLevel=0x17; // default Contrast Level 1a lcd_cmd(0xab); //new lcd_cmd(0xaf); // display on lcd_cmd(0x40); // display start line=0 lcd_cmd(0xc8); // Common output mode select= reverse lcd_cmd(0xa6); // normal display lcd_cmd(0xa4); // Duisplay all point = off lcd_cmd(0xa3); // LCD bias = 1/9 a2 lcd_cmd(0x2f); // Power control = all on lcd_cmd(0x25); // Rab Ratio 26 lcd_cmd(0x81); // E-Vol setting lcd_cmd(ContrastLevel); // (2byte command) } //----------------------------------- // Main Program //----------------------------------- void main() { SP=0x60; EA = 0; // disable interrupts _CS =1; _RST =1; A0 =1; SCK =1; DIN =1; initLCDM(); WriteScreen(Logo); while(1) { } } //end of program
The error it shoes that P4 is an undefined identifier. error C202
C:\KEIL\C51\INC\PHILIPS\P89V66X.H(13): error C231: 'P0': redefinition
Error like redefinition means that all theese are already defined. You should use only one header file, not both reg52.h and p89v66x.h
Now It shows only this error on compiling and thanks for the support...
Build target 'Target 1' assembling STARTUP.A51... compiling test.glcd.c... TEST.GLCD.C(10): error C146: 'P4': invalid base address TEST.GLCD.C(11): error C146: 'P4': invalid base address TEST.GLCD.C(107): error C202: 'SCK': undefined identifier TEST.GLCD.C(110): error C202: 'DIN': undefined identifier TEST.GLCD.C(110): error C202: 'SCK': undefined identifier TEST.GLCD.C(110): error C202: 'SCK': undefined identifier TEST.GLCD.C(111): error C202: 'DIN': undefined identifier TEST.GLCD.C(111): error C202: 'SCK': undefined identifier TEST.GLCD.C(111): error C202: 'SCK': undefined identifier TEST.GLCD.C(112): error C202: 'DIN': undefined identifier TEST.GLCD.C(112): error C202: 'SCK': undefined identifier TEST.GLCD.C(112): error C202: 'SCK': undefined identifier TEST.GLCD.C(113): error C202: 'DIN': undefined identifier TEST.GLCD.C(113): error C202: 'SCK': undefined identifier TEST.GLCD.C(113): error C202: 'SCK': undefined identifier TEST.GLCD.C(114): error C202: 'DIN': undefined identifier TEST.GLCD.C(114): error C202: 'SCK': undefined identifier TEST.GLCD.C(114): error C202: 'SCK': undefined identifier TEST.GLCD.C(115): error C202: 'DIN': undefined identifier TEST.GLCD.C(115): error C202: 'SCK': undefined identifier TEST.GLCD.C(115): error C202: 'SCK': undefined identifier TEST.GLCD.C(116): error C202: 'DIN': undefined identifier TEST.GLCD.C(116): error C202: 'SCK': undefined identifier TEST.GLCD.C(116): error C202: 'SCK': undefined identifier TEST.GLCD.C(117): error C202: 'DIN': undefined identifier TEST.GLCD.C(117): error C202: 'SCK': undefined identifier TEST.GLCD.C(117): error C202: 'SCK': undefined identifier TEST.GLCD.C(123): error C202: 'SCK': undefined identifier TEST.GLCD.C(126): error C202: 'DIN': undefined identifier TEST.GLCD.C(126): error C202: 'SCK': undefined identifier TEST.GLCD.C(126): error C202: 'SCK': undefined identifier TEST.GLCD.C(127): error C202: 'DIN': undefined identifier TEST.GLCD.C(127): error C202: 'SCK': undefined identifier TEST.GLCD.C(127): error C202: 'SCK': undefined identifier TEST.GLCD.C(128): error C202: 'DIN': undefined identifier TEST.GLCD.C(128): error C202: 'SCK': undefined identifier TEST.GLCD.C(128): error C202: 'SCK': undefined identifier TEST.GLCD.C(129): error C202: 'DIN': undefined identifier TEST.GLCD.C(129): error C202: 'SCK': undefined identifier TEST.GLCD.C(129): error C202: 'SCK': undefined identifier TEST.GLCD.C(130): error C202: 'DIN': undefined identifier TEST.GLCD.C(130): error C202: 'SCK': undefined identifier TEST.GLCD.C(130): error C202: 'SCK': undefined identifier TEST.GLCD.C(131): error C202: 'DIN': undefined identifier TEST.GLCD.C(131): error C202: 'SCK': undefined identifier TEST.GLCD.C(131): error C202: 'SCK': undefined identifier TEST.GLCD.C(132): error C202: 'DIN': undefined identifier TEST.GLCD.C(132): error C202: 'SCK': undefined identifier TEST.GLCD.C(132): error C202: 'SCK': undefined identifier TEST.GLCD.C(133): error C202: 'DIN': undefined identifier TEST.GLCD.C(133): error C202: 'SCK': undefined identifier TEST.GLCD.C(133): error C202: 'SCK': undefined identifier TEST.GLCD.C(219): error C202: 'SCK': undefined identifier TEST.GLCD.C(220): error C202: 'DIN': undefined identifier Target not created
sfr P4 = 0xA1;
TEST.GLCD.C(10): error C146: 'P4': invalid base address
It should be noticed that the fifth port P4(4bit) is not addressed as a bit addressable SFR because the "base address" 0xA1 is not evenly divided by 8. So bit access to this port cannot be done using "sbit" in C language. The bits in P4 have to be manipulated by other means.
macros can be used to set or clear P4 bits
#define SCK_bit 0 #define DIN_bit 2 P4 |= (1<<SCK_bit); P4 |= (1<<DIN_bit); P4 &= !(1<<SCK_bit); // Take care of ! or ~ operator for bits P4 &= !(1<<DIN_bit);
Other options are to use another port like P0, P1, P2, P3 to locate the SCK and DIN pin drivers to GLCD. Also if the GLSD is using an SPI interface the native SPI of the P89V664 can be used.
#define SCK_bit 0 #define DIN_bit 2 P4 |= (1<<SCK_bit); // Set SCK bit at P4 port P4 |= (1<<DIN_bit); // Set DIN bit at P4 port P4 &= ~(1<<SCK_bit); // Clear SCK bit at P4 port P4 &= ~(1<<DIN_bit); // Clear SCK bit at P4 port
more at http://www.keil.com/support/docs/1162.htm C51: ACCESSING BITS ON P5 OF PHILIPS 552
Note that sbit is a proprietary extension to the 'C' language, provided by Keil's C51 - it is not part of the standard language.
After writing this there is a new error....
Build target 'Target 1' assembling STARTUP.A51... compiling test.glcd.c... TEST.GLCD.C(8): error C129: missing ';' before '|=' Target not created
As you see, this is a typical syntax error. Review the code and correct the typo(s). If you post the code it should be clear enough where these typo(s) are.
this is the code
#include<stdio.h> #include<intrins.h> #include<P89v66x.h> #define SCK_bit 0 #define DIN_bit 2 P4 |= (1<<SCK_bit); // Set SCK bit at P4 port <------ line no 8, here error comes P4 |= (1<<DIN_bit); // Set DIN bit at P4 port P4 &= ~(1<<SCK_bit); // Clear SCK bit at P4 port P4 &= ~(1<<DIN_bit); // Clear SCK bit at P4 port // #define unsigned char unsigned char // 0~255 // #define unsigned int unsigned int // 0~65535 sbit _CS = P2^3; sbit _RST = P2^1; sbit A0 = P2^2; sbit SCK = P4^0; sbit DIN = P4^1; unsigned char ContrastLevel; // for contrast setting level //----------------------------------- // dispaly data (128x64) //-----------------------------------
As you can see the "copy - paste" method can not solve any problems, instead creates more.
Every instruction as SCK = 1; or DIN = 1; or SCK = 0; or DIN = 0; has to be replaced accordingly with the bit manipulating istructions: SCK = 1; has to be replaced with P4 |= (1<<SCK_bit); DIN = 1; has to be replaced with P4 |= (1<<DIN_bit); SCK = 0; has to be replaced with P4 &= ~(1<<SCK_bit); DIN = 0; has to be replaced with P4 &= ~(1<<DIN_bit);
another convenient way is to use macro definitions
#define SCK_bit 0 #define DIN_bit 2 #define SCK_set P4 |= (1<<SCK_bit) #define DIN_set P4 |= (1<<DIN_bit) #define SCK_clear P4 &= ~(1<<SCK_bit) #define DIN_clear P4 &= ~(1<<DIN_bit)
... so insted of
SCK = 1;
use the macro
SCK_set;
...
All these are happening because the SCK and DIN pins are connected to a port that is not directly bit addressable (sfr P4 = A1;) using the sbit extention of C (C51)as Andy noted.
but the DIN is the pin from where i have to give the input from controller to LCD , so i have to make the DIN pin floating for varying the data
One of the first things to do, when designing a circuit, is to evaluate the functionality of all processor pins, and then carefully select a mapping between processor pins and signals to get the most out of the processor.
It often costs a lot of grief to connect the signals first, and then see what happens.
There is a kit on which i am evaluting the program, it has pin connections connected as described by me here,
it has SDCC compitible commands which are not being executed by the Keil, so I want to convert the program into keil for ease of use
I often use a header file with inlined functions for affecting processor pins, allowing program or code blocks to be moved between different hw revisions or different platforms with a minimum of changes to the code.
But is there any chance to compile the keil code on the kit without adding too much stuff, because i am doing this from many days and the thing is that it is not compiling or executing on the kit, the code is modified as per the blog's instructions but it can't help me to execute the right code for the serial graphical lcd.
You may try this as it is formed using code from original post with added macros. [Compiled with uVision3 v3.72] [C51 v8.17] [Code Optimization Level 8] There might be a timing issue with the sequence SCK_clear; SCK_set; and one or more _nop(); must be added. Hints: The delayms function is based on software loops. This is not a good solution for accurate timing. At some optimization level this will be eliminated. A timer must be used for delay purposes at millisecond level, or a well written ASM module for accurate timing. The lcd_cmd and lcd_data is better to be rewritten using loops.
#include <Philips\P89V66x.h> //#include <reg52.H> #include <stdio.h> #include <intrins.h> #define SCK_bit 0 #define DIN_bit 2 #define SCK_set P4 |= (1<<SCK_bit) #define DIN_set P4 |= (1<<DIN_bit) #define SCK_clear P4 &= ~(1<<SCK_bit) #define DIN_clear P4 &= ~(1<<DIN_bit) sbit _CS = P2^3; sbit _RST = P2^2; sbit A0 = P2^1; /* These are not working because P4 is located at 0xA1, not bit addressable with sbit extension * sbit SCK = P4^0; * sbit DIN = P4^2; */ unsigned char ContrastLevel; // for contrast setting level //----------------------------------- // display data (128x64) //----------------------------------- unsigned char code Logo[]={ // DisplayData should be 164x64/8 = 1312byte //.... 0x15,0x06,0x00,0x00,0x10,0x1F,0x10,0x00,0x00,0x12,0x15,0x15,0x15,0x88,0xC0 }; //----------------------------------- // Delay Routine //----------------------------------- void delayms(unsigned int m) // 12MHz Xtal, close to ms value { unsigned int j; unsigned int i; for(i=0; i<m; i++) for(j=0; j<109; j++) _nop_(); } //----------------------------------- // IO Routine //----------------------------------- void lcd_cmd(unsigned char Command) // Send command { SCK_set; A0 = 0; _CS = 0; if (Command & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set; _CS = 1; } void lcd_data(unsigned char DData) // Send data { SCK_set; A0 = 1; _CS = 0; if (DData & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (DData & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set; _CS = 1; } //----------------------------------- // Write a Screen //----------------------------------- void WriteScreen(unsigned char *DisplayData) // DisplayData should be 164x64/8 = 1312byte { unsigned char TempData; unsigned char i, j; for(i = 0; i < 8; i++) { lcd_cmd(0xb0 | i); // select page 0~7 lcd_cmd(0x10); // start form column 4 lcd_cmd(0x00); // (2byte command) for(j=0;j<128;j++) { TempData=(*(DisplayData+(i*128)+j)); lcd_data(TempData); } } } //----------------------------------- // Contrast control //----------------------------------- void LCD_Darker(void) { if (ContrastLevel < 0x3F) { ContrastLevel++; } lcd_cmd(0x81); // E-Vol setting lcd_cmd(ContrastLevel); // (2byte command) } void LCD_Lighter(void) { if (ContrastLevel>0x00) { ContrastLevel--; } lcd_cmd(0x81); // E-Vol setting lcd_cmd(ContrastLevel); // (2byte command) } //----------------------------------- // Init LCD module //----------------------------------- void initLCDM(void) { _RST = 1; // hardware reset LCD module _RST = 0; delayms(1); _RST = 1; delayms(800); ContrastLevel = 0x17; // default Contrast Level 1a lcd_cmd(0xab); // new lcd_cmd(0xaf); // display on lcd_cmd(0x40); // display start line=0 lcd_cmd(0xc8); // Common output mode select= reverse lcd_cmd(0xa6); // normal display lcd_cmd(0xa4); // Duisplay all point = off lcd_cmd(0xa3); // LCD bias = 1/9 a2 lcd_cmd(0x2f); // Power control = all on lcd_cmd(0x25); // Rab Ratio 26 lcd_cmd(0x81); // E-Vol setting lcd_cmd(ContrastLevel); // (2byte command) } //----------------------------------- // Main Program //----------------------------------- void main() { /* In C never try to manipulate Stack Pointer, it is too dangerous !!! * SP = 0x60; */ EA = 0; // disable interrupts _CS = 1; _RST = 1; A0 = 1; SCK_set; DIN_set; initLCDM(); LCD_Darker(); LCD_Lighter(); WriteScreen(Logo); while(1) ; } //end of program
if (Command & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x10) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x08) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x04) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x02) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x01) DIN_set; else DIN_clear; SCK_clear; SCK_set;
comes out as
if (Command & 0x80) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x40) DIN_set; else DIN_clear; SCK_clear; SCK_set; if (Command & 0x20) DIN_set; else DIN_clear; SCK_clear; SCK_set; ..............
which will clock a lot of time evidently the "zeusti" language does not have the 'C' construct of "else if"
Erik