⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd_driver_ks0107.c

📁 lcd driver for 8051 and other controllers
💻 C
字号:
//*****************************************************************************//// Work File		: lcd_driver_KS0107.c// Description		: Driver for KS0107 driven LCD display//            		  Implementations for lcd_driver_KS0107.h//// Author		: Sami Varjo// Created		: 2008-23-06// Revised		: 2008-29-06// Version		: 0.04// Target MCU	        : Atmel AVR series - ATMEGA5815 (or equivalent)// Uses                 : avr-libc lcd_driver_KS0107.h font5x7.h//// This code is distributed under the GNU Public License// which can be found at http://www.gnu.org/licenses/gpl.txt//// Change history:  //       ver 0.04: Fixed LCD_readStatus() + changed LCD_allPixelsOn() to //                 LCD_allPagesOn(byte) + added starting x to LCD_putsp()//       ver 0.03: Bugs fixed//       ver 0.02: Added several functions//       ver 0.01: Project started - basic definition////*****************************************************************************#include "lcd_driver_KS0107.h"#include <util/delay.h>#include <avr/pgmspace.h>#include <avr/io.h>#include "font5x7.h"//------------------------------------------------------------------------------//Global variables used by driveruint8_t LCD_currentX, LCD_currentY;//------------------------------------------------------------------------------//Send a binary command to LCD // Target is currently selected controller chipvoid LCD_sendCommand(uint8_t command){  LCD_CPDIRECTION  = 0xff;     //send data out  LCD_DATAPORT     = command;  //load command to port  LCD_CONTROLPORT |= LCD_E;    //execute  (LCD_RS and LCD_RW by default low)  LCD_wait_execution();              LCD_CONTROLPORT &= ~LCD_E;   //stop execition    LCD_wait_execution();}//------------------------------------------------------------------------------//Write a byte to LCD.  Single 8 bit segment is send to current cursor position//void LCD_writeByte(uint8_t data){  LCD_setCursorXY(LCD_currentX,LCD_currentY); //address and chip selected   LCD_DPDIRECTION  = 0xff;     //send data out   LCD_DATAPORT     = data;     //load data to port  LCD_CONTROLPORT |= (LCD_RS | LCD_E);   LCD_wait_execution();              LCD_CONTROLPORT &= ~LCD_E;  LCD_CONTROLPORT &= ~LCD_RS;  //stop and go back to command mode  LCD_wait_execution();              LCD_currentX++;}//-----------------------------------------------------------------------------//Read a byte from LCD DDRAM (using modify_read mode)//uint8_t _LCD_readByte(void){  uint8_t data;  LCD_setCursorXY(LCD_currentX,LCD_currentY);    //address and chip selected  LCD_DPDIRECTION &= 0x00;                       //set read data from port  LCD_CONTROLPORT |= ( LCD_E | LCD_RS | LCD_RW); //select read data mode and execute  LCD_wait_execution();  data=LCD_DATA_IN;  LCD_CONTROLPORT &= ~( LCD_E | LCD_RS | LCD_RW); //select read data mode and execute  LCD_wait_execution();  LCD_DPDIRECTION |= 0xff;                      LCD_setCursorXY(LCD_currentX,LCD_currentY);   //move back to where was red  return data;}uint8_t LCD_readByte(){  _LCD_readByte();       //dummy read needed  return _LCD_readByte();}//------------------------------------------------------------------------------//Functions to inquiry the status of S6B0724uint8_t LCD_readStatus(void){  uint8_t status;  LCD_selectChip();  LCD_DPDIRECTION  =  0x00;     //read data from port  LCD_CONTROLPORT &= ~LCD_RS; //=0  LCD_CONTROLPORT |= (LCD_RW | LCD_E); //=1  LCD_wait_execution();  status=LCD_DATA_IN;  LCD_DPDIRECTION |= 0xff;                      LCD_CONTROLPORT &= ~(LCD_E | LCD_RW);    return status;}//------------------------------------------------------------------------------//Initialize LCD //void LCD_init(void){   LCD_CPDIRECTION |=0xff;      // controlport pins for output (needed for reset)  LCD_DPDIRECTION |=0xff;      // dataport pins for output      LCD_CONTROLPORT &= ~LCD_RST; //0 -reset the chip  _delay_ms(20);               //  -wait for reset  LCD_CONTROLPORT |= LCD_RST;  //1     while(LCD_isReseting()) LCD_wait_execution();  //This might be omitted   //  _delay_ms(50);           //  -wait for reset   LCD_on();  LCD_clr();                   //clear LCD memory  LCD_setCursorXY(0,0);        //set cursor to "home"}//------------------------------------------------------------------------------//clear LCD DDRAM void LCD_clr(void){    LCD_allPagesOn(0x00);}//-----------------------------------------------------------------------//fill all pages with selected bytevoid LCD_allPagesOn(uint8_t byte){  uint8_t i,j;  for (i=0;i<LCD_LINES/LCD_PAGE_HEIGHT;i++){    LCD_setCursorXY(0,i*LCD_PAGE_HEIGHT);    for(j=0;j<LCD_LINE_LENGTH;j++){      LCD_writeByte(byte);    }  }}//------------------------------------------------------------------------------//Move cursor to position x yvoid LCD_setCursorXY(uint8_t x, uint8_t y){  LCD_currentX=x;  LCD_currentY=y;  LCD_selectChip();  LCD_setColumnAddress(x);  LCD_setPageAddress(y/LCD_PAGE_HEIGHT); }//------------------------------------------------------------------------------//Draw pixel at x yvoid LCD_pixelOn(uint8_t x, uint8_t y){    uint8_t mask=0x00;   LCD_setCursorXY(x,y);    mask=LCD_readByte();  LCD_writeByte( mask | (1<< (y&0b111))); //shift to selected bit on page}//------------------------------------------------------------------------------//Dim pixel at x yvoid LCD_pixelOff(uint8_t x, uint8_t y){  uint8_t mask;  LCD_setCursorXY(x,y);  mask=LCD_readByte();  LCD_writeByte(mask & ~(1<<(y&0b111)));  //select bit on page to operate on}//------------------------------------------------------------------------------//Invert pixel value at x yvoid LCD_invertPixel(uint8_t x, uint8_t y){  uint8_t mask;  LCD_setCursorXY(x,y);  mask=LCD_readByte();  if (mask &(1<<(y&0b111))) mask &= ~(1<<(y&0b111));  else  mask |= (1<<(y&0b111));  LCD_writeByte(mask);}//------------------------------------------------------------------------------//invert pixels on a page from x1 to x2// x1 must be smaller than x2void LCD_invertPage(uint8_t page, uint8_t x1, uint8_t x2){  uint8_t mask,i;  LCD_setCursorXY(x1,page*LCD_PAGE_HEIGHT);  for (i=x1;i<=x2;i++){    mask=LCD_readByte();    LCD_writeByte(~mask);  }}//------------------------------------------------------------------------------//clear a single page in LCD DDRAM from x1 to x2void LCD_offPage(uint8_t p,uint8_t x1, uint8_t x2){  uint8_t i;  LCD_setCursorXY(x1,p*LCD_PAGE_HEIGHT);  for(i=x1;i<x2;i++){      LCD_writeByte(0x00);    }}//------------------------------------------------------------------------------//Turn pixels on in a single page in LCD DDRAM from x1 to x2void LCD_onPage(uint8_t p,uint8_t x1, uint8_t x2){  uint8_t i;  LCD_setCursorXY(x1,p*LCD_PAGE_HEIGHT);  for(i=x1;i<=x2;i++){      LCD_writeByte(0xff);    }}//------------------------------------------------------------------------------//Put a single char to LCD on line at current cursor position// Note that page is used not exact coordinates void LCD_putchar(uint8_t c){  uint8_t i = 0;    for(i=0; i<5; i++){             if (LCD_currentX>=LCD_LINE_LENGTH){      if (LCD_currentY<LCD_LINES+LCD_PAGE_HEIGHT){	LCD_setCursorXY(0,LCD_currentY+LCD_PAGE_HEIGHT);	}      else {	LCD_setCursorXY(0,0);	        }    }    LCD_writeByte(pgm_read_byte(&Font5x7[(c - 0x20)*5 + i]));   }      LCD_writeByte(0x00);  }//---------------------------------------------------------------------------------//Put a string on display - auto for next line is default (from LCD_putchar)//null terminated strings are expected// /n  for new line void LCD_puts(uint8_t* pString){    	  uint8_t i=0;  while (pString[i] != '\0'){    if (pString[i]=='\n'){                 LCD_currentX=0;      LCD_currentY+=LCD_PAGE_HEIGHT;        }    else {      LCD_putchar(pString[i]);    }    i++;        }}//-----------------------------------------------------------------------------//Put a string on selected page (line) starting at x//void LCD_putsp(uint8_t* pString, uint8_t page, uint8_t x){  LCD_currentX=x;  LCD_currentY=page*LCD_PAGE_HEIGHT;  LCD_selectChip();  LCD_setColumnAddress(x);  LCD_setPageAddress(page);   LCD_puts(pString);}//-----------------------------------------------------------------------------uint8_t LCD_isBusy(void){  uint8_t status=LCD_readStatus();  if (status & LCD_D7) return TRUE;  else return FALSE; }//-----------------------------------------------------------------------------uint8_t LCD_isOff(void){  uint8_t status=LCD_readStatus();  if (status & LCD_D5) return TRUE;  else return FALSE;}//-----------------------------------------------------------------------------uint8_t LCD_isReseting(void)    //by RESETB signal{  uint8_t status=LCD_readStatus();  if (status & LCD_D4) return TRUE;  else return FALSE;}//------------------------------------------------------------------------------//Functions to set display DDRAM page addressesvoid LCD_setPageAddress(uint8_t page) {  LCD_sendCommand(SET_PAGE_ADDRESS(page));}//------------------------------------------------------------------------------//Select x-coordinate in  LCD memory //void LCD_setColumnAddress(uint8_t col){    if (col<LCD_LINE_LENGTH/LCD_NUM_CHIPS){     LCD_selectLeftChip();    LCD_sendCommand(SET_COLUMN_ADDRESS(col));  }  else {    LCD_selectRightChip();    LCD_sendCommand(SET_COLUMN_ADDRESS( (col - (LCD_LINE_LENGTH/LCD_NUM_CHIPS)) ));  }	}//------------------------------------------------------------------------------//Select display memory line for current chip //can be used to scroll data up and down (LCD memory is looped)//void LCD_setInitialLineAddress(uint8_t line){  LCD_sendCommand(SET_INIT_DISPLAY_LINE(line));}//------------------------------------------------------------------------------//function to be used with low level commands// be sure to have long enough waittime for your target MCUvoid LCD_wait_execution(void){   asm("nop"); asm("nop");   //  asm("nop"); asm("nop"); asm("nop"); asm("nop");  //  asm("nop"); asm("nop"); asm("nop"); asm("nop");}   //------------------------------------------------------------------------------//function to wait for LCD_operations (wait_execution() is faster!)void LCD_wait_busy(void){ while(LCD_isBusy()) LCD_wait_execution(); }//------------------------------------------------------------------------------//Select the right controller chip depending on LCD_currentX value //void LCD_selectChip(void){  if (LCD_currentX<LCD_LINE_LENGTH/LCD_NUM_CHIPS){    LCD_selectLeftChip();  }  else {    LCD_selectRightChip();  }} //------------------------------------------------------------------------------//Enable left controller && disable right controllervoid LCD_selectLeftChip(void){       LCD_CONTROLPORT &= ~LCD_CS2;     LCD_CONTROLPORT |=  LCD_CS1;   }//------------------------------------------------------------------------------//Enable right controller && disable left controllervoid LCD_selectRightChip(void){    LCD_CONTROLPORT &= ~LCD_CS1;     LCD_CONTROLPORT |=  LCD_CS2; }//------------------------------------------------------------------------------//Turn display on void LCD_on(void){  LCD_selectLeftChip();          LCD_sendCommand(SET_DISPLAY_ON);  LCD_selectRightChip();  LCD_sendCommand(SET_DISPLAY_ON);}//------------------------------------------------------------------------------//Turn display offvoid LCD_off(void){  LCD_selectLeftChip();        //turn whole display on  LCD_sendCommand(SET_DISPLAY_OFF);  LCD_selectRightChip();  LCD_sendCommand(SET_DISPLAY_OFF);} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -