STM32通过串口发送指令控制LED灯亮灭OLED并显示命令

先来看看程序运行的结果吧:

接下来就不说废话了,自己看源代码吧!每一行我都做了注释:

首先是主函数main.c文件:

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "Serial.h"
#include "Delay.h"
#include "String.h"
#include "LED.h"

int main(void)
{
	OLED_Init();       //oled  屏幕初始化
	Serial_Init();      //串口初始化
	LED_Init();        //LED灯初始化
	
	while(1)
	{
		if(Rx_Flag)                                         //如果接收到数据
		{
			if(strcmp(Rx_Data, "LED_ON") == 0)                  //如果接收到的数据是LED_ON
			{
				OLED_ShowString(1,1,"                ");            //OLED显示16个空格,清屏
				LED_ON();                                           //执行开灯函数
				OLED_ShowString(1,1,Rx_Data);                       //OLED显示LED_ON
				Send_String("LED    ON");                           //串口发送LED    ON,反馈控制者灯已经打开
			}
			else if(strcmp(Rx_Data, "LED_OFF") == 0)            //如果接收到的数据是LED_OFF
			{
				OLED_ShowString(1,1,"                ");            //OLED显示16个空格,清屏
				LED_OFF();                                          //执行关灯函数
				OLED_ShowString(1,1,Rx_Data);                       //OLED显示LED_OFF
				Send_String("LED    OFF");                          //串口发送LED    OFF,反馈控制者灯已经关闭
			}
			Rx_Flag=0;                                      //接收到数据标志位置0,为下次接收字符串做准备
		}
		Delay_ms(1000);                                      //延时50毫秒,不用那么快
	}
}

接下来是LED.h文件:

#ifndef __LED_H
#define __LED_H



void LED_Init(void);
void LED_ON(void);
void LED_OFF(void);

#endif

接下来是LED.c文件:

#include "stm32f10x.h"                  // Device header

//  LED灯初始化函数
void LED_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;                 //创建GPIOA初始化的结构体
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出模式
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;             //引脚5
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;     //频率50MHz
	GPIO_Init(GPIOA, &GPIO_InitStruct);                //GPIOA初始化
	GPIO_SetBits(GPIOA, GPIO_Pin_5);                   //引脚5设置高电平,防止LED灯初始化后亮
}


// 打开LED灯的函数
void LED_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_5);  //引脚5置低电平
}

// 关闭LED灯的函数
void LED_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_5);   //引脚5置高电平
}

记下来是串口相关的Serial.h文件:

#ifndef __SERIAL_H
#define __SERIAL_H

extern char Rx_Data[];
extern uint8_t Rx_Flag;

void Serial_Init(void);
void Send_Byte(uint8_t Byte);
void Send_String(char *str);

#endif

接下来就是最后一个serial.c文件了:

#include "stm32f10x.h"                  // Device header

char Rx_Data[100];                 //创建接收字符串的变量能盛放100个字节,闲小可以扩大
uint8_t Rx_Flag = 0;               //创建接收到字符串的标志位。1表示接收到了字符串,0表示没有接收到字符串


//串口初始化函数
void Serial_Init(void)
{
	//1:RCC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //开始串口1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 开启GPIOA的时钟
	//2:GPIO_init
	GPIO_InitTypeDef GPIO_InitStruct;                        //创建GPIO初始化的结构体
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;             // GPIO的模式为推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;                   //GPIO的引脚9
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO的频率50MHz
	GPIO_Init(GPIOA, &GPIO_InitStruct);                      //GPIO初始化
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;               //GPIO的模式为上拉输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;                  //GPIO引脚10
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO的频率50MHz
	GPIO_Init(GPIOA, &GPIO_InitStruct);                      //GPIO初始化
	//3:USART_Init
	USART_InitTypeDef USART_InitStruct;                                          //创建串口初始化的结构体
	USART_InitStruct.USART_BaudRate = 9600;                                      // 波特率为9600
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 没有硬件流控制
	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 // 串口1的接收和发送模式
	USART_InitStruct.USART_Parity = USART_Parity_No;                             // 串口无校验
	USART_InitStruct.USART_StopBits = USART_StopBits_1;                          // 串口停止位1位
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;                     // 串口数据位长度:8位
	USART_Init(USART1, &USART_InitStruct);                                       // 串口初始化
	//4:NVIC_Init
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //NVIC的分组选择2组                       
	NVIC_InitTypeDef NVIC_InitStruct;                      //NVIC初始化的结构体
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;          //通道选择串口1
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            //NVIC串口通道使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  //NVIC抢占优先级:1
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;          //NVIC响应优先级:1
	NVIC_Init(&NVIC_InitStruct);                            //NVIC初始化
	//5:USART_Cmd
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);          //开启串口1的接收数据中断
	USART_Cmd(USART1, ENABLE);                           //串口1使能
}


