tianxiaoMCU 发表于 2013-6-9 21:56:44

LPC1788驱动LCD1602的程序,写得不好,还请大家指点

前段时间练手留下的程序,整理好了放上来,当作备份吧。大家发现有什么缺点还请指点一二。


LCD1602.H#ifndef __LCD1602_H
#define __LCD1602_H

#include "stdint.h"   

/****************************************************************************/
/*Display On/Off Control                                                */
/****************************************************************************/

/*Turn on display*/
#define DISPLAYON         0X0C

/*Turn off display */
#define DISPLAYOFF          0X08

/*Turn on cursor   */
#define DISPCURSORON      0X0A

/*Turn off cursor*/
#define DISPCURSOROFF       0X08

/*Cursor blinking*/
#define CURSORBLINKYON      0X09

/*Cursor not blinking*/
#define CURSORBLINKYOFF   0X08

/****************************************************************************/
/*Entry Mode Set                                                          */
/****************************************************************************/

/*Cursor move direction : Increment*/
#define CURSORADD         0X06

/*Cursor move direction : Decrement*/
#define CURSORCUT         0X04

/*Display shift when write or read   */
#define SCREENSCROLLMOVE    0X05

/*Display hold when write or read    */
#define SCREENSCROLLHOLD    0X04

/****************************************************************************/
/*Cursor or Display Shift                                                 */
/*Moves cursor and shifts display without changing DDRAM contents.      */
/****************************************************************************/

/*Cursor shift      */
#define CURSORSHIFT         0X10

/*Display shift       */
#define SCREENSHIFT         0X18

/*Shift to the left   */
#define SHIFTLEFT         0X10

/*Shift to the right*/
#define SHIFTRIGHT          0X14


/*The LCD1602 API*/
void LCD1602_GPIO_Init(void);
void LCD1602_Init(void);

void LCD1602_SetCousor(uint8_t x, uint8_t y);
void LCD1602_DisplayString(const uint8_t *str);
void LCD1602_DisplayNum(uint32_t n);
void LCD1602_DisplayClear(void);
void LCD1602_DisplayHome(void);

void LCD1602_DisplayOn(void);
void LCD1602_DisplayOff(void);
void LCD1602_CursorOn(uint8_t blink);
void LCD1602_CursorOff(void);

void LCD1602_CursorMoveLeft(uint8_t n);
void LCD1602_CursorMoveRight(uint8_t n);
void LCD1602_DisplayShiftLeft(uint8_t n);
void LCD1602_DisplayShiftRight(uint8_t n);


/*If the LCD API can not meet your need, you can use the API below operated*/
/*on the lowlayer.                                                         */
uint8_t LCD1602_ReadState(void);
uint8_t LCD1602_CheckBusy(void);
uint8_t LCD1602_ReadData(void);
void LCD1602_WriteData(uint8_t Data);
void LCD1602_WriteCommand(uint8_t Command);


#endif
LCD1602.C#include "lpc177x_8x_gpio.h"
#include "lcd1602.h"


/*   LCD1602 pin preset       */
#define BRD_LCD1602_RS_PORT   (4)
#define BRD_LCD1602_RS_PIN      (0)
#define BRD_LCD1602_RS_MASK   (1 << BRD_LCD1602_RS_PIN)

#define BRD_LCD1602_RW_PORT   (4)
#define BRD_LCD1602_RW_PIN      (1)
#define BRD_LCD1602_RW_MASK   (1 << BRD_LCD1602_RW_PIN)

#define BRD_LCD1602_E_PORT      (4)
#define BRD_LCD1602_E_PIN       (2)
#define BRD_LCD1602_E_MASK      (1 << BRD_LCD1602_E_PIN)

#define BRD_LCD1602_DATA_PORT   (4)
#define BRD_LCD1602_DATA_BYTE   (1)


/*********************************************************************//**
* @brief                Initialize the pins that LCD1602 use
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_GPIO_Init(void)
{
    FIO_SetDir(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK, GPIO_DIRECTION_OUTPUT);
    FIO_SetDir(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK, GPIO_DIRECTION_OUTPUT);
    FIO_SetDir(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, GPIO_DIRECTION_OUTPUT);   
    FIO_ByteSetDir(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, GPIO_DIRECTION_OUTPUT);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
}


/*********************************************************************//**
* @brief                Delay function
* @param        tick - number milisecond of delay time
* @return                 None
**********************************************************************/
static void LCD1602_DelayMs(uint8_t tick)
{
   uint8_t i;
   uint16_t j;
   for (i=tick; i>0; i--)
      for (j=0; j<10000; j++);
}


