开发板芯片:STM32F407ZGT6

PA9-USART1_TX,PA10-USART1_RX;

PF9-LED0,PF10-LED1;

一、串口1配置过程(不使用串口中断):

1.使能时钟,包括GPIO时钟和串口1时钟使能,注意它们是挂载在不同的时钟总线上的。

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);    //使能端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能串口时钟

2.端口映射到串口1。

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);//端口映射到串口
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

3.GPIO初始化,注意配置模式时,要设置为复用模式,其他和GPIO基本配置相同

    IO_Init。GPIO_Mode = GPIO_Mode_AF;            //设置为复用模式
IO_Init。GPIO_OType = GPIO_OType_PP;
IO_Init。GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
IO_Init。GPIO_PuPd = GPIO_PuPd_UP;
IO_Init。GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &IO_Init);

4.串口1初始化,包括:波特率,发送接收使能,数据位,停止位,奇偶校验,硬件控制流

    UT_Init。USART_BaudRate = ;        //波特率
UT_Init。USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件控制流
UT_Init。USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送接收
UT_Init。USART_Parity = USART_Parity_No; //无奇偶校验
UT_Init。USART_StopBits = USART_StopBits_1; //停止位1
UT_Init。USART_WordLength = USART_WordLength_8b; //数据位8
USART_Init(USART1, &UT_Init);

5.串口1使能。

    USART_Cmd(USART1, ENABLE);            //串口使能

二、相关的函数和寄存器介绍

1、数据接收

1.1.状态寄存器

其中的位5:RXNE就是可以接收完成标志位,当数据接收完成时,RXNE会自动置1,我们可以通过读取该位的状态,来判断是否接收到数据,直接读取该位的方法是

  u8 Receive_Data = 0;

 Receive_Flag = USART1->SR &  << ;        //若接收到数据则标志位=1

上面的方法就是直接读取位5的值,接收完成则Receive_Flag=1。

其实我们更喜欢用一个函数来读取RXNE的状态:

USART_GetFlagStatus(USART1, USART_IT_RXNE)

该函数不仅可以读取RXNE的状态,还可以读取其他位的状态,若标志置1,该函数则会返回SET,即1。

我们可以看看该函数是如何实现的呢?

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_FLAG(USART_FLAG)); /* The CTS flag is not available for UART4 and UART5 */
if (USART_FLAG == USART_FLAG_CTS)
{
assert_param(IS_USART_1236_PERIPH(USARTx));
} if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}

可以看出该函数也是通过读取寄存器相应的位来返回相应的状态。

还有另一个函数和这个很相似:

USART_GetITStatus(USART1, USART_IT_RXNE);

这个函数也是读取RXNE的状态,不同的是当我们打开了串口中断,接收到数据时,这个函数才会返回1.

也就是说,无论串口中断是打开,接受完成后RXNE标志位都会置1,即USART_GetFlagStatus(USART1, USART_IT_RXNE)返回1,如果开启了中断,那么USART_GetFlagStatus(USART1, USART_IT_RXNE)和USART_GetITStatus(USART1, USART_IT_RXNE)都会置1。

当RXNE置1,即接收到数据后,我们要及时的读取接收到的数据,相应的函数是Receive_Data = USART_ReceiveData(USART1);

我们也可以直接读取USART1->DR寄存器,如Receive_Data = USART1->DR;

1.2.数据寄存器

当读取完成后,RXNE将自动清零,如果没有读取数据,则需要软件清零,可以使用函数USART_ClearFlag(USART1,USART_IT_RXNE);来进行手动清零,或通过将状态寄存器位5-RXNE置为0:USART1->SR &= ~(1 << 5);这一点是很重要的。

2.数据发送

将数据进行处理后,我们需要回复一些数据,我们可以通过函数USART_SendData(USART1,data);来向外发送数据,当然我们也可以像读取数据那样,将数据写入DR寄存器来实现 USART1->DR=data。其实我们更多的是通过重定向printf()函数来向外格式化输出数据,如printf("Receive Succsed: %d \r\n", Data);这个更方便一些。

三、程序实现

那么我们怎么来实现电脑发送0x01来控制LED反转呢?

1.串口配置函数

void USART1_Config()
{
GPIO_InitTypeDef IO_Init;
USART_InitTypeDef UT_Init; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能串口时钟 GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);//端口映射到串口
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); IO_Init.GPIO_Mode = GPIO_Mode_AF; //设置为复用模式
IO_Init.GPIO_OType = GPIO_OType_PP;
IO_Init.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
IO_Init.GPIO_PuPd = GPIO_PuPd_UP;
IO_Init.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &IO_Init); UT_Init.USART_BaudRate = ; //波特率
UT_Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件控制流
UT_Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送接收
UT_Init.USART_Parity = USART_Parity_No; //无奇偶校验
UT_Init.USART_StopBits = USART_StopBits_1; //停止位1
UT_Init.USART_WordLength = USART_WordLength_8b; //数据位8
USART_Init(USART1, &UT_Init); USART_Cmd(USART1, ENABLE); //串口使能
}

2.主函数

主函数怎么写呢?其实很简单,就是对接收的数据进行一下判断就OK了,如果接收到的数据==0x01,那么LED=!LED,是不是很简单呢?

