第一次深入学习stm32,花了好长时间才看懂代码(主要是C语言学习不够深入),又花了段时间自己敲了一遍,然后比对教程,了解了利用中断来串口通信的设置方法。

板子是探索版f407,本实验工程把正点原子库函数工程模版拿来使用,自己主要敲了一下main.c、usart.h和.c文件。

一、头文件usart.h

 #ifndef __USART_H      //定义同时防止重复定义
#define __USART_H #include "stdio.h"
#include "stm32f4xx_conf.h"
#include "sys.h" #define USART_REC_LEN 200 //最大接收字节数
#define EN_USART1_RX 1 //(1)使能串口接收 /*extern外部声明引用这个变量,在.c文件寻找。*/
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大字节为USART_REC_LEN,末字符为换行符
extern u16 USART_RX_STA; //接收状态标记
void uart_init(u32 bound); //.c文件里面的函数声明 #endif

头文件主要是其他文件需要用到的一些参数()的宏定义及声明,加.c文件的函数

二、usart.c文件

1、所需要的头文件

2、定义参数并且使能串口接收

3、uart_init(u32 bound) //主函数调用设置波特率

参数结构:GPIO/USART/NVIC.InitSturcture

a,使能GPIOA和USART1时钟,它们分别挂在在AHB1和APB2。

b,GPIOA的PA9和PA10复用为USART1。

c,串口1复用对应的IO口设置

d,串口1初始化设置(波特率、字长、停止位、奇偶、硬件流、模式)

e,使能串口1USART_Cmd(x,x)

f,宏定义

  #if 条件

  USART_ITConfig(         )开启中断

  设置中断通道、优先级、子优先级、IRQ使能

  初始化NVIC_Init(   )

4、串口1中断服务函数(当一个字节数据接收到,会触发中断,该函数处理中断)

USART_IRQHandler()

参数USART_RX_STA是上一次累计的字节接收量,Res是这一次接收的一个字节数据

 #include "sys.h"
#include "usart.h" //加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
}; FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif #if EN_USART1_RX
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大字节为USART_REC_LEN,末字符为换行符
u16 USART_RX_STA=; //接收状态标记初始化为0 void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//使能gpioa的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);//复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);//复用为USART1 //串口1复用对应的
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;//复用推挽
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化 USART_InitStructure.USART_BaudRate=bound;//设置波特率
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位
USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//发送接收模式
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件流控制
USART_Init(USART1, &USART_InitStructure);//初始化串口 USART_Cmd(USART1,ENABLE);//使能串口1 #if EN_USART1_RX //开启串口接收相关的中断
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口1中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=; NVIC_Init(&NVIC_InitStructure); #endif } /*串口1中断服务函数,接收到一个数据就产生一次中断,当接收到两次数据为0X0D和OXOA时,
USART_RX_STA最高位置1,此时main函数while循环执行。*/ void USART1_IRQHandler(void)
{
u8 Res;
if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//接收中断
{
Res=USART_ReceiveData(USART1);
if((USART_RX_STA&0x8000)==)
{
if(USART_RX_STA&0x4000)
{
if(Res==0x0a)
{
USART_RX_STA|=0x8000;//将bit15位置1,此时main函数while循环里面的判断生效。
}
else
{
USART_RX_STA=;//上一次标志位bit14置1,此次数据不为0x0a,说明输入错误,只有整段数据末尾为0x0d,0x0a数据才有效。
}
}
else
{
if(Res==0x0d)
{
USART_RX_STA|=0x4000;}//这次数据为0x0d,将bit14位置1。
else
{
USART_RX_STA++;
USART_RX_BUF[USART_RX_STA]=Res; if(USART_RX_STA >USART_REC_LEN-) //如果接收到的长度大于规定的长度,说明发送错误,状态清零。
USART_RX_STA=;
}
}
}
}
}
#endif

三、main.c

头文件

定义参数t,len(发送长度),times(时间参数)

设置系统中断优先级分组2

初始化延时、串口(波特率)

while(1)

{

  if判断USART_RX_STA的Bit15位是否 为1,若是意味发送完成。

    {

      数据长度赋给len

        for(0;t<len,t++)

        {

          将USART_RX_BUF[t]数组一个个通过串口1发送回数据

          whilewhile(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);一直轮询,直到当前数据发送完

        }

        当所有数据发送完成后,USART_RX_STA置0

    }

  else

  打印提示内容

}

 #include"stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include "sys.h" int main()
{
u8 t;
u8 len=;
u16 times;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组2
delay_init();
uart_init(); while()
{ if(USART_RX_STA&0x8000)
{
printf("\r\n您打印的消息为:\r\n");
len = USART_RX_STA&0x3fff; //接收到此次接收到的数据长度
for(t=;t<len;t++)
{
USART_SendData(USART1,USART_RX_BUF[t]); //将单片机接收到的数据发送回电脑
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); //获取发送的状态,轮询直到这一条数据发送成功
}
printf("\r\n\r\n"); //插入换行
USART_RX_STA =;
}
else
{
times++;
if(times%==)
{
printf("\r\nALIENTEK 探索者STM32F407开发板 串口实验\r\n");
}
if(times%==)printf("请输入数据,以回车键结束\r\n");
delay_ms();
}
}
}

其中

USART_GetFlagStatus(main.c用到)和USART_GetITStatus(usart.c用到),敲代码容易弄混,