/*********************************************************************//**
* @brief                Read the state from LCD1602
* @param        None
* @return                 the current state of LCD1602
**********************************************************************/
uint8_t LCD1602_ReadState(void)
{
    uint8_t state = 0;

    FIO_ByteSetDir(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, GPIO_DIRECTION_INPUT);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
   
    /*RS: L,RW: H,E: H*/
    FIO_SetMask(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK);
    FIO_SetMask(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK, 0);
    FIO_SetValue(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK);
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_SetValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);   
   
    FIO_ByteSetMask(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, 0);
    state = FIO_ByteReadValue(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);

    FIO_ByteSetDir(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, GPIO_DIRECTION_OUTPUT);

    return (state);
}


/*********************************************************************//**
* @brief                Read data from LCD1602
* @param        None
* @return                 the data of LCD1602
**********************************************************************/
uint8_t LCD1602_ReadData(void)
{
    uint8_t data = 0;

    FIO_ByteSetDir(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, GPIO_DIRECTION_INPUT);
   
    /*   RS: H,RW: H,E: H   */
    FIO_SetMask(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK, 0);
    FIO_SetValue(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK);
    FIO_SetMask(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK, 0);
    FIO_SetValue(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK);
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_SetValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
   
    FIO_ByteSetMask(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, 0);
    data = FIO_ByteReadValue(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE);   

    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);

    FIO_ByteSetDir(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, GPIO_DIRECTION_OUTPUT);

    return (data);
}


/*********************************************************************//**
* @brief                Determine LCD1602 is busy or not
* @param        None
* @return                 the busy flag of LCD1602
**********************************************************************/
uint8_t LCD1602_CheckBusy(void)
{
    return (LCD1602_ReadState() & 0x80);
}


/*********************************************************************//**
* @brief                Write data into LCD1602
* @param        Data which will write into LCD1602
* @return                 None
**********************************************************************/
void LCD1602_WriteData(uint8_t Data)
{
    /*   RS: H,RW: L,E: hight pluse*/
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
    FIO_SetMask(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK, 0);
    FIO_SetValue(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK);
    FIO_SetMask(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK);
   
    FIO_ByteSetMask(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, 0);
    FIO_ByteClearValue(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF);
    FIO_ByteSetMask(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, 0);
    FIO_ByteSetValue(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, Data);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_SetValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);   
}


/*********************************************************************//**
* @brief                Write command into LCD1602
* @param        Command which will write into LCD1602
* @return                 None
**********************************************************************/
void LCD1602_WriteCommand(uint8_t Command)
{   
    /*   RS: L,RW: L,E: hight pluse*/
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
    FIO_SetMask(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_RS_PORT, BRD_LCD1602_RS_MASK);
    FIO_SetMask(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_RW_PORT, BRD_LCD1602_RW_MASK);

    FIO_ByteSetMask(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, 0);
    FIO_ByteClearValue(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF);
    FIO_ByteSetMask(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, 0xFF, 0);
    FIO_ByteSetValue(BRD_LCD1602_DATA_PORT, BRD_LCD1602_DATA_BYTE, Command);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_SetValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);
   
    FIO_SetMask(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK, 0);
    FIO_ClearValue(BRD_LCD1602_E_PORT, BRD_LCD1602_E_MASK);   
}


/*********************************************************************//**
* @brief                Reset LCD1602
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_Init(void)
{
    LCD1602_DelayMs(15);
    LCD1602_WriteCommand(0X38);
    LCD1602_DelayMs(5);
    LCD1602_WriteCommand(0X38);
    LCD1602_DelayMs(5);
    LCD1602_WriteCommand(0X38);
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0X38);
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0X08);
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0X01);
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0X06);
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0X0C);
}


/*********************************************************************//**
* @brief                Set coordinate of cursor
* @param        x - x-axis,y - y-axis
* @return                 None
**********************************************************************/
void LCD1602_SetCousor(uint8_t x, uint8_t y)
{
    if ((0 == y) && (x < 40))
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteCommand(0x80 | x);
    }
    else if ((1 == y) && (x < 40))
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteCommand(0xC0 | x);
    }
}


