新聞中心

        EEPW首頁 > 設計應用 > 功率監測與控制系統DIY——實現OLED屏幕顯示信息

        功率監測與控制系統DIY——實現OLED屏幕顯示信息

        作者:CoderX9527 時間:2025-07-16 來源:EEPW 收藏

        1   任務目標

        實現OLED 屏幕顯示信息

        2   OLED介紹

        此款OLED是Seeed Studio 出品的Grove 接口的0.96英寸OLED 顯示屏,驅動IC 為SSD1315.

        OLEDDisplay 0.96” SSSD1315 V1.1分辨率為128×64。

        供電為3.3 V 或者5 V,通信接口為I2C。

        1752660559610148.png

        考慮到電流表INA219也是I2C通信接口,在STM32開發板上使用同一組I2C 硬件,OLED和INA219配置不同的器件地址,就可以一個I2C控制器驅動兩個I2C器件。

        此開發板有Arduino接口,恰好把Seeed Base Shield擴展板接上。

        1752660614452574.png

        3   STM32 I2C配置

        3.1 選用I2C1

        image.png

        1752665013726317.png

        Nucleo-F411RE管腳分配

        3.2 STM32CubeMX工程配置

        ●   在Connecity 中選擇I2C1

        ●   在右側使能i2c

        ●   配置I2C 參數為Standard Mode,速率100 KHz,地址為7 比特,主要的從器件地址為0×78

        1752665076520129.png

        3.3 PB8配置為SCL

        1752665129122692.png

        3.4 PB9配置為SDA

        1752665230614103.png

        4   PCtoLCD漢字取模軟件

        此次任務在OLED 上展示中文字符如下:

        電子產品世界

        得捷

        你好

        功率檢測

        系統控制

        電壓電流

        所有取模的文字:

        電子產品世界得捷你好功率監測系統控制電壓流

        PCtoLCD2002軟件配置如下:

        ●   點陣格式:陰碼

        ●   取模方式:列行式

        ●   取模走向:逆向(低位在前)

        ●   自定義格式:C51 格式,且行前綴、行后綴都為空。

        1752665418993763.png

        1752665443771541.png

        在輸入框輸入文字后點擊“生成字模”,拷貝到工程中即可。

        5 流程圖

        樸信惠.jpg

        6   關鍵代碼

        6.1 主函數

        ●   HAL庫初始化

        ●   時鐘初始化

        ●   硬件初始化,如GPIO,TIM,UART,I2C 等

        ●   OLED 初始化,清屏

        ●   顯示界面,界面切換,死循環

        view plaincopy to clipboardprint?

        1. int main(void)

        2. {

        3. /* USER CODE BEGIN 1 */

        4.

        5. /* USER CODE END 1 */

        6.

        7. /* MCU Configuration--------------------------

        ------------------------------*/

        8.

        9. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

        10. HAL_Init();

        11.

        12. /* USER CODE BEGIN Init */

        13.

        14. /* USER CODE END Init */

        15.

        16. /* Configure the system clock */

        17. SystemClock_Config();

        18.

        19. /* USER CODE BEGIN SysInit */

        20.

        21. /* USER CODE END SysInit */

        22.

        23. /* Initialize all configured peripherals */

        24. MX_GPIO_Init();

        25. MX_USART2_UART_Init();

        26. MX_TIM1_Init();

        27. MX_I2C1_Init();

        28.

        29. /* USER CODE BEGIN 2 */

        30.

        31. printf(“rn”);

        32. printf(“tt EEPW_2025_DIY1_Task2_

        OLED rn”);

        33. printf(“tt Build: %s %s rn”, __DATE

        __, __TIME__);

        34. printf(“rn”);

        35.

        36. HAL_TIM_Base_Start_IT(&htim1);

        37.

        38. OLED_Init();

        39.

        40. /* USER CODE END 2 */

        41.

        42. /* Infinite loop */

        43. /* USER CODE BEGIN WHILE */

        44. while (1) {

        45. screen_00_welcome();

        46. HAL_Delay(1000 * 3);

        47. screen_01_welcome();

        48. HAL_Delay(1000 * 3);

        49. screen_02_diy_power_monitor();

        50. HAL_Delay(1000 * 5);

        51. /* USER CODE END WHILE */

        52.

        53. /* USER CODE BEGIN 3 */

        54. // HAL_Delay(2000);

        55. }

        56. /* USER CODE END 3 */

        57. }

        6.2 I2C 初始化

        這里的初始化代碼是STM32CubeMX生成的,初始化參數來自界面配置的參數。

        ●   函數MX_I2C1_Init() 先保存I2C 參數到hi2c1 結構體上,調用HAL_I2C_Init() 初始化硬件

        ●   函數HAL_I2C_MspInit() 由HAL_I2C_Init() 函數調用,初始化I2C1 管腳,配置為復用功能

        view plaincopy to clipboardprint?

        1. void MX_I2C1_Init(void)

        2. {

        3.

        4. /* USER CODE BEGIN I2C1_Init 0 */

        5.

        6. /* USER CODE END I2C1_Init 0 */

        7.

        8. /* USER CODE BEGIN I2C1_Init 1 */

        9.

        10. /* USER CODE END I2C1_Init 1 */

        11. hi2c1.Instance = I2C1;

        12. hi2c1.Init.ClockSpeed = 100000;

        13. hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

        14. hi2c1.Init.OwnAddress1 = 240;

        15. hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

        16. hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

        17. hi2c1.Init.OwnAddress2 = 0;

        18. hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

        19. hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

        20. if (HAL_I2C_Init(&hi2c1) != HAL_OK)

        21. {

        22. Error_Handler();

        23. }

        24. /* USER CODE BEGIN I2C1_Init 2 */

        25.

        26. /* USER CODE END I2C1_Init 2 */

        27.

        28. }

        29.

        30. void HAL_I2C_MspInit(I2C_HandleTypeDef*i2cHandle)

        31. {

        32.

        33. GPIO_InitTypeDef GPIO_InitStruct = {0};

        34. if(i2cHandle->Instance==I2C1)

        35. {

        36. /* USER CODE BEGIN I2C1_MspInit 0 */

        37.

        38. /* USER CODE END I2C1_MspInit 0 */

        39.

        40. __HAL_RCC_GPIOB_CLK_ENABLE();

        41. /**I2C1 GPIO Configuration

        42. PB8 ------> I2C1_SCL

        43. PB9 ------> I2C1_SDA

        44. */

        45. GPIO_InitStruct.Pin = OLED_SCL_Pin|OLED_SDA_Pin;

        46. GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

        47. GPIO_InitStruct.Pull = GPIO_NOPULL;

        48. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

        49. GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;

        50. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

        51.

        52. /* I2C1 clock enable */

        53. __HAL_RCC_I2C1_CLK_ENABLE();

        54. /* USER CODE BEGIN I2C1_MspInit 1 */

        55.

        56. /* USER CODE END I2C1_MspInit 1 */

        57. }

        58. }

        6.3 OLED接口函數

        OLED 接口層,主要實現兩個函數,其他的OLED

        API 都是依賴這兩個函數

        ● Oled_Write_Data() 發送數據到OLED IC

        ● Oled_Write_Cmd() 發送命令到OLED I

        6.3.1 Oled_Write_Data() 實現

        這里直接調用HAL API 往OLED 發送數據

        view plaincopy to clipboardprint?

        1. void Oled_Write_Data(uint8_t data)

        2. {

        3. HAL_I2C_Mem_Write(&HI2CX, OLED_ID,

        OLED_WR_DATA, I2C_MEMADD_SIZE_8BIT,

        &data, 1, 0×100);

        4. }

        6.3.2 Oled_Write_Cmd() 實現

        這里直接調用HAL API 往OLED 發送命令

        view plaincopy to clipboardprint?

        1. void Oled_Write_Cmd(uint8_t cmd)

        2. {

        3. HAL_I2C_Mem_Write(&HI2CX, OLED_ID,

        OLED_WR_CMD, I2C_MEMADD_SIZE_8BIT,

        &cmd, 1, 0×100);

        4. }

        6.4 OLED API

        這里僅列舉幾個常用的API 實現。

        6.4.1 OLED_Init()初始化

        OLED 上電后需要發送命令配置參數

        view plaincopy to clipboardprint?

        1.void OLED_Init(void)

        2.{

        3./*設置顯示打開/ 關閉

        4.*AE--->顯示打開

        5.*AF--->顯示關閉( 休眠模式)

        6.*/

        7.Oled_Write_Cmd(0xAE);

        8.

        9./*==========基本命令表==========*/

        10./*設置對比度

        11.*0~255:數值越大 亮度越亮

        12.*/

        13.Oled_Write_Cmd(0×81);

        14.Oled_Write_Cmd(0×FF);

        15.

        16./*使能全屏顯示

        17.*A4--->恢復到RAM 內容顯示

        18.*A5--->忽略RAM 內容顯示

        19.*/

        20.Oled_Write_Cmd(0×A4);

        21.

        22./*設置顯示模式

        23.*A6--->正常顯示:0 滅1 亮

        24.*A7--->逆顯示:1滅0亮

        25.*/

        26.Oled_Write_Cmd(0×A6);

        27.

        28./*==========滾動命令表==========*/

        29./*滾動使能/ 失能

        30.*2E--->失能

        31.* 2F--->使能

        32.*/

        33.Oled_Write_Cmd(0×2E);

        34.

        35./*七字節命令: 連續水平滾動設置 */

        36.

        37./*左/ 右水平滾動設置

        38.*26---> 右水平滾動

        39.*27---> 左水平滾動

        40.*/

        41.Oled_Write_Cmd(0×26);

        42./*虛擬字節*/

        43.Oled_Write_Cmd(0×00);

        44./*設置滾動起始頁地址*/

        45.Oled_Write_Cmd(0×00);

        46./*設置滾動間隔*/

        47.Oled_Write_Cmd(0×03);

        48./*設置滾動結束地址 */

        49.Oled_Write_Cmd(0×07);

        50./*虛擬字節*/

        51.Oled_Write_Cmd(0×00);

        52.Oled_Write_Cmd(0×FF);

        53.

        54./*==========尋址設置命令表==========*/

        55.

        56./*雙字節命令: 寄存器尋址模式 */

        57.Oled_Write_Cmd(0×20);

        58.

        59./* 10:頁尋址模式

        60.* 01:垂直尋址模式

        61.* 00:水平尋址模式

        62.*/

        63.Oled_Write_Cmd(0×10);

        64./*單字節命令: 設置頁尋址的起始頁地址 */

        65.Oled_Write_Cmd(0×B0);

        66./* 單字節命令: 設置頁尋址的起始列地址低位 */

        67.Oled_Write_Cmd(0×00);

        68. /* 單字節命令: 設置頁尋址的起始列地址高位 */

        69.Oled_Write_Cmd(0×10);

        70.

        71./*========== 硬件配置命令表 ==========*/

        72.

        73./*設置顯示開始線

        74.*0×40~0×7F 對應0~63

        75.*/

        76.Oled_Write_Cmd(0×40);

        77.

        78./*設置列重映射

        79.*A0:addressX--->segX

        80.*A1:addressX--->seg(127-X)

        81.*/

        82.Oled_Write_Cmd(0×A1);

        83.

        84./*設置多路復用比 */

        85.Oled_Write_Cmd(0×A8);

        86.Oled_Write_Cmd(0×3F);

        87.

        88./*設置COM 輸出掃描方向

        89.*C0:COM0--->COM63( 從上往下掃描)

        90.*C8:COM63--->COM0( 從下往上掃描)

        91.*/

        92.Oled_Write_Cmd(0×C8);

        93.

        94./*雙字節命令:設置COM 顯示偏移量 */

        95.Oled_Write_Cmd(0×D3);

        96.Oled_Write_Cmd(0×00); /* COM 不偏移 */

        97.

        98./*雙字節命令:配置COM 重映射 */

        99.Oled_Write_Cmd(0×DA);

        100.Oled_Write_Cmd(0×12);

        101.

        102./*雙字節命令:設置預充期 */

        103.Oled_Write_Cmd(0×D9);

        104.Oled_Write_Cmd(0×22); /* 階段一2 個無效DCLK 時鐘/ 階段二2 個無效DCLK 時鐘 */

        105.

        106./*設置VCOMH 取消選擇電平

        107.*00:0.65xVcc

        108.*20:0.77xVcc

        109.*30:0.83xVcc

        110.*/

        111.Oled_Write_Cmd(0×DB);

        112.Oled_Write_Cmd(0×20);

        113.

        114./*雙字節命令:設置電荷泵 */

        115.Oled_Write_Cmd(0×8d);

        116.Oled_Write_Cmd(0×14);

        117.

        118.Oled_Write_Cmd(0×AF);

        119.}

        6.4.2 OLED_Fill()刷屏

        m表示page地址,數值0~7,n 表示列地址,數值0~127。

        填充的數據fill_data,設置為0,則屏幕為黑色;設置為1,則屏幕白色;設置為其他值,屏幕顯示條紋。

        view plaincopy to clipboardprint?

        1.void OLED_Fill(uint8_t fill_data) // 全屏填充

        2.{

        3.unsigned char m, n;

        4.for (m = 0; m < 8; m++) {

        5.Oled_Write_Cmd(0×b0 + m); // page0-page1

        6.Oled_Write_Cmd(0×00); // low column st art address

        7.Oled_Write_Cmd(0×10); // high column s tart address

        8.for (n = 0; n < 128; n++) {

        9.Oled_Write_Data(fill_data);

        10.}

        11.}

        12.}

        6.4.3 OLED_ShowStr()

        這里支持兩種字體大小,分別是6×8 和8×16 大小。

        view plaincopy to clipboardprint?

        1./**

        2.*@brief 顯示 ASCII 字符,有 6×8 和 8×16 字體大小可以選擇

        3.*

        4.*@param x起始點坐標x[0, 127]

        5.*@param y 起始點坐標 y [0, 7]

        6.*@param ch 要顯示的字符串

        7.*@param textsize 1 表示字體大小 6×8; 2 表示字體大小 8×16

        8.*/

        9.void OLED_ShowStr(uint16_t x, uint16_t y,uint8_t ch[], ascii_font_e font)

        10. {

        11.uint8_t c = 0, i = 0, j = 0;

        12.switch (font) {

        13.case ASCII_FONT_6×8: {

        14.while (ch[j] != ‘

        主站蜘蛛池模板: 蛟河市| 黎城县| 邵阳县| 格尔木市| 英超| 中江县| 永新县| 蒲城县| 寿光市| 剑川县| 青田县| 碌曲县| 定南县| 湛江市| 武宣县| 城口县| 永靖县| 阜新| 甘洛县| 佛冈县| 响水县| 长汀县| 康保县| 祁连县| 五莲县| 吉安县| 乌什县| 广水市| 陵川县| 刚察县| 九江县| 高邑县| 曲松县| 卢湾区| 昌都县| 丰原市| 南京市| 高青县| 彝良县| 嘉黎县| 浮山县|