用UART写了一段Bootloader代码,遇到了一个很奇怪的现象。

代码如下:简单介绍一下就是先统一配置MCU的IO端口,然后配置串口参数,然后循环发送‘0’和'\r’。16进制是0x30 0x0d

int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
RCC_HSE_Configuration();//外部高速时钟初始化
SysTick_Init();
IO_Init();//初始化板子端口
Uart_Init(115200);//初始化串口 while (1)/* Infinite loop */
{
UART_SendByte( '0');
UART_SendByte('\r');
Delay(1000);
}
} void IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置 USART1 Tx (PA.09) 作为功能引脚并上拉输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_9); //配置 USART1 Tx (PA.10) 作为功能引脚并是浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
} void Uart_Init(uint32_t Baud)
{
USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitStructure.USART_BaudRate = Baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_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; USART_Init(USART1, &USART_InitStructure);
// USART_ClearFlag(USART1, USART_FLAG_TC);
USART_Cmd(USART1,ENABLE);
}

结果下载完程序,运行后发送出来的第一字节是0x3f 然后才正常的0x30 0x0d,感觉很奇怪,花时间去测试。

尝试一:把串口的两个端口配置放在串口配置函数里,如下

void Uart_Init(uint32_t Baud)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 配置 USART1 Tx (PA.09) 作为功能引脚并上拉输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //配置 USART1 Tx (PA.10) 作为功能引脚并是浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = Baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_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; USART_Init(USART1, &USART_InitStructure);
// USART_ClearFlag(USART1, USART_FLAG_TC);
USART_Cmd(USART1,ENABLE);
}

这样就正常了,上电就收到0x30 0x0d

尝试二:这样修改,把串口外设时钟在端口配置函数里面就打开。

void IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//这里提前打开串口外设时钟 // 配置 USART1 Tx (PA.09) 作为功能引脚并上拉输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_9); //配置 USART1 Tx (PA.10) 作为功能引脚并是浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
} 

也是可以正常输出0x30 0x0d

总结:stm32的外设时钟应该在此外设端口配置之前打开。

stm32f103c8串口USART1发送多一字节的更多相关文章

  1. STM32串口USART1的使用方法和程序

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

  2. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十二:串口模块① — 发送

    实验十二:串口模块① — 发送 串口固然是典型的实验,想必许多同学已经作烂,不过笔者还要循例介绍一下.我们知道串口有发送与接收之分,实验十二的实验目的就是实现串口发送,然而不同的是 ... 笔者会用另 ...

  3. STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085和串口只发送数据不能接收数据问题

    STM32移植RT-Thread后的串口在调试助手上出现:(mq != RT_NULL) assert failed at rt_mq_recv:2085的问题讨论:http://www.rt-thr ...

  4. (已解决)STM32L151使用串口发送数据第一字节为FE问题!

    最近学习到串口发送数据时遇到一个问题:第一个字节总是FE,后面才是对的数据. 最终解决的方法是: 讲GPIO复用的操作放到GPIO配置之前! 体现在代码中就是: //打开GPIO时钟 RCC_AHBP ...

  5. 串口应用:遵循uart协议,发送多个字节的数据(状态机)

    上一节中,我们遵循uart协议,它发送一次只能发送6/7/8位数据,我们不能随意更改位数(虽然在代码上可行),不然就不遵循uart协议了,会造成接收端无法接收. 在现实生活中,我们有时候要发的数据不止 ...

  6. STM32串口USART1的使用方法

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

  7. STM32串口usart发送数据

    主函数请直接关注41行到47行代码!! #include "stm32f10x.h" // 相当于51单片机中的 #include <reg51.h> #include ...

  8. 为何串口dma发送数据可能不完整

    串口dma数据发送不完整, 1. 通过打印log说明数据合成,送给dma buff都是正常的. 2. 数据通过硬件串口直接配置,是正常的 3. 数据通过单片机dma转发后数据异常,通过检查发现 dma ...

  9. CC2530学习路线-基础实验-串口通讯发送字符串(4 未完待续)

    目录 1. 前期预备知识 1.1 串口通讯电路图 1.2 实验相关寄存器 1.2 常用波特率设置 本章未完待续..... 原来写的文章已经丢失了,只能找到这一小部分,看什么时候有时间再补上. 1. 前 ...

随机推荐

  1. CSPS_115

  2. PKUSC2019滚粗记

    PKUSC2019滚粗记 Day -INF 在\(\text{APIO}\)时得知省选考崩的自己居然能参加\(\text{SC}\),真是非常意外啊. Day 0 上午机房充斥着放假的气息,居然还成功 ...

  3. JS回调函数怎么写的?

    相信每个做前端的同学都用过太多太多的回调函数, 接下来就看看回调函数是怎么来的. 这玩意儿也没那么神秘,直接看代码: 声明函数的时候,把回调函数用作参数,并且在函数内调用它 function getD ...

  4. 5G 融合计费系统架构设计与实现(一)

    5G 融合计费系统架构设计与实现(一) 随着5G商用临近,5G的各个子系统也在加紧研发调试,本人有兴全程参与5G中的融合计费系统(CCS)的设计.开发.联调工作.接下来将用几篇文章介绍我们在CCS实现 ...

  5. CCF认证 201903-4消息传递接口

    题目 代码 #include <iostream> #include <stdio.h> #include <stdlib.h> #include <stri ...

  6. 分析 Kaggle TOP0.1% 如何处理文本数据

    感觉大佬的代码写的就是好,在处理数据的方面,首先定义一个 提取特征的类, class Extractor(object):,然后每一种方法对这个类进行重构,这个类主要结构就是: class Extra ...

  7. ConcurrentHashMap 无锁读

    ConcurrentHashMap 可以做到无锁读,而写使用分段锁机制,把整个哈希表切分成段segment(默认为16段),每段有一个锁,最多可以同时有16个写线程.而读不受限制. 下文转自http: ...

  8. Guava 库

    https://www.yiibai.com/guava https://wizardforcel.gitbooks.io/guava-tutorial/content/1.html com.goog ...

  9. 【传输协议】thrift的IDL语法

    一.IDL Thrift 采用IDL(Interface Definition Language)来定义通用的服务接口,然后通过Thrift提供的编译器,可以将服务接口编译成不同语言编写的代码,通过这 ...

  10. C++11原子操作与无锁编程(转)

    不讲语言特性,只从工程角度出发,个人觉得C++标准委员会在C++11中对多线程库的引入是有史以来做得最人道的一件事:今天我将就C++11多线程中的atomic原子操作展开讨论:比较互斥锁,自旋锁(sp ...