SSD1306 OLED 驱动

来源:互联网 发布:凯文约翰逊生涯数据 编辑:程序博客网 时间:2024/06/10 15:11

前一阵子回家买了个 OLED (128 x 64,SSD1306)——Mini STM32 板的配件,这两天把驱动做完了,拿出来晾晾。


驱动是 pixel device 形式的。一开始本来打算做 frame buffer 形式的,但在测试时遇到了 hard fault 。俺怀疑是 RTGUI 的 frame buffer 驱动对单色显示的支持还不完善,但没有深究。
选用 pixel device 形式,也需要修改 RTGUI 代码以增加对单色显示的支持(”pixel_driver.c” and “color.h”)。
上图的 demo 使用新版 RTGUI,显示了一个 window,window 里有一个 label,没用 container。另外还显示了一张 bmp 图。图本身是单色的,加载时大小缩至 1/8。

和 LCD 对比一下, :) 。


再发点牢骚,新版 RTGUI 似乎在显示更新上有效率问题。比如上图的 demo ,有三个 window。按说每个 window 应该只绘制一次,但实际上似乎每个都绘制了三次。
现象:demo 中,背景的 main window 里面有个 container。在处理绘制 container 的 RTGUI_EVENT_PAINT 事件时,加载了一张图。最终,此图被加载了三次。
对于要加载大图的程序来说,这基本是噩梦。俺记得旧版没有这个问题。当然,有可能是俺对新版还不了解、使用不当。以后再研究吧。


更新:

跟 grissiom 兄在 github 上讨教了一下。感觉重复绘制问题是由于俺对新版 API 不了解所导致的。旧版有 workbench 、 view 的概念;新版没有,但多了  application 。使得有些功能在新版中得到了简化,还有些似乎是重新组织了一下。

俺的 demo (可在 RT-Thread EFM32 分支的代码中找到)在旧版中大概是这样的结构:

app --|--> workbench1 --> view1 --> (child) lable1        |--> workbench2 --> view2 (load image when painting) --> (child) lable2       |--> win_hello + box --> (child) lable3
当移植到新版时,俺根据一些例程和猜测,把 demo 改成了这个样子:

app --|--> win_info --> (child) container1 --> (child) lable1       |--> win_main --> (child) container2 (load image when painting) --> (child) lable2       |--> win_hello + box --> (child) lable3
在和 grissiom 兄讨教之后,俺又改成了这样:
app --|--> win_info --> (child) lable1      |--> win_main (load image when painting) --> (child) lable2      |--> win_hello + box --> (child) lable3

现在就没有重复绘制的问题了。看来新版 API 确实在简化应用程序开发方面做了不少努力。但是控件分组的功能要咋实现呢?待俺以后再研究吧。
下面是代码:

drv_oled.c

