STM32F4_通过RS232实现和PC端通讯

news2024/11/25 16:44:34

目录

1. RS232通讯

2. 实验程序

2.1 main.c

2.2 RS232.c

2.3 RS232.h


        通过上一节的学习,已经基本了解了RS232的通讯过程,实际上,不管是RS485还是RS232都是基于串口的一种通讯方式

        STM32F4_RS485、RS232_light_2025的博客-CSDN博客

1. RS232通讯

        RS232协议是1970年美国电子工业协会 EIA 联合贝尔系统、调制解调器厂家、计算机终端生产厂家共同制定的用于串行通信的标准(从上面介绍的UART的缺点来看,串口通信最致命的缺点就是没有统一的标准,导致不同器件之间的通讯变得异常的复杂,而 RS232 和 RS485 就是这样的一个标准,应用在串口之上,使得串口通信具有一定的标准)。

        该标准规定采用一个标准的连接器,标准中对连接器的每个引脚的作用都加以规定,同时也对信号的电平加以规定。

接口:

        该标准规定采用一个 25 引脚的 DB-25 连接器,标准中对连接器的每个引脚的信号内容加以规定。还对各种信号的电平加以规定;后来1BM的PC机将RS232简化成了 DB-9 连接器,再后来成了事实的标准(就像我们家用的三头插座一样,火线、零线、地线);现在工业控制的RS-232接口一般只使用RXD、TXD、GND三条线(STM32开发板中的原理图上也是如此)。

信号:

        RS232标准规定逻辑 “1” 的电平为-5V到-15V,逻辑 “0” 的电平为+5V到+15V,选择该电气标准的目的在于提高抗干扰能力,增大通信距离,其传送的距离一般可达15m。

C1+:倍增器电荷泵电容器的正极。

V+:充电泵产生的+5.5V。

C1-:倍增器电荷泵电容器的负极。

C2+:反转电荷泵电容器的正极。

C2-:反转电荷泵电容器的负极。

V-:-5.5V由电荷泵产生。

DOUT2:RS-232驱动输出。

RIN2:RS-232接收输入。

VCC:+3V~+5.5V供给电圧。

GND:地。

DOUT1:RS-232驱动输出。

RIN1:RS-232接收输入。

ROUT1:RS-232接收输出。

DIN1:RS-232驱动输入。

DIN2:RS-232驱动输入。

ROUT2:RS-232接收输出。

RS232存在的问题:

        1. 接口的信号电平较高(-15V~+15V),易损坏接口电路芯片,又因为与TTL电平不兼容,所以需要使用电平转换芯片才能与TTL电路连接。

        2. 通信速度较低,不适合用于那些高速通信的场合。        

        3. 易产生共模干扰,抗噪声干扰性弱。

        4. 传输距离较短,一般情况只有15m。

最后强调一点:程序编程方面 RS232 和 串口 没有任何区别,只是在硬件方面做出了一些改善。(所以说 RS232 本质上还是通过串口在收发数据,简单点来说,不过是把接线接口的电气特性更换了)

2. 实验程序

实验准备:

        本实验最终实现STM32F407开发板和电脑通过RS232进行通讯,所以需要 USB转RS232 串口线; USB 端接电脑USB接口,DB-9 接口接自己的开发板,至于是公头还是母头,根据自己的开发板选择即可;

        STM32F407开发板还需要将P9插针中的COM2_RX和TX接,COM2_TX和RX接;PA2,PA3引脚为串口 2 的收发引脚;

实验现象:

        本实验的实验现象为:程序烧录后,通过串口助手可以发送命令控制开发板LED0、LED1 以及蜂鸣器;同样开发板上也可以通过按键发送信息给串口,实现 STM32F4 通过 RS232 和电脑进行简单通讯;

2.1 main.c

#include "stm32f4xx.h"                 
#include "delay.h"
#include "usart.h"
#include "LED.h"
#include "lcd.h"
#include "Key.h"
#include "RS232.h"
#include "beep.h"

//函数声明
void LED_BEEP_Control(void);
void Key_InterruptInit(void);
void EXTI4_IRQHandler(void);
void EXTI2_IRQHandler(void);
void USART2_IRQHandler(void);


int Control_Flag=0; //设置一个状态位
unsigned int i;


