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_ONSend_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_OFFSend_String("LED    OFF");                          //串口发送LED    OFF,反馈控制者灯已经关闭}Rx_Flag=0;                                      //接收到数据标志位置0,为下次接收字符串做准备}Delay_ms(1000);                                      //延时50毫秒,不用那么快}
}

接下来是LED.h文件:

#ifndef __LED_H
#define __LED_Hvoid 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;             //引脚5GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;     //频率50MHzGPIO_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_Hextern 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 headerchar Rx_Data[100];                 //创建接收字符串的变量能盛放100个字节,闲小可以扩大
uint8_t Rx_Flag = 0;               //创建接收到字符串的标志位。1表示接收到了字符串,0表示没有接收到字符串//串口初始化函数
void Serial_Init(void)
{//1:RCCRCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);   //开始串口1时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // 开启GPIOA的时钟//2:GPIO_initGPIO_InitTypeDef GPIO_InitStruct;                        //创建GPIO初始化的结构体GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;             // GPIO的模式为推挽输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;                   //GPIO的引脚9GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO的频率50MHzGPIO_Init(GPIOA, &GPIO_InitStruct);                      //GPIO初始化GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;               //GPIO的模式为上拉输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;                  //GPIO引脚10GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO的频率50MHzGPIO_Init(GPIOA, &GPIO_InitStruct);                      //GPIO初始化//3:USART_InitUSART_InitTypeDef USART_InitStruct;                                          //创建串口初始化的结构体USART_InitStruct.USART_BaudRate = 9600;                                      // 波特率为9600USART_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_InitNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //NVIC的分组选择2组                       NVIC_InitTypeDef NVIC_InitStruct;                      //NVIC初始化的结构体NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;          //通道选择串口1NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;            //NVIC串口通道使能NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  //NVIC抢占优先级:1NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;          //NVIC响应优先级:1NVIC_Init(&NVIC_InitStruct);                            //NVIC初始化//5:USART_CmdUSART_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.mzph.cn/news/766927.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python工具-清理Unity(批量深度)清理U3D项目工程保留关键工程文件

前沿 1. Unity工程越来越多,很久不用的工程里存在了很多无用的大文件夹,极大的影响电脑容量。 2. 我电脑里面U3D工程只有17个,但容量就高达60GB,使用自己编写的工具清理后,减到了30GB多。清理了不是很重要的文件和文件…

【CTA动画】制作全记录 笔记

3Dxchange的使用 让图片跳舞 导入:I:\安装包\#动画开发\test\跳舞 model(includeTPose).fbx 转成非标准角色 手动点击骨骼,然后点击人物骨骼,选择00_t-pose 绿灯了就可以转换了,记得启用。 上面的自定义可以先选择3DS 转换后…

Java数据结构-顺序表

目录 1. 顺序表的相关概念1.1 线性表1.2 顺序表2. 功能实现2.1 整体框架2.2 乱七八糟的功能(bushi)2.2.1 判断容量是否满2.2.2 返回顺序表当前长度2.2.3 扩容2.2.4 清空整个顺序表 2.3 插入数据2.3.1 头插数据2.3.2 尾插数据2.3.3 指定位置插入 2.4 删除数据2.4.1 删除第一次出…

微服务之Nacos配置管理

文章目录 前言一、统一配置管理Nacos操作二、统一配置管理java操作1.引入依赖2.创建配置文件3.测试4.总结 三、Nacos配置自动更新1.添加注解RefreshScope2.使用ConfigurationProperties注解3.总结 四、Nacos多环境配置共享1.配置文件2.多种配置的优先级3.总结 总结 前言 一、统…

leetcode 150.逆波兰表达式求值

题目 思路 逆波兰表达式也是经典的栈的应用问题。 先说什么是逆波兰表达式(也叫后缀表达式) 我们习惯的是这样的表达式:1 2 / 3 ,这也叫中缀表达式。 但是对于计算机来说不好理解,当从左扫描到 2 的时候还需要再判断2后面是什…

STM32 | Systick定时器(第四天源码解析)

STM32 | Systick定时器(第四天)STM32 | STM32F407ZE中断、按键、灯(续第三天)1、参考delay_us代码,完成delay_ms的程序 定时器频率换算单位:1GHZ=1000MHZ=1000 000KHZ = 1000 000 000HZ 定时器定时时间:计数个数/f(频率) 或者 (1/f(频率))*计数的个数 500/1MHZ = 500/1…

C++面向对象三大特征-----继承(详细版)

目录 继承 一、继承的基础介绍 普通版网页和继承版网页的区别 语法 二、继承方式 三种继承方式 三、继承中的对象模型 四、继承中构造和析构函数 五、继承同名成员的处理方式 访问同名成员: 作用域写法: 六、继承同名静态成员的处理方式 访问…

Qt播放音乐代码示例

主界面 点击play按钮播放或暂停音乐,拖动进度条,音乐对应播放。 QWidget window;QPushButton* playButton new QPushButton("Play");// Qt 播放音乐// 创建 QMediaPlayer 对象QMediaPlayer* player new QMediaPlayer;// 指定音频文件的路径…

MySQL B+树索引 和 Redis 中跳表索引的区别

一、MySQL B树索引 和 Redis 中跳表索引 在 MySQL 中常用的索引是 B树索引,而 Redis 中,例如 zset 使用的的是跳表索引,两者有什么区别呢,MySQL 为什么不使用 跳表 呢?或者说 Redis 中为什么不使用 B树 呢&#xff1f…

章节10实验--Ubuntu18.04 Qt MySQL libqsqlmysql.so

前言: 内容参考《操作系统实践-基于Linux应用与内核编程》一书的示例代码和教材内容,所做的读书笔记。本文记录再这里按照书中示例做一遍代码编程实践加深对操作系统的理解。 引用: 《操作系统实践-基于Linux应用与内核编程》 作者:房胜、李旭健、黄…

golang 对接第三方接口 RSA 做签(加密) 验签(解密)

一、过程 1.调用第三方接口前,一般需要按规则将参数按key1value1&key2value2 阿斯克码排序,sign参数不参与加密 2.将排序并连接好的参数字符串通过我方的私钥证书(.pem)进行加密得到加密串,当然加密得到的是 []byte 字节流&…

看完就等于拿捏浮点数在内存中的储存了

诸君又该学习了,今天我们继续来一睹浮点数的奥妙真容。 经过前面文章对整形提升相关的解释,我们都对整形和字符在内存空间上的储存已经有了大概的认知,那么现在我们就来好好讲讲浮点数在内存中的储存规则。 目录 浮点数与整形储存的不同 …

41-Vue-webpack基础

webpack基础 前言什么是webpackwebpack的基本使用指定webpack的entry和output 前言 本篇开始来学习下webpack的使用 什么是webpack webpack: 是前端项目工程化的具体解决方案。 主要功能:它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览…

自定义序列化

3.2.2.自定义序列化 RedisTemplate可以接收任意Object作为值写入Redis: 只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果是这样的: 缺点: 可读性差内存占用较大 我们可以自定义RedisTempla…

NASA数据集——2015 年30 米分辨率的地衣地面覆盖率模型估计值

cABoVE: Lichen Forage Cover over Fortymile Caribou Range, Alaska and Yukon, 2000-2015 文件修订日期:2021-07-21 数据集版本: 1 摘要 本数据集提供了美国阿拉斯加东部内陆和加拿大育空地区 Fortymile 研究区 2015 标称年 30 米分辨率的地衣地面覆盖率模型估…

YOLOv8-ROS-noetic+USB-CAM目标检测

环境介绍 Ubuntu20.04 Ros1-noetic Anaconda-yolov8虚拟环境 本文假设ROS和anaconda虚拟环境都已经配备,如果不知道怎么配备可以参考: https://blog.csdn.net/weixin_45231460/article/details/132906916 创建工作空间 mkdir -p ~/catkin_ws/srccd ~/ca…

湖北专升本报名照片需要<40kb怎么解决

湖北专升本报名照片需要<40kb怎么解决

vue 修改element-plus主题色

一、安装SCSS npm install sass --save-dev npm install sass-loader --save-dev npm install node-sass --save-dev npm install vue-style-loader --sava-dev 二、添加主题文件theme.scss forward "element-plus/theme-chalk/src/common/var.scss" with ($col…

kubernetes负载均衡-service

一、service的概念 1、什么是service 在Kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;当我们需要访问这个应用时&#xff0c;可以通过Pod的IP进行访问&#xff0c;但是这里有两个问题:1、Pod的IP地址不固定&#xff0c;一旦Pod异常退出、节点故障&#xff0c;则会…

【STM32】读写BKP备份寄存器RTC实时时钟

目录 BKP BKP简介 BKP基本结构 BKP测试代码 RTC RTC简介 RTC框图 RTC基本结构 硬件电路 RTC操作注意事项 接线图 初始化 使用BKP解决只初始化一次时间 初始化参考代码 RTC设置时间 RTC读取时间 完整代码 MyRTC.c MyRTC.h main.c BKP BKP简介 BKP&#xff0…