oled.c
代码语言:javascript复制#include "oled.h"
#include "usart.h"
#include "oled_font.h"
#include "sys_tick.h"
static __IO uint32_t I2CTimeout = I2CT_LONG_TIMEOUT;
void I2C_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(IIC_GPIO_CLK,ENABLE);
//SCL
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin = IIC_SCL_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IIC_SCL_GPIO_PORT,&GPIO_InitStructure);
//SDA
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin = IIC_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IIC_SDA_GPIO_PORT,&GPIO_InitStructure);
}
void I2C_Mode_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(IIC_CLK,ENABLE);
/* I2C 配置 */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
/* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2Cx_OWN_ADDRESS7;
//
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
//寻址模式
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//通信速率
I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;
I2C_Init(I2C1,&I2C_InitStructure);
I2C_Cmd(I2C1,ENABLE);
}
void I2CInit(void)
{
I2C_GPIO_Config();
I2C_Mode_Config();
}
/**
* @brief OLED 写入字节
* @param addr 地址(写指令/写数据)
* @param data 数据
* @retval 无
*/
void I2cWriteByte(uint8_t addr,uint8_t data)
{
//发送起始信号
I2C_GenerateSTART(I2C1,ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
//等待EV5事件
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0)
{
printf("I2C 等待超时!errorCode is 0rn");
return;
}
}
I2CTimeout = I2CT_FLAG_TIMEOUT;
//发送设备地址
I2C_Send7bitAddress(I2C1,OLED_ADDR,I2C_Direction_Transmitter);
//等待EV6事件
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == 0)
{
printf("I2C 等待超时!errorCode is 1rn");
return;
}
}
//发送地址
I2C_SendData(I2C1,addr);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0)
{
printf("I2C 等待超时!errorCode is 2rn");
return;
}
}
//发送数据
I2C_SendData(I2C1,data);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((I2CTimeout--) == 0)
{
printf("I2C 等待超时!errorCode is 3rn");
return;
}
}
}
/**
* @brief OLED 指令
* @param command 写指令
* @retval 无
*/
void OLED_WriteCommand(unsigned char command)
{
I2cWriteByte(0x00,command);
}
/**
* @brief OLED 写数据
* @param data 数据
* @retval 无
*/
void OLED_WriteData(unsigned char data)
{
I2cWriteByte(0x40,data);
}
/**
* @brief OLED设置光标位置
* @param Y 以左上角为原点,向下方向的坐标,范围:0~7
* @param X 以左上角为原点,向右方向的坐标,范围:0~127
* @retval 无
*/
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
OLED_WriteCommand(0xB0 | Y); //设置Y位置
OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位
OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位
}
/**
* @brief OLED清屏
* @param 无
* @retval 无
*/
void OLED_Clear(void)
{
uint8_t i, j;
for (j = 0; j < 8; j )
{
OLED_SetCursor(j, 0);
for(i = 0; i < 128; i )
{
OLED_WriteData(0x00);
}
}
}
/**
* @brief OLED显示一个字符
* @param Line 行位置,范围:1~4
* @param Column 列位置,范围:1~16
* @param Char 要显示的一个字符,范围:ASCII可见字符
* @retval 无
*/
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{
uint8_t i;
OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分
for (i = 0; i < 8; i )
{
OLED_WriteData(OLED_F8x16[Char - ' '][i]); //显示上半部分内容
}
OLED_SetCursor((Line - 1) * 2 1, (Column - 1) * 8); //设置光标位置在下半部分
for (i = 0; i < 8; i )
{
OLED_WriteData(OLED_F8x16[Char - ' '][i 8]); //显示下半部分内容
}
}
/**
* @brief OLED显示字符串
* @param Line 起始行位置,范围:1~4
* @param Column 起始列位置,范围:1~16
* @param String 要显示的字符串,范围:ASCII可见字符
* @retval 无
*/
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
{
uint8_t i;
for (i = 0; String[i] != '