int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);
	uart_init(115200); //切记:不初始化延迟函数和串口是不能用LCD的
	
	LED_Init();
	LCD_Init();
    BEEP_Init();
	RS232_Init(9600);  //初始化RS232,设置波特率为9600
    Key_InterruptInit();
    
	POINT_COLOR=RED;
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
	LCD_ShowString(30,70,200,16,16,"RS232 TEXT");
	LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,110,200,16,16,"2023/06/08");
    
    LCD_ShowString(30,140,200,16,16,"Input 0,LED0 Light");
	LCD_ShowString(30,160,200,16,16,"Input 1,LED1 Light");
	LCD_ShowString(30,180,200,16,16,"Input 2,Turn on the buzzer");
	LCD_ShowString(30,200,200,16,16,"Input 3,Turn off the buzzer");
    
    RS232_SendString(USART2,"请输入您的指令:\r\n");
    RS232_SendString(USART2,"  输入0: LED0点亮\r\n");
    RS232_SendString(USART2,"  输入1: LED1点亮\r\n");
    RS232_SendString(USART2,"  输入2: 打开蜂鸣器\r\n");
    RS232_SendString(USART2,"  输入3: 关闭蜂鸣器\r\n");
	
    
    while(1)
    {
       LED_BEEP_Control();
    }
}

void LED_BEEP_Control(void)
{
    switch(Control_Flag)
    {
        case 1:
            LED0=0;
            LED1=1;
            delay_ms(10);
            LCD_ShowString(30,230,200,16,16,"LED0 Light");  
            //RS232_SendString(USART2,"LED0已点亮\r\n\r\n");  打开此功能可以看到,按下按键后串口显示的现象
            break;
        case 2:
            LED0=1;
            LED1=0;
            delay_ms(10);
            LCD_ShowString(30,230,200,16,16,"LED1 Light");
            //RS232_SendString(USART2,"LED1已点亮\r\n\r\n");
            break;
        case 3:
            LED0=!LED0;
            delay_ms(20);
            LED1=1;
            delay_ms(20);
            GPIO_SetBits(GPIOF,GPIO_Pin_8);
            delay_ms(20);
            LCD_ShowString(30,230,200,16,16,"Turn on the buzzer");
            //RS232_SendString(USART2,"蜂鸣器已打开\r\n\r\n");
            break;
        case 4:
            LED1=!LED1;
            delay_ms(20);
            LED0=1;
            delay_ms(20);
            GPIO_ResetBits(GPIOF,GPIO_Pin_8);
            delay_ms(20);
            LCD_ShowString(30,230,200,16,16,"Turn off the buzzer");
            //RS232_SendString(USART2,"蜂鸣器已关闭\r\n\r\n");
            break;
    }
}

void USART2_IRQHandler(void)
{
    uint8_t temp;
    if(USART_GetFlagStatus(USART2,USART_IT_RXNE)!=0)
    {
        temp=USART_ReceiveData(USART2); //通过电脑串口助手发命令给temp,根据temp的不同数值设置相关状态位
        //USART_SendData(USART2,temp);
        
        switch(temp)
        {
            case'0':
                Control_Flag=1;
                RS232_SendString(USART2,"LED0已点亮\r\n\r\n");
                break;
            case'1':
                Control_Flag=2;
                RS232_SendString(USART2,"LED1已点亮\r\n\r\n");
                break;
            case'2':
                Control_Flag=3;
                RS232_SendString(USART2,"蜂鸣器已打开\r\n\r\n");
                break;
            case'3':
                Control_Flag=4;
                RS232_SendString(USART2,"蜂鸣器已关闭\r\n\r\n");
                break;
        }
    }
}

void Key_InterruptInit(void)
{
    KEY_Init();  //按键对应的IO初始化
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //想要使用按键控制外部中断,必须使能SYSCFG时钟
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2); //PE2连接中断线2,映射按键KEY2
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource4); //PE4连接中断线4,映射按键KEY0
    EXTI_ClearITPendingBit(EXTI_Line2);
    EXTI_ClearITPendingBit(EXTI_Line4);
    
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line=EXTI_Line2 | EXTI_Line4; //KEY0 和 KEY2
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;  //KEY0 和 KEY2 按下,对应引脚输入低电平
    EXTI_Init(&EXTI_InitStructure);
    
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x03;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;
    NVIC_Init(&NVIC_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel=EXTI4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;
    NVIC_Init(&NVIC_InitStructure);
}

void EXTI2_IRQHandler(void) //对应于KEY2
{
    
    delay_ms(10); //按键消抖
	if(KEY2==0)//KEY2按下
	{
		Control_Flag++;   //按键控制状态位改变
        if(Control_Flag>4)
            Control_Flag=1;
	}
	EXTI_ClearITPendingBit(EXTI_Line2);//消除中断线2上的中断标志位
        
}

void EXTI4_IRQHandler(void) //对应于KEY0
{
    delay_ms(10);//按键消抖
	if(KEY0==0)//KEY0按下
	{
		Control_Flag--;
        if(Control_Flag<1)
            Control_Flag=4;
	}
	EXTI_ClearITPendingBit(EXTI_Line4);//消除中断线4上的中断标志位
}



2.2 RS232.c

