查看: 1240|回复: 0
打印 上一主题 下一主题

NewHaven_LCD驱动开发心得笔记1 -- 支持CooCox开源活动

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-12 20:05:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
前几天在 http://www.amobbs.com/thread-5555252-1-1.html 看到了CooCox的开源活动,正好我刚刚移植了个NewHaven_LCD的驱动,拿出来和大家分享下。
我使用的是cox代码,这个可以在cortex-m各个系列平滑移植。当然前提是这个系列支持了cox。程序我已经上传到了CoIDE,大家也可以到 http://www.coocox.org/driver_com ... html?mc=4&sc=48 下载

我的驱动包含了两个文件一个NewHaven_LCD.c 和一个 NewHaven_LCD.h ,下面我来说说我这个驱动是如何保证可移植性的。

在NewHaven_LCD.h 中做了两件事儿

1.定义这个LCD用到的GPIO管脚,这样做的好处是,当硬件连接发生变化时,只需要在这儿修改就可以了。当然如果需要移植到其他库,这里也要对应的变化
//! user cofig

//! data bus
#define NHLCD_D0                PA0
#define NHLCD_D1                PA1
#define NHLCD_D2                PA2
#define NHLCD_D3                PA3
#define NHLCD_D4                PA4
#define NHLCD_D5                PA5
#define NHLCD_D6                PA6
#define NHLCD_D7                PA7

//! control signal

#define NHLCD_E                 PA8
#define NHLCD_RW                PA9
#define NHLCD_CS                PA10
#define NHLCD_RST               PA11
#define NHLCD_A0                PA12

2. 定义这个LCD的API函数指针,并声明我实现的指针MyLCD。

typedef struct NHLCD {
//    public:
        /* Creates a Newhaven LCD interface using several DigitalOut pins and a 8-bit BusInOut
         *
         * @param PIN_E Operation enable signal
         * @param PIN_RW Read/Write select signal (1 = read, 0 = write)
         * @param PIN_A0 Register select signal (1 = data, 0 = command)
         * @param PIN_CS Active LOW chip select
         * @param PIN_RST Active LOW reset signal
         * @param BUSLCD Bi-directional 8-bit data bus
         */
        //NHLCD(PinName PIN_E,PinName PIN_RW,PinName PIN_A0,PinName PIN_CS,PinName PIN_RST, BusInOut *BUSLCD);

        /* Initializes the LCD
         */
        void (*Init)(void);

        /* Outputs a command across the 8-bit bus to the LCD
         *
         * @param j hex-code of command
         */
        void (*comm_out)(unsigned char j);

        /* Outputs data across the 8-bit bus to the LCD
         *
         * @param j data to send
         */
        void (*data_out)(unsigned char j);

        /* Clears the entire screen of set pixels
         */
        void (*clearScreen)();

        /* Writes text to the LCD (with a resolution of 40x30 characters)
         *
         * @param text a string of text to write on the screen
         * @param row the row of the first character
         * @param col the column of the first character
         */
        void (*text)(char* text, char row, char col);

        /* Sets an individual pixel on the LCD (with a resolution of 320x240 pixels)
         *
         * @param row the row of the pixel
         * @param col the column of the pixel
         * @param color 1 = on, 0 = off
         */
        void (*setPixel)(int row, int col, int color);

        /* draws a line on the LCD
         *
         * @param r1 the row of the first endpoint
         * @param c1 the column of the first endpoint
         * @param r2 the row of the second endpoint
         * @param c2 the column of the second endpoint
         * @param color 1 = on, 0 = off
         */
        void (*drawLine)(int r1, int c1, int r2, int c2, int color);

        /* draws and fills a rectangle on the LCD
         *
         * @param row the row of the top-left pixel
         * @param col the column of the top-left pixel
         * @param width the width of the rectangle
         * @param height the height of the rectangle
         * @param color 1 = on, 0 = off
         */
        void (*fillRect)(int row, int col, int width, int height, int color);

//    private:
//        DigitalOut E,RW,A0,CS,RST;
//        BusInOut *LCD_PORT;
//        unsigned char screenBuffer[240*40];

}
NHLCD;

在NewHaven_LCD.c中,可以分为三部分:

1. port层,这层主要是移植用的,port层分两部分,
一个是头文件,这里包含 cox库对应的头文件,移植到其他库,以下头文件需要对应变化
#include "xhw_types.h"
#include "xhw_ints.h"
#include "xhw_nvic.h"
#include "xhw_memmap.h"
#include "xdebug.h"
#include "xcore.h"
#include "xhw_sysctl.h"
#include "xsysctl.h"
#include "xgpio.h"

两一个是底层函数,我将驱动用到的底层函数全部用define形式或者 static函数来表示

#define LCD_PORT_output(x)
#define LCD_PORT_write(x)                                                     \
        do                                                                    \
        {                                                                     \
                        xGPIOSPinWrite(NHLCD_D7, (x >> 7) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D6, (x >> 6) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D5, (x >> 5) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D4, (x >> 4) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D3, (x >> 3) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D2, (x >> 2) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D1, (x >> 1) & 0x01);                        \
                        xGPIOSPinWrite(NHLCD_D0, (x >> 0) & 0x01);                        \
       } while (0);


#define A0(x)                   xGPIOSPinWrite(NHLCD_A0, x);
#define CS(x)                   xGPIOSPinWrite(NHLCD_CS, x);
#define RW(x)                   xGPIOSPinWrite(NHLCD_RW, x);
#define E(x)                    xGPIOSPinWrite(NHLCD_E, x);
#define RST(x)                  xGPIOSPinWrite(NHLCD_RST, x);

static void NHLCDGPIOInit(void);

值得一提的是 LCD_PORT_write我这里是 一个个pin来显示的,这样可以很好的保证通用性,当然,如果一个LCD的IO都在一个port上,比如GPIOA,这里可以优化一下,直接对一个port进行操作。

2. 驱动逻辑现实层,实现头文件结构体NHLCD里面定义的API函数。这里实现代码不一一展示,有兴趣的可以自己看源码

3. 定义一个Mylcd的结构体,这个结构体包含所有实现的API
NHLCD MyLCD=
{
        .Init = NHLCDInit,
        .comm_out = NHLCDcomm_out,
        .data_out = NHLCDdata_out,
        .clearScreen = NHLCDclearScreen,
        .text = NHLCDtext,
        .setPixel = NHLCDsetPixel,
        .drawLine = NHLCDdrawLine,
        .fillRect = NHLCDfillRect,
};

至此,驱动结束,简洁而不失移植性。

---------------
这是一个简单的使用例子
#include "NewHaven_LCD.h"

    MyLCD.Init();
    MyLCD.clearScreen();
    MyLCD.text("CooCox!", 0, 15);

另外有人说,专门用port.c和port.h来写这种可移植接口。我暂时没试过
水平有限,来这里抛砖引玉,望大家多多指点
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表