STM32CubeMx使用教程(六)—— OLED屏使用

2023-05-16

前言

在前面一章中, 学习了 串口通信以及定时器, 本章节中将介绍I2C通信,使用 I2C 通信方式点亮 OLED 模块。由于 OLED 模块支持多种通信方式, OLED 模块的 I2C 通信过程主要通过在数据层进行二次打包, 以达到分类数据包的目的, 以便适配 OLED 的多种通信方式。

准备工具

软件:STM32CubeMx、Keil5 MDK

硬件:STM32F103C8T6核心板、下载器ST_LINK、OLEDI2C通信4针屏幕

本章节工程已上传至百度网盘,此链接永久有效

链接:https://pan.baidu.com/s/13UiC3hnn84yIsA5N1nrmmg?pwd=w8cx 
提取码:w8cx

I2C通信

I2C 是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。两线制代表 I2C 只需两根信号线,一根数据线 SDA,另一根是时钟线 SCL。I2C 总线允许挂载多个主设备, 但总线时钟同一时刻只能由一个主设备产生,并且要求每个连接到总线上的器件都有唯一的 I2C 地址,从设备可以被主设备寻址。I2C 通信具有几类信号:

开始信号 S: 当 SCL 处于高电平时, SDA 从高电平拉低至低电平,代表数据传输的开始。

结束信号 P: 当 SCL 处于高电平时, SDA 从低电平拉高至高电平,代表数据传输结束。

数据信号: 数据信号每次都传输 8 位数据,每一位数据都在一个时钟周期内传递,当SCL 处于高电平时候, SDA 数据线上的电平需要稳定,当 SCL 处于低电平的时候,SDA 数据线上的电平允许改变。

应答信号 ACK/NACK: 应答信号是主机发送 8bit 数据,从机对主机发送低电平,表示已经接受数据。
常见用于读取传感器数据的 I2C 传输过程如下表所示:

