|
前几天在 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来写这种可移植接口。我暂时没试过
水平有限,来这里抛砖引玉,望大家多多指点 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|