stm32笔记[11]-驱动SSD1306屏幕

摘要

在蓝桥杯物联网的CT127C开发板上驱动SSD1306的0.91寸显示屏.

平台信息

  • Keil MDK-ARM (μVision) V5.35.0.0
  • STM32CubeMX 6.2.1

原理简介

CT127C开发板简介

蓝桥物联网竞赛实训装置省赛训练套装,适用于蓝桥杯大赛(电子类)物联网设 计与开发科目竞赛训练及高校日常教学实训环节。
省赛训练套装产品核心微控制器为 ST 公司的 STM32L071KBU,LoRa 收发器解决方案 为Semtech 公司SX1278芯片,硬件的设计意在帮助用户学习和评估STM32L0系列 微控制器的性能、微控制周边典型外设的驱动程序设计方法和 LoRa 无线通信解决 方案,硬件配置了简单的外设资源用于功能验证,设计了一个通用扩展接口,方便 扩展各类传感器和执行器。省赛训练套装板载 CMSIS-DAP Link 调试器和 USB 虚拟 串口,支持程序在线下载、仿真调试功能。

蓝桥杯(电子类)物联网设计与开发科目省赛训练套装由 2 个 LoRa 终端和 5 个传 感器模块(温度传感器、矩阵键盘、模拟电压输出、脉冲输出、光敏与红外热释电) 组成。各传感器模块可以直接安装在 LoRa 终端的通用接口上,用于学习和训练。

  • LoRa 终端
  • 设计基于 ARM Cortex M0+ 微控制器 STM32L071KBU,具有 128Kbytes Flash 存储器、6Kbyte EEPROM 存储器和 20Kbyte RAM 存储器,QFPN32 封装
  • 5V 电源供电,支持通过供电探针或 CMSIS DAP Link USB 接口供电
  • 0.91 寸 OLED 显示器
  • User & Reset 按键
  • 继电器: 2 路
  • 通用接口: 1 个
  • 大电流驱动接口: 2 个
  • User LED: 1 个
  • LoRa 单元: 1 个
  • 板载 USB 转串口功能,与微控制器 USART2 连接
  • 集成开发环境支持: Keil、IAR 和各类基于 GCC 的集成开发环境
  • 传感器模块
  • 温度传感器模块: I2C 接口,传感器型号: STS30-DIS-B
  • 模拟电压输出模块: 2 路连续可调电压输出,4 个 LED 指示灯
  • 矩阵键盘模块: 2 x 3 矩阵按键
  • 脉冲输出模块: 1 路模拟电压输出、1 路脉冲信号输出、2 个 LED 指示灯
  • 光敏与红外热释电模块: 1 路光敏电阻分压输出、1 路热释电传感器输出信号。
CT127C外观
CT127C原理图1 CT127C原理图2 CT127C原理图3

stm32l071简介

The ultra-low-power STM32L071xx are offered in 9 different package types from 32 pins to 100 pins. Depending on the device chosen, different sets of peripherals are included.

ARM Cortex M0+微控制器 STM32L071KBU,具有 128Kbytes Flash 存储器、6Kbyte EEPROM 存储器和 20Kbyte RAM 存储器,QFPN32 封装.

驱动显示屏

  • 芯片:SSD1306
  • 分辨率:128x32
  • 通信:I2C

实现

配置引脚

单个LoRa节点:

  • OLED_SCL:PA8(I2C3_SCL)
  • OLED_SDA:PB4(I2C3_SDA)
  • OLED_PWR:PB5(低电平有效)
配置引脚 配置时钟

核心代码

主要修改main.c,i2c.h,i2c.c和oled.c文件;
提示:i2c.c中的延时不能漏;

i2c.h

/* USER CODE BEGIN Prototypes */
extern I2C_HandleTypeDef hi2c3;
void OLED_Write(uint8_t ucType, uint8_t ucData);
/* USER CODE END Prototypes */

i2c.c

I2C_HandleTypeDef hi2c3;

/* I2C3 init function */
void MX_I2C3_Init(void)
{

  /* USER CODE BEGIN I2C3_Init 0 */

  /* USER CODE END I2C3_Init 0 */

  /* USER CODE BEGIN I2C3_Init 1 */

  /* USER CODE END I2C3_Init 1 */
  hi2c3.Instance = I2C3;
  hi2c3.Init.Timing = 0x00707CBB;
  hi2c3.Init.OwnAddress1 = 0;
  hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c3.Init.OwnAddress2 = 0;
  hi2c3.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C3_Init 2 */
  HAL_Delay(100); // 延时以初始化完成
  /* USER CODE END I2C3_Init 2 */

}

oled.c