整个 I2C 通信过程理解成收发快递的过程,设备 I2C 地址理解成学校快递柜的地址,读写位代表寄出和签收快递,寄存器地址则是快递柜上的箱号, 而数据便是需要寄出或者签收的快递。整个过程便是如同到学校的快递柜(从机 I2C 地址),对第几号柜箱(寄存器地址 ,进行寄出或者签收快递(数据) 的过程。 

IIC在CubeMx中的配置

1. 在 connectivity 下找到 I2C1;
2. 配置成 I2C;
3. 配置成 Fast Mode;
4. 其他保持默认。

 

生成代码,打开工程。

添加以下代码到工程中

/**
  * @brief          写数据或者指令到OLED, 如果使用的是SPI,请重写这个函数
  * @param[in]      dat: 要写入的字节
  * @param[in]      cmd: OLED_CMD 代表写入的字节是指令; OLED_DATA 代表写入的字节是数据
  * @retval         none
  */
void oled_write_byte(uint8_t dat, uint8_t cmd)
{
    static uint8_t cmd_data[2];
    if(cmd == OLED_CMD)
    {
        cmd_data[0] = 0x00;
    }
    else
    {
        cmd_data[0] = 0x40;
    }
    cmd_data[1] = dat;
    HAL_I2C_Master_Transmit(&hi2c1, OLED_I2C_ADDRESS, cmd_data, 2, 10);
}

根据 OLED 的通信方式,需要在第一个字节中指明之后的数据类型,如果是控制指令则需要发送 0x00, 如果是数据指令则需要发送 0x40。

/**
  * @brief          初始化OLED模块,
  * @param[in]      none
  * @retval         none
  */
void OLED_init(void)
{
    oled_write_byte(0xAE, OLED_CMD);    //display off
    oled_write_byte(0x20, OLED_CMD);    //Set Memory Addressing Mode	
    oled_write_byte(0x10, OLED_CMD);    //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
    oled_write_byte(0xb0, OLED_CMD);    //Set Page Start Address for Page Addressing Mode,0-7
    oled_write_byte(0xc8, OLED_CMD);    //Set COM Output Scan Direction
    oled_write_byte(0x00, OLED_CMD);    //---set low column address
    oled_write_byte(0x10, OLED_CMD);    //---set high column address
    oled_write_byte(0x40, OLED_CMD);    //--set start line address
    oled_write_byte(0x81, OLED_CMD);    //--set contrast control register
    oled_write_byte(0xff, OLED_CMD);    //brightness 0x00~0xff
    oled_write_byte(0xa1, OLED_CMD);    //--set segment re-map 0 to 127
    oled_write_byte(0xa6, OLED_CMD);    //--set normal display
    oled_write_byte(0xa8, OLED_CMD);    //--set multiplex ratio(1 to 64)
    oled_write_byte(0x3F, OLED_CMD);    //
    oled_write_byte(0xa4, OLED_CMD);    //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    oled_write_byte(0xd3, OLED_CMD);    //-set display offset
    oled_write_byte(0x00, OLED_CMD);    //-not offset
    oled_write_byte(0xd5, OLED_CMD);    //--set display clock divide ratio/oscillator frequency
    oled_write_byte(0xf0, OLED_CMD);    //--set divide ratio
    oled_write_byte(0xd9, OLED_CMD);    //--set pre-charge period
    oled_write_byte(0x22, OLED_CMD);    //
    oled_write_byte(0xda, OLED_CMD);    //--set com pins hardware configuration
    oled_write_byte(0x12, OLED_CMD);
    oled_write_byte(0xdb, OLED_CMD);    //--set vcomh
    oled_write_byte(0x20, OLED_CMD);    //0x20,0.77xVcc
    oled_write_byte(0x8d, OLED_CMD);    //--set DC-DC enable
    oled_write_byte(0x14, OLED_CMD);    //
    oled_write_byte(0xaf, OLED_CMD);    //--turn on oled panel
}

OLED_init 函数,该函数主要配置 OLED 参数, 通过调用 oled_write_byte 传入OLED_CMD, 传输控制指令完成配置 。

/**
  * @brief          操作GRAM内存(128*8char数组)
  * @param[in]      pen: 操作类型.
                    PEN_CLEAR: 设置为0x00
                    PEN_WRITE: 设置为0xff
                    PEN_INVERSION: 按位取反
  * @retval         none
  */
void OLED_operate_gram(pen_typedef pen)
{
    uint8_t i, n;

    for (i = 0; i < 8; i++)
    {
        for (n = 0; n < 128; n++)
        {
            if (pen == PEN_WRITE)
            {
                OLED_GRAM[n][i] = 0xff;
            }
            else if (pen == PEN_CLEAR)
            {
                OLED_GRAM[n][i] = 0x00;
            }
            else
            {
                OLED_GRAM[n][i] = 0xff - OLED_GRAM[n][i];
            }
        }
    }
}

/**
  * @brief          发送数据到OLED的GRAM
  * @param[in]      none
  * @retval         none
  */
void OLED_refresh_gram(void)
{
    uint8_t i, n;

    for (i = 0; i < 8; i++)
    {
        OLED_set_pos(0, i);
        for (n = 0; n < 128; n++)
        {
            oled_write_byte(OLED_GRAM[n][i], OLED_DATA);
        }
    }
}

/**
  * @brief          显示一个字符
  * @param[in]      row: 字符的开始行
  * @param[in]      col: 字符的开始列
  * @param[in]      chr: 字符
  * @retval         none
  */
void OLED_show_char(uint8_t row, uint8_t col, uint8_t chr)
{
    uint8_t x = col * 6;
    uint8_t y = row * 12;
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    chr = chr - ' ';

    for (t = 0; t < 12; t++)
    {
        temp = asc2_1206[chr][t];

        for (t1 = 0; t1 < 8; t1++)
        {
            if (temp&0x80)
                OLED_draw_point(x, y, PEN_WRITE);
            else
                OLED_draw_point(x, y, PEN_CLEAR);

            temp <<= 1;
            y++;
            if ((y - y0) == 12)
            {
                y = y0;
                x++;
                break;
            }
        }
    }
}

/**
  * @brief          显示一个字符串
  * @param[in]      row: 字符串的开始行
  * @param[in]      col: 字符串的开始列
  * @param[in]      chr: 字符串
  * @retval         none
  */
void OLED_show_string(uint8_t row, uint8_t col, uint8_t *chr)
{
    uint8_t n =0;

    while (chr[n] != '\0')
    {
        OLED_show_char(row, col, chr[n]);
        col++;

        if (col > 20)
        {
            col = 0;
            row += 1;
        }
        n++;
    }
}

显示过程如下:
1. OLED 模块的初始化,调用 OLED_init
2. 通过显示字符函数,对 stm32 内的 GRAM 数组进行操作
3. 调用 OLED_refresh_gram 函数将 GRAM 数据传输到 OLED 模块的 GRAM 进行显示。
主函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM4_Init();
  MX_I2C1_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1); //初始化BUZZER
	HAL_TIM_Base_Start_IT(&htim3);	//开启定时器3中断
	OLED_init(); //OLED初始化
