stm32f103c8t6连接ZE08甲醛传感器和0.96寸的7线spiOLED显示,ZE08甲醛传感器连接单片机PB10和PB11通信,7线spiOLED显示的D0连单片机PA5,D1连单片机PA7,RES连单片机PB0,DC连单片机PB1,CS连单片机PA4,单片机PA 6连接一个无源蜂鸣器,输出高电平时蜂鸣器报警,单片机将甲醛传感器每秒主动反馈的甲醛浓度信号转化为具体数值后在OLED屏幕上显示出来,如果甲醛浓度超过0.01毫克每立方米,就在显示屏上持续显示30秒,同时30秒内蜂鸣器报警并不接收甲醛传感器数据,使用库函数进行程序设计
时间: 2023-07-15 09:15:42 浏览: 114
首先需要初始化相关的引脚和外设,包括GPIO、SPI和定时器。以下是初始化代码:
```c
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
// 定义相关引脚
#define OLED_RES_PIN GPIO_Pin_0
#define OLED_RES_GPIO GPIOB
#define OLED_DC_PIN GPIO_Pin_1
#define OLED_DC_GPIO GPIOB
#define OLED_CS_PIN GPIO_Pin_4
#define OLED_CS_GPIO GPIOA
#define OLED_D0_PIN GPIO_Pin_5
#define OLED_D0_GPIO GPIOA
#define OLED_D1_PIN GPIO_Pin_7
#define OLED_D1_GPIO GPIOA
#define ZE08_TX_PIN GPIO_Pin_10
#define ZE08_TX_GPIO GPIOB
#define ZE08_RX_PIN GPIO_Pin_11
#define ZE08_RX_GPIO GPIOB
#define BEEP_PIN GPIO_Pin_6
#define BEEP_GPIO GPIOA
// 定义SPI和定时器
#define OLED_SPI SPI1
#define OLED_SPI_CLK RCC_APB2Periph_SPI1
#define OLED_SPI_DMA_Channel DMA1_Channel3
#define OLED_SPI_DMA_FLAG DMA1_FLAG_TC3
#define OLED_TIM TIM3
#define OLED_TIM_CLK RCC_APB1Periph_TIM3
// 初始化函数
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 初始化OLED的RES、DC、CS、D0和D1引脚
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = OLED_D0_PIN | OLED_D1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(OLED_D0_GPIO, &GPIO_InitStructure);
GPIO_Init(OLED_D1_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = OLED_RES_PIN | OLED_DC_PIN | OLED_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(OLED_RES_GPIO, &GPIO_InitStructure);
GPIO_Init(OLED_DC_GPIO, &GPIO_InitStructure);
GPIO_Init(OLED_CS_GPIO, &GPIO_InitStructure);
// 初始化ZE08的TX和RX引脚
GPIO_InitStructure.GPIO_Pin = ZE08_TX_PIN | ZE08_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ZE08_TX_GPIO, &GPIO_InitStructure);
GPIO_Init(ZE08_RX_GPIO, &GPIO_InitStructure);
// 初始化无源蜂鸣器引脚
GPIO_InitStructure.GPIO_Pin = BEEP_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(BEEP_GPIO, &GPIO_InitStructure);
}
void SPI_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
// 初始化SPI
RCC_APB2PeriphClockCmd(OLED_SPI_CLK, ENABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(OLED_SPI, &SPI_InitStructure);
SPI_Cmd(OLED_SPI, ENABLE);
// 初始化SPI使用的DMA
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
SPI_I2S_DMACmd(OLED_SPI, SPI_I2S_DMAReq_Tx, ENABLE);
}
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 初始化定时器
RCC_APB1PeriphClockCmd(OLED_TIM_CLK, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(OLED_TIM, &TIM_TimeBaseStructure);
TIM_Cmd(OLED_TIM, ENABLE);
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
// 初始化USART
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
```
接下来就是甲醛传感器的读取和OLED显示的代码:
```c
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
// 定义相关引脚和外设
#define OLED_RES_PIN GPIO_Pin_0
#define OLED_RES_GPIO GPIOB
#define OLED_DC_PIN GPIO_Pin_1
#define OLED_DC_GPIO GPIOB
#define OLED_CS_PIN GPIO_Pin_4
#define OLED_CS_GPIO GPIOA
#define OLED_D0_PIN GPIO_Pin_5
#define OLED_D0_GPIO GPIOA
#define OLED_D1_PIN GPIO_Pin_7
#define OLED_D1_GPIO GPIOA
#define ZE08_TX_PIN GPIO_Pin_10
#define ZE08_TX_GPIO GPIOB
#define ZE08_RX_PIN GPIO_Pin_11
#define ZE08_RX_GPIO GPIOB
#define BEEP_PIN GPIO_Pin_6
#define BEEP_GPIO GPIOA
#define OLED_SPI SPI1
#define OLED_SPI_CLK RCC_APB2Periph_SPI1
#define OLED_SPI_DMA_Channel DMA1_Channel3
#define OLED_SPI_DMA_FLAG DMA1_FLAG_TC3
#define OLED_TIM TIM3
#define OLED_TIM_CLK RCC_APB1Periph_TIM3
// 定义甲醛传感器读取的相关变量
uint8_t ze08_data[9];
uint16_t ze08_ppm;
// 定义OLED显示的相关变量
uint8_t oled_buf[128 * 64 / 8];
// 甲醛传感器读取的函数
void ZE08_ReadData(void)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
; // 等待接收数据
if (USART_ReceiveData(USART1) == 0xFF)
; // 接收到帧头
else
return; // 帧头错误,退出函数
for (uint8_t i = 0; i < 8; i++)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
; // 等待接收数据
ze08_data[i] = USART_ReceiveData(USART1);
}
ze08_ppm = (ze08_data[3] << 8) | ze08_data[4];
}
// OLED显示的函数
void OLED_Display(void)
{
static uint32_t alarm_time = 0;
// 清空OLED显示缓存
memset(oled_buf, 0, sizeof(oled_buf));
// 将甲醛浓度转化为字符串并显示
char ppm_str[32];
sprintf(ppm_str, "PPM:%d.%02d", ze08_ppm / 100, ze08_ppm % 100);
OLED_ShowString(0, 0, ppm_str, 1);
// 如果甲醛浓度超过0.01毫克每立方米,持续显示30秒
if (ze08_ppm > 1)
{
alarm_time = TIM_GetCounter(OLED_TIM);
OLED_ShowString(0, 2, "WARNING!", 1);
BEEP_ON(); // 开启蜂鸣器
}
else if (TIM_GetCounter(OLED_TIM) - alarm_time < 30000)
{
OLED_ShowString(0, 2, "WARNING!", 1);
BEEP_ON(); // 开启蜂鸣器
}
else
{
BEEP_OFF(); // 关闭蜂鸣器
}
// 将OLED缓存中的数据写入OLED显示屏
OLED_Refresh_Gram(oled_buf);
}
int main(void)
{
GPIO_Configuration();
SPI_Configuration();
TIM_Configuration();
USART_Configuration();
OLED_Init(); // 初始化OLED显示屏
OLED_Clear(); // 清空OLED显示屏
while (1)
{
ZE08_ReadData(); // 读取甲醛传感器数据
OLED_Display(); // 显示数据
}
}
```
以上代码仅供参考,具体实现还需要根据具体情况进行调整。
阅读全文