【前言】
在上篇文章【MAX7800】查找I2C总线上的器件-电子产品世界论坛
我详细的分享了如何查找挂在I2C1上的外设,这一篇,我将分享如何配置OLED的发送命令与发送数据命令,快速移植SSD1306的驱动,并实现一个字符串的显示。
【I2C总线的初始化】
1、在工程中新建5个文件,分别为oled.h、oled.c、gui.c、gui.h、oledfont.h。
2、复制开源ssd1306到相应的文件中。其中gui.c/h、oledfont.h是不用修改的,直接可以使用。
3、修改oled.c。首先要引用MAX7800的I2C外设库以及必须的头文件:
#include "board.h" #include "mxc_device.h" #include "i2c.h"
在这oled.c中,我们需要修改三个地方,一个是i2c_Init,即是初始化I2C。对应的代码如下:
#define I2C_MASTER MXC_I2C1 // SCL P0_16; SDA P0_17 #define I2C_SCL_PIN 16 #define I2C_SDA_PIN 17 #define I2C_FREQ 400000 // 100kHZ mxc_i2c_req_t reqMaster; //声明结构体 void i2cm_Init(void) { int error; //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { printf("-->I2C Master Initialization failed, error:%d\n", error); return; } else { printf("\n-->I2C Master Initialization Complete\n"); } printf("-->Scanning started\n"); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); reqMaster.i2c = I2C_MASTER; reqMaster.addr = 0; reqMaster.tx_buf = NULL; reqMaster.tx_len = 0; reqMaster.rx_buf = NULL; reqMaster.rx_len = 0; reqMaster.restart = 0; reqMaster.callback = NULL; }
在上面的代码中,首先声明I2C结构体指针,用于存放他的操作,首先初始化i2c1外设,然后使用
MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ);
设置通信速度为400K。
然后再指定i2c1为主设备,清空对应的参数,在后面,我们就可以使用这个全局参数来进行操作。
4、修改ssd1306的写入一个字节的函数,代码如下:
/******************************************************************* * @name :void OLED_WR_Byte(unsigned dat,unsigned cmd) * @date :2018-08-27 * @function :Write a byte of content to the OLED screen * @parameters :dat:Content to be written cmd:0-write command 1-write data * @retvalue :None ********************************************************************/ void OLED_WR_Byte(unsigned char dat,unsigned char cmd) { unsigned char i2c_tx_buff[2]; int error; if(cmd) { i2c_tx_buff[0] = 0x40; } else { i2c_tx_buff[0] = 0x00; } i2c_tx_buff[1] = dat; reqMaster.tx_buf = i2c_tx_buff; reqMaster.addr = SSD1306_ADDR; reqMaster.tx_len = 2; error = MXC_I2C_MasterTransaction(&reqMaster); if (error != E_NO_ERROR) { printf("-->I2C send failed, error:%d\n", error); return; } }
在这个函数里,我们需要组装需要发送的数据,指定发送的是数据还是命令,指定从机的地址(7bit),需要发送数据的长度,以及发送缓冲区的地址,最后执行
MXC_I2C_MasterTransaction(&reqMaster);
这发送数据,并根据返回的状态打印相关日。
再就是修改发送整屏的参数即OLED_DISPLY
void OLED_Display(void) { OLED_WR_Byte(0x21, 0); // 设置列地址 OLED_WR_Byte(0x00, 0); // 起始列地址 OLED_WR_Byte(SSD1306_WIDTH - 1, 0); // 结束列地址 OLED_WR_Byte(0x22, 0); // 设置页地址 OLED_WR_Byte(0x00, 0); // 起始页地址 OLED_WR_Byte(OLED_PAGE_SIZE - 1, 0); // 结束页地址 Flash_OLED_Buffer[0] = 0x40; reqMaster.tx_buf = Flash_OLED_Buffer; reqMaster.tx_len = 1025; reqMaster.addr = SSD1306_ADDR; MXC_I2C_MasterTransaction(&reqMaster); }
如上述代码所示,我们需要再次指定从机地址、数组的地址、发送的长度,最后执行发送。
到些SSD1306的代码就移植完成,在main.c中添加测试代码:
int main(void) { printf("Hello World!\n"); OLED_Init(); GUI_ShowString(0,0,(uint8_t *)"hellowld",16,0); OLED_Display(); while (1) { LED_On(LED1); MXC_Delay(500000); LED_Off(LED1); MXC_Delay(500000); } return 0; }
【效果】
下载到开发后,成功的驱动OLED屏:
【总结】
MAX7800的i2c库提供了完美的API只需要少数配置,便可以快速的驱动I2C设备。