手中有块SSD1306 128x64的OLED显示屏幕,使用的是I2C模式驱动。现在想让其的能够在Z-Stack CC2530 驱动OLED显示。要让CC2530驱动OLED显示,需要实现:
CC2530芯片上面并没有I2C控制器,所以只能使用IO口模拟的方式模拟I2C的控制时序。并且Ti提供RemoTI协议栈中已经实现好了I2C控制逻辑(hal_i2c.h,hal_i2c.c),或者自己实现I2C控制逻辑。自己实现I2C控制时序时,需要参考SSD1306数据手册[8.1.5 MCU I2C Interface 及14AC CHARACTERISTICS 中的I2C interface Timing characteristics],注意I2C上各种时序的要求。
I2C文件下载地址:http://download.csdn.net/detail/oxp7085915/9895098
u8g2是一个开源的嵌入式显示库,其功能非常强大,最小只占128Byte内存,可以显示文字,图片,几何图形等。并且支持非常多的显示屏。SSD1306就是其支持的一款OLED显示屏幕。
开源地址
https://github.com/olikraus/u8g2
WIKI https://github.com/olikraus/u8g2/wiki
u8g2将已C-library的方式提供给Z-Stack调用。将代码下载到本地,主要修改的目录位于csrc目录下。
移植u8g2需要实现需要实现两个步骤:
1、实现u8x8_Setup中byte_cb回调函数,该函数主要用于调用I2C驱动接口对SSD1306进行初始化和读写数据
uint8_t u8x8_byte_UltraIto_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t *data;
switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
HalI2CSendByte(data, arg_int);//发送数据
break;
case U8X8_MSG_BYTE_INIT:
HalI2CInit();//I2C初始化
break;
case U8X8_MSG_BYTE_SET_DC:
break;
case U8X8_MSG_BYTE_START_TRANSFER:
HalI2cStart(u8x8_GetI2CAddress(u8x8));//发送开始信号及发送设备地址
break;
case U8X8_MSG_BYTE_END_TRANSFER:
HalI2CStop();//发送停止信号
break;
default:
return 0;
}
return 1;
}
其中I2C的控制逻辑都在都在CC2530 hal_i2c.c中实现的。
uint8_t u8x8_byte_UltraIto_sw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
2、实现u8x8_Setup中gpio_and_delay_cb回调函数,控制GPIO的逻辑和延时
由于I2C中已经拥有了GPIO的控制及延时逻辑,所以在gpio_and_delay_cb,值用定义一个空函数结构就可以了。
创建u8x8cb.c/u8x8cb.h文件,并在.c文件中实现gpio_and_delay_cb函数,在.h中声明gpio_and_delay_cb函数。
#include "chip.h"
#include "delay.h"
#include "u8x8.h"
uint8_t u8x8_gpio_and_delay_Ultriot(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch(msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT:
/* only support for software I2C*/
break;
case U8X8_MSG_DELAY_NANO:
/* not required for SW I2C */
break;
case U8X8_MSG_DELAY_10MICRO:
/* not used at the moment */
break;
case U8X8_MSG_DELAY_100NANO:
/* not used at the moment */
break;
case U8X8_MSG_DELAY_MILLI:
//delay_micro_seconds(arg_int*1000UL);
break;
case U8X8_MSG_DELAY_I2C:
/* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
// delay_micro_seconds(arg_int<=2?5:1);
break;
case U8X8_MSG_GPIO_I2C_CLOCK:
break;
case U8X8_MSG_GPIO_I2C_DATA:
break;
/*
case U8X8_MSG_GPIO_MENU_SELECT:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN));
break;
case U8X8_MSG_GPIO_MENU_NEXT:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN));
break;
case U8X8_MSG_GPIO_MENU_PREV:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN));
break;
case U8X8_MSG_GPIO_MENU_HOME:
u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN));
break;
*/
default:
//u8x8_SetGPIOResult(u8x8, 1);
break;
}
return 1;
}
3、测试
在Components\hal\target中创建hal_oled.c/hal_oled.h
hal_oled.c:
/**************************************************************************************************
Filename: hal_oled.c
Revised: $Date: 2012-09-30 16:36:36 -0700 (Sun, 30 Sep 2012) $
Revision: $Revision: 31658 $
Description: This file contains the interface to the HAL oled Service.
**************************************************************************************************/
/**************************************************************************************************
* INCLUDES
**************************************************************************************************/
#include "hal_types.h"
#include "hal_oled.h"
#include "OSAL.h"
#include "OnBoard.h"
#include "hal_assert.h"
#include "hal_i2c.h"
#include "u8x8.h"
#include "u8g2.h"
#include "u8x8cb.h"
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
#include "DebugTrace.h"
#endif
#if (HAL_OLED == TRUE)
u8g2_t u8g2;
#endif
/**************************************************************************************************
* CONSTANTS
**************************************************************************************************/
/**************************************************************************************************
* MACROS
**************************************************************************************************/
/**************************************************************************************************
* LOCAL VARIABLES
**************************************************************************************************/
/**************************************************************************************************
* FUNCTIONS - API
**************************************************************************************************/
void HalOledInit(void)
{
#if (HAL_OLED == TRUE)
u8g2_Setup_ssd1306_i2c_128x64_noname_1(&u8g2, U8G2_R0, u8x8_byte_UltraIto_sw_i2c, u8x8_gpio_and_delay_Ultriot);
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
u8g2_SetFont(&u8g2, u8g2_font_6x12_tr);
u8g2_FirstPage(&u8g2);
do
{
u8g2_DrawStr(&u8g2, 0,15,"UltraIot");
u8g2_SendBuffer(&u8g2);
} while( u8g2_NextPage(&u8g2) );
#endif
}
/**************************************************************************************************
**************************************************************************************************/
#ifndef HAL_OLED
#define HAL_OLED TRUE
#endif
#if (defined HAL_OLED) && (HAL_OLED==TRUE)
HalOledInit();
#endif