// 发送字节的函数(参数:8位的一个字节)
void Send_Byte(uint8_t Byte)
{
	USART_SendData(USART1, Byte);                                //发送1个字节
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);     //等待发送完成的标志位置1,是0时就等待
	USART_ClearFlag(USART1, USART_FLAG_TXE);                         //发送完成的标志位置0,为下次发送做准备
}


// 发送字符串函数(参数char类型的指针)
void Send_String(char *str)
{ 
	while(*str)         //如果解引用指针内容不是0就循环
	{
		Send_Byte(*str);      //发送字节当前指针所指向的内容
		str++;                // 指针++,指向下一个字节的内容
	}
}


// 串口1中断函数
void USART1_IRQHandler(void)
{
	static uint8_t state =0;        // 定义接收状态码
	static uint8_t i=0;                 //定义接收数组的下标
	uint8_t Dat;                                    //定义每次进中断接收当前字节的变量
	if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE))  //如果接收标志置位了
	{
		Dat = USART_ReceiveData(USART1);           // 变量接收当前收到的字节
		if(state == 0)                      // 如果状态码是0
		{
			if(Dat == '@')                            //如果收到的字节是@
			{
				state = 1;                            //状态码置1
			}
		}
		else if(state == 1)             // 如果状态码是1
		{
			if(Dat == '$')                      //如果收到的字节是$
			{
				state = 2;                            //状态码置2
			}
			else                       //否则
			{
				Rx_Data[i]=Dat;                 //接收数组的第i个下标赋值为当前接收的字节 
				i++;                            //下标++,移到数组下一个位置,准备下次接收
			}
		}
		else if(state == 2)          // 如果状态码是2
		{
			if(Dat == '&')                    //如果收到的字节是&
			{
				state = 0;                              //状态码置0   结束这次的接收
				i = 0;                                  //小标置0    这一串字符串接收完毕,下串从头覆盖
			}
		}
		
	}
	Rx_Flag = 1;                               // 接收标志位置1, 证明这段字符串接收完毕
	USART_ClearFlag(USART1, USART_FLAG_RXNE);  // 清除接收标志位

}


所有文件在工程中的目录为:

工程编译后下载到单片机就能实现串口控制LED灯的亮灭了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/484956.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis中RDB中的文件写入

RDB文件的创建与载入。 有两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE. SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器 不能处理任何命令请求: 127.0.0.1:6…

竞赛 python opencv 深度学习 指纹识别算法实现

1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 python opencv 深度学习 指纹识别算法实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:4分创新点:4分 该项目较为新颖…

如何使用OpenCV扫描图像、查找表和时间测量

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV4.9.0开源计算机视觉库核心功能(核心模块) ​ 编辑 目标 我们将寻求以下问题的答案: 如何浏览图像的每个像素?OpenCV 矩…

SVN的branch分支合并完要不要删除

在 SVN 中,当一个分支(branch)的工作已经完成并成功合并回主干(trunk)后,通常不需要立即删除该分支。保留分支可以有一些好处,例如: 历史记录和追溯:保留分支可以帮助团…

pycharm搭建新的解释器及删除处理

目录 1.创建虚拟环境 个人实际操作: 对于“继承全局站点包”: 2.创建一个新项目 3.删除操作 (1)删除解释器 (2)删除新建项目 1.创建虚拟环境 Pycharm官方文档说明网址: Configure a virt…

StringRedisTemplate

Redis快速入门 3.2.3.StringRedisTemplate 为了节省内存空间,我们可以不使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。…

芯片工程系列(5)2.5D 3D封装