USART_GetFlagStatus是在没有使能相应的中断函数时,通常使用该函数来判断标志位是否置位。

USART_GetITStatus则相反,参考关于STM32的USART_GetFlagStatus和USART_GetITStatus解析(异步通信) - CSDN博客

stm32串口通信实验,一点笔记的更多相关文章

  1. STM32F407 串口通信实验 视频第27节 个人笔记

    前言 第26节也是串口,笔记链接在此:https://www.cnblogs.com/YuQiao0303/p/10019362.html github地址:https://github.com/Yu ...

  2. STM32串口通信UART使用

    STM32串口通信UART使用 uart使用的过程为: 1. 使能GPIO口和UART对应的总线时钟 2. 配置GPIO口的输出模式 3. 配置uart口相关的基本信息 4. 使能uart口的相关的中 ...

  3. Stm32串口通信(USART)

    Stm32串口通信(UART) 串口通信的分类 串口通信三种传递方式 串口通信的通信方式 串行通信的方式: 异步通信:它用一个起始位表示字符的开始,用停止位表示字符的结束.其每帧的格式如下: 在一帧格 ...

  4. STM32 串口通信使用奇偶校验

    STM32串口通信如果使用奇偶校验,需要设置数据位长度为9bit USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USAR ...

  5. STM32F407 串口通信实验 第26节 个人笔记

    前言 这篇笔记对应正点原子STM32F407探索者 ,教学视频第26节,网址如下: https://ke.qq.com/webcourse/index.html#cid=279403&term ...

  6. 【GMT43智能液晶模块】例程二:串口通信实验

    实验原理: GMT43智能液晶模块的串口包括USB_UART(CH340),TTL,RS-232,RS-485/ RS-422等四部分,USB_UART部分通过CH340芯片与STM32F429的US ...

  7. STM32串口通信配置(USART1+USART2+USART3+UART4) (转)

    一.串口一的配置(初始化+中断配置+中断接收函数) 1 /*====================================================================== ...

  8. STM32串口通信USART1转USART2问题解决

    使用的是STM32f103ZET6. 1.把文件main.c和usart.c中的所有usart1换成usart2 2.查看手册得知USART2的引脚是Tx->PA2,Rx->PA3,改变u ...

  9. STM32串口IAP实验笔记

    STM32的IAP功能确实方便,以前对此如何实现有所了解,但是一直没去测试,这两天来练了下,可谓困难重重,搞了两天问题也一一解决,下面做些简要的笔记 IAP就是在线应用编程,方便程序升级,可以不用打开 ...

随机推荐

  1. 一些baidu面经

    百度问的一些问题供参考: 1. epoll 和 select,epoll 两种模式,阻塞非阻塞: 2. 两个严格递增链表找出相同的元素组成新的链表: ref1   ref 3. 网络传输中如何传送一个 ...

  2. Intel酷睿前世今生(一)

    Intel酷睿系列自诞生起就树立了桌面CPU霸主的地位,酷睿i系列更是无人能敌.它是Intel阻击AMD多核构架的救赎主,也是AMD复兴梦想的收割者.而Intel酷睿系列已经经历几代了,不知还有多少看 ...

  3. iOS设计模式 - 原型

    iOS设计模式 - 原型 原理图 说明 1. 原型模式指的是从一个已有的对象复制并创建出新的对象 2. 当一个类的实例之间存在差异,而这些差异仅是状态的若干组合,复制原型要比手工实例化更加方便 3. ...

  4. listview的pushBackDefaultItem中的item属性被修改问题

    time:2015/05/04 1. 描述 在cocostudio中有两个控件,一个listview,另外一个是隐藏的imageview,其中后者作为listview的元素.每次使用的时候把Image ...

  5. [Tyvj 模拟赛] 运

    运 [问题背景] zhx和妹子们玩数数游戏. [问题描述] 仅包含4或7的数被称为幸运数. 一个序列的子序列被定义为从序列中删去若干个数,剩下的数组成的新序列.两个子序列被定义为不同的当且仅当其中的元 ...

  6. lisp base

    一 .quote lisp 使用s-expr表示数据和代码,通常会将第一项作为函数,而将后续元素当做参数传给第一项进行计算.可以通过quote来进行其他解析,quote可用(‘)表示: ( + 1 1 ...

  7. OS开发小记:iOS富文本框架DTCoreText在UITableView上的使用

    要在页面中显示自己的布局,比如文字的字体和颜色.图文并排的样式,我们要用iOS SDK的原生UI在app本地搭建,如果一个页面需要在服务器端获取数据的话,我们也要在本地搭建好固定的布局,解析服务器传回 ...

  8. Django的视图流式响应机制

    Django的视图流式响应机制 Django的响应类型:一次性响应和流式响应. 一次性响应,顾名思义,将响应内容一次性反馈给用户.HttpResponse类及子类和JsonResponse类属于一次性 ...

  9. Linux 问题处理集锦

    安装nginx,编译过程中遇到的问题 wget command not found yum -y install wget c compiler cc is not found yum -y inst ...

  10. virtualbox+vagrant学习-4-Vagrantfile-7-WinRM Settings

    WinRM Settings 配置命名空间config.winrm config.winrm配置与如何通过winrm配置vagrant访问你的Windows客户相关.与大多数vagrant设置一样,默 ...