jjzjj

stm32f1串口发送与接收

朴实妲己 2023-06-21 原文

目录

串口配置

串口发送

1使用SendString函数发送

2使用printf函数发送

​串口接收


 串口配置

首先对串口进行初始化

包括使能串口时钟,这里我使用的是usart2,使能GPIO时钟,这里我用的是A口,以及GPIO口的配置,这里我的串口输出是PA2,输入是PA3

然后初始化usart2,再使能usart2,具体代码如下:

/* 串口初始化 */

void STM_EVAL_COMInit(USART_InitTypeDef* USART_InitStruct)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIOA使能

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);USART2时钟使能

  /* Configure USART Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//输出PA2
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure USART Rx as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//输入PA3
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* USART configuration */
  USART_Init(USART2, USART_InitStruct);//USART2初始化
    
  /* Enable USART */
  USART_Cmd(USART2, ENABLE);//使能USART2
}

之后需要配置串口的参数

参数包括波特率,数据位个数,是否有校验位等

void USART2_Init (void)
{
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	USART_InitStructure.USART_BaudRate = 115200;                  //波特率
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //数据位个数=8
  USART_InitStructure.USART_StopBits = USART_StopBits_1;        //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;

  STM_EVAL_COMInit(&USART_InitStructure);
	
	
//数据接收的使能中断
  /* Enable the USARTz Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//为USART2
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
	
  /* Enable the USARTz Receive Interrupt */
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//
}

为了保证串口随时都能接收数据,需要开启中断

串口发送

串口发送是指,将stm32的数据发送给上位机(串口助手)

1使用SendString函数发送

在.c文件里面定义SendString函数

对应USART数据发送有两个标志, 一个是TXE=发送数据寄存器空,另一个是TC=发送结束

void SendString (char *s)
{
	while(*s)
	{
		USART_SendData(USART2, *s++);//依次发送

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)//TC标志位为reset发送结束
  {}
	}
}

在发送数据时出现第一个字符打印不出来的情况,例如发送“hello”,串口助手只接收到了“ello”,没有h

这是因为stm32的usart的sr寄存器的TC初始为1,导致第一次while时第一个数据被覆盖

这种情况,将TC修改为TXE即可

void SendString (char *s)
{
	while(*s)
	{
		USART_SendData(USART2, *s++);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  {}
	}
}

在main.c文件里面调用SendString函数

USART2_Init();//打开串口
SendString("字符串");

2使用printf函数发送

在使用printf函数之前需要先勾选微库

在.c文件里面定义printf函数 ,代码如下

int fputc(int ch, FILE *f)
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART2, (uint8_t) ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  {}

  return ch;
}

 在main.c文件里面调用printf函数

USART2_Init();
 printf(" ", ); 

关于printf函数的使用方法可以参考下面的表格:

串口接收

串口接收是指,将上位机(串口助手)的数据发送给stm32,由stm32进行接收

 USART_IT_RXNE为接收中断标志位,一旦接收数据,USART_IT_RXNE会置位

u8 RxCounter = 0;//定义计数值
u8	RxBuffer2[10];//定义缓冲区为10

void USART2_IRQHandler(void)
{
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//串口接收中断
  {
    USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除标志位
		/* Read one byte from the receive data register */
		
    RxBuffer2[RxCounter++] = USART_ReceiveData(USART2);
		
		
		if(RxCounter>6)//定义接收的字节个数
		{
			RxCounter=0;
		}
}	
}

首先构建缓冲区和计数器

串口接收中断之后,清除 USART_IT_RXNE中断接收标志位,将串口接收到的数据存入缓冲区

可以通过debug里面的watch来看缓冲区数据是否正确

有关stm32f1串口发送与接收的更多相关文章

  1. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  2. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  3. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  4. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  5. ruby - 如何理解 Ruby 中的发送者和接收者? - 2

    我很难理解Ruby中sender和receiver的实际含义。它们一般是什么意思?到目前为止,我只是将它们理解为方法调用和获取其返回值的调用。但是,我知道我的理解还远远不够。谁能给我一个Ruby中发送者和接收者的具体解释? 最佳答案 面向对象中的一个核心概念是消息传递和早期概念化,这在很大程度上借鉴了计算的Actor模型。艾伦·凯(AlanKay)创造了面向对象一词并发明了最早的OO语言之一SmallTalk,他拥有voicedregretatusingatermwhichputthefocusonobjectsinsteadofo

  6. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  7. ruby - 接收 block 作为参数的模拟方法 - 2

    我有一个或多或少这样的场景classAdefinitialize(&block)b=B.new(&block)endend我正在对A类进行单元测试,我想知道B#new是否正在接收传递给A#new的block。我使用Mocha作为模拟框架。这可能吗? 最佳答案 我用Mocha和RSpec都试过了,虽然我可以通过测试,但行为不正确。从我的实验中,我得出结论,验证block是否已通过是不可能的。问题:为什么要传递一个block作为参数?block将用于什么目的?什么时候调用?也许这确实是您应该用类似的东西测试的行为:classBlockP

  8. 1个串口用1根线实现多机半双工通信+开机控制电路 - 2

    功能需求:主机使用一个串口,与两个从机进行双向通信,主机向从机发送数据,从机能够返回数据,由于结构限制,主机与从机之间只有3根线(电源、地、数据线),并且从机上没有设物理的电源开关,需要通过与主机连接的数据线来控制开机,总结如下:1、数据线只有1根2、能够双向通信3、主机能够控制从机开机4、主机可以单独向1个从机发数据,也可以同时向两个从机发送数据根据需求,设计出如下电路:工作原理分析:VCC_24V_IN、GND、LINE_L(LINE_R)三根线接线连接到从机,电源开启电路是从机内部的电源控制。开机的逻辑:*主机先上电,LINE_L因为主机的R1上拉而有高电平,使Q6导通,Q5的G极电压被

  9. ESP32学习入门:WiFi连接网络 - 2

    目录一、ESP32简单介绍二、ESP32Wi-Fi模块介绍三、ESP32Wi-Fi编程模型四、ESP32Wi-Fi事件处理流程 五、ESP32Wi-Fi开发环境六、ESP32Wi-Fi具体代码七、ESP32Wi-Fi代码解读6.1主程序app_main7.2自定义代码wifi_init_sta()八、ESP32Wi-Fi连接验证8.1测试方法8.2服务器模拟工具sscom58.3测试代码8.4测试结果前言为了开发一款亚马逊物联网产品,开始入手ESP32模块。为了能够记录自己的学习过程,特记录如下操作过程。一、ESP32简单介绍ESP32是一套Wi-Fi(2.4GHz)和蓝牙(4.2)双模解决方

  10. Spring Security 6.0系列【32】授权服务器篇之默认过滤器 - 2

    有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N

随机推荐