#include "stm32f4xx.h"              
#include "RS232.h"
#include "delay.h"
 
 
//初始化RS232 
//初始化IO口 和 串口2
//根据STM32F407开发板P9插针,只需要将跳线帽的PA2和COM2_RX接,PA3和COM2_TX接即可;
//bound:波特率
void RS232_Init(u32 bound)
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);  //使能GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);   //使能USART2时钟
	
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); //GPIOA2复用为串口2
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); //GPIOA3复用为串口2
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //设置为推挽输出
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOG,&GPIO_InitStructure);
	
	//串口2初始化
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate=bound; //设置波特率
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //无硬件数据流控制
	USART_InitStructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx; //模式为串口收发模式
	USART_InitStructure.USART_Parity=USART_Parity_No;  //无奇偶校验位
	USART_InitStructure.USART_StopBits=USART_StopBits_1;  //1个停止位
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;  //字长为8位
	USART_Init(USART2,&USART_InitStructure);
	
	USART_Cmd(USART2,ENABLE); //使能串口2
	
	USART_ClearFlag(USART2,USART_FLAG_TC);  //清除串口2中断标志位
	
 
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE); //串口中断命令,USART_IT_RXNE是串口状态寄存器的接收缓存区的标志位,该函数表示开启接收中断
	
	//串口2中断优先级配置
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;  //子优先级3
	NVIC_Init(&NVIC_InitStructure);
	
}
 
//RS232发送字符
unsigned char RS232_SendChar(USART_TypeDef* USARTx,unsigned char ucChar)
{
    while(!USART_GetFlagStatus(USARTx,USART_FLAG_TXE));
    USART_SendData(USARTx,ucChar);
    return ucChar;
}

//RS232发送字符串
void RS232_SendString(USART_TypeDef* USARTx,unsigned char* pucStr)
{
    while(*pucStr!='\0')
    {
        RS232_SendChar(USARTx,*pucStr++);
    }
}

//接收缓存区标志位置1下的非阻塞接收字符
unsigned char RS232_ReceiveChar_NonBlocking(USART_TypeDef* USARTx)
{
    if(USART_GetFlagStatus(USARTx,USART_FLAG_RXNE))
    {
        return USART_ReceiveData(USARTx);
    }
    else
        return 0;
}


2.3 RS232.h

#ifndef _RS232__H_
#define _RS232__H_
 
 
void RS232_Init(u32 bound);
unsigned char RS232_SendChar(USART_TypeDef* USARTx,unsigned char ucChar);
void RS232_SendString(USART_TypeDef* USARTx,unsigned char* pucStr);
unsigned char RS232_ReceiveChar_NonBlocking(USART_TypeDef* USARTx);

 
#endif
 

 

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

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

相关文章

[opencv]opencv-python环境搭建

删除源信息 conda config --remove-key channels 添加源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/ conda config --add chan…

ChatGPT 会带来失业潮吗?

&#xff08;永久免费&#xff0c;扫码加入&#xff09; 最近在翻知乎上的一些文章&#xff0c;很多都是跟ChatGPT有关的。因为本身是搞Python编程的&#xff0c;知乎推荐系统给我推荐了一篇廖雪峰老师的文章&#xff0c;觉得很有意思。 一共1119个赞&#xff0c;还是很厉害的&…

HTTPS 协议

哥几个来学 HTTPS 协议 啦 ~~ 目录 &#x1f332;一、HTTPS 是什么&#xff1f; &#x1f333;二、何为 “加密” &#x1f334;三、HTTPS 的工作过程 &#x1f366;1. 引入对称加密 &#x1f367;2. 引入非对称加密 &#x1f368;3.引入证书 &#x1f332;一、HTTPS 是什…

【前端 - HTML】第 4 课 - 列表标签

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、列表 3、无序列表 4、有序列表 5、定义列表 6、总结 1、缘起 微信小程序的列表标签是一种用于展示多个数据项的…

2023Java面试题库新合集,突击春招已助1000+人顺利入职大厂

前言&#xff1a; 互联网公司的面试&#xff0c;从形式上说&#xff0c;一般分为 2~3 轮技术面 1 轮 HR 面&#xff0c;不过某些公司没有 HR 面试。 在技术面试中&#xff0c;面试官一般会就你所应聘的岗位进行相关知识的考察&#xff0c;也叫基础知识和业务逻辑面试&#xf…

tp6用redis存储session

随着业务量的增加&#xff0c;很多时候会需要共享session的情况。共享session&#xff0c;其实就是说多台服务器共用一个session&#xff0c;或者是说一个主域跟多个子域之间共用一个session。工作中用tp也多一些&#xff0c;那么&#xff0c;我就用tp6来给大家讲解一下。 在共…

PyCharm显示python文件的函数和类的列表 structure视图的使用与介绍

