使用驱动芯片SSD1306的OLED时, 我使用的是I2C通信
在看网上一些代码时, 发现基本都是每发送一个字节命令/数据, 都会发送信号, 从机地址, 发送完后就立马发送终止信号, 整个流程像这样:

起始信号-发送从机地址-控制字节-数据字节-终止信号

发送一个命令/数据相关代码

void OLED_WR_Byte(u8 dat,u8 mode)
{
	I2C_Start();
	Send_Byte(0x78);
	I2C_WaitAck();
	if(mode){Send_Byte(0x40);}
  else{Send_Byte(0x00);}
	I2C_WaitAck();
	Send_Byte(dat);
	I2C_WaitAck();
	I2C_Stop();
}

但是如果初始化要发送很多命令, 或者像需要写入很多数据时, 就会每次发送完一个命令/数据后, 然后就发送终止信号. 这里以初始化为例.

初始化相关代码:

void OLED_Init(void)
{
	OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
	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  Set Mapping RAM Display Start Line (0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
	OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
	OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
	OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
	OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
	OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
	OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
	OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
	OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
	OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
	OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
	OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
	OLED_WR_Byte(0x12,OLED_CMD);
	OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
	OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
	OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//
	OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
	OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
	OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
	OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
	OLED_WR_Byte(0xAF,OLED_CMD);
}

这样大数据的传输就相当于大部分无用时间都耗在了发送开始, 发送从机地址和发送结束信号中. 然而我在SSD1306的Datasheet中看到了是可以连续发送数据的
在这里插入图片描述
只要将控制字节的Co位从0改成1即可, 就能连续发送
若是发送命令, 控制字节是0x00, 改成0x80;
若是发送数据, 控制字节是0x40, 改成0xC0;
每次发送一个控制字节, 一个数据字节, 再接着发送一个控制字节, 一个数据字节..

附上我自己写的代码

发送单个字节

ErrorStatus Send_SingleData(uint8_t Data)
{
	SendByte(Data);                           //发送个控制字节
	 
	if( NOACK == WaitAck() )                     //从设备不应答
	{
		I2C_OLED_USART1("从设备没有应答"); 
		I2C_Stop();
		return ERROR;
	}
	
	return SUCCESS;
}

发送一个控制字节和一个数据字节

ErrorStatus Send_TwoData(SENDTYPE Type, uint8_t Data)
{
	if( ERROR == Send_SingleData(Type) )
		return ERROR;
	if( ERROR == Send_SingleData(Data) )
		return ERROR;
	
	return SUCCESS;
}

初始化相关代码, 其中ContCOMMAND是0x80;

void I2C_CmdInit(void)
{		
	I2C_Start();
	Send_SingleData(I2C_SLAVE_ADDRESS8);
		
	Send_TwoData(ContCOMMAND,0xAE);// turn off oled panel	
	Send_TwoData(ContCOMMAND,0x00);// set low column address	
	Send_TwoData(ContCOMMAND,0x10);// set high column address	
	Send_TwoData(ContCOMMAND,0x40);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
	Send_TwoData(ContCOMMAND,0x81);//--set contrast control register
	Send_TwoData(ContCOMMAND,0xCF);// Set SEG Output Current Brightness	
	Send_TwoData(ContCOMMAND,0xA1);// Set SEG/Column Mapping  		
	Send_TwoData(ContCOMMAND,0xC8);// Set COM/Row Scan Direction 
	Send_TwoData(ContCOMMAND,0xA6);// set normal display		
	Send_TwoData(ContCOMMAND,0xA8);// set multiplex ratio(1 to 64)		
	Send_TwoData(ContCOMMAND,0x3f);// 1/64 duty		
	Send_TwoData(ContCOMMAND,0xD3);// set display offset	Shift Mapping RAM Counter (0x00~0x3F)		
	Send_TwoData(ContCOMMAND,0x00);// not offset		
	Send_TwoData(ContCOMMAND,0xd5);// set display clock divide ratio/oscillator frequency		
	Send_TwoData(ContCOMMAND,0x80);// set divide ratio, Set Clock as 100 Frames/Sec		
	Send_TwoData(ContCOMMAND,0xD9);// set pre-charge period		
	Send_TwoData(ContCOMMAND,0xF1);// Set Pre-Charge as 15 Clocks & Discharge as 1 Clock		
	Send_TwoData(ContCOMMAND,0xDA);// set com pins hardware configuration		
	Send_TwoData(ContCOMMAND,0x12);		
	Send_TwoData(ContCOMMAND,0xDB);// set vcomh		
	Send_TwoData(ContCOMMAND,0x40);// Set VCOM Deselect Level		
	Send_TwoData(ContCOMMAND,0x20);// Set Page Addressing Mode (0x00/0x01/0x02)		
	Send_TwoData(ContCOMMAND,0x02);		
	Send_TwoData(ContCOMMAND,0x8D);// set Charge Pump enable/disable		
	Send_TwoData(ContCOMMAND,0x14);// set(0x10) disable	
	Send_TwoData(ContCOMMAND,0xA4);// Disable Entire Display On (0xa4/0xa5)		
	Send_TwoData(ContCOMMAND,0xA6);// Disable Inverse Display On (0xa6/a7)		
	Send_TwoData(ContCOMMAND,0xAF);	
	I2C_Stop();
}

文章写的不好, 如有问题希望大家多多指教

版权声明:本文为thefuck原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/thefuck/p/14036516.html