/***************************************************************************//** * @file dev_oled.c * @brief OLED driver of RT-Thread RTOS for MiniSTM32 * COPYRIGHT (C) 2012, RT-Thread Development Team * @author onelife * @version 1.0 ******************************************************************************* * @section License * The license and distribution terms for this file may be found in the file *  LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE ******************************************************************************* * @section Change Logs * DateAuthorNotes * 2012-06-15onelifeInitial creation for MiniSTM32 ******************************************************************************//***************************************************************************//** * @addtogroup MiniSTM32 * @{ ******************************************************************************//* Includes ------------------------------------------------------------------*/#include "board.h"#include "drv_oled.h"#if defined(MINISTM32_USING_OLED)#include <rtgui/rtgui.h>#include <rtgui/driver.h>/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*/#ifdef MINISTM32_OLED_DEBUG#define oled_debug(format,args...)      rt_kprintf(format, ##args)#else#define oled_debug(format,args...)#endif/* Private function prototypes -----------------------------------------------*/static void oled_setPixel(rtgui_color_t *c, int x, int y);static void oled_getPixel(rtgui_color_t *c, int x, int y);static void oled_drawHLine(rtgui_color_t *c, int x1, int x2, int y);static void oled_drawVLine(rtgui_color_t *c, int x , int y1, int y2);static void oled_drawRawHLine(rt_uint8_t *pixels, int x1, int x2, int y);/* Private variables ---------------------------------------------------------*/static struct rt_device oled_device;struct rt_semaphore oled_lock;static struct rt_device_graphic_info oled_info;//static rt_uint8_t frame_buffer[MINISTM32_OLED_HEIGHT/8][MINISTM32_OLED_WIDTH];static const struct rtgui_graphic_driver_ops oled_ops =    {        oled_setPixel,        oled_getPixel,        oled_drawHLine,        oled_drawVLine,        oled_drawRawHLine    };/* Private functions ---------------------------------------------------------*/rt_inline void oled_delayUs(rt_uint32_t us){    /* This function is not that accurate */    rt_uint32_t i = SystemCoreClock / 1000000 * us / 3;    for(; i > 0; i--);}rt_inline void ssd1306_writeByte(rt_uint8_t data){    MINISTM32_OLED_DATA_OUT(data);    MINISTM32_OLED_WR_RESET;    MINISTM32_OLED_WR_SET;}rt_inline void ssd1306_readByte(rt_uint8_t *data){    GPIOB->CRL = 0x88888888;    GPIOB->ODR = (GPIOB->ODR & 0x0000FF00) | 0x000000FF;    MINISTM32_OLED_RD_RESET;    MINISTM32_OLED_DATA_IN(data);    MINISTM32_OLED_RD_SET;GPIOB->CRL = 0x33333333;    GPIOB->ODR = (GPIOB->ODR & 0x0000FF00) | 0x000000FF;}rt_inline void ssd1306_readBuffer(rt_uint8_t *data, rt_uint8_t size){    rt_uint8_t i;    GPIOB->CRL = 0x88888888;    GPIOB->ODR = (GPIOB->ODR & 0x0000FF00) | 0x000000FF;    for (i = 0; i < size; i++)    {        MINISTM32_OLED_RD_RESET;        MINISTM32_OLED_DATA_IN(data++);        MINISTM32_OLED_RD_SET;    }GPIOB->CRL = 0x33333333;    GPIOB->ODR = (GPIOB->ODR & 0x0000FF00) | 0x000000FF;}static void oled_writeCmd(rt_uint8_t data){    MINISTM32_OLED_CS_RESET;    MINISTM32_OLED_DC_RESET;    ssd1306_writeByte(data);    MINISTM32_OLED_DC_SET;    MINISTM32_OLED_CS_SET;}static void oled_writeLongCmd(rt_uint8_t *data, rt_uint8_t size){    rt_uint8_t i;    MINISTM32_OLED_CS_RESET;    MINISTM32_OLED_DC_RESET;    for (i = 0; i < size; i++)    {        ssd1306_writeByte(*data++);    }    MINISTM32_OLED_DC_SET;    MINISTM32_OLED_CS_SET;}static void oled_writeData(rt_uint8_t *data, rt_uint8_t size){    rt_uint8_t i;    MINISTM32_OLED_CS_RESET;    for (i = 0; i < size; i++)    {        ssd1306_writeByte(*data++);    }    MINISTM32_OLED_CS_SET;}static void oled_readStatus(rt_uint8_t *data){    MINISTM32_OLED_CS_RESET;    MINISTM32_OLED_DC_RESET;    ssd1306_readByte(data);    MINISTM32_OLED_DC_SET;    MINISTM32_OLED_CS_SET;}static void oled_readData(rt_uint8_t *data, rt_uint8_t size){    rt_uint8_t dummy;    MINISTM32_OLED_CS_RESET;    ssd1306_readByte(&dummy);    ssd1306_readBuffer(data, size);    MINISTM32_OLED_CS_SET;}void oled_clear(void){rt_uint32_t i;    rt_uint8_t data[3];    // Set column address    data[0] = 0x21;    data[1] = 0x00;    data[2] = MINISTM32_OLED_WIDTH - 1;    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = 0x00;    data[2] = (MINISTM32_OLED_HEIGHT - 1) / 8;    oled_writeLongCmd(data, 3);    MINISTM32_OLED_CS_RESET;for (i = 0; i < (MINISTM32_OLED_WIDTH * (MINISTM32_OLED_HEIGHT / 8)); i++)    {        ssd1306_writeByte(0x00);//        oled_delayUs(100);}    MINISTM32_OLED_CS_SET;}static void ssd1306_gpio_init(void){    GPIO_InitTypeDef GPIO_InitStructure;    /* Config GPIO */    RCC_APB2PeriphClockCmd(MINISTM32_OLED_DATA_CLOCK | \        MINISTM32_OLED_CTRL_CLOCK | RCC_APB2Periph_AFIO, ENABLE);    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Pin   = \        GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | \        GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;    GPIO_Init(MINISTM32_OLED_DATA_PORT, &GPIO_InitStructure);    GPIO_Write(MINISTM32_OLED_DATA_PORT, GPIO_InitStructure.GPIO_Pin);    GPIO_InitStructure.GPIO_Pin   = \        MINISTM32_OLED_CS_PIN | MINISTM32_OLED_DC_PIN | \        MINISTM32_OLED_WR_PIN | MINISTM32_OLED_RD_PIN;    GPIO_Init(MINISTM32_OLED_CTRL_PORT, &GPIO_InitStructure);    GPIO_Write(MINISTM32_OLED_CTRL_PORT, GPIO_InitStructure.GPIO_Pin);    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);}static rt_err_t ssd1306_init(void){    rt_uint8_t data[2];    ssd1306_gpio_init();    // Turn off panel    oled_writeCmd(0xAE);    // Set display clock    data[0] = 0xD5;    data[1] = 0x80;         // default    oled_writeLongCmd(data, 2);    // Set charge pump    data[0] = 0x8D;    data[1] = 0x14;         // enable    oled_writeLongCmd(data, 2);    // Set pre-charge period    data[0] = 0xD9;    data[1] = 0xF1;    oled_writeLongCmd(data, 2);    // Set Vcomh deselect level    data[0] = 0xDB;    data[1] = 0x30;         // 0x83 x Vcc    oled_writeLongCmd(data, 2);    // Set contrast    data[0] = 0x81;    data[1] = 0xEF;    oled_writeLongCmd(data, 2);    // Set memory addressing mode    data[0] = 0x20;    data[1] = 0x00;         // horizontal mode    oled_writeLongCmd(data, 2);    // Set segment remap    oled_writeCmd(0xA1);    // colume 127 -> SEG0    // Set normal display    oled_writeCmd(0xA6);    // Set multiplex ratio    data[0] = 0xA8;    data[1] = 0x3f;         // N = 64, default    oled_writeLongCmd(data, 2);    // Set COM output scan direction    oled_writeCmd(0xC8);    // from COM[N-1] to COM0    // Set COM pin    data[0] = 0xDA;    data[1] = 0x12;         // alternative, disable left/right remap, default    oled_writeLongCmd(data, 2);    // Set display offset    data[0] = 0xD3;    data[1] = 0x00;         // default    oled_writeLongCmd(data, 2);    // Set low column address//    oled_writeCmd(0x00);    // default    // Set high column address//    oled_writeCmd(0x10);    // default    // Set display start line    oled_writeCmd(0x40);    // default    // Turn on display    oled_writeCmd(0xA4);    // Turn on panel    oled_writeCmd(0xAF);    oled_clear();    return RT_EOK;}/***************************************************************************//** * @brief *   Get the color of a pixel * * @details * * @note * * @param[out] c *  Pointer to color * * @param[in] x *  Horizontal position * * @param[in] y *  Vertical position ******************************************************************************/static void oled_getPixel(rtgui_color_t *c, int x, int y){    rt_err_t ret;    rt_uint8_t color, data[3];    if ((x >= MINISTM32_OLED_WIDTH) || (y >= MINISTM32_OLED_HEIGHT))    {        return;    }    if (rt_hw_interrupt_check())    {        ret = rt_sem_take(&oled_lock, RT_WAITING_NO);    }    else    {        ret = rt_sem_take(&oled_lock, RT_WAITING_FOREVER);    }    if (ret != RT_EOK)    {        return;    }    // Set column address    data[0] = 0x21;    data[1] = x;    data[2] = x;    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = y / 8;    data[2] = y / 8;    oled_writeLongCmd(data, 3);    oled_readData(&color, 1);    if (color & (1 << (y % 8)))    {        *(rt_uint8_t *)c = 0x01;    }    else    {        *(rt_uint8_t *)c = 0x00;    }    rt_sem_release(&oled_lock);}/***************************************************************************//** * @brief *   Draw a pixel with specified color * * @details * * @note * * @param[in] c *  Pointer to color * * @param[in] x *  Horizontal position * * @param[in] y *  Vertical position ******************************************************************************/static void oled_setPixel(rtgui_color_t *c, int x, int y){    rt_err_t ret;    rt_uint8_t color, data[3];    if ((x >= MINISTM32_OLED_WIDTH) || (y >= MINISTM32_OLED_HEIGHT))    {        return;    }    if (rt_hw_interrupt_check())    {        ret = rt_sem_take(&oled_lock, RT_WAITING_NO);    }    else    {        ret = rt_sem_take(&oled_lock, RT_WAITING_FOREVER);    }    if (ret != RT_EOK)    {        return;    }    // Set column address    data[0] = 0x21;    data[1] = x;    data[2] = x;    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = y / 8;    data[2] = y / 8;    oled_writeLongCmd(data, 3);    oled_readData(&color, 1);    color &= ~(1 << (y % 8));    if (*(rt_uint8_t *)c)    {        color |= 1 << (y % 8);    }    oled_writeData(&color, 1);    rt_sem_release(&oled_lock);}/***************************************************************************//** * @brief *   Draw a horizontal line with raw color * * @details * * @note * * @param[in] pixels *  Pointer to raw color * * @param[in] x1 *  Horizontal start position * * @param[in] x2 *  Horizontal end position * * @param[in] y *  Vertical position ******************************************************************************/static void oled_drawRawHLine(rt_uint8_t *pixels, int x1, int x2, int y){    rt_err_t ret;    rt_uint8_t color[MINISTM32_OLED_WIDTH], data[3];    rt_uint32_t i;    if ((x1 >= MINISTM32_OLED_WIDTH) || (y >= MINISTM32_OLED_HEIGHT))    {        return;    }    if (x2 >= MINISTM32_OLED_WIDTH)    {        x2 = MINISTM32_OLED_WIDTH - 1;    }    if (rt_hw_interrupt_check())    {        ret = rt_sem_take(&oled_lock, RT_WAITING_NO);    }    else    {        ret = rt_sem_take(&oled_lock, RT_WAITING_FOREVER);    }    if (ret != RT_EOK)    {        return;    }    // Set column address    data[0] = 0x21;    data[1] = x1;    data[2] = x2;    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = y / 8;    data[2] = y / 8;    oled_writeLongCmd(data, 3);    oled_readData(color, x2 - x1 + 1);    for (i = 0; i < x2 - x1; i++)    {        color[i] &= ~(1 << (y % 8));        if (*pixels++)        {            color[i] |= 1 << (y % 8);        }    }    oled_writeData(color, x2 - x1 + 1);    rt_sem_release(&oled_lock);    oled_debug("rawH (%d-%d, %d) %x\n", x1, x2, y, *pixels);}/***************************************************************************//** * @brief *   Draw a horizontal line with specified color * * @details * * @note * * @param[in] c *  Pointer to color * * @param[in] x1 *  Horizontal start position * * @param[in] x2 *  Horizontal end position * * @param[in] y *  Vertical position ******************************************************************************/static void oled_drawHLine(rtgui_color_t *c, int x1, int x2, int y){    rt_err_t ret;    rt_uint8_t color[MINISTM32_OLED_WIDTH], data[3];    rt_uint32_t i;    if ((x1 >= MINISTM32_OLED_WIDTH) || (y >= MINISTM32_OLED_HEIGHT))    {        return;    }    if (x2 >= MINISTM32_OLED_WIDTH)    {        x2 = MINISTM32_OLED_WIDTH - 1;    }    if (rt_hw_interrupt_check())    {        ret = rt_sem_take(&oled_lock, RT_WAITING_NO);    }    else    {        ret = rt_sem_take(&oled_lock, RT_WAITING_FOREVER);    }    if (ret != RT_EOK)    {        return;    }    // Set column address    data[0] = 0x21;    data[1] = x1;    data[2] = x2;    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = y / 8;    data[2] = y / 8;    oled_writeLongCmd(data, 3);    oled_readData(color, x2 - x1 + 1);    for (i = 0; i < x2 - x1; i++)    {        color[i] &= ~(1 << (y % 8));    }    if (*(rt_uint8_t *)c)    {        for (i = 0; i < x2 - x1; i++)        {            color[i] |= 1 << (y % 8);        }    }    oled_writeData(color, x2 - x1 + 1);    rt_sem_release(&oled_lock);}/***************************************************************************//** * @brief *   Draw a vertical line with specified color * * @details * * @note * * @param[in] c *  Pointer to color * * @param[in] x *  Horizontal position * * @param[in] y1 *  Vertical start position * * @param[in] y2 *  Vertical end position ******************************************************************************/static void oled_drawVLine(rtgui_color_t *c, int x , int y1, int y2){    rt_err_t ret;    rt_uint8_t color[MINISTM32_OLED_HEIGHT], data[3];    rt_uint32_t i;    if ((x >= MINISTM32_OLED_WIDTH) || (y1 >= MINISTM32_OLED_HEIGHT))    {        return;    }    if (y2 >= MINISTM32_OLED_HEIGHT)    {        y2 = MINISTM32_OLED_HEIGHT - 1;    }    if (rt_hw_interrupt_check())    {        ret = rt_sem_take(&oled_lock, RT_WAITING_NO);    }    else    {        ret = rt_sem_take(&oled_lock, RT_WAITING_FOREVER);    }    if (ret != RT_EOK)    {        return;    }    // Set memory addressing mode    data[0] = 0x20;    data[1] = 0x01;         // vertical mode    oled_writeLongCmd(data, 2);    // Set column address    data[0] = 0x21;    data[1] = x;    data[2] = x;    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = y1 / 8;    data[2] = y2 / 8;    oled_writeLongCmd(data, 3);    oled_readData(color, (y2 - y1 + 1 + 7) / 8);    if (*(rt_uint8_t *)c)    {        for (i = y1; i <= y2; i++)        {            color[i / 8] |= 1 << (i % 8);        }    }    else    {        for (i = y1; i <= y2; i++)        {            color[i / 8] &= ~(1 << (i % 8));        }    }    oled_writeData(color, (y2 - y1 + 1 + 7) / 8);    // Set memory addressing mode    data[0] = 0x20;    data[1] = 0x00;         // horizontal mode    oled_writeLongCmd(data, 2);    rt_sem_release(&oled_lock);    oled_debug(" VLine (%d, %d-%d) %x\n", x, y1, y2, *(rt_uint8_t *)c);}/***************************************************************************//** * @brief *   Open OLED device * * @details * * @note * * @param[in] dev *   Pointer to device descriptor * * @param[in] oflag *   Device open flag * * @return *   Error code ******************************************************************************/static rt_err_t miniStm32_oled_open(rt_device_t dev, rt_uint16_t oflag){    return RT_EOK;}/***************************************************************************//** * @brief *   Close OLED device * * @details * * @note * * @param[in] dev *   Pointer to device descriptor * * @return *   Error code ******************************************************************************/static rt_err_t miniStm32_oled_close(rt_device_t dev){    return RT_EOK;}/*static void miniStm32_oled_update(struct rt_device_rect_info *rect){    rt_uint8_t i, data[3];    if ((rect->x >= MINISTM32_OLED_WIDTH) || (rect->y >= MINISTM32_OLED_HEIGHT))    {        return;    }    // Set column address    data[0] = 0x21;    data[1] = rect->x;    if ((rect->x + rect->width) >= MINISTM32_OLED_WIDTH)    {        data[2] = MINISTM32_OLED_WIDTH - 1;    }    else    {        data[2] = rect->x + rect->width;    }    oled_writeLongCmd(data, 3);    // Set page address    data[0] = 0x22;    data[1] = rect->y / 8;    if ((rect->y + rect->height) >= MINISTM32_OLED_HEIGHT)    {        data[2] = (MINISTM32_OLED_HEIGHT - 1) / 8;    }    else    {        data[2] = (rect->y + rect->height) / 8;    }    oled_writeLongCmd(data, 3);    for (i = data[1]; i <= data[2]; i++)    {        oled_writeData(&frame_buffer[i][rect->x], rect->width);    }}*//***************************************************************************//*** @brief*   Configure OLED device** @details** @note** @param[in] dev*   Pointer to device descriptor** @param[in] cmd*   IIC control command** @param[in] args*   Arguments** @return*   Error code******************************************************************************/static rt_err_t miniStm32_oled_control(rt_device_t dev, rt_uint8_t cmd, void *args){switch (cmd){case RTGRAPHIC_CTRL_RECT_UPDATE://        miniStm32_oled_update((struct rt_device_rect_info *)args);        oled_debug("OLED: update\n");break;case RTGRAPHIC_CTRL_POWERON:break;case RTGRAPHIC_CTRL_POWEROFF:break;case RTGRAPHIC_CTRL_GET_INFO:rt_memcpy(args, &oled_info, sizeof(oled_info));break;case RTGRAPHIC_CTRL_SET_MODE:break;}return RT_EOK;}/***************************************************************************//** * @brief *Register OLED device * * @details * * @note * * @param[in] device *Pointer to device descriptor * * @param[in] name *Device name * * @param[in] flag *Configuration flags * * @param[in] iic *Pointer to IIC device descriptor * * @return *Error code ******************************************************************************/static rt_err_t miniStm32_oled_register(rt_device_t        device,const char          *name,rt_uint32_t         flag,void                *data){RT_ASSERT(device != RT_NULL);device->type = RT_Device_Class_Graphic;device->rx_indicate = RT_NULL;device->tx_complete = RT_NULL;device->init = RT_NULL;device->open= miniStm32_oled_open;device->close= miniStm32_oled_close;device->read = RT_NULL;device->write = RT_NULL;device->control = miniStm32_oled_control;device->user_data= data;/* register a character device */return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);}/***************************************************************************//** * @brief *   Initialize OLED device * * @details * * @note * ******************************************************************************/void miniStm32_hw_oled_init(void){    rt_uint32_t flag;    rt_uint8_t status;    do    {        /* Init OLED info */        flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE; //RT_DEVICE_FLAG_DMA_TX        oled_info.pixel_format      = RTGRAPHIC_PIXEL_FORMAT_MONO;        oled_info.bits_per_pixel    = 1;        oled_info.width             = MINISTM32_OLED_WIDTH;        oled_info.height            = MINISTM32_OLED_HEIGHT;        oled_info.framebuffer       = RT_NULL; //(rt_uint8_t *)frame_buffer;//        if (miniStm32_oled_register(&oled_device, OLED_DEVICE_NAME, flag, RT_NULL) != RT_EOK)        if (miniStm32_oled_register(&oled_device, OLED_DEVICE_NAME, flag,            (void *)&oled_ops) != RT_EOK)        {            break;        }        /* Init OLED lock */        if (rt_sem_init(&oled_lock, OLED_DEVICE_NAME, 1, RT_IPC_FLAG_FIFO) != RT_EOK)        {            break;        }        /* Init ssd1306 */        if (ssd1306_init() != RT_EOK)        {            break;        }        oled_readStatus(&status);        oled_debug("OLED: status %x\n", status);        /* Set as rtgui graphic driver */        if (rtgui_graphic_set_device(&oled_device) != RT_EOK)        {            break;        }        oled_debug("OLED: H/W init OK!\n");        return;    } while(0);    oled_debug("OLED err: H/W init failed!\n");}#endif /* defined(MINISTM32_USING_OLED) *//***************************************************************************//** * @} ******************************************************************************/