目录 打开structure视图structure视图的使用与介绍1.排序方式按字母升序or降序排列2. 是否显示有关联的函数和类&#xff08;一般不用激活&#xff09;3. 展示类中的字段4. 点击后是否定位到目标5. 自动定位到当前文件 总结 欢迎关注 『Python』 系列&#xff0c;持续更新中 欢…

redolog与binlog为什么需要两阶段提交?

MySQL事务提交的时候&#xff0c;需要同时完成redo log和binlog的提交&#xff0c;为了保证两个日志的一致性&#xff0c;需要用到两阶段提交&#xff08;与分布式的两阶段提交不同&#xff0c;这里的两阶段提交是发生在数据库内部&#xff09; 数据库两阶段提交的流程 假设执行…

【P59】JMeter 用表格查看结果(View Results in Table)

文章目录 一、用表格查看结果&#xff08;View Results in Table&#xff09;参数说明二、准备工作三、测试计划设计 一、用表格查看结果&#xff08;View Results in Table&#xff09;参数说明 可以将取样器请求以表格的方式分析展示 使用场景&#xff1a;一般在调试测试计…

深入理解相机服务层 CameraService

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、简介二、Camera AIDL 接口三、Camera Service 主程序 一、简介 Camera Service被设计成一个独立进程&#xff0c;作为一个服务端&#xff0c;处理来…

LIMS实验室信息管理系统源码 lims系统源码

一、LIMS概况 LIMS实验室管理系统是为实验、检测等业务板块提供流程化、模块化、标准化操作管理系统&#xff0c;打造基于行业法规的实验室全流程质量控制管理系统&#xff0c;实现实验室“人、机、料、法、环”关键环节管理。 二、技术框架说明 开发语言&#xff1a;C# 开…

是否需要更换CRM系统如何评估?如何确保更换成功?

很多企业在使用CRM客户管理系统的过程中&#xff0c;并没有达到预期的效果&#xff0c;甚至出现了实施失败的情况。部分企业可能会考虑更换CRM系统&#xff0c;以期获得更好的结果。但是&#xff0c;更换CRM系统是否值得呢&#xff1f;下面我们就来说说。 一、是否该更换CRM …

电容笔和触控笔两者的区别是什么?好用苹果电容笔推荐

如今&#xff0c;随着无纸化教育的兴起&#xff0c;电容笔也成为了人们关注的焦点。很多人对于电容笔和触控笔的区别很疑惑&#xff0c;其实&#xff0c;这两者是很好区分的&#xff0c;电容笔只能应用在我们最常用的电容屏上&#xff0c;例如我们的平板、手机屏幕等都是电容屏…

Redis 消息队列 Stream

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 &#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#…

电脑技巧:Windows微信3.9.5更新一览

目录 01、新增锁定功能 02、可直接撤回正在发送的消息 03、翻译多个网页 04、搜一搜新增历史记录 05、视频号页面再次优化 近期&#xff0c;Windows微信又更新至3.9.5版本&#xff0c;新增了许多实用的功能&#xff0c;以下将对这些新功能进行介绍。 官方更新内容&#x…

mybatis-plus用法(一)

MyBatis-plus 是一款 Mybatis 增强工具&#xff0c;用于简化开发&#xff0c;提高效率。下文使用缩写 mp来简化表示 MyBatis-plus&#xff0c;本文主要介绍 mp 整合 Spring Boot 的使用。 (5条消息) mybatis-plus用法&#xff08;二&#xff09;_渣娃工程师的博客-CSDN博客 1…

【K哥爬虫普法】一个人、一年半、挣了2000万!

我国目前并未出台专门针对网络爬虫技术的法律规范&#xff0c;但在司法实践中&#xff0c;相关判决已屡见不鲜&#xff0c;K 哥特设了“K哥爬虫普法”专栏&#xff0c;本栏目通过对真实案例的分析&#xff0c;旨在提高广大爬虫工程师的法律意识&#xff0c;知晓如何合法合规利用…

2023免费版电脑视频剪辑软件会声会影

提到视频剪辑软件&#xff0c;浮现在我们脑海的可能就是满屏的功能键和眼花缭乱的操作界面。类似pr、AE之类的视频软件&#xff0c;操作界面看起来十分复杂&#xff0c;很多用户上手困难。而会声会影界面简单&#xff0c;功能齐全&#xff0c;也能完成专业级的视频制作。操作简…

基于SSM+JSP的疫情居家办公OA系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

springboot+vue.js大学生竞赛报名作品评分管理系统

本文介绍了大学生竞赛管理系统的开发全过程。通过分析大学生竞赛管理系统管理的不足&#xff0c;创建了一个计算机管理大学生竞赛管理系统的方案。文章介绍了大学生竞赛管理系统的系统分析部分&#xff0c;包括可行性分析等&#xff0c;系统设计部分主要介绍了系统功能设计和数…