/*********************************************************************//**
* @brief                Print one string on LCD1602
* @param        *strpiont to which will print
* @return                 None
**********************************************************************/
void LCD1602_DisplayString(const uint8_t *str)
{
    uint8_t i = 0;
    if (0 == str) return;
    while ((i < 40) && (str != 0))
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteData(str);
      i++;
    }
}


/*********************************************************************//**
* @brief                Print a number on LCD1602
* @param        nthe number which will print
* @return                 None
**********************************************************************/
void LCD1602_DisplayNum(uint32_t n)
{
    uint8_t pcBuf, *p;
   
    if (0 == n)
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteData('0');   
    }
    else
    {
      p = pcBuf;
      while (n != 0)
      {
            *p++ = (n % 10) + '0';
            n /= 10;
      }
    }
   
    while (p > pcBuf)
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteData(*--p);
    }
}


/*********************************************************************//**
* @brief                Clear the screen
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_DisplayClear(void)
{
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0x01);
}


/*********************************************************************//**
* @brief                Set cursor return (0,0)
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_DisplayHome(void)
{
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(0x02);
}


/*********************************************************************//**
* @brief                Turn on LCD1602
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_DisplayOn(void)
{
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(DISPLAYON);
}


/*********************************************************************//**
* @brief                Turn off LCD1602
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_DisplayOff(void)
{
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(DISPLAYOFF);
}


/*********************************************************************//**
* @brief                Move the cursor n unit to the left.
* @param        n is the unit number to move.
* @return                 None
**********************************************************************/
void LCD1602_CursorMoveLeft(uint8_t n)
{
    while (n--)
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteCommand(CURSORSHIFT | SHIFTLEFT);
    }
}


/*********************************************************************//**
* @brief                Move the cursor n unit to the right.
* @param        n is the unit number to move.
* @return                 None
**********************************************************************/
void LCD1602_CursorMoveRight(uint8_t n)
{
    while (n--)
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteCommand(CURSORSHIFT | SHIFTRIGHT);
    }
}


/*********************************************************************//**
* @brief                Shift the entire displayn unit to the left.
* @param        n is the unit number to shift.
* @return                 None
**********************************************************************/
void LCD1602_DisplayShiftLeft(uint8_t n)
{
    while (n--)
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteCommand(SCREENSHIFT | SHIFTLEFT);
    }
}


/*********************************************************************//**
* @brief                Shift the entire displayn unit to the right.
* @param        n is the unit number to shift.
* @return                 None
**********************************************************************/
void LCD1602_DisplayShiftRight(uint8_t n)
{
    while (n--)
    {
      while (LCD1602_CheckBusy());
      LCD1602_WriteCommand(SCREENSHIFT | SHIFTRIGHT);
    }   
}


/*********************************************************************//**
* @brief                Sets cursor on.
* @param        blink determines the cursor style.
                - DISPCURSORON:Turn on cursor
                - DISPCURSOROFF: Turn off cursor
* @return                 None
**********************************************************************/
void LCD1602_CursorOn(uint8_t blink)
{
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(DISPLAYON | DISPCURSORON | blink);
}


/*********************************************************************//**
* @brief                Sets cursor off.
* @param        None
* @return                 None
**********************************************************************/
void LCD1602_CursorOff(void)
{
    while (LCD1602_CheckBusy());
    LCD1602_WriteCommand(DISPLAYON | DISPCURSOROFF);
}
工程文件:

tiger5 发表于 2013-6-9 21:59:48

看起来不错。
为啥不用寄存器操作?GPIO库绕。
大材小用。
上4"以上的大屏。

lcofjp 发表于 2013-6-9 22:06:55

哈哈,用了1788这么大个片子,用了1602的小液晶。

tianxiaoMCU 发表于 2013-6-9 22:19:41

lcofjp 发表于 2013-6-9 22:06 static/image/common/back.gif
哈哈,用了1788这么大个片子,用了1602的小液晶。

本来是用TFT屏的,但是主管说练手就不要弄那么复杂了

xiefy21 发表于 2013-8-11 22:50:12

mark....
顶一个....{:lol:}

hyh19890917 发表于 2013-12-9 10:53:39

亲用的是库函数啊?可以 共享么?我初学,求赐教
页: [1]
查看完整版本: LPC1788驱动LCD1602的程序,写得不好,还请大家指点