drv_oled.h

/***************************************************************************//** * @file dev_oled.h * @brief OLED driver of RT-Thread RTOS for MiniSTM32 * COPYRIGHT (C) 2012, RT-Thread Development Team * @author onelife * @version 1.0 ******************************************************************************* * @section License * The license and distribution terms for this file may be found in the file *  LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE ******************************************************************************* * @section Change Logs * DateAuthorNotes * 2012-06-15onelifeInitial creation for MiniSTM32 ******************************************************************************/#ifndef __DEV_OLED_H__#define __DEV_OLED_H__/* Includes ------------------------------------------------------------------*//* Exported types ------------------------------------------------------------*//* Exported constants --------------------------------------------------------*//* Exported macro ------------------------------------------------------------*/#define MINISTM32_OLED_WIDTH            (128)   /* Screen Width (in pixels) */#define MINISTM32_OLED_HEIGHT           (64)    /* Screen Hight (in pixels) */#define MINISTM32_OLED_CTRL_SUSPEND     (0x00)#define MINISTM32_OLED_CTRL_RESUME      (0x01)#defineMINISTM32_OLED_DATA_IN(data)    (*(data) = GPIOB->IDR & 0x000000FF)#defineMINISTM32_OLED_DATA_OUT(data)   (GPIOB->ODR = (GPIOB->ODR & 0xFFFFFF00) | data)#defineMINISTM32_OLED_CS_SET           (GPIOC->BSRR = GPIO_Pin_9)#defineMINISTM32_OLED_DC_SET           (GPIOC->BSRR = GPIO_Pin_8)#defineMINISTM32_OLED_WR_SET           (GPIOC->BSRR = GPIO_Pin_7)#defineMINISTM32_OLED_RD_SET           (GPIOC->BSRR = GPIO_Pin_6)#defineMINISTM32_OLED_CS_RESET         (GPIOC->BRR = GPIO_Pin_9)#defineMINISTM32_OLED_DC_RESET         (GPIOC->BRR = GPIO_Pin_8)#defineMINISTM32_OLED_WR_RESET         (GPIOC->BRR = GPIO_Pin_7)#defineMINISTM32_OLED_RD_RESET         (GPIOC->BRR = GPIO_Pin_6)#defineMINISTM32_OLED_DATA_CLOCK       (RCC_APB2Periph_GPIOB)#defineMINISTM32_OLED_CTRL_CLOCK       (RCC_APB2Periph_GPIOC)#defineMINISTM32_OLED_DATA_PORT        (GPIOB)#defineMINISTM32_OLED_CTRL_PORT        (GPIOC)#defineMINISTM32_OLED_CS_PIN           (GPIO_Pin_9)#defineMINISTM32_OLED_DC_PIN           (GPIO_Pin_8)#defineMINISTM32_OLED_WR_PIN           (GPIO_Pin_7)#defineMINISTM32_OLED_RD_PIN           (GPIO_Pin_6)/* Exported functions ------------------------------------------------------- */void miniStm32_hw_oled_init(void);#endif /* __DEV_OLED_H__ */

