MSP430F5529硬件I2C驱动SH1106芯片显示屏
目录
MSP430F5529硬件I2C驱动SH1106芯片显示屏
前言
最近在捣鼓MSP4300F5299LP开发板,搞了两天,刚好看到这个芯片的USCI模块,以前接触的单片机都是一个UART或USART,遂在数据手册中了解到,原来是集合了UART、SPI、I2C为一体外设,可以说十分给力了,直接包含了三种。然后看着手册试了下UART模式,觉得还不错挺好用。然后刚好手上还有块0.96寸的小屏,I2C协议通信的,正好拿来试手。
SH1106芯片
下面来看下SH1106芯片的读写时序图
由于没读数据,所有只需要看写数据或命令的过程。
由图可知发送一个字节的顺序为:起始位+从机地址+应答+控制字节+应答+数据字节+应答+结束位即完成一帧数据的发送。
这里的从机地址为0x78
控制字节分别控制后面数据是发命令还是数据,如0x00即后面所跟的数据为命令,0x40即后面所跟的数据为RAM操作。
MSP430F5529USCI初始化。
IO初始化。
P4REN = 0x00;
//in/out: 0:in 1:out
// P47 P46 P45 P44 P43 P42 P41 P40
// 1 1 1 1 1 1 1 1
P4DIR = 0xff;
//驱动强度控制寄存器 0:降低的 1:最强的 默认为降低的
// P47 P46 P45 P44 P43 P42 P41 P40
// 0 0 0 0 0 0 0 0
P4DS = 0x00;
//IO 复用功能寄存器 0:普通 IO 1:外设模块复用
// P47 P46 P45 P44 P43 P42 P41 P40
// 0 0 0 0 0 1 1 0
P4SEL = 0x06;
// P47 P46 P45 P44 P43 P42 P41 P40
// 0 0 0 0 0 0 0 0
P4OUT = 0x00;
I2C 初始化。
配置的系统时钟为 DCOCLK,频率为 25MHz,I2C 时钟源为 SMCLK=25MHz
UCB1CTL1 |= UCSWRST; // 软件复位 USCI
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 模式、主机、同步设置
UCB1CTL1 = UCSSEL_2 + UCSWRST; // 设置 SMCLK 为时钟源同时复位 USCI
UCB1BR0 = 250; // 时钟分频系数 25MHz/250 =~100KHz
UCB1BR1 = 0;
UCB1I2CSA = 0x3c; // 从机地址 0x78,右移一位为 0x3c
UCB1CTL1 &= ~UCSWRST; // 清除复位
发送单个字节函数,这里没用中断的方式,用的查询法,可修改为中断法。
void oled_send_byte(unsigned char byte,unsigned char com)
{
while(UCB1CTL1 & UCTXSTP); // 检测结束信号是否结束
UCB1CTL1 |= UCTXSTT | UCTR; // 发送起始信号并设置为发送机
UCB1TXBUF = com; // 发送控制数据字节,0x00为命令,0x40为数据
while(!(UCB1IFG & UCTXIFG)); // 等待发送缓存区空
UCB1TXBUF = byte; // 发送数据字节
while(!(UCB1IFG & UCTXIFG)); // 等待发送缓存区空
UCB1CTL1 |= UCTXSTP; // 发送结束信号
while(UCB1CTL1 & UCTXSTP); // 检测结束信号是否结束
}
OLED 初始化
void oled_init(void)
{
oled_send_byte(0xAE,OLED_CMD);//--display off
oled_send_byte(0x00,OLED_CMD);//---set low column address
oled_send_byte(0x10,OLED_CMD);//---set high column address
oled_send_byte(0x40,OLED_CMD);//--set start line address
oled_send_byte(0xB0,OLED_CMD);//--set page address
oled_send_byte(0x81,OLED_CMD); // contract control
oled_send_byte(0xFF,OLED_CMD);//--128
oled_send_byte(0xA1,OLED_CMD);//set segment remap
oled_send_byte(0xA6,OLED_CMD);//--normal / reverse
oled_send_byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
oled_send_byte(0x3F,OLED_CMD);//--1/32 duty
oled_send_byte(0xC8,OLED_CMD);//Com scan direction
oled_send_byte(0xD3,OLED_CMD);//-set display offset
oled_send_byte(0x00,OLED_CMD);//
oled_send_byte(0xD5,OLED_CMD);//set osc division
oled_send_byte(0x80,OLED_CMD);//
oled_send_byte(0xD8,OLED_CMD);//set area color mode off
oled_send_byte(0x05,OLED_CMD);//
oled_send_byte(0xD9,OLED_CMD);//Set Pre-Charge Period
oled_send_byte(0xF1,OLED_CMD);//
oled_send_byte(0xDA,OLED_CMD);//set com pin configuartion
oled_send_byte(0x12,OLED_CMD);//
oled_send_byte(0xDB,OLED_CMD);//set Vcomh
oled_send_byte(0x30,OLED_CMD);//
oled_send_byte(0x8D,OLED_CMD);//set charge pump enable
oled_send_byte(0x14,OLED_CMD);//
oled_send_byte(0xAF,OLED_CMD);//--turn on oled panel
}
最后结果