stm32f103c8t6按键切换0.96寸oled使用iic通信
时间: 2023-09-01 12:13:00 浏览: 125
基于stm32显示oled,用的是iic通信,可以直接使用,可以直接使用,可以直接使用
下面是STM32F103C8T6通过I2C接口控制0.96寸OLED的按键切换代码示例。
首先,需要在STM32CubeMX中配置I2C接口和GPIO口,具体步骤如下:
1. 打开STM32CubeMX软件,选择对应的芯片型号。
2. 在Pinout选项卡中,将SCL和SDA引脚配置为I2C接口。
3. 在Configuration选项卡中,配置I2C接口的速度、地址等参数。
4. 配置按键所需的GPIO口,设置为输入模式。
5. 生成代码并导入到Keil中。
接下来,可以使用以下代码实现按键切换OLED显示内容:
```c
/* I2C相关定义 */
#define I2C_SCL_Pin GPIO_PIN_6
#define I2C_SCL_GPIO_Port GPIOB
#define I2C_SDA_Pin GPIO_PIN_7
#define I2C_SDA_GPIO_Port GPIOB
#define OLED_I2C_ADDR 0x78
/* 按键相关定义 */
#define KEY1_Pin GPIO_PIN_13
#define KEY1_GPIO_Port GPIOC
#define KEY2_Pin GPIO_PIN_14
#define KEY2_GPIO_Port GPIOC
/* OLED相关定义 */
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_CMD 0x00
#define OLED_DAT 0x40
/* OLED初始化命令 */
const uint8_t InitCmd[] = {
0xAE, // 关闭显示
0xD5, 0x80, // 设置时钟分频因子,震荡频率
0xA8, 0x3F, // 设置驱动路数
0xD3, 0x00, // 设置显示偏移
0x40, // 设置起始行
0x8D, 0x14, // 设置电荷泵
0x20, 0x00, // 设置地址模式,水平寻址模式
0xA0, // 设置段重定义
0xC8, // 设置COM扫描方向
0xDA, 0x12, // 设置COM硬件引脚配置
0x81, 0xCF, // 设置对比度
0xD9, 0xF1, // 设置预充电周期
0xDB, 0x40, // 设置VCOMH
0xA4, // 全局显示开启
0xA6, // 设置正反显示
0xAF, // 打开显示
};
/* OLED清屏命令 */
const uint8_t ClearCmd[] = {
0x00, 0x10, // 设置列起始地址
0x00, 0x7F, // 设置列结束地址
0xB0, // 设置页地址
};
/* OLED显示内容 */
const uint8_t Logo[] = {
0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF,
0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF,
0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF,
0xFF, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
/* I2C初始化函数 */
void I2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
/* 配置SCL和SDA引脚 */
GPIO_InitStruct.Pin = I2C_SCL_Pin | I2C_SDA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* 配置I2C1 */
I2C_HandleTypeDef hi2c1 = {0};
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c1);
}
/* I2C发送数据函数 */
void I2C_SendData(uint8_t addr, uint8_t *data, uint16_t len)
{
HAL_I2C_Master_Transmit_IT(&hi2c1, addr, data, len);
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
}
/* OLED写命令函数 */
void OLED_WriteCmd(uint8_t cmd)
{
uint8_t data[] = {OLED_CMD, cmd};
I2C_SendData(OLED_I2C_ADDR, data, sizeof(data));
}
/* OLED写数据函数 */
void OLED_WriteDat(uint8_t dat)
{
uint8_t data[] = {OLED_DAT, dat};
I2C_SendData(OLED_I2C_ADDR, data, sizeof(data));
}
/* OLED初始化函数 */
void OLED_Init(void)
{
for (uint16_t i = 0; i < sizeof(InitCmd); i++) {
OLED_WriteCmd(InitCmd[i]);
}
}
/* OLED清屏函数 */
void OLED_Clear(void)
{
OLED_WriteCmd(ClearCmd[0]);
OLED_WriteCmd(ClearCmd[1]);
OLED_WriteCmd(ClearCmd[2]);
for (uint16_t i = 0; i < OLED_HEIGHT / 8; i++) {
OLED_WriteCmd(0xB0 + i);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
for (uint16_t j = 0; j < OLED_WIDTH; j++) {
OLED_WriteDat(0x00);
}
}
}
/* OLED显示函数 */
void OLED_Show(uint8_t *data)
{
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
for (uint16_t i = 0; i < OLED_HEIGHT / 8; i++) {
OLED_WriteCmd(0xB0 + i);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
for (uint16_t j = 0; j < OLED_WIDTH; j++) {
OLED_WriteDat(data[i * OLED_WIDTH + j]);
}
}
}
/* 按键扫描函数 */
uint8_t KEY_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
static uint8_t key_up = 1;
if (key_up && HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_RESET) {
HAL_Delay(10);
key_up = 0;
if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_RESET) {
return 1;
}
} else if (HAL_GPIO_ReadPin(GPIOx, GPIO_Pin) == GPIO_PIN_SET) {
key_up = 1;
}
return 0;
}
int main(void)
{
HAL_Init();
I2C_Init();
OLED_Init();
uint8_t show_logo = 1;
while (1) {
if (KEY_Scan(KEY1_GPIO_Port, KEY1_Pin)) {
show_logo = !show_logo;
}
if (KEY_Scan(KEY2_GPIO_Port, KEY2_Pin)) {
OLED_Clear();
}
if (show_logo) {
OLED_Show((uint8_t *)Logo);
} else {
OLED_Clear();
}
HAL_Delay(10);
}
}
```
在上述代码中,首先定义了I2C相关的引脚和OLED的I2C地址,以及按键和OLED的分辨率等参数。
然后,通过I2C_Init函数初始化I2C接口,并实现了I2C_SendData、OLED_WriteCmd、OLED_WriteDat等函数用于控制OLED的显示和清屏操作。
最后,在主函数中使用KEY_Scan函数对按键进行扫描,根据按键状态切换OLED显示内容或清屏,并通过OLED_Show函数将数据发送给OLED进行显示。
需要注意的是,本例中使用了HAL库进行操作,如果使用其他库或裸机编程,可能需要做出一些修改。
阅读全文