编译环境:keil 5.38 使用板载的AT-link调试器
1 I2C简介
I2C(内部集成电路总线)模块提供了符合工业标准的两线串口接口,是一种简单双向的同步串行总线,可用于MCU和外部I2C设备的通讯。总线由两根串行线组成:SDA(串行数据线)和SCL(串行时钟线),这两根线是双向IO线,所以总线的接口是开漏输出的,使用的时候需要通过上拉电阻至VDD5,总线才能正常工作。
I2C原理说明
总线在空闲时SDA和SCL都是高电平,这是器件检测总线是否空闲的唯一依据,在传输过程中总线上有且只有一个主器件和至少一个从器件处于活跃状态,在这种情况下,其他器件如果想发起I2C通讯,都必须等待直到当前通讯结束,I2C总线空闲才能控制总线。主器件用于启动总线传输数据,并且通过SCL向所有器件发送时钟信号,通过SDA发送从机地址和读写模式。如果总线上有器件匹配该地址,那么该器件将作为从器件。在总线上主从器件和数据收发的关系不是恒定的。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送,通讯过程如图所示;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程,通讯过程如图所示。在这种情况下.主机负责产生定时时钟和终止数据传送。
2:OLED屏幕知识:
一、OLED 简介:
OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从 2003 年开始,这种显示设备在 MP3 播放器上得到了广泛应用,而对于同属数码类产品的 DC 与手机,此前只是在一些展会上展示过采用 OLED 屏幕的工程样品。自 2007 年后,寿命得 到很大提高,具备了许多 LCD 不可比拟的优势。
GND:电源地 VCC:2.2V~5.5V SCL(D0):CLK 时钟 (高电平 2.2V~5.5V) SDA(D1):MOSI 数据(高电平 2.2V~5.5V) RST:复位(高电平 2.2V~5.5V) D/C:数据/命令(高电平 2.2V~5.5V) 兼容 3.3V 和 5V 控制芯片的 I/O 电平(无需任何设置,直接兼容)。
实物图片
二:汉字显示方法:
需要使用软件做自己的字库
软件代码如下:
#define I2Cx_ADDRESS 0x78
#define I2Cx_PORT I2C1
#define I2Cx_CLK CRM_I2C1_PERIPH_CLOCK
#define I2Cx_DMA DMA1
#define I2Cx_DMA_CLK CRM_DMA1_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_PIN GPIO_PINS_6
#define I2Cx_SCL_GPIO_PinsSource GPIO_PINS_SOURCE6
#define I2Cx_SCL_GPIO_PORT GPIOB
#define I2Cx_SCL_GPIO_MUX GPIO_MUX_4
#define I2Cx_SDA_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SDA_GPIO_PIN GPIO_PINS_7
#define I2Cx_SDA_GPIO_PinsSource GPIO_PINS_SOURCE7
#define I2Cx_SDA_GPIO_PORT GPIOB
#define I2Cx_SDA_GPIO_MUX GPIO_MUX_4
#define I2Cx_CLKCTRL 0x10F03C6A //200K
i2c_handle_type hi2cx;
/**
* @brief initializes peripherals used by the i2c.
* @param none
* @retval none
*/
void i2c_lowlevel_init(i2c_handle_type *hi2c)
{
gpio_init_type gpio_init_structure;
if (hi2c->i2cx == I2Cx_PORT) {
/* i2c periph clock enable */
crm_periph_clock_enable(I2Cx_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
/* gpio configuration */
gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
/* condiv i2c pins: scl */
gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_structure.gpio_mode = GPIO_MODE_MUX;
gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_structure.gpio_pull = GPIO_PULL_UP;
gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN;
gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);
/* condiv i2c pins: sda */
gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN;
gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);
/* config i2c */
i2c_init(hi2c->i2cx, 0x0F, I2Cx_CLKCTRL);
i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);
}
}
void II2CGpioInit(void)
{
gpio_init_type gpio_init_structure;
crm_periph_clock_enable(I2Cx_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
/* gpio configuration */
gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
/* condiv i2c pins: scl */
gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_structure.gpio_mode = GPIO_MODE_MUX;
gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_structure.gpio_pull = GPIO_PULL_UP;
gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN;
gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);
/* condiv i2c pins: sda */
gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN;
gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);
hi2cx.i2cx = I2Cx_PORT;
/* i2c config */
i2c_config(&hi2cx);
}
void IIC_Start(void)
{
OLED_SCL_SET();
OLED_SDA_SET();
OLED_SDA_CLR();
OLED_SCL_CLR();
}
void IIC_Stop(void)
{
OLED_SCL_SET();
OLED_SDA_CLR();
OLED_SDA_SET();
}
void IIC_Wait_Ack(void)
{
OLED_SCL_SET();
OLED_SCL_CLR();
}
void Write_IIC_Byte(uint8_t IIC_Byte)
{
i2c_status_type i2c_status;
#if 0
uint8_t i;
uint8_t m, da;
da = IIC_Byte;
OLED_SCL_CLR();
for (i = 0; i < 8; i++) {
m = da;
m = m & 0x80;
if (m == 0x80) {
OLED_SDA_SET();
} else {
OLED_SDA_CLR();
}
da = da << 1;
OLED_SCL_SET();
OLED_SCL_CLR();
}
#else
uint8_t buff[2] = {0};
buff[0] = IIC_Byte;
i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 1, 1000);
if (i2c_status != I2C_OK) {
printf("erro send %d", i2c_status);
}
#endif
}
void Write_IIC_Command(uint8_t IIC_Command)
{
i2c_status_type i2c_status;
#if 0
IIC_Start();
Write_IIC_Byte(IIC_SLAVE_ADDR); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
#else
uint8_t buff[2] = {0};
buff[0] = 0x00;
buff[1] = IIC_Command;
i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 2, 1000);
if (i2c_status != I2C_OK) {
printf("erro send %d", i2c_status);
}
#endif
}
void Write_IIC_Data(uint8_t IIC_Data)
{
i2c_status_type i2c_status;
#if 0
IIC_Start();
Write_IIC_Byte(IIC_SLAVE_ADDR); //D/C#=0; R/W#=0
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
#else
uint8_t buff[2] = {0};
buff[0] = 0x40;
buff[1] = IIC_Data;
i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 2, 1000);
if (i2c_status != I2C_OK) {
printf("erro send %d", i2c_status);
}
#endif
}
测试实物图片如下:
全部评论