pixel_driver.c (修改部分)

static void _pixel_mono_set_pixel(rtgui_color_t *c, int x, int y){rt_uint8_t pixel;pixel = rtgui_color_to_mono(*c);gfx_device_ops->set_pixel((char*)&pixel, x, y);}static void _pixel_mono_get_pixel(rtgui_color_t *c, int x, int y){rt_uint8_t pixel;gfx_device_ops->get_pixel((char*)&pixel, x, y);*c = rtgui_color_from_mono(pixel);}static void _pixel_mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y){rt_uint8_t pixel;pixel = rtgui_color_to_mono(*c);gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);}static void _pixel_mono_draw_vline(rtgui_color_t *c, int x, int y1, int y2){rt_uint8_t pixel;pixel = rtgui_color_to_mono(*c);gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);}static void _pixel_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y){gfx_device_ops->blit_line((char*)pixels, x1, x2, y);}const struct rtgui_graphic_driver_ops _pixel_mono_ops ={_pixel_mono_set_pixel,_pixel_mono_get_pixel,_pixel_mono_draw_hline,_pixel_mono_draw_vline,_pixel_draw_raw_hline,};const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_format){switch (pixel_format){    case RTGRAPHIC_PIXEL_FORMAT_MONO:        return &_pixel_mono_ops;case RTGRAPHIC_PIXEL_FORMAT_RGB565:return &_pixel_rgb565_ops;case RTGRAPHIC_PIXEL_FORMAT_RGB565P:return &_pixel_rgb565p_ops;case RTGRAPHIC_PIXEL_FORMAT_RGB888:return &_pixel_rgb888_ops;}return RT_NULL;}

color.h (修改部分)

/* convert rtgui color to mono */rt_inline rt_uint8_t rtgui_color_to_mono(rtgui_color_t c){rt_uint8_t pixel;pixel = (RTGUI_RGB_R(c) | RTGUI_RGB_G(c) | RTGUI_RGB_B(c)) ? 0x01 : 0x00;return pixel;}rt_inline rtgui_color_t rtgui_color_from_mono(rt_uint8_t pixel){rtgui_color_t color;if (pixel){    color = white;}    else    {        color = black;    }return color;}

文章转自: http://piao.sg/onelife/?p=213#comment-8

                                             
0 0