I2C向SSD1306的OLED连续发送数据

使用驱动芯片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();
}

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

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值