Introduction: This article mainly introduces the 240x128 LCD T6963 controller driver (C51).
#include "absacc.h"
#include "math.h"
#include "ASCII816.h" //Standard ASCII library
#include "HZTable.h" //Chinese character dot matrix library (self-made)
#include "menu.h" //Menu library (self-made)
#define ComPort 0xB101
#define DataPort 0xB000
#define GraphAddr 0x0000 //head of graph
//Calculated based on 8*8 characters, the number of characters that can be displayed horizontally and vertically on the display
//Take 240*128 as an example:
#define LineChar 30 //16 characters per line (8*8)
#define ColumnChar 16 //Total 16 columns
//Instructions, data read and write status check
#define RWCheck() { unsigned char sta; do{ sta=XBYTE[ComPort] & 0x03; } while(sta!=0x03); }
//Data automatic read status check
#define AutoRCheck() { unsigned char sta; do{ sta=XBYTE[ComPort] & 0x04; } while(sta!=0x04); }
//Data automatic write status check
#define AutoWCheck() { unsigned char sta; do{ sta=XBYTE[ComPort] & 0x08; } while(sta!=0x08); }
/*------Input/output function, communication with T6963------------------------------------------------*/
/*------------------------------------------------------------------------*/
// Send Data to the data port
#define OutPortData(dat ) { RWCheck(); XBYTE[DataPort]=that; }
//Write a command with 1 parameter
#define OutPortCom1(command) { RWCheck(); XBYTE[ComPort]= command; }
//Write a command with 2 parameters
#define OutPortCom2(dat, command) { OutPortData(dat); OutPortCom1(command); }
//Write a command with 3 parameters
#define OutPortCom3(data1, data2, command) { OutPortData(data1); OutPortData(data2); OutPortCom1(command);}
unsigned char InPortData() { RWCheck(); return(XBYTE[DataPort]); }
/*-----------------------------------------------------------------------------------*/
//Display 8*16 characters
//lin: row (0-7), column: column (0-15)
//ch: character code (standard ASCII code)
void ShowChar(unsigned char lin,unsigned char column,unsigned char ch)
{
unsigned char i;
unsigned char dat;
unsigned int StartAddr;
StartAddr=lin*LineChar +column; //Locate the starting line
for(i=0;i<16;i++)
{
dat=ASCII816[ ch-0x20 ][i];
OutPortCom3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8), 0x24); //set address
OutPortCom2( dat, 0xc4);
StartAddr=StartAddr + LineChar;
}
}
/*----------------------------------------------------------------------------------------------*/
//Display a Chinese character (16*16 dot matrix)
//lin: row (0-7), column: column (0-7)
//hzcode: Chinese character code (customized)
void ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode)
{
unsigned char i;
unsigned int StartAddr;
StartAddr=lin*LineChar + column; //Locate the starting line
for(i=0;i<16;i++)
{
OutPortCom3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8), 0x24);
OutPortCom2( HZTable[hzcode][i*2], 0xc0); //Add one to the left half of the address
OutPortCom2( HZTable[hzcode][i*2+1], 0xc4); //add one to the right half of the font address
StartAddr=StartAddr + LineChar;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
//Display a Chinese character (16*16 dot matrix)
//lin: row (0-7), column: column (0-7)
//hzcode: Chinese character code (customized)
void ShowHZD(unsigned char lin,unsigned char column,unsigned int hzcode)
{
unsigned char i,j;
unsigned int StartAddr;
StartAddr=lin*LineChar*16 +column; //Locate the starting line
for(i=0;i<35;i++)
{
OutPortCom3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8), 0x24); //Locate the current operation position
for(j=0;j<5;j++) OutPortCom2( HZTable[hzcode][i*5+j], 0xc0); //Display the current line
StartAddr=StartAddr + LineChar;
}
}
////////////////////////////////////////////////////////////////////////////////////////////
/*-----------------------------------------------------------------------------------*/
//Display a line of string (Chinese characters, letters mixed, 16 bytes per line)
//lin: line
//lineheadaddr: the first address of the Chinese character code area in this line
void ShowLine(unsigned char lin,unsigned char column,unsigned char linehead[])
{
unsigned char i,j;
unsigned char byte;
unsigned int hzcode;
for( i= column,j=0; i< column+14 ; )
{ byte=linehead[j];
if(byte < 0x80) //letter
{
ShowChar(lin, i , byte);
i=i+1;j=j+1;
}
else // byte >= 0x80 (Chinese character)
{
byte=byte & 0x7f; //The highest position is 0, that is: minus 0x8000
hzcode=byte*256 + linehead[j+1]; //Add the lower 8 bits to form an integer address
ShowHZ( lin,i,hzcode);
i=i+2;j=j+2;
}
}
}
/*-----------------------------------------------------------------------------------*/
//Display a screen of Chinese characters
//pageheadaddr: the first address of the Chinese character code address area on this screen
void ShowPage(unsigned char lin,unsigned char column1,unsigned char pagehead[][14])
{
unsigned char i;
for(i=0;i< 4 ;i++)
ShowLine((lin+i*20),column1,pagehead[i]); //1 line of 8 Chinese characters, 16 bytes
}
/*----------------------------------------------------------------------------------------------------*/
//Reverse display a character
//lin: row (0-7), column: column (0-15)
void ReverseShowChar(unsigned char lin,unsigned char column)
{
unsigned char i;
unsigned char dat;
unsigned int StartAddr;
StartAddr=lin*LineChar +column; //Locate the starting line
for(i=0;i<16;i++)
{
OutPortCom3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8), 0x24); //set address
OutPortCom1( 0xc5 ); //Read data once, address remains unchanged
dat=InPortData(); //Read data
that=~that; //取反
OutPortCom2(dat, 0xc4); //Send back
StartAddr=StartAddr+ LineChar;
}
}
/*----------------------------------------------------------------------------------------------------*/
//Reverse display a Chinese character
//lin: row (0-7), column: column (0-15)
void ReverseShowHZ(unsigned char lin,unsigned char column)
{
ReverseShowChar(lin,column);
ReverseShowChar(lin,column+1);
}
/*----------------------------------------------------------------------------------------------------*/
//Reverse display of a line of Chinese characters
//lin: row (0-7)
void ReverseShowLine(unsigned char lin)
{
unsigned char column;
for(column=0; column< ColumnChar; column++) ReverseShowChar(lin,column);
}
//////////////////////////////////////////////////////////////////////////////////////
void ShowPicture(unsigned char Startline,unsigned char Startcolumn,unsigned char LineWidth,unsigned char ColumnWidth,unsigned int address)
{
unsigned char i,j;
unsigned int StartAddr;
StartAddr=Startline*LineChar + Startcolumn; //Locate the starting position
for(i=0;i OutPortCom3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8), 0x24); //set address for(j=0;j OutPortCom2( CBYTE[address + i*LineWidth+ j ], 0xc0); } StartAddr=StartAddr + LineChar; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// //Graphics function, used to draw points //--------------------------------------------------------------------------- // Display a point at the specified position //If the display exceeds 256*256, please modify the type of this function PointX, PointY //Mode 1: Display 0: Clear the point Pixel(unsigned char PointX,unsigned char PointY, bit Mode) { unsigned int StartAddr=0; unsigned char dat; StartAddr=PointX*LineChar + PointY/8; dat=0xf0+7-PointY%8; if(Mode) dat=dat|0x08; OutPortCom3( (unsigned char)(StartAddr),(unsigned char)(StartAddr>>8),0x24 ); //Set the unit address of this point OutPortCom1(dat); } //------------------------------------------------------------------------------- //Strikethrough function void Line( unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, bit Mode) { unsigned char x,y; double k,b; if( abs(y1-y2) <= abs(x1-x2) ) // |k|<=1 { k=(float)(y2-y1) / (float)(x2-x1) ; b=y1-k*x1; if( x1 <= x2 ) { for(x=x1;x<=x2;x++) { y=k*x+b; Pixel(x, y, Mode); } } else { for(x=x2;x<=x1;x++) { y=k*x+b; Pixel(x, y, Mode); } } } else // abs(y1-y2) > abs(x1-x2) |K|>1 { k=(float)(x2-x1) / (float)(y2-y1) ; b=x1-k*y1; if( y1 <= y2 ) { for(y=y1;y<=y2;y++) { x=k*y+b; Pixel( x , y,Mode ); } } else { for(y=y2;y<=y1;y++) { x=k*y+b; Pixel( x , y,Mode ); } } } } /*---------------------------------------------------------------------------------------------------*/ void ClearScreen() { unsigned int i; ///////// Clear display RAM area 0000h--2000h (8k) OutPortCom3(0x00,0x00,0x24); //Set pointer address to 0000H OutPortCom1(0xb0); //Set automatic write status for(i=0x00;i<0x2000;i++) OutPortData(0x00); // data=0; OutPortCom1(0xb2); // Automatic write end } // Initialize LCD // Need to set manually void InitLCD() { OutPortCom3( 0x00,0x00,0x42 ); //Set the first address of the graphics display area GraphAddr OutPortCom3( 30,0x00,0x43 ); //Set the width of the graphics display area: LineChar // OutPortCom3( 0x00,0x00,0x42 ); //Set the first address of the graphics display area GraphAddr // OutPortCom3(0x10,0x00,0x43); //Set the width of the graphics display area: 10H OutPortCom1(0xa7); //Set cursor shape cursor size 8x8 OutPortCom1(0x80); //Set the display mode: CGROM mode text graphics "or" OutPortCom1(0x98); //Set display switch: 1001 1100 graphics ClearScreen(); }
Previous article:A brief discussion on the debounce problem of single-chip microcomputer buttons
Next article:Flowing water lamp made with timer
Recommended ReadingLatest update time:2024-11-16 14:44
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- EEWORLD University-What is I2C design tool?
- LCD1602 dynamic display--based on MSP430F149 single chip microcomputer
- Operating handle failure
- Electronic Design Tips
- [First come first served double gift] Become the first 100 pioneers to experience the Fluke New Era 640 Infrared Thermal Imager
- The dynamic diagram explains the lead and lag of voltage and current
- Parallel switch type voltage regulator circuit
- Can STM32 USB AUDIO realize recording?
- EEWORLD University - From entry to mastery of Huawei IoT technology
- A First Look at TouchGFX