oled驱动调整

This commit is contained in:
许晟昊 2024-12-18 21:53:21 +08:00
parent 1b2512b4c4
commit e96c958fb1
13 changed files with 1443 additions and 782 deletions

View File

@ -33,14 +33,14 @@
/* USER CODE END 1 */
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
* Free pins are configured automatically as Analog (this feature is enabled through
* the Code Generation settings)
*/
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
* Free pins are configured automatically as Analog (this feature is enabled through
* the Code Generation settings)
*/
void MX_GPIO_Init(void)
{
@ -56,7 +56,7 @@ void MX_GPIO_Init(void)
LL_GPIO_ResetOutputPin(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
/**/
LL_GPIO_ResetOutputPin(GPIOB, OLED_SDA_Pin|OLDE_SCK_Pin);
LL_GPIO_ResetOutputPin(GPIOB, OLED_SDA_Pin | OLDE_SCK_Pin);
/**/
GPIO_InitStruct.Pin = LED_BLUE_Pin;
@ -66,32 +66,27 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(LED_BLUE_GPIO_Port, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_14|LL_GPIO_PIN_15;
GPIO_InitStruct.Pin = LL_GPIO_PIN_14 | LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_2|LL_GPIO_PIN_3|LL_GPIO_PIN_4
|LL_GPIO_PIN_5|LL_GPIO_PIN_6|LL_GPIO_PIN_7|LL_GPIO_PIN_8
|LL_GPIO_PIN_11|LL_GPIO_PIN_12|LL_GPIO_PIN_15;
GPIO_InitStruct.Pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_2 | LL_GPIO_PIN_3 | LL_GPIO_PIN_4 | LL_GPIO_PIN_5 | LL_GPIO_PIN_6 | LL_GPIO_PIN_7 | LL_GPIO_PIN_8 | LL_GPIO_PIN_11 | LL_GPIO_PIN_12 | LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1|LL_GPIO_PIN_2|LL_GPIO_PIN_10
|LL_GPIO_PIN_11|LL_GPIO_PIN_14|LL_GPIO_PIN_15|LL_GPIO_PIN_3
|LL_GPIO_PIN_4|LL_GPIO_PIN_5|LL_GPIO_PIN_6|LL_GPIO_PIN_7
|LL_GPIO_PIN_8|LL_GPIO_PIN_9;
GPIO_InitStruct.Pin = LL_GPIO_PIN_0 | LL_GPIO_PIN_1 | LL_GPIO_PIN_2 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11 | LL_GPIO_PIN_14 | LL_GPIO_PIN_15 | LL_GPIO_PIN_3 | LL_GPIO_PIN_4 | LL_GPIO_PIN_5 | LL_GPIO_PIN_6 | LL_GPIO_PIN_7 | LL_GPIO_PIN_8 | LL_GPIO_PIN_9;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = OLED_SDA_Pin|OLDE_SCK_Pin;
GPIO_InitStruct.Pin = OLED_SDA_Pin | OLDE_SCK_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */

View File

@ -68,8 +68,8 @@
/* Cortex-M3 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
@ -83,8 +83,8 @@ void NMI_Handler(void)
}
/**
* @brief This function handles Hard fault interrupt.
*/
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
@ -98,8 +98,8 @@ void HardFault_Handler(void)
}
/**
* @brief This function handles Memory management fault.
*/
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
@ -113,8 +113,8 @@ void MemManage_Handler(void)
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
@ -128,8 +128,8 @@ void BusFault_Handler(void)
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
@ -143,8 +143,8 @@ void UsageFault_Handler(void)
}
/**
* @brief This function handles System service call via SWI instruction.
*/
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
@ -156,8 +156,8 @@ void SVC_Handler(void)
}
/**
* @brief This function handles Debug monitor.
*/
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
@ -169,8 +169,8 @@ void DebugMon_Handler(void)
}
/**
* @brief This function handles Pendable request for system service.
*/
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
@ -182,8 +182,8 @@ void PendSV_Handler(void)
}
/**
* @brief This function handles System tick timer.
*/
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
@ -203,8 +203,8 @@ void SysTick_Handler(void)
/******************************************************************************/
/**
* @brief This function handles DMA1 channel4 global interrupt.
*/
* @brief This function handles DMA1 channel4 global interrupt.
*/
void DMA1_Channel4_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
@ -217,8 +217,8 @@ void DMA1_Channel4_IRQHandler(void)
}
/**
* @brief This function handles DMA1 channel5 global interrupt.
*/
* @brief This function handles DMA1 channel5 global interrupt.
*/
void DMA1_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
@ -231,8 +231,8 @@ void DMA1_Channel5_IRQHandler(void)
}
/**
* @brief This function handles TIM1 update interrupt.
*/
* @brief This function handles TIM1 update interrupt.
*/
void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
@ -249,8 +249,8 @@ void TIM1_UP_IRQHandler(void)
}
/**
* @brief This function handles TIM3 global interrupt.
*/
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
@ -265,8 +265,8 @@ void TIM3_IRQHandler(void)
}
/**
* @brief This function handles USART1 global interrupt.
*/
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */

