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

📄 lcd_4bit.c

📁 最新的LPC214X LCD驱动程序
💻 C
字号:
////  $Id: lcd_4bit.c 328 2008-11-09 05:00:23Z jcw $//  $Revision: 328 $//  $Author: jcw $//  $Date: 2008-11-09 00:00:23 -0500 (Sun, 09 Nov 2008) $//  $HeadURL: http://tinymicros.com/svn_public/arm/lpc2148_demo/trunk/lcd/lcd_4bit.c $//#include <stdio.h>#include "FreeRTOS.h"#include "task.h"#include "queue.h"#include "../main.h"#include "lcd.h"////  This is where the various LCD control pins are assigned.  Currently they're//  all assigned on port 1.  If you have to break them up, you'll need to edit//  the functions them.  It's very convienent to have the D7..D0 lines grouped//  together.  Otherwise you'll have to bit test each bit and assign the pin.//  Much slower.//#define LCD_D4        GPIO_IO_P16#define LCD_D5        GPIO_IO_P17#define LCD_D6        GPIO_IO_P18#define LCD_D7        GPIO_IO_P19#define LCD_DATA      (LCD_D7 | LCD_D6 | LCD_D5 | LCD_D4)#define LCD_Dx_SHIFT  ((unsigned int) 16)#define LCD_RS        GPIO_IO_P20#define LCD_RW        GPIO_IO_P21#define LCD_E         GPIO_IO_P22//////#define LCD_COMMAND_CLEAR       0x01#define LCD_COMMAND_HOME        0x02#define LCD_COMMAND_MODE        0x04#define LCD_COMMAND_DISPLAY     0x08#define LCD_COMMAND_SHIFT       0x10#define LCD_COMMAND_FUNCTION    0x20#define LCD_COMMAND_CGRAM       0x40#define LCD_COMMAND_DDRAM       0x80#define LCD_MODE_SHIFT_NO       0x00#define LCD_MODE_SHIFT_YES      0x01#define LCD_MODE_DECREMENT      0x00#define LCD_MODE_INCREMENT      0x02#define LCD_MODE_MASK           0x03#define LCD_SHIFT_CURSOR        0x00#define LCD_SHIFT_DISPLAY       0x04#define LCD_SHIFT_LEFT          0x00#define LCD_SHIFT_RIGHT         0x08#define LCD_SHIFT_MASK          0x0c#define LCD_FUNCTION_FONT_5X8   0x00#define LCD_FUNCTION_FONT_5X11  0x04#define LCD_FUNCTION_LINES_1    0x00#define LCD_FUNCTION_LINES_2    0x08#define LCD_FUNCTION_BUS_4      0x00#define LCD_FUNCTION_BUS_8      0x10#define LCD_FUNCTION_MASK       0x1c#define LCD_DISPLAY_BLINK_OFF   0x00#define LCD_DISPLAY_BLINK_ON    0x01#define LCD_DISPLAY_CURSOR_OFF  0x00#define LCD_DISPLAY_CURSOR_ON   0x02#define LCD_DISPLAY_DISPLAY_OFF 0x00#define LCD_DISPLAY_DISPLAY_ON  0x04#define LCD_DISPLAY_MASK        0x07#define LCD_PWM_FREQ 20000////  If CFG_LCD is not defined, we still compile the code, it's just not included.//  Define TASKHANDLE_LCD so we compile.  Normally this is defined in main.h,//  but it's #ifndef'ed out so that we don't allocate a task handle slot for it//  when LCD support isn't included.//#ifndef CFG_LCD#define TASKHANDLE_LCD 0#endif////  Structure for passing messages to the LCD//typedef struct{  const char *pcMessage;} xLCDMessage_t;//////static xQueueHandle xLCDQueue = NULL;////  Each operation is 83.33ns.  Cumlative delays make be longer, but not shorter.//  This delay assumes a 48Mhz clock and MAM=partial//#define delay166ns() do { asm volatile (" push {r0}" : /* no output */ : /* no inputs */ ); \                          asm volatile (" pop  {r0}" : /* no output */ : /* no inputs */ ); \                        } while (0)////  166ns measured//static inline void lcdDelay140ns (void){  delay166ns ();}////  333ns measured//static inline void lcdDelay320ns (void){  delay166ns ();  delay166ns ();}////  500ns measured//static inline void lcdDelay450ns (void){  delay166ns ();  delay166ns ();  delay166ns ();}////  666ns measured//static inline void lcdDelay550ns (void){  delay166ns ();  delay166ns ();  delay166ns ();  delay166ns ();}static inline void lcdDataToPort (unsigned char c){  GPIO1_FIOCLR = (~c & 0x0f) << LCD_Dx_SHIFT;  GPIO1_FIOSET = ( c & 0x0f) << LCD_Dx_SHIFT;}static inline unsigned int lcdDataFromPort (void){  return (GPIO1_FIOPIN & LCD_DATA) >> LCD_Dx_SHIFT;}static inline void lcdSelectCommandRegister (void){  GPIO1_FIOCLR = LCD_RS;}static inline void lcdSelectDataRegister (void){  GPIO1_FIOSET = LCD_RS;}static inline void lcdSelectWriteMode (void){  GPIO1_FIOCLR = LCD_RW;}static inline void lcdSelectReadMode (void){  GPIO1_FIOSET = LCD_RW;}static inline void lcdEnableHigh (void){  GPIO1_FIOSET = LCD_E;}static inline void lcdEnableLow (void){  GPIO1_FIOCLR = LCD_E;}static inline void lcdDataAsInputs (void){  GPIO1_FIODIR &= ~LCD_DATA;}static inline void lcdDataAsOutputs (void){  GPIO1_FIODIR |= LCD_DATA;}//////static void lcdWritePort4 (unsigned char c){  lcdEnableHigh ();  lcdDataToPort (c & 0x0f);  lcdDelay140ns ();  lcdEnableLow ();  lcdDelay550ns ();  lcdDelay550ns ();}static void lcdWriteData (unsigned char c){  lcdSelectDataRegister ();  lcdSelectWriteMode ();  lcdWritePort4 (c >> 4);  lcdWritePort4 (c & 0x0f);}static void lcdWriteCommand4 (unsigned char c){  lcdSelectCommandRegister ();  lcdSelectWriteMode ();  lcdWritePort4 (c);}static void lcdWriteCommand (unsigned char c){  lcdSelectCommandRegister ();  lcdSelectWriteMode ();  lcdWritePort4 (c >> 4);  lcdWritePort4 (c & 0x0f);}static int lcdReadStatus4 (void){  unsigned char c;  lcdEnableHigh ();  lcdDataAsInputs ();  lcdDelay140ns ();  c = lcdDataFromPort ();  lcdEnableLow ();  lcdDelay550ns ();  lcdDelay550ns ();  return c & 0x0f;}static int lcdReadStatus (void){  unsigned char c;  lcdSelectCommandRegister ();  lcdSelectReadMode ();  c  = lcdReadStatus4 () << 4;  c |= lcdReadStatus4 ();  lcdSelectWriteMode ();  lcdDataAsOutputs ();    return c;}static void lcdWaitWhileBusy (void){  while (lcdReadStatus () & 0x80)    ;}//////static void lcdDisplay (unsigned char display){  lcdWaitWhileBusy ();  lcdWriteCommand (LCD_COMMAND_DISPLAY | (display & LCD_DISPLAY_MASK));}static void lcdMode (unsigned char mode){  lcdWaitWhileBusy ();  lcdWriteCommand (LCD_COMMAND_MODE | (mode & LCD_MODE_MASK));}static void lcdClear (void){  lcdWaitWhileBusy ();  lcdWriteCommand (LCD_COMMAND_CLEAR);}static void lcdHome (void){  lcdWaitWhileBusy ();  lcdWriteCommand (LCD_COMMAND_HOME);}static void lcdGotoXY (unsigned int x, unsigned int y){  lcdWaitWhileBusy ();  lcdWriteCommand (LCD_COMMAND_DDRAM | (y ? 0x40 : 0x00) | (x & 0x0f));  lcdWaitWhileBusy ();}static void lcdPutChar (char c){  lcdWaitWhileBusy ();  lcdWriteData (c);}static void lcdWriteStringCtl (const char *s){  while (*s)  {    char c = *s++;    switch (c)    {      case '\f' :        lcdClear ();        break;      case 0x1e :        lcdHome ();        break;      case 0x1b :        {          switch (*s++)          {            case '=' :              {                unsigned char x = *s++;                unsigned char y = *s++;                lcdGotoXY (x, y);              }              break;            case '*' :              lcdClear ();              break;            case '.' :              {                switch (*s++)                {                  case '0' :                     lcdDisplay (LCD_DISPLAY_DISPLAY_ON | LCD_DISPLAY_CURSOR_OFF | LCD_DISPLAY_BLINK_OFF);                    break;                  case '1' :                     lcdDisplay (LCD_DISPLAY_DISPLAY_ON | LCD_DISPLAY_CURSOR_ON | LCD_DISPLAY_BLINK_ON);                    break;                  case '2' :                     lcdDisplay (LCD_DISPLAY_DISPLAY_ON | LCD_DISPLAY_CURSOR_ON | LCD_DISPLAY_BLINK_OFF);                    break;                }              }          }        }        break;      default :         lcdPutChar (c);        break;    }  }}//////static void lcdDelayMs (unsigned int timeInMs){  vTaskDelay (timeInMs / portTICK_RATE_MS);}//////static void lcdControllerInit (void){  lcdWriteCommand4 ((LCD_COMMAND_FUNCTION | LCD_FUNCTION_BUS_4) >> 4);  lcdDelayMs (30);  lcdWriteCommand4 ((LCD_COMMAND_FUNCTION | LCD_FUNCTION_BUS_4) >> 4);  lcdDelayMs (30);  lcdWriteCommand4 ((LCD_COMMAND_FUNCTION | LCD_FUNCTION_BUS_4) >> 4);  lcdDelayMs (30);  lcdWriteCommand (LCD_COMMAND_FUNCTION | LCD_FUNCTION_BUS_4 | LCD_FUNCTION_LINES_2 | LCD_FUNCTION_FONT_5X8);  lcdDelayMs (30);  lcdWriteCommand (LCD_COMMAND_FUNCTION | LCD_FUNCTION_BUS_4 | LCD_FUNCTION_LINES_2 | LCD_FUNCTION_FONT_5X8);  lcdDelayMs (30);  lcdDisplay (LCD_DISPLAY_DISPLAY_ON | LCD_DISPLAY_CURSOR_OFF | LCD_DISPLAY_BLINK_OFF);  lcdClear ();  lcdMode (LCD_MODE_INCREMENT | LCD_MODE_SHIFT_NO);  lcdGotoXY (0, 0);}void lcdWriteChar (char c){  static char buffer [2];  buffer [0] = c;  buffer [1] = '\0';  lcdWriteText (buffer);}void lcdWriteText (const char *s){  xLCDMessage_t xLCDMessage;    xLCDMessage.pcMessage = s;  xQueueSend (xLCDQueue, &xLCDMessage, portMAX_DELAY);}void lcdCursorXY (int x, int y){  static char buffer [5];  buffer [0] = '\033';  buffer [1] = '=';  buffer [2] = x;  buffer [3] = y;  buffer [4] = '\0';  lcdWriteText (buffer);}//////void lcdInit (void){  GPIO1_FIODIR |= (LCD_E | LCD_RS | LCD_RW);  lcdEnableLow ();  lcdSelectWriteMode ();  lcdSelectCommandRegister ();  lcdDataAsOutputs ();  lcdDataToPort (0xff);  //  //  Queue used to send LCD task messages, only 1 outstanding message  //  (so static buffers, such as those used in lcdCursorAt() don't  //  get lost)  //  if (!xLCDQueue)    xLCDQueue = xQueueCreate (1, sizeof (xLCDMessage_t));}//////static portTASK_FUNCTION (vLCDTask, pvParameters __attribute__ ((unused))){  lcdInit ();  lcdControllerInit ();  for (;;)  {    xLCDMessage_t xMessage;          xQueueReceive (xLCDQueue, &xMessage, portMAX_DELAY);    lcdWriteStringCtl (xMessage.pcMessage);  }}//////signed portBASE_TYPE lcdTaskStart (void){  return xTaskCreate (vLCDTask, (const signed portCHAR * const) "LCD", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1), &taskHandles [TASKHANDLE_LCD]);}signed portBASE_TYPE lcdTaskStop (void){  if (!taskHandles [TASKHANDLE_LCD])    return 0;  vTaskDelete (taskHandles [TASKHANDLE_LCD]);  taskHandles [TASKHANDLE_LCD] = NULL;  return 1;}

⌨️ 快捷键说明

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