前几天在 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来写这种可移植接口。我暂时没试过 
水平有限,来这里抛砖引玉,望大家多多指点 
 |