在基础实验成功的基础上,对串口的调试方法进行实践。硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中。

  b) 初始化函数定义:

  void USART_Configuration(void); //定义串口初始化函数

  c) 初始化函数调用:

  void UART_Configuration(void); //串口初始化函数调用

  初始化代码:

  void USART_Configuration(void) //串口初始化函数

  {

  //串口参数初始化

  USART_InitTypeDef USART_InitStructure; //串口设置恢复默认参数

  //初始化参数设置

  USART_InitStructure.USART_BaudRate = 9600; //波特率9600

  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;//打开Rx接收和Tx发送功能

  USART_Init(USART1, &USART_InitStructure); //初始化

  USART_Cmd(USART1, ENABLE); //启动串口

  }

  RCC中打开相应串口

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);

  GPIO里面设定相应串口管脚模式

  //串口1的管脚初始化

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //管脚9

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

  GPIO_Init(GPIOA, &GPIO_InitStructure); //TX初始化

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //管脚10

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入

  GPIO_Init(GPIOA, &GPIO_InitStructure); //RX初始化

  d) 简单应用:

  发送一位字符

  USART_SendData(USART1, 数据); //发送一位数据

  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待发送完毕

  接收一位字符

  while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){} //等待接收完毕

  变量= (USART_ReceiveData(USART1)); //接受一个字节

  发送一个字符串

  先定义字符串:char rx_data[250];

  然后在需要发送的地方添加如下代码

  int i; //定义循环变量

  while(rx_data!='\0') //循环逐字输出,到结束字'\0'

  {USART_SendData(USART1, rx_data); //发送字符

  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待字符发送完毕

  i++;}

  e) USART注意事项:

  发动和接受都需要配合标志等待。

  只能对一个字节操作,对字符串等大量数据操作需要写函数

  使用串口所需设置:RCC初始化里面打开RCC_APB2PeriphClockCmd

  (RCC_APB2Periph_USARTx);GPIO里面管脚设定:串口RX(50Hz,IN_FLOATING);串口TX(50Hz,AF_PP);

  f) printf函数重定义(不必理解,调试通过以备后用)

  (1) 需要c标准函数:

  #include "stdio.h"

  (2) 粘贴函数定义代码

  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) //定义为putchar应用

  (3) RCC中打开相应串口

  (4) GPIO里面设定相应串口管脚模式

  (6) 增加为putchar函数。

  int putchar(int c) //putchar函数

  {

  if (c == '\n'){putchar('\r');} //将printf的\n变成\r

  USART_SendData(USART1, c); //发送字符

  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待发送结束

  return c; //返回值

  }

  (8) 通过,试验成功。printf使用变量输出:%c字符,%d整数,%f浮点数,%s字符串,/n或/r为换行。注意:只能用于main.c中。

  3、 NVIC串口中断的应用

  a) 目的:利用前面调通的硬件基础,和几个函数的代码,进行串口的中断输入练习。因为在实际应用中,不使用中断进行的输入是效率非常低的,这种用法很少见,大部分串口的输入都离不开中断。

  b) 初始化函数定义及函数调用:不用添加和调用初始化函数,在指定调试地址的时候已经调用过,在那个NVIC_Configuration里面添加相应开中断代码就行了。

  c) 过程:

  i. 在串口初始化中USART_Cmd之前加入中断设置:

  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//TXE发送中断,TC传输完成中断,RXNE接收中断,PE奇偶错误中断,可以是多个。

  ii. RCC、GPIO里面打开串口相应的基本时钟、管脚设置

  iii. NVIC里面加入串口中断打开代码:

  NVIC_InitTypeDef NVIC_InitStructure;//中断默认参数

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;//通道设置为串口1中断

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断占先等级0

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级0

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断

  NVIC_Init(&NVIC_InitStructure); //初始化

  iv. 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。

  void USART1_IRQHandler(void) //串口1中断

  {

  char RX_dat; //定义字符变量

  if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断发生接收中断

  {USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志

  GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)0x01); //开始传输

  RX_dat=USART_ReceiveData(USART1) & 0x7F; //接收数据,整理除去前两位

  USART_SendData(USART1, RX_dat); //发送数据

  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}//等待发送结束

  }

  }

  d) 中断注意事项:

  可以随时在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);来关闭中断响应。

  NVIC_InitTypeDef NVIC_InitStructure定义一定要加在NVIC初始化模块的第一句。

  全局变量与函数的定义:在任意.c文件中定义的变量或函数,在其它.c文件中使用extern+定义代码再次定义就可以直接调用了。

  STM32笔记之九:打断它来为我办事,EXIT (外部I/O中断)应用

  a) 目的:跟串口输入类似,不使用中断进行的IO输入效率也很低,而且可以通过EXTI插入按钮事件,本节联系EXTI中断。

  b) 初始化函数定义:

  void EXTI_Configuration(void); //定义IO中断初始化函数

  c) 初始化函数调用:

  EXTI_Configuration();//IO中断初始化函数调用简单应用:

  d) 初始化函数:

  void EXTI_Configuration(void)

  { EXTI_InitTypeDef EXTI_InitStructure; //EXTI初始化结构定义

  EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中断标志

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管脚选择

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式

  EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //线路选择

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//启动中断

  EXTI_Init(&EXTI_InitStructure);//初始化

  }

  e) RCC初始化函数中开启I/O时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

  GPIO初始化函数中定义输入I/O管脚。

  //IO输入,GPIOA的4脚输入

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入

  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化

  f) 在NVIC的初始化函数里面增加以下代码打开相关中断:

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //通道

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先级

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应级

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动

  NVIC_Init(&NVIC_InitStructure); //初始化

  g) 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。

  if(EXTI_GetITStatus(EXTI_Line3) != RESET) //判断中断发生来源

  { EXTI_ClearITPendingBit(EXTI_Line3); //清除中断标志

  USART_SendData(USART1, 0x41); //发送字符“a”

  GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED发生明暗交替

  }

  h) 中断注意事项:

  中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。

  使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码。

  -----------------------------------------------------------------------------------

  补充

  上边的不足之处就是无法发送char类型数据,是u16类型的,会报错

  后续可以更换为3.5的固件库,

  d) 简单应用中

  超级简单应用只可以发送u16类型数据

  下面发送char数组时,

  “{USART_SendData(USART1, rx_data);、、” 中rx_data需要改为

  rx_data[i]才可以,不然就会报错数据类型不匹配,

  最后还是给在学的朋友分享一些stm32方面的资料

  (stm32 USART串口应用)

  http://www.makeru.com.cn/live/1392_1164.html?s=45051

  PWM脉宽调制技术

  http://www.makeru.com.cn/live/4034_2146.html?s=45051

  基于STM32讲解串口操作

  http://www.makeru.com.cn/live/1758_490.html?s=45051

  通过Z-stack协议栈实现串口透传

  http://www.makeru.com.cn/live/1758_330.html?s=45051

  (stm32直流电机驱动)

  http://www.makeru.com.cn/live/1392_1218.html?s=45051

  通信协议 - UART串口协议

  http://www.makeru.com.cn/live/3576_1437.html?s=45051

  stm32之SPI通信

  http://www.makeru.com.cn/live/3523_1795.html?s=45051

  SPI通信协议驱动norFlash

  http://www.makeru.com.cn/live/4034_2151.html?s=45051

stm32中的串口通信你了解多少的更多相关文章

  1. 在C#中实现串口通信的方法

    通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围.可以访问h ...

  2. c#中实现串口通信的几种方法

    c#中实现串口通信的几种方法 通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册 ...

  3. 嵌入式02 STM32 实验07 串口通信

    STM32串口通信(F1系列包含3个USART和2个UART) 一.单片机与PC机串行通信研究目的和意义: 单片机自诞生以来以其性能稳定,价格低廉.功能强大.在智能仪器.工业装备以及日用电子消费产品中 ...

  4. C#中的串口通信

    关于串行接口 串行接口(Serial port)又称“串口”,主要用于串行式逐位数据传输.常见的有一般电脑应用的RS-232(使用 25 针或 9 针连接器)和工业电脑应用的半双工RS-485与全双工 ...

  5. C#中显现串口通信SerialPort类

    SerialPort类的常用属性 名 称 说 明 BaseStream 获取 SerialPort 对象的基础 Stream 对象 BaudRate 获取或设置串行波特率 BreakState 获取或 ...

  6. stm32 hal库串口通信资料汇集

    串口的发送接收函数:HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制.HAL_UART_Receive();串口轮询模式发送,使用超时管理机制.HAL_UART_Transm ...

  7. (三)stm32之串口通信DMA传输完成中断

    一.DMA功能简介 首先唠叨一下DMA的基本概念,DMA的出现大大减轻了CPU的工作量.在硬件系统中,主要由CPU(内核).外设.内存(SRAM).总线等结构组成,数据经常要在内存和外设之间,外设和外 ...

  8. stm32与三菱PLC通信

    一.三菱PLC通讯概要   三菱PLC FX系列通信结构如下图所示: 三菱PLC FX系列的通信规格如下图所示: 三菱PLC FX系列一般有以下几种通信模块,以FX2N为例: FX2N-232-BD ...

  9. 创建C#串口通信程序详解

    在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports.这个新的框架不但可以访问计算机上的串口,还可以和串口设备进行通信.我们将使用标准 ...

随机推荐

  1. Lambda表达式——注重过程的编程思想

    一.使用匿名内部类的匿名对象创建线程和Lambda表达式写法 Lambda表达式写法不用去定义一个Runable接口的实现类: 二.方法入参是一个接口或者接口的实现类 三.对某个类的一些对象实例进行排 ...

  2. Spring Boot中使用@Async实现异步调用,加速任务的执行!

    什么是"异步调用"?"异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行 ...

  3. 开源自己编写的半人工标注平台PaddleOCRLabel(.NET Winform版本)

    大家好, 我是博客园的老用户了,许久不做.NET技术了,从2013年起,开始从事App技术,写过书,在Linux上搭建区块链,用GO写智能合约,使用nodejs搭建过微服务,用python写过爬虫,写 ...

  4. python模块--collections(容器数据类型)

    Counter类(dict的子类, 计数器) 方法 返回值类型 说明 __init__ Counter 传入可迭代对象, 会对对象中的值进行计数, 值为键, 计数为值 .elements() 迭代器 ...

  5. EL-ADMIN学习笔记

    一,支持接口限流,避免恶意请求导致服务层压力过大 常见的限流功能一般有两个关注点: 1.限流原则,即以什么样的条件对请求进行识别以及放行.常见的作法是给予每个调用API的系统不同的唯一编码,用于监控某 ...

  6. Gotop安装

    一个方便的图形面板 Github:https://github.com/cjbassi/gotop 安装 git clone --depth 1 https://github.com/cjbassi/ ...

  7. Java Web下MySQL数据库的增删改查(二)

    前文:https://www.cnblogs.com/Arisf/p/14095002.html 在之前图书管理系统上做了改进优化 图书管理系统v2 首先是项目结构: 1.数据库的连接: 1 pack ...

  8. 【原创】【长期更新】【未完待续】自制vector类型

    继<自制string类型>以来的第二篇自制类型的文章.马上要开学了,时间也不多了,争取在今年写完吧. 目录 一,vector类型简单介绍 1.简介 1.1.STL 1.2.vector 2 ...

  9. Django学习day08随堂笔记

    今日考题 """ 今日考题 1.聚合查询,分组查询的关键字各是什么,各有什么特点或者注意事项 2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他用法 3.列举常 ...

  10. 一起搞懂PHP的错误和异常(三)

    关于错误与异常的最后一篇文章,我们来进行一些总结. PHP中错误和异常的区别 通过前面两篇文章的学习,我们来直接将错误和异常摆上来进行对比,看看他们的区别与联系: 错误的出现通常是语法或编译运行时错误 ...