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
- SSD1306 OLED 驱动
- Arduino驱动SSD1306 OLED
- stm32 ssD1306 OLED驱动架构
- OpenWrt驱动OLED(SSD1306)过程记录
- Intel Edison arduino代码驱动OLED(SSD1306)
- dm3730平台oled显示时钟——ssd1306驱动
- dm3730平台oled显示时钟——ssd1306驱动
- OLED(128*64)SSD1306驱动学习总结
- 【单片机笔记】OLED控制器SSD1306及驱动代码
- 【巨窝】stm32c8t6 驱动ssd1306 oled IIC显示屏,HAL库,cubeMX配置。
- ESP8266基于microPython的OLED(SSD1306)驱动程序
- OLED驱动
- 【Arduino】【MATLAB】用ssd1306 oled屏显示任意图片
- 28035spi驱动OLED
- K60 OLED驱动
- 转 OLED 驱动
- SPI驱动模型---Oled
- 树莓派B+使用OLED(SSD1306)屏幕,SPI接口通信,编程语言python
- iphone开发资源汇总
- [hdu4815]Little Tiger vs. Deep Monkey
- USACO 3.2.2:Stringsobits
- gcc编译c++程序
- Q24:二叉搜索树的后序遍历序列
- SSD1306 OLED 驱动
- 泛型
- 远程监控之图形处理杂谈
- hdu1505 暴力或dp优化
- Linux 命令行学习(持续更新中)
- 博客更新迁移到新地址
- 作业
- 西西弗斯式的命运
- 通过SPY++实测WinForm和WPF控件的差异