0 英语缩写 硅通孔(Through Silicon Via,TSV)硅中介层(Silicon Interposer)物理气象沉淀法(Physical Vapor Deposition,PVD)DRIE、CVD、PVD、CMP等设备CoWoS(Chip on Wa…

SpringMVC | SpringMVC中的 “文件上传和下载”

目录: 一、文件上传1.1 文件上传“概述”1.2 文件上传“具体配置” :“前端”中配置“文件上传” ( type“file” 满足3个条件 )“后端”中配置“文件上传” ( 配置id为“CommonsMultipartResolver”的bean 配置“文件上传”的“约束条件” 通过“MultipartFile接口”参数接…

【C语言数据结构】排序

1.排序的概念 在深入研究各个排序算法之前,首先,我们要对排序有个大概的了解,即与排序相关的一些概念 Q:什么是排序? A:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小…

Rust egui(3) 增加多个tab

话说不知道咋写,要不直接上git patch吧。代码都是移植的官方demo,核心改动就是把原来的line_demo换成了plot_demo,里面实现多个ui,然后点击tab标题会切换不同的ui。 如下图,Lines和Markers两个不同的标签对应不同的ui。…

pytest框架的封装以及用例管理框架

pytest框架的封装以及用例管理框架 公共类统一封装requests_util02.pytest_api01.py 自动化测试的基础自动化测试的介入点自动化测试和手工测试占比自动化实施过程 pytest元素定位元素定位查找元素定位的方式通过 ID 定位通过 Name 定位通过 Class Name 定位通过 Tag Name 定位…

数据结构面试常见问题之串的模式匹配(KMP算法)系列-简单解决方案

😀前言 字符串匹配是计算机科学中一个常见的问题,指的是在一个长字符串中查找一个短字符串的出现位置。在文本编辑、生物信息学、数据挖掘等领域都有着广泛的应用。 本文将介绍 KMP 算法,一种用于解决字符串匹配问题的经典算法。KMP 算法可以…

鸿蒙网络开发学习:【ylong_http】

简介 ylong_http 构建了完整的 HTTP 能力,支持用户使用 HTTP 能力完成通信场景的需求。 ylong_http 使用 Rust 编写,为 OpenHarmony 的 Rust 能力构筑提供支持。 ylong_http 在 OpenHarmony 中的位置 ylong_http 向 OpenHarmony 系统服务层中的网络协…

flutter实现视频播放器,可根据指定视频地址播放、设置声音,进度条拖动,下载等

需要装依赖&#xff1a; gallery_saver: ^2.3.2video_player: ^2.8.3 AndroidManifest.xml <uses-permission android:name"android.permission.INTERNET"/> 实现代码 import dart:async; import dart:io;import package:flutter/material.dart; import pa…

深入理解栈和队列(二):队列

个人主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《数据结构》 一、队列的概念和结构 队列是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的…

OC对象 - 关联对象(如何给分类添加成员变量)

文章目录 OC对象 - 关联对象&#xff08;如何给分类添加成员变量&#xff09;1. 基本使用1.1 提供的API1.1.1 添加关联对象1.1.2 获得关联对象1.1.3 移除所有关联对象1.1.3 修饰符 1.2 使用方法1.2 Key的常见用法1.2.1 使用的get方法的selecor作为key1.2.2 使用指针的地址作为k…

【Node.js】zlib

gzip 和 deflate 的基本使用 const zlib require("zlib"); const fs require(fs)// 压缩 1. createGzip .gz 2. createDeflate .deflate // const readStream fs.createReadStream(index.txt) // const writeStream fs.createWriteStream(index.txt.gz) // rea…

Python Flask 自定义404错误

from flask import Flask, abort, make_response, request, render_templateapp Flask(__name__)# 重定向到百度 app.route(/index, methods["GET", "POST"]) def index():if request.method "GET":return render_template("index.html&q…

Python Flask 自定义过滤器

{{ data.list | li2 }} li2就是自定义的 from flask import Flask, render_templateapp Flask(__name__)app.route("/index") def index():data {name: "张三","age": 18,list: [123123, 41, 123]}return render_template("index2.html…

nodejs+vue高校二手商品交易平台的设计与实现python-flask-django-php

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统高校二手商品交易采取了人工的管理方法&#xf…
最新文章