/*************************************************
Copyright (c)Guoxinchangtian Technologies Co., Ltd. 2008-2019. All rights reserved.
File name: oled.c
Author:      Version:   Date:2019.10.10
Description: 实现对LoRa模块的OLED显示屏的读写操作。
Others:
History:

1. Date:
Author:
Modification:
*************************************************/
#include "i2c.h"
#include "oled.h"
#include "font.h"
void OLED_Write(uint8_t type,uint8_t data)
{
	uint8_t pTx[2]={type,data};
	HAL_I2C_Master_Transmit(&hi2c3,0x78,pTx,2,10);
}
/* 设置位置(参考表3.6) */
void OLED_SetPos(unsigned char x, unsigned char y)
{
	OLED_Write(TYPE_COMMAND, x & 0x0f);
	OLED_Write(TYPE_COMMAND, 0x10 + ((x & 0xf0) >> 4));
	OLED_Write(TYPE_COMMAND, 0xB0 + y);
}
/* 清除屏幕 */
void OLED_Clear(void)
{
	unsigned char i, j;

	for(i = 0; i < 4; i++)
	{
		OLED_SetPos(0, i);
		for(j = 0; j < 128; j++)
			OLED_Write(TYPE_DATA, 0);
	}
}
/**
  * @brief OLED屏幕初始化。
  * @param None
  * @retval None
  */
void OLED_Init(void)
{
	OLED_Write(TYPE_COMMAND, 0xA1);	/* 段重映射, b0:0,0->0(复位值);1,0->127 */

	OLED_Write(TYPE_COMMAND, 0xA8);	/* 复用比 */
	OLED_Write(TYPE_COMMAND, 0x1F);	/* 0F~3F,16MUX~64MUX(复位值) */

	OLED_Write(TYPE_COMMAND, 0xC8);	/* COM扫描方向, b3:0,正常模式(复位值);b3:1,反转模式 */

	OLED_Write(TYPE_COMMAND, 0xDA);	/* COM引脚配置 */
	OLED_Write(TYPE_COMMAND, 0x00);	/* D4:0,顺序;1,交替(复位值) */

	OLED_Write(TYPE_COMMAND, 0x8D);	/* 充电泵 */
	OLED_Write(TYPE_COMMAND, 0x14);	/* D2:0,禁止(复位值);1,允许 */

	OLED_Clear();										/* 清除屏幕 */
	OLED_Write(TYPE_COMMAND, 0xAF);	/* 开启显示 */
}

/**
  * @brief OLED屏幕显示一个字符。
  * @param x 横向选择位置;
					 y 纵向选择位置;
					 chr 需要显示的字符;
					 size 需要显示的字符大小;
					 @arg 16,选择8*16点阵大小字符。其他均选择6*8点阵字符
  * @retval None
  */
void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char chr, unsigned char size)
{
    unsigned char  c, i;

  	c = chr - ' ';
    if(x > Max_Column - 1)
    {
        x = 0;
        y = y + 2;
    }
    if(size == 16)
    {
        OLED_SetPos(x, y);
        for(i = 0; i < 8; i++)
            OLED_Write(TYPE_DATA, g_F8X16[c * 16 + i]);
        OLED_SetPos(x, y + 1);
        for(i = 0; i < 8; i++)
            OLED_Write(TYPE_DATA, g_F8X16[c * 16 + i + 8]);
    }
    else
    {
        OLED_SetPos(x, y);
        for(i = 0; i < 6; i++)
        {
            OLED_Write(TYPE_DATA, g_F6x8[c][i]);
        }
    }
}

/**
  * @brief OLED屏幕显示一个字符串。
  * @param x 横向选择位置;
					 y 纵向选择位置;
					 chr 需要显示的字符串;
					 size 需要显示的字符大小;

  * @retval None
  */
void OLED_ShowString(unsigned char x, unsigned char y, unsigned char *chr, unsigned char size)
{
    unsigned char j = 0;
	
    while(chr[j] != '\0')
    {
        OLED_ShowChar(x, y, chr[j], size);
        x += 8;
        if(x > 120)
        {
            x = 0;
            y += 2;
        }
				j++;
    }
}

main.c

#include "oled.h"
struct Time{
	uint8_t Hours;
	uint8_t Mins;
	uint8_t secs;
	uint8_t Subsecs;
}g_time={23,59,55}; // 时间
uint8_t g_oled_buf[17]; // 显示屏缓存
OLED_Init();
sprintf((char*)g_oled_buf,"%02d:%02d:%02d",g_time.Hours,g_time.Mins,g_time.secs);
OLED_ShowString(24,0,g_oled_buf,16);

编译&烧录后需要按一下RST键才能看到显示屏画面

效果

效果图

附录

第十四届蓝桥杯物联网选择题 第十四届蓝桥杯物联网编程题 第十四届蓝桥杯物联网编程题
posted @ 2024-01-15 20:27  qsBye  阅读(304)  评论(0编辑  收藏  举报