写一个可以直接使用的stm32 I2C 0.96寸oled屏幕局部清零程序
时间: 2024-02-09 20:13:16 浏览: 202
0.96寸OLED测试程序(STM32)
以下是一个可以直接使用的 STM32 I2C 控制 0.96 寸 OLED 屏幕进行局部清零的程序示例,基于 STM32 HAL 库:
```
#include "stm32f4xx_hal.h"
#include <string.h>
#define OLED_ADDR 0x3C // OLED屏幕I2C地址
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
I2C_HandleTypeDef hi2c1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
void OLED_Init();
void OLED_Clear();
void OLED_PartialClear(int x, int y, int w, int h);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
OLED_Init();
while (1) {
// 指定需要清空的区域坐标
int x = 0;
int y = 0;
int w = 64;
int h = 32;
// 清空指定区域的像素点
OLED_PartialClear(x, y, w, h);
HAL_Delay(1000); // 等待一段时间后再进行下一次局部清空
}
}
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
Error_Handler();
}
}
static void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
static void MX_I2C1_Init(void) {
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;
if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
Error_Handler();
}
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) {
Error_Handler();
}
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) {
Error_Handler();
}
}
void OLED_Init() {
uint8_t buf[] = { 0x00, 0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0x8D,
0x14, 0x20, 0x00, 0xA1, 0xC8, 0xDA, 0x12, 0x81, 0xCF, 0xD9,
0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0xAF };
HAL_I2C_Master_Transmit(&hi2c1, OLED_ADDR, buf, sizeof(buf), HAL_MAX_DELAY);
}
void OLED_Clear() {
uint8_t data[SCREEN_WIDTH / 8];
memset(data, 0x00, sizeof(data));
for (int i = 0; i < SCREEN_HEIGHT / 8; i++) {
HAL_I2C_Mem_Write(&hi2c1, OLED_ADDR, 0x40, 1, data, sizeof(data), HAL_MAX_DELAY);
HAL_I2C_Mem_Write(&hi2c1, OLED_ADDR, 0xB0 + i, 1, data, sizeof(data), HAL_MAX_DELAY);
}
}
void OLED_PartialClear(int x, int y, int w, int h) {
int x_end = x + w;
int y_end = y + h;
for (int i = x; i < x_end; i++) {
for (int j = y; j < y_end; j++) {
int page = j / 8;
int bit = j % 8;
int data = ~(1 << bit);
uint8_t buf[] = { 0x40, 0xB0 + page, i & 0x0F, 0x10 | (i >> 4), data };
HAL_I2C_Master_Transmit(&hi2c1, OLED_ADDR, buf, sizeof(buf), HAL_MAX_DELAY);
}
}
}
```
在该程序中,首先初始化了系统时钟、GPIO 和 I2C 接口,并定义了 OLED 初始化、全局清屏和局部清屏等函数。在 `main()` 函数中,调用了 `OLED_Init()` 函数初始化 OLED 显示屏,然后使用 `OLED_PartialClear()` 函数进行局部清空。
在 `OLED_PartialClear()` 函数中,首先根据传入的坐标和大小计算出需要清空的区域,并使用 `HAL_I2C_Master_Transmit()` 函数将每个像素点的数据写入 OLED 显示屏,从而实现局部清空的效果。
需要注意的是,在使用 `HAL_I2C_Master_Transmit()` 函数时,需要确保写入的数据格式正确,否则会导致程序出错或程序崩溃。同时,在进行局部清空时,也需要确保指定的区域不超出 OLED 显示屏的有效范围。
阅读全文