极海半导体-G32A1465开发板测评 05-OLED模块测试
准备目标硬件(开发板/芯片/模组)
本教程将使用极海G32A1465开发板进行示例移植。调试ARM Cortex M核还需要仿真器,如果您的开发板或者芯片模组没有板载仿真器,就需要连接外置的仿真器,如DAPLink]、JLINK之类的。
I2C协议
I2C OLED 显示函数支持
OLED 显示字符、字符串 汉字
void OLED_ShowChar_06x08(uint8_t X, uint8_t Y, uint8_t Char);//显示字符函数
void OLED_ShowString_06x08(uint8_t X, uint8_t Y, uint8_t *String);//显示字符串函数
void OLED_ShowCHinese(uint8_t X,uint8_t Y,uint8_t Chinese);//显示汉字函数
void OLED_ShowChar_08x16(uint8_t X, uint8_t Y, uint8_t Char);//显示字符函数
void OLED_ShowString_16x16(uint8_t X, uint8_t Y, uint8_t *String);//显示字符串函数
OLED 显示整型数字/浮点型数字/二进制数字/十六进制数字
void OLED_ShowNumber_SignedInteger_06x08(uint8_t X, uint8_t Y, int16_t IntegerNumber, uint8_t Count);//显示有符号整型数字函数
void OLED_ShowNumber_UnsignedInteger_06x08(uint8_t X, uint8_t Y, uint16_t IntegerNumber, uint8_t Count);//显显示无符号整型数字函数
void OLED_ShowNumber_Float_06x08(uint8_t X, uint8_t Y, float FloatNumber, uint8_t Count1, uint8_t Count2);//显示浮点数函数
void OLED_ShowNumber_Binary_06x08(uint8_t X, uint8_t Y, unsigned long BinaryNumber, uint8_t Count);//显示数组函数
void OLED_ShowNumber_Hex_06x08(uint8_t X, uint8_t Y, unsigned long BinaryNumber, uint8_t Count);//显示十六进制数字函数
OLED 基本绘图函数
// OLED 绘制直线
void OLED_DrawLine(uint8_t X, uint8_t Y, uint8_t PointData);
// OLED 绘制图像
void OLED_RollDisplay(void);//设置水平左右移
void Draw_BMP(uint8_t x0,uint8_t y0,uint8_t x1,uint8_t y1,uint8_t BMP[]);
//画点函数
void OLED_DrawDot(uint8_t X,uint8_t Y,uint8_t T);
//画直线函数
void LCD_DrawLine(uint32_t X1, uint32_t Y1, uint32_t X2,uint32_t Y2);
//dot ==1 表示亮显示出来
void OLED_Fill_Draw_circle(uint8_t X0,uint8_t Y0,uint8_t r,uint8_t dot);
//ucFilled ==1 表示填充 //画直圆函数
void OLED_DrawCircle( uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled );
//画矩形函数
void LCD_DrawRectangle(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2);
3.模拟IIC移植 OLED屏幕驱动
1. 建立工程模板,添加相关驱动文件
在之前的工程模板上进行添加文件drv_oled,olde_draw。
drv_oled.c drv_oled.h // oled底层驱动文件,包括软件iic实现,oled引脚配置,oled初始化.
olde_draw.c olde_draw.h // oled应用层文件,主要是绘图api实现(可以移植到其他开发板,不需要改,仅配置好驱动文件即可
2. 配置引脚与相关操作
选择引脚,进入工程开始编写屏幕引脚初始化代码。
为了方便后续移植,我在drv_oled.h处宏定义了每一个引脚,后续根据需要进行修改即可。
#define OLED_SCL_PORT_BASE PMA
#define OLED_SCL_GPIO_BASE GPIOA
#define OLED_SCL_GPIO_PIN (10U)
#define OLED_SDA_PORT_BASE PMA
#define OLED_SDA_GPIO_BASE GPIOA
#define OLED_SDA_GPIO_PIN (4U)
//--------------------------------------------------------------------------------------------------
// 硬件端口定义 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//--------------------------------------------------------------------------------------------------
//-----------------OLED IIC端口定义----------------
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
#define OLED_ENABLE 1
#define OLED_DISENABLE 0
#define OLED_SCLK_Clr() PINS_WritePin(OLED_SCL_GPIO_BASE,OLED_SCL_GPIO_PIN,OLED_DISENABLE) //SCL IIC接口的时钟信号
#define OLED_SCLK_Set() PINS_WritePin(OLED_SCL_GPIO_BASE,OLED_SCL_GPIO_PIN,OLED_ENABLE)
#define OLED_SDIN_Clr() PINS_WritePin(OLED_SDA_GPIO_BASE,OLED_SDA_GPIO_PIN,OLED_DISENABLE) //SDA IIC接口的数据信号
#define OLED_SDIN_Set() PINS_WritePin(OLED_SDA_GPIO_BASE,OLED_SDA_GPIO_PIN,OLED_ENABLE)
3.端口配置函数OLED_GPIO_Configuare
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_GPIO_Configuare
// 函数说明: GPIO端口配置
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_GPIO_Configuare(void)
{
/* Enable Clock to Port A */
CLOCK_SYS_ConfigModuleClock(PMA_CLK, NULL);
/* Set pin mode */
PINS_SetMuxModeSel(OLED_SCL_PORT_BASE, OLED_SCL_GPIO_PIN, PM_MUX_AS_GPIO);
PINS_SetMuxModeSel(OLED_SDA_PORT_BASE, OLED_SDA_GPIO_PIN, PM_MUX_AS_GPIO);
/* Set pin interrupt */
PINS_SetPinIntSel(OLED_SCL_PORT_BASE, OLED_SCL_GPIO_PIN, PM_DMA_INT_DISABLED);
PINS_SetPinIntSel(OLED_SDA_PORT_BASE, OLED_SDA_GPIO_PIN, PM_DMA_INT_DISABLED);
/* GPIO Initialization */
PINS_SetPins(OLED_SCL_GPIO_BASE, 1U << OLED_SCL_GPIO_PIN);
PINS_SetPins(OLED_SDA_GPIO_BASE, 1U << OLED_SDA_GPIO_PIN);
/* Set pin as output */
PINS_SetPinDir(OLED_SCL_GPIO_BASE, OLED_SCL_GPIO_PIN, 1U);
PINS_SetPinDir(OLED_SDA_GPIO_BASE, OLED_SDA_GPIO_PIN, 1U);
}
4.软件IIC代码实现
//==================================================================================================
// 函数功能: 软件IIC外设驱动函数部分
// 函数标记: IIC_Start
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void IIC_Start()
{
OLED_SCLK_Set();
delay_us(3);
OLED_SDIN_Set();
delay_us(3);
OLED_SDIN_Clr();
delay_us(3);
OLED_SCLK_Clr();
delay_us(3);
}
//==================================================================================================
// 函数功能: 软件IIC外设驱动函数部分
// 函数标记: IIC_Stop
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void IIC_Stop()
{
OLED_SCLK_Set() ;
delay_us(3);
OLED_SDIN_Clr();
delay_us(3);
OLED_SDIN_Set();
delay_us(3);
}
//==================================================================================================
// 函数功能: 软件IIC外设驱动函数部分
// 函数标记: IIC_Stop
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void IIC_Wait_Ack()
{
OLED_SCLK_Set();
delay_us(3);
OLED_SCLK_Clr();
delay_us(3);
}
//==================================================================================================
// 函数功能: 软件IIC外设驱动函数部分
// 函数标记: Write_IIC_Byte
// * @brief IIC总线写入一个字节数据
// * @details
// * - 按照IIC时序标准,依次发送8位数据
// * - MSB先发送(最高位先发)
// * - 时钟周期约为6us(由delay_us(3)决定)
// *
// * @param IIC_Byte - 要发送的一个字节数据
// * @return 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void Write_IIC_Byte(uint8_t IIC_Byte)
{
uint8_t i; // 位计数器
uint8_t m,da; // m用于位操作,da保存待发送数据
da = IIC_Byte; // 保存待发送的数据
OLED_SCLK_Clr(); // 时钟线初始置低
// 循环发送8位数据
for(i = 0; i < 8; i++)
{
m = da; // 取出当前数据
m = m & 0x80; // 获取最高位(与0x80相与)
// 根据最高位值设置SDA线电平
if(m == 0x80)
{
OLED_SDIN_Set(); // 数据线置高
}
else
{
OLED_SDIN_Clr(); // 数据线置低
}
da = da << 1; // 数据左移一位,准备发送下一位
delay_us(3); // 等待数据线稳定
OLED_SCLK_Set(); // 时钟线拉高,开始采样
delay_us(3); // 保持采样时间
OLED_SCLK_Clr(); // 时钟线拉低,结束采样
delay_us(3); // 等待时钟周期结束
}
}
//==================================================================================================
// 函数功能: IIC外设驱动函数部分
// 函数标记: Write_IIC_Command
// 函数说明: OLED写命令函数
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void Write_IIC_Command(uint8_t IIC_Command)
{
IIC_Start();
Write_IIC_Byte(I2C_SLAVE_OLED_ADDRESS7); //Slave address,SA0=0 I2C_SLAVE_OLED_ADDRESS7=0x78
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
}
//==================================================================================================
// 函数功能: IIC外设驱动函数部分
// 函数标记: Write_IIC_Data
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void Write_IIC_Data(uint8_t IIC_Data)
{
IIC_Start();
Write_IIC_Byte(I2C_SLAVE_OLED_ADDRESS7); //D/C#=0; R/W#=0 I2C_SLAVE_OLED_ADDRESS7=0x78
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
5.OLED模块初始化代码
//==================================================================================================
// 函数功能: OLED外设驱动函数部分
// 函数标记: OLED_WR_Byte
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_WR_Byte(uint8_t data,uint8_t cmd)
{
if(cmd)
{
Write_IIC_Data(data);
}
else
{
Write_IIC_Command(data);
}
}
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_Display_On
// 函数说明: 开启OLED显示
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_Display_Off
// 函数说明: 关闭OLED显示
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_Clear
// 函数说明: 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_Clear(void)
{
uint8_t count,num;
for(count=0;count<8;count++)
{
OLED_WR_Byte (0xb0+count,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(num=0;num<128;num++)
OLED_WR_Byte(0x00,OLED_DATA);
} //更新显示
}
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_Fill
// 函数说明: OLED_Fill 填充整个屏幕 fill_Data:要填充的数据
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_Fill(uint8_t fill_Data)//全屏填充
{
uint8_t m,n;
for(m=0;m<8;m++)
{
OLED_WR_Byte(0xb0+m,OLED_CMD); //page0-page1
OLED_WR_Byte(0x00,OLED_CMD); //low column start address
OLED_WR_Byte(0x10,OLED_CMD); //high column start address
for(n=0;n<128;n++)
{
OLED_WR_Byte(fill_Data,OLED_DATA);
}
}
}
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_DATA_FILL
// 函数说明: OLED_DATA_FILL 填充
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_DATA_FILL(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t dot)
{
uint8_t x,y;
for(x=x1;x<=x2;x++)
for(y=y1;y<=y2;y++)
OLED_DrawDot(x,y,dot);
OLED_Refresh_Gram();//更新显示
}
//==================================================================================================
// 函数功能: OLED 外设驱动函数部分
// 函数标记: OLED_Init
// 函数说明: 初始化函数配置
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_Init(void)
{
#if USE_HARDWARE_IIC
I2C_Configuration();
#else
OLED_GPIO_Configuare();
#endif
OLED_WR_Byte(0xAE,OLED_CMD);//--display off
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
OLED_WR_Byte(0x81,OLED_CMD); // contract control
OLED_WR_Byte(0xFF,OLED_CMD);//--128
OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
OLED_WR_Byte(0x00,OLED_CMD);//
OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
OLED_WR_Byte(0x80,OLED_CMD);//
OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
OLED_WR_Byte(0x05,OLED_CMD);//
OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
OLED_WR_Byte(0xF1,OLED_CMD);//
OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
OLED_WR_Byte(0x12,OLED_CMD);//
OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
OLED_WR_Byte(0x30,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
OLED_WR_Byte(0x14,OLED_CMD);//
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
OLED_Clear();
OLED_Set_Pos(0,0);
}
6.测试效果 软件IIC
全部评论