View File

@ -125,7 +125,7 @@
<SetRegEntry>
<Number>0</Number>
<Key>CMSIS_AGDI</Key>
<Name>-X"Any" -UAny -O206 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0CS32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:CS32F103C8$Flash\CS32F10x_128.FLM)</Name>
<Name>-X"" -O206 -S0 -C0 -P00000000 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO65554 -TC10000000 -TT10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0CS32F10x_128.FLM -FS08000000 -FL020000 -FP0($$Device:CS32F103C8$Flash\CS32F10x_128.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
@ -148,24 +148,7 @@
<Name></Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>146</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>134224336</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>..\User\board\ssd096_oled.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\motor\../User/board/ssd096_oled.c\146</Expression>
</Bp>
</Breakpoint>
<Breakpoint/>
<WatchWindow1>
<Ww>
<count>0</count>
@ -187,6 +170,26 @@
<WinNumber>1</WinNumber>
<ItemText>ch</ItemText>
</Ww>
<Ww>
<count>4</count>
<WinNumber>1</WinNumber>
<ItemText>dd</ItemText>
</Ww>
<Ww>
<count>5</count>
<WinNumber>1</WinNumber>
<ItemText>i,0x0A</ItemText>
</Ww>
<Ww>
<count>6</count>
<WinNumber>1</WinNumber>
<ItemText>progress_text</ItemText>
</Ww>
<Ww>
<count>7</count>
<WinNumber>1</WinNumber>
<ItemText>x,0x0A</ItemText>
</Ww>
</WatchWindow1>
<Tracepoint>
<THDelay>0</THDelay>
@ -794,8 +797,8 @@
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\board\ssd096_oled.c</PathWithFileName>
<FilenameWithoutPath>ssd096_oled.c</FilenameWithoutPath>
<PathWithFileName>..\User\lib\driver\ssd1306_oled.c</PathWithFileName>
<FilenameWithoutPath>ssd1306_oled.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>

View File

@ -339,7 +339,7 @@
<MiscControls></MiscControls>
<Define>STM32,STM32F103xB,USE_FULL_LL_DRIVER,HSE_VALUE=8000000,HSE_STARTUP_TIMEOUT=100,LSE_STARTUP_TIMEOUT=5000,LSE_VALUE=32768,HSI_VALUE=8000000,LSI_VALUE=40000,VDD_VALUE=3300,PREFETCH_ENABLE=1</Define>
<Undefine></Undefine>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../User;../User/application;../User/board;../User/system/inc;../User/system/bsp;../User/lib/inc;../User/lib/flow;../User/lib/control/inc</IncludePath>
<IncludePath>../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../User;../User/application;../User/board;../User/system/inc;../User/system/bsp;../User/lib/inc;../User/lib/flow;../User/lib/control/inc;../User/lib/driver</IncludePath>
</VariousControls>
</Cads>
<Aads>
@ -1254,9 +1254,9 @@
<FilePath>..\User\board\board.c</FilePath>
</File>
<File>
<FileName>ssd096_oled.c</FileName>
<FileName>ssd1306_oled.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\board\ssd096_oled.c</FilePath>
<FilePath>..\User\lib\driver\ssd1306_oled.c</FilePath>
</File>
</Files>
</Group>

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@
#include "board.h"
#include "flow.h"
static struct flow business_fw; // 业务流程
static struct flow idle_fw; // 空闲任务
@ -15,7 +14,13 @@ static uint8_t business_inspection(struct flow *fl)
for (;;)
{
FL_LOCK_DELAY(fl, FL_CLOCK_100MSEC);
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
// ssd1306_clear_buffer();
// ssd1306_f8x16_string(0, 0, " PERCENT:");
// ssd1306_f8x16_number(88, 0, 100, 0);
// ssd1306_f8x16_string(0, 2, " CUR:");
// ssd1306_f8x16_number(48, 2, 0, 0);
// ssd1306_update_screen();
}
FL_TAIL(fl);
}
@ -31,9 +36,13 @@ static uint8_t business_inspection(struct flow *fl)
static uint8_t idle_inspection(struct flow *fl)
{
FL_HEAD(fl);
static uint32_t tick = 0;
for (;;)
{
GPIO_TOGGLE(LED_BLUE_GPIO_Port, LED_BLUE_Pin);
ssd1306_f6x8_string(0, 2, " tick:");
ssd1306_f6x8_number(40, 2, tick++, 0);
ssd1306_update_screen();
FL_LOCK_DELAY(fl, FL_CLOCK_SEC);
}
FL_TAIL(fl);
@ -59,10 +68,20 @@ void app_run(void)
*/
void app_init(void)
{
ssd1306_draw_text_center(3, "LOADING...");
delay_ms(200);
// 显示加载进度条
ssd1306_clear_buffer();
for (uint8_t i = 0; i <= 100; i += 10)
{
ssd1306_draw_progress_bar(i);
}
FL_INIT(&business_fw); // 业务流程
FL_INIT(&idle_fw); // 空闲任务
ENABLE_TIM(TASK_TIM);
ENABLE_TIM(WORK_TIM);
ssd1306_clear();
}

View File

@ -38,5 +38,5 @@ void uart_send(uint8_t *data, uint16_t len)
void board_init(void)
{
uart_init();
ssd096_init();
ssd1306_init();
}

View File

@ -1,7 +1,7 @@
#ifndef __BOARD_H__
#define __BOARD_H__
#include "lib.h"
#include "ssd096_oled.h"
#include "ssd1306_oled.h"
#define UART_RXSIZE (240u) // 接收240个字节
#define UART_TXSIZE (240u) // 发送240个字节

View File

@ -1,147 +0,0 @@
#include "ssd096_oled.h"
static void i2c_start(void)
{
GPIO_SET(SSD096_SDA_PORT, SSD096_SDA_PIN);
GPIO_SET(SSD096_SCK_PORT, SSD096_SCK_PIN);
GPIO_RESET(SSD096_SDA_PORT, SSD096_SDA_PIN);
GPIO_RESET(SSD096_SCK_PORT, SSD096_SCK_PIN);
}
static void i2c_stop(void)
{
GPIO_RESET(SSD096_SDA_PORT, SSD096_SDA_PIN);
GPIO_SET(SSD096_SCK_PORT, SSD096_SCK_PIN);
GPIO_SET(SSD096_SDA_PORT, SSD096_SDA_PIN);
}
void i2c_write_byte(uint8_t data)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
if ((data & 0x80) >> i)
GPIO_SET(SSD096_SDA_PORT, SSD096_SDA_PIN);
else
GPIO_RESET(SSD096_SDA_PORT, SSD096_SDA_PIN);
data <<= 1;
GPIO_SET(SSD096_SCK_PORT, SSD096_SCK_PIN);
GPIO_RESET(SSD096_SCK_PORT, SSD096_SCK_PIN);
}
GPIO_SET(SSD096_SCK_PORT, SSD096_SCK_PIN); // 额外的一个时钟,不处理应答信号
GPIO_RESET(SSD096_SCK_PORT, SSD096_SCK_PIN);
}
/**
* @brief I2C设备写入命令
*
* I2C接口向指定设备写入一个命令字节
*
* @param command
*/
static void i2c_write_command(uint8_t command)
{
i2c_start();
i2c_write_byte(0x78);
i2c_write_byte(0x00);
i2c_write_byte(command);
i2c_stop();
}
/**
* @brief I2C设备写入一个字节的数据
*
* I2C总线向指定设备写入一个字节的数据
*
* @param data
*/
static void i2c_write_data(uint8_t data)
{
i2c_start();
i2c_write_byte(0x78);
i2c_write_byte(0x40);
i2c_write_byte(data);
i2c_stop();
}
/**
* @brief SSD096 OLED显示屏上的光标位置
*
* SSD096 OLED显示屏上的光标位置到指定的x和y坐标
*
* @param x 0127
* @param y 063
*/
void ssd096_set_position(uint8_t x, uint8_t y)
{
i2c_write_command(0xb0 | y);
i2c_write_command(0x10 | ((x & 0xf0) >> 4));
i2c_write_command(0x00 | (x & 0x0f));
}
/**
* @brief SSD096显示屏
*
* SSD096显示屏的内容清空
*
* @note I2C接口向SSD096发送数据
*/
void ssd096_clear(void)
{
uint8_t i, j;
for (i = 0; i < 8; i++)
{
ssd096_set_position(i, 0);
for (j = 0; j < 128; j++)
{
i2c_write_data(0x00);
}
}
}
void ssd096_full(void)
{
uint8_t i, j;
for (i = 0; i < 8; i++)
{
ssd096_set_position(i, 0);
for (j = 0; j < 128; j++)
{
i2c_write_data(0xff);
}
}
}
/**
* @brief SSD096显示驱动
*
* SSD096显示驱动
*/
void ssd096_init(void)
{
i2c_write_command(0xae);
i2c_write_command(0xd5);
i2c_write_command(0x80);
i2c_write_command(0xa8);
i2c_write_command(0x3f);
i2c_write_command(0xd3);
i2c_write_command(0x00);
i2c_write_command(0x40);
i2c_write_command(0xa1);
i2c_write_command(0xc8);
i2c_write_command(0xda);
i2c_write_command(0x12);
i2c_write_command(0x81);
i2c_write_command(0xcf);
i2c_write_command(0xd9);
i2c_write_command(0xf1);
i2c_write_command(0xdb);
i2c_write_command(0x30);
i2c_write_command(0xa4);
i2c_write_command(0xa6);
i2c_write_command(0x8d);
i2c_write_command(0x14);
i2c_write_command(0xaf);
ssd096_clear();
ssd096_full();
}