int main(void)
{
LED_Init();
delay_init();
USART1_Config();
LED0_OFF;
LED1_OFF;
while()
{
u8 Receive_Data = ;
if(USART_GetITStatus(USART1, USART_IT_RXNE)) //若接收到数据
{
Receive_Data = USART_ReceiveData(USART1); //读取数据后,RXNE标志位自动清零;
printf("Receive Succsed: %2x \r\n", Receive_Data);
if(Receive_Data == 0x01)
LED0 = !LED0;
// USART_ClearFlag(USART1,USART_IT_RXNE); //手动清零
}
else
{
LED1 = !LED1;
printf("Running....\r\n");
delay_ms();
}
}
}

这里使用了串口发送“Running....”和LED1闪烁来指示程序正在运行,这种方法很常用,可以指示程序的运行状态。

本文章没有使用串口中断来进行控制,下一篇文章将会介绍如何使用串口中断来控制LED。

参考资料:

STM32F4xx中文参考手册

STM32F4开发指南-库函数版本_V1.1

USART_百度百科

以上是我学习过程的一些个人理解,有不对或不准确的地方,欢迎各位大神指正。

2017年4月16日21:58:46

欢迎大家关注我的个人博客 http://www.wangchaochao.top/
微信扫码关注我的公众号

不定期更新个人学习笔记和技术总结,欢迎大家互相学习交流!

STM32学习笔记(二)——串口控制LED的更多相关文章

  1. stm32学习笔记----双串口同时打开时的printf()问题

    stm32学习笔记----双串口同时打开时的printf()问题 最近因为要使用串口2外接PN532芯片实现通信,另一方面,要使用串口1来将一些提示信息输出到上位机,于是重定义了printf(),使其 ...

  2. STM32学习笔记(二) 基于STM32-GPIO的流水灯实现

    学会了如何新建一个工程模板,下面就要开始动手实践了.像c/c++中经典的入门代码"hello world"一样,流水灯作为最简单的硬件设备在单片机领域也是入门首推.如果你已经有了一 ...

  3. stm32学习笔记之串口通信

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

  4. STM32学习笔记——USART串口

    转载自:http://www.cnblogs.com/microxiami/p/3752715.html 一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异 ...

  5. STM32学习笔记——USART串口(向原子哥和火哥学习)

    一.USART简介 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的波特率选择. S ...

  6. Arduino学习笔记二:修改LED点灯程序

    看了开源社区的LED控制程序,开始上手代码编写,修改,下载以及调试,原文地址:http://www.arduino.cn/thread-1072-1-1.html,这个帖子写的比较通俗易懂. 自己移植 ...

  7. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

  8. STM32学习笔记——点亮LED

    STM32学习笔记——点亮LED 本人学习STM32是直接通过操作stm32的寄存器,使用的开发板是野火ISO-V2版本: 先简单的介绍一下stm32的GPIO: stm32的GPIO有多种模式: 1 ...

  9. stm32学习笔记——外部中断的使用

    stm32学习笔记——外部中断的使用 基本概念 stm32中,每一个GPIO都可以触发一个外部中断,但是,GPIO的中断是以组为一个单位的,同组间的外部中断同一时间只能使用一个.比如说,PA0,PB0 ...

  10. STM32学习笔记——OLED屏

    STM32学习笔记--OLED屏 OLED屏的特点: 1.  模块有单色和双色可选,单色为纯蓝色,双色为黄蓝双色(本人选用双色): 2.  显示尺寸为0.96寸 3.  分辨率为128*64 4.   ...

随机推荐

  1. Linux进程管理详解

    何谓进程?进程,就是正在执行的一个程序或命令,每一个进程都是一个运行实体,有自己的地址空间,并占用一定的系统资源.简而言之,进程就是运行中的程序.在Linux中,诸如ls等命令都是进程,只不过某些命令 ...

  2. 使用python操作InfluxDB

    环境: CentOS6.5_x64InfluxDB版本:1.1.0Python版本 : 2.6 准备工作 启动服务器 执行如下命令: service influxdb start 示例如下: [roo ...

  3. mysql命令[转]

    来自:http://www.cnblogs.com/zhangzhu/archive/2013/07/04/3172486.html 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录my ...

  4. Spring还使用基于 JSR-250 注释,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释

    @PostConstruct 和 @PreDestroy 注释: 你可以使用 @PostConstruct 注释作为初始化回调函数的一个替代,@PreDestroy 注释作为销毁回调函数的一个替代,其 ...

  5. Python--定时给Ta讲笑话

    受到这篇文章的启发http://python.jobbole.com/84796/,我也动手写了个程序玩一玩. 接口请求说明: 接口请求地址http://api.1-blog.com/biz/bizs ...

  6. JavaWeb之Listener监听器

    监听在Java体系中运用的很广泛,在安卓开发.JavaWeb开发中到处存在,在其他语言也有类似的,如果有了解过设计模式那很容易理解实现的原理.不过对于开发者来说,使用观察者模式只需实现相应的接口就好, ...

  7. 因为本地没有配置 localhost 导致的 eclipse 的奇葩问题

    因为电脑没有配置 127.0.0.1 localhost,已经碰到两次奇葩问题了. 问题一: 我的博文http://www.cnblogs.com/sonofelice/p/5143746.html中 ...

  8. Json 与GeoJson

    1.JSON介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后 ...

  9. [SQL] SQL 基础知识梳理(七)- 集合运算

    SQL 基础知识梳理(七)- 集合运算 目录 表的加减法 联结(以列为单位) 一.表的加减法 1.集合:记录的集合(表.视图和查询的执行结果). 2.UNION(并集):表的加法 -- DDL:创建表 ...

  10. JS停止事件冒泡

    ..停止事件冒泡 JavaScript代码 //如果提供了事件对象,则这是一个非IE浏览器 if ( e && e.stopPropagation ) //因此它支持W3C的stopP ...