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键才能看到显示屏画面
效果
效果图 |
---|
附录
第十四届蓝桥杯物联网选择题 | 第十四届蓝桥杯物联网编程题 | 第十四届蓝桥杯物联网编程题 |
---|---|---|