View File

@ -1,12 +0,0 @@
#ifndef __SSD096_OLED_H
#define __SSD096_OLED_H
#include "main.h"
#define SSD096_SDA_PORT OLED_SDA_GPIO_Port
#define SSD096_SDA_PIN OLED_SDA_Pin
#define SSD096_SCK_PORT OLDE_SCK_GPIO_Port
#define SSD096_SCK_PIN OLDE_SCK_Pin
void ssd096_init(void);
void ssd096_clear(void);
void ssd096_set_position(uint8_t x, uint8_t y);
#endif // __SSD096_OLED_H

View File

@ -1,13 +1,12 @@
/**
* @file ssd1306_oled.c
* @author xushenghao
* @brief SSD1306 OLED display driver
* @brief 0.96 SSD1306 OLED display driver
* @version 0.1
* @note PB13-SCK PB12-SDA
*/
#include "ssd1306_oled.h"
#include "ssd1306_oled.h"
#include "string.h"
/************************************6*8的点阵************************************/
const uint8_t F6x8[][6] =
@ -205,7 +204,76 @@ const uint8_t F8X16[] =
0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //~ 94
};
static uint8_t _buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8]; // 定义屏幕缓冲区
const uint8_t LOGO[] = {
0x00, 0x03, 0x05, 0x09, 0x11, 0xFF, 0x11, 0x89, 0x05, 0xC3, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0xFF, 0x11, 0xAA, 0x44, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, 0x38, 0x44, 0x82, 0x92,
0x92, 0x74, 0x01, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x44, 0xC7, 0x01, 0x7D,
0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0x7D, 0x7D, 0x7D, 0x7D, 0x01, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x40, 0x40,
0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00,
0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDB, 0xDB,
0xDB, 0xDB, 0xDB, 0x00, 0x00, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0x00, 0x00, 0xD8, 0xD8, 0xD8, 0xD8,
0xD8, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x80,
0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06,
0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0xE6, 0x66, 0x20, 0x00, 0x06, 0x06, 0x86, 0x06,
0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x86, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00,
0x00, 0x86, 0x86, 0x86, 0x86, 0x86, 0x80, 0x80, 0x86, 0x86, 0x06, 0x86, 0x86, 0xC0, 0xC0, 0x86,
0x86, 0x86, 0x06, 0x06, 0xD0, 0x30, 0x76, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06,
0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06,
0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0xFE, 0x00, 0x01,
0x02, 0x00, 0xC4, 0x18, 0x20, 0x02, 0x9E, 0x63, 0xB2, 0x0E, 0x00, 0xFF, 0x81, 0x81, 0xFF, 0x00,
0x00, 0x80, 0x40, 0x30, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x23, 0xEA, 0xAA, 0xBF, 0xAA,
0xEA, 0x03, 0x3F, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x08, 0x00, 0x00, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81, 0x80, 0x80, 0x81, 0x80,
0x81, 0x80, 0x80, 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x01, 0x09, 0x0C, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E, 0x00, 0x1E, 0x21, 0x40, 0x40, 0x50, 0x21, 0x5E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC1, 0xC1, 0xFF,
0xFF, 0xC1, 0xC1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0xFC, 0xF3, 0xEF, 0xF3, 0xFC,
0x80, 0xFF, 0x80, 0xEE, 0xEE, 0xEE, 0xF5, 0xFB, 0xFF, 0x9C, 0xBE, 0xB6, 0xB6, 0x88, 0xFF, 0x00,
// end
};
static uint8_t _buffer[SSD1306_WIDTH * SSD1306_HEIGHT / 8]; // 定义屏幕缓冲区
static uint8_t _buffer_copy[SSD1306_WIDTH * SSD1306_HEIGHT / 8]; // 屏幕缓冲区副本
static void i2c_start(void)
{
@ -408,11 +476,16 @@ void ssd1306_init(void)
i2c_write_command(SSD1306_CMD_CHARGE_PUMP); //--set DC-DC enable
i2c_write_command(SSD1306_CMD_SET_DC_DC_ENABLE); //
i2c_write_command(SSD1306_CMD_DISPLAY_ON); //--turn on oled panel
ssd1306_fill(0);
ssd1306_clear();
// ssd1306_test();
}
void ssd1306_logo(void)
{
ssd1306_draw_bmp(0, 0, SSD1306_WIDTH, 2, LOGO);
}
void ssd1306_display_on(void)
{
i2c_write_command(SSD1306_CMD_CHARGE_PUMP); // 设置电荷泵
@ -440,14 +513,28 @@ void ssd1306_update_screen(void)
{
for (uint8_t i = 0; i < SSD1306_HEIGHT / 8; i++)
{
i2c_write_command(0xb0 + i);
i2c_write_command(0x01);
i2c_write_command(0x10);
uint8_t update_needed = 0;
for (uint8_t j = 0; j < SSD1306_WIDTH; j++)
{
i2c_write_data(_buffer[j + i * SSD1306_WIDTH]);
if (_buffer[j + i * SSD1306_WIDTH] != _buffer_copy[j + i * SSD1306_WIDTH])
{
update_needed = 1;
break;
}
}
if (update_needed)
{
i2c_write_command(0xb0 + i);
i2c_write_command(0x01);
i2c_write_command(0x10);
for (uint8_t j = 0; j < SSD1306_WIDTH; j++)
{
i2c_write_data(_buffer[j + i * SSD1306_WIDTH]);
}
}
}
osel_memcpy(_buffer_copy, _buffer, ARRAY_LEN(_buffer));
}
/**
@ -455,10 +542,11 @@ void ssd1306_update_screen(void)
*
* SSD1306 OLED
*
* @param color 0x00 0xFF
* @param color SSD1306_BLACK SSD1306_WHITE
*/
void ssd1306_fill(uint8_t color)
{
ssd1306_clear_buffer();
osel_memset(_buffer, color, ARRAY_LEN(_buffer));
ssd1306_update_screen();
}
@ -478,13 +566,14 @@ void ssd1306_fill(uint8_t color)
*/
void ssd1306_clear(void)
{
osel_memset(_buffer, 0, ARRAY_LEN(_buffer));
ssd1306_clear_buffer();
ssd1306_update_screen();
}
void ssd1306_clear_buffer(void)
{
osel_memset(_buffer, 0, ARRAY_LEN(_buffer));
osel_memset(_buffer, SSD1306_BLACK, ARRAY_LEN(_buffer));
osel_memset(_buffer_copy, 0xff, ARRAY_LEN(_buffer_copy));
}
/**
@ -497,11 +586,11 @@ void ssd1306_clear_buffer(void)
* @param x1 BMP绘制的结束X坐标
* @param y1 BMP绘制的结束Y坐标
*/
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *bmp)
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t *bmp)
{
uint8_t j = 0;
uint8_t x, y;
osel_memset(_buffer, 0, ARRAY_LEN(_buffer));
ssd1306_clear_buffer();
if (y1 % 8 == 0)
y = y1 / 8;
else
@ -543,6 +632,93 @@ void ssd1306_f6x8_string(uint8_t x, uint8_t y, const uint8_t *ch)
}
}
/**
* @brief SSD1306显示屏上
*
* num转换为字符串SSD1306显示屏的指定位置
*
* @param x x坐标
* @param y y坐标
* @param num
* @param dot_num 0
*/
void ssd1306_f6x8_number(uint8_t x, uint8_t y, float32 num, uint8_t dot_num)
{
uint8_t ch[9] = {'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};
uint8_t c = 0, i = 0, j = 0;
if (num < 0)
{
ch[i++] = '-';
num = -num;
}
if (num > 32000)
return;
c = 8 - i;
if (num >= 10000)
{
ch[i++] = num / 10000 + 48;
ch[i++] = (int32_t)(num) % 10000 / 1000 + 48;
ch[i++] = (int32_t)(num) % 1000 / 100 + 48;
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 1000)
{
ch[i++] = (int32_t)(num) % 10000 / 1000 + 48;
ch[i++] = (int32_t)(num) % 1000 / 100 + 48;
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 100)
{
ch[i++] = (int32_t)(num) % 1000 / 100 + 48;
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 10)
{
ch[i++] = (int32_t)(num) % 100 / 10 + 48;
ch[i++] = (int32_t)(num) % 10 + 48;
}
else if (num >= 0)
{
ch[i++] = (int32_t)(num) % 10 + 48;
}
if (dot_num > 0 && i < 7)
{
ch[i++] = '.';
num = num - (int32_t)num;
if (dot_num == 1 && i < 8)
{
num = num * 10;
ch[i++] = (int32_t)(num + 0.5) % 10 + 48;
}
if (dot_num >= 2 && i < 8)
{
num = num * 100;
ch[i++] = (int32_t)num % 100 / 10 + 48;
if (i < 8)
ch[i++] = (int32_t)(num + 0.5) % 10 + 48;
}
}
while (ch[j] != '\0')
{
c = ch[j] - 32;
if (x > 120)
{
x = 0;
y++;
}
for (i = 0; i < 6; i++)
_buffer[(y * SSD1306_WIDTH) + x + i] = F6x8[c][i];
x += 6;
j++;
}
}
/**
* @brief SSD1306 OLED屏幕上显示字符串和数字
*
@ -735,3 +911,101 @@ void ssd1306_f8x16_number(uint8_t x, uint8_t y, float32 num, uint8_t dot_num)
j++;
}
}
// 在 SSD1306 显示屏上绘制一个像素
void ssd1306_draw_pixel(uint8_t x, uint8_t y, uint8_t color)
{
if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT)
{
// 超出屏幕范围
return;
}
// 设置像素颜色
if (color == SSD1306_WHITE)
{
_buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8);
}
else
{
_buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8));
}
}
// 在 SSD1306 显示屏上绘制一条线
void ssd1306_draw_line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color)
{
int16_t dx, dy, sx, sy, err, e2;
dx = ABS(x2 - x1);
dy = ABS(y2 - y1);
sx = (x1 < x2) ? 1 : -1;
sy = (y1 < y2) ? 1 : -1;
err = dx - dy;
while (1)
{
ssd1306_draw_pixel(x1, y1, color);
if (x1 == x2 && y1 == y2)
break;
e2 = err * 2;
if (e2 > -dy)
{
err -= dy;
x1 += sx;
}
if (e2 < dx)
{
err += dx;
y1 += sy;
}
}
}
// 在 SSD1306 显示屏上绘制一个矩形
void ssd1306_draw_rect_angle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color)
{
// 绘制矩形的四条边
ssd1306_draw_line(x, y, x + w, y, color); // 上边
ssd1306_draw_line(x, y + h, x + w, y + h, color); // 下边
ssd1306_draw_line(x, y, x, y + h, color); // 左边
ssd1306_draw_line(x + w, y, x + w, y + h, color); // 右边
}
// 在 SSD1306 显示屏上绘制一个填充矩形
void ssd1306_fill_rect_angle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color)
{
for (uint8_t i = 0; i < h; i++)
{
ssd1306_draw_line(x, y + i, x + w, y + i, color);
}
}
// 绘制进度条
void ssd1306_draw_progress_bar(uint8_t progress)
{
uint8_t offset_y = 10;
char progress_text[5]; // 用于存储百分比文本
// 绘制边框
ssd1306_draw_rect_angle(10, 24 + offset_y, 108, 10, SSD1306_WHITE);
// 绘制进度条
ssd1306_fill_rect_angle(12, 26 + offset_y, 4 + progress, 7, SSD1306_WHITE);
// 显示百分比文本
snprintf(progress_text, sizeof(progress_text), "%3d%%", progress);
ssd1306_f8x16_string(SSD1306_WIDTH * 0.35, 2, (const uint8_t *)progress_text);
// 更新显示
ssd1306_update_screen();
}
// 在中间显示文字
void ssd1306_draw_text_center(uint8_t y, const char *text)
{
uint8_t x = (SSD1306_WIDTH - strlen(text) * 6) / 2;
ssd1306_f6x8_string(x, y, (const uint8_t *)text);
// 更新显示
ssd1306_update_screen();
}

View File

@ -14,6 +14,9 @@
// OLED显示参数
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
// OLED颜色
#define SSD1306_WHITE 1
#define SSD1306_BLACK 0
// OLED命令定义
#define SSD1306_CMD_DISPLAY_OFF 0xAE
@ -53,6 +56,7 @@
// 函数声明
void ssd1306_init(void);
void ssd1306_logo(void);
void ssd1306_display_on(void);
void ssd1306_display_off(void);
void ssd1306_update_screen(void);
@ -60,9 +64,17 @@ void ssd1306_update_screen(void);
void ssd1306_fill(uint8_t color);
void ssd1306_clear(void);
void ssd1306_clear_buffer(void);
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *bmp);
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t *bmp);
void ssd1306_f6x8_string(uint8_t x, uint8_t y, const uint8_t *ch);
void ssd1306_f6x8_number(uint8_t x, uint8_t y, float32 num, uint8_t dot_num);
void ssd1306_f6x8_string_number(uint8_t x, uint8_t y, const uint8_t *ch, uint8_t unit, float32 num);
void ssd1306_f8x16_string(uint8_t x, uint8_t y, const uint8_t *ch);
void ssd1306_f8x16_number(uint8_t x, uint8_t y, float32 num, uint8_t dot_num);
void ssd1306_draw_text_center(uint8_t y, const char *text);
void ssd1306_draw_progress_bar(uint8_t progress);
void ssd1306_fill_rect_angle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color);
void ssd1306_draw_rect_angle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color);
void ssd1306_draw_line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color);
void ssd1306_draw_pixel(uint8_t x, uint8_t y, uint8_t color);
#endif // __SSD1306_OLED_H

View File

@ -88,14 +88,14 @@ PA9.Signal=USART1_TX
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
PB12.GPIO_Label=OLED_SDA
PB12.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
PB12.GPIO_PuPd=GPIO_NOPULL
PB12.GPIO_PuPd=GPIO_PULLUP
PB12.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PB12.PinState=GPIO_PIN_RESET
PB12.Signal=GPIO_Output
PB13.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
PB13.GPIO_Label=OLDE_SCK
PB13.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
PB13.GPIO_PuPd=GPIO_NOPULL
PB13.GPIO_PuPd=GPIO_PULLUP
PB13.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PB13.PinState=GPIO_PIN_RESET
PB13.Signal=GPIO_Output