//	Solitary_brave();
	OLED_operate_gram(PEN_CLEAR);
	OLED_show_string(0,6,"LRJ_ROBOT");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(tim3_delay.count_10ms != tim3_delay.last_count_10ms)
		{
			GPIO_PinState pin_state = HAL_GPIO_ReadPin(LEDD_GPIO_Port, LEDD_Pin);//获取LED电平
			OLED_printf(2,5,"LED_PIN = %d",pin_state);
			tim3_delay.last_count_10ms = tim3_delay.count_10ms;
		}
		if(tim3_delay.count_400ms != tim3_delay.last_count_400ms)
		{
			OLED_refresh_gram();//屏幕刷新 400ms
			HAL_GPIO_TogglePin(LEDD_GPIO_Port, LEDD_Pin);
			tim3_delay.last_count_400ms = tim3_delay.count_400ms;
		}
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

OLED屏幕实时显示LED电平变化

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32CubeMx使用教程(六)—— OLED屏使用 的相关文章

随机推荐

  • 【vxe-table】复选框设置为单选,隐藏表头复选框

    vxe table和el table有些许不同 el table复选框只允许点击单选的话 xff0c 可以这样 64 row click span class token operator 61 span span class token
  • 【el-table】设置行变色,以及鼠标移入的时候保持背景色不变

    1 根据条件设置行变色 xff0c 这个官网上也有示例 xff0c 没啥难的 xff0c 直接贴代码了 span class token operator lt span el table data span class token ope
  • 【vxe-table】自定义表头列是否可以排序

    vxe table真是让人又爱又恨 xff0c 官网示例还有文档都很详细 xff0c 但是可能是用的人少 xff0c 每次遇到问题 xff0c 都百度不到啥解决方法 xff0c 不像el table 全是方法 今天给我提了个bug xff0
  • Python中的列表,元组和字典

    一 列表 xff1a 数组 xff1a 存储同一种数据类型的集合 score 61 12 13 14 列表 xff08 被称为打了激素的数组 xff09 xff1a 可以存储任意数据类型的集合 xff08 一个变量中可以存储多个信息 xff
  • 【瀑布流插件】vue-masonry

    最近一直在画静态页面 xff0c 有个图片列表 xff0c 布局很紧凑 xff0c 图片宽度一样 xff0c 高度不一样 xff0c 但是效果图上都是紧挨在一起 xff0c 我用普通的v for循环加css布局 xff0c 它会以这一行最高
  • [svg-icon]引入vue项目后,use标签为0,已解决

    这个bug我之前遇到过一次 xff0c 解决了也就没记录 但是好记性不如烂笔头 xff0c 这次重新遇到 xff0c 又重新排查bug花了1个多小时 svg引入vue项目 xff0c 需要依赖svg sprite loader span c
  • 【css】字体渐变色,边框渐变色等笔记,按钮渐变色等持续更新~~

    一 字体渐变色 span class token operator lt span h2 span class token assign left variable class span span class token operator
  • 【vue】处理数组,无关联父id的情况下,根据特定条件区分父子项,单独给子项加事件

    先说下具体的场景 xff0c 有个列表数组 xff0c 有一列是科目代码 xff0c 这个和财务息息相关 xff0c 财务里还有借方 xff0c 贷方 xff0c 利润表之类的 xff0c 这里不详细阐述了 科目代码的规律是101 xff0
  • 2020-08-22

    广西 河池学院 广西高校重点实验室培训基地 系统控制与信息处理重点实验室 本篇博客来自河池学院 智控无人机小组 写作时间 xff1a 2020 8 22 有关系统节拍定时器的设计思路及方法源于 DataH的msOS学习之路 xff08 1
  • 2020-09-29

    广西 河池学院 广西高校重点实验室培训基地系统控制与信息处理重点实验室 本篇博客来自河池学院 智控无人机小组 写作时间 xff1a 2020 9 29 刚刚接触STM32f103 xff0c 简单了解了基本内容 有48个引脚 xff0c 其
  • DHT11温湿度传感器——学习总结(最详细,最容易适合新手看的资料)

    一 DHT11的简单介绍 DHT11是一款有已校准数字信号输出的温湿度传感器 其精度湿度 5 RH xff0c 温度 2 xff0c 量程湿度20 90 RH xff0c 温度0 50 百度百科 注解 xff1a 相对湿度 xff08 RH
  • 【零基础学STM32】CubeMX+HAL玩转电机控制

    Motor 主要内容前置知识CubeMX配置代码出现的问题参考文献 主要内容 基于被我鸽了的电控作业 主控 STM32F429IGT6 电机TT小黄 模拟小车所以两路编码器 前置知识包括 PID PWM 定时器 LM2596 L298N等
  • 解决ubuntu虚拟机没有公钥问题

    成功解决ubuntu虚拟机升级出现提示 xff1a 没有公钥的问题 把终端提示缺少的公钥复制到代码后面 span class token function sudo span apt key adv keyserver keyserver
  • H3C交换机常用命令

    H3C S5800 显示当前配置 lt H3C gt display current configuration 缩写 xff1a dis cur 恢复出厂设置 lt H3C gt reset saved configuration 按y
  • SVN 增加patch打包管理

    系统上线后必然面临系统的维护 xff0c 目前我们对系统维护和新需求开发 xff0c 是以打patch包形式更新程序 xff0c 但对打包的文件不能很好的搜寻出来 xff0c 为解决这个问题 xff0c 我新开发一插件 xff0c 在svn
  • 1.1 海思3518E视频编解码的一些概念

    目录 1 1 1 前言1 1 2 视频编解码的基本概念了解 1 1 1 前言 这是我第一次写博客 xff0c 我写博客的目的是为了记录我的学习笔记 xff0c 同时也是想把我的学习记录分享出来 xff0c 供参考学习 这个学习笔记是关于海思
  • Git 客户端 - 可视化工具 Fork 使用

    Fork 是什么 当我们在多人协同开发项目的过程中 xff0c Git 是必不可少的代码托管工具 xff0c 但是繁琐的操作命令 抽象的文件状态 xff0c 多个不同分支需要花费大量的时间进行分配管理与维护 xff0c 至此 Fork 拥有
  • STM32串口外设是否需要加上拉电阻?

    STM32F103串口TX一般设置为GPIO Mode AF PP xff08 复用推挽输出 xff09 xff1b RX一般设置为RX一般设置为GPIO Mode IN FLOATING 模拟输入 xff1b 如图所示 xff0c STM
  • Windows11升级踩坑过程与镜像下载地址汇总

    第一天开始写博客 xff0c 之前一直想写但是各种原因没有开始 xff0c 今天折腾了一天升级完了windows11 xff0c 想分享一下过程和踩的坑 xff0c 也算是给自己一个开始的契机 xff0c 有些东西重新配置的时候看自己的博客
  • STM32CubeMx使用教程(六)—— OLED屏使用

    前言 在前面一章中 xff0c 学习了 串口通信以及定时器 xff0c 本章节中将介绍I2C通信 xff0c 使用 I2C 通信方式点亮 OLED 模块 由于 OLED 模块支持多种通信方式 xff0c OLED 模块的 I2C 通信过程主