这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » Let'sdo2025年第2期—智能手环:③过程帖二:点亮OLED:HelloW

共1条 1/1 1 跳转至

Let'sdo2025年第2期—智能手环:③过程帖二:点亮OLED:HelloWorld!

菜鸟
2025-10-08 20:49:01     打赏


本篇我们来点亮iic协议的OLED屏幕(主控SSD1306)。

image.png

接线很简单,OLED屏幕的iic  SCL、SDA线分别对接开发板的SCL(P0.16)、SDA(P0.17),他们也是开发板的i2c1模块。


涉及到ssd1306的函数接口,都已经定义在ssd1306.c和ssd1306.h中

我们简要看下ssd1306.h中都定义了哪些函数:

    // 初始化 SSD1306  
    void SSD1306_Init(void);  
  
    // 清屏  
    void SSD1306_Clear(void);  
  
    // 显示测试图案  
    void SSD1306_DisplayDemo(void);  
  
    // 显示缓冲区数据  
    void SSD1306_DisplayFrame(uint8_t *buffer);  
  
    // 打印字符串(支持 6x8 ASCII)  
    void SSD1306_Print(uint8_t x, uint8_t page, const char *str);  
  
    // 全屏缓冲区  
    extern uint8_t SSD1306_Buffer[SSD1306_PAGE_NUM * SSD1306_WIDTH];  
  
    // 打印整数  
    void SSD1306_PrintInt(uint8_t x, uint8_t page, int32_t num);  
  
    // 打印浮点数  
    void SSD1306_PrintFloat(uint8_t x, uint8_t page, float num, uint8_t decimals);


而具体的实现都在ssd1306.c中

所有这些函数都引用了最核心的 SSD1306_Write 函数,也就是写寄存器函数。

// I2C 写入函数,带返回值
static int SSD1306_Write(uint8_t control, uint8_t *data, uint16_t len)  
{  
    mxc_i2c_req_t req;  //定义i2c结构体
    req.i2c = MXC_I2C1; // 硬件I2C1
    req.addr = SSD1306_ADDR;   //i2c地址
  
    uint8_t buffer[len + 1];  //+1位读/写位
    buffer[0] = control;    //读或者写
    memcpy(buffer + 1, data, len);  //把指令赋值给 buffer
  
    req.tx_buf = buffer;   //发送缓存
    req.tx_len = len + 1;  //发送长度
    req.rx_buf = NULL;  
    req.rx_len = 0;  
    req.restart = 0;  
    req.callback = NULL;  
  
    int ret = MXC_I2C_MasterTransaction(&req);  //发送数据
    if (ret != 0)  
    {  
        SSD1306_LOG("[SSD1306] I2C Write failed, addr=0x%02X, control=0x%02X, ret=%d\n", SSD1306_ADDR, control, ret);  
    }  
    else  
    {  
        SSD1306_LOG("[SSD1306] I2C Write success, addr=0x%02X, control=0x%02X, len=%d\n", SSD1306_ADDR, control, len);  
    }  
    MXC_Delay(MXC_DELAY_MSEC(5)); // 给总线一些时间  
    return ret;  
}


这个函数先定义了一个i2c结构体,准备好各参数,包括地址、长度、发送内容等

最后一个MXC_I2C_MasterTransaction(&req) 就执行了,那具体是怎么执行的呢?

我们看下i2c.h中MXC_I2C_MasterTransaction的介绍。

int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req);

/**
 * @brief   Performs a non-blocking I2C master transaction.
 *
 * Performs a non-blocking I2C master transaction.  These actions will be performed:
 *   1. If necessary, generate a start condition on the bus. //启动通讯
 *   2. Send the slave address with the low bit set to 0 (indicating a write).//写地址
 *   3. Transmit req->tx_len bytes of req->tx_buff. //写数据
 *   4. Generate a repeated start condition on the bus.//读启动
 *   5. Send the slave address with the low bit set to 1 (indicating a read).//读地址
 *   6. Receive req->rx_len bytes into req->rx_buf, acknowledging each byte.//读数据
 *   7. Generate a stop (or repeated start) condition on the bus. //停止
 *   8. Execute req->callback to indicate the transaction is complete. //通讯完成
 *   Steps 3-6 will be skipped if tx_len and rx_len are both 0.
 *   Steps 2-4 will be skipped if tx_len equals 0.
 *   Steps 4-6 will be skipped if rx_len equals 0.
 *
 * @note    MXC_I2C_AsyncHandler() must be called periodically for this function
 *          to operate properly. Ideally from the I2C ISR.
 *
 * @param   req         Pointer to details of the transaction.  The memory
 *                      used by this parameter must remain available until
 *                      the callback is executed.
 *
 * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
 */


看完上述,我们大概明白了OLED是怎么执行的。


回到主程序main.c


#include <stdio.h>
#include "board.h"
#include "mxc_device.h"
#include "mxc_delay.h"
#include "i2c.h"
#include "ssd1306.h"

int i=0;

int main(void)
{
    printf("SSD1306 0.96 inch Example\n");

    // 初始化 I2C
    int res = MXC_I2C_Init(MXC_I2C1, 1, 0);
    printf("I2C Init: %d\n", res);
    MXC_I2C_SetFrequency(MXC_I2C1, 400000);
    printf("I2C Frequency: %d\n", MXC_I2C_GetFrequency(MXC_I2C1));
    // 初始化 OLED
    SSD1306_Init();

    // 清屏
    SSD1306_Clear();

    // 打印文字
    SSD1306_Print(0, 0, "Hello World!");
    SSD1306_Print(0, 1, "SSD1306 0.96' Example");
    SSD1306_Print(0, 2, "EEPW & DigiKeyLet's do 2025");
    SSD1306_Print(0, 3, "Let's do 2025");



    while (1)   //绘制动态效果
    {
    	for(i=0;i<128;i++)
        {
    		SSD1306_Print(i, 4, "*");
    		SSD1306_Print(127-i, 5, "#");
            MXC_Delay(100);
        }

    }

    return 0;
}


运行结果如图:

245e36db531368fe9c56b24d4e397960.jpg

OLED.gif










关键词: MAX78000    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]