串口配置
最近闲来无事,发现以前买的esp 12E开发板在抽屉里躺灰就网上找资料折腾了两三天,结果一顿操作猛如虎,一看是个辣鸡。怎么也烧写不了固件,我怀疑是开发板有问题。所以我又在乐鑫官网买了个新的。然后脑子一热,想用STM32做个串口转发的程序来玩一下串口。
我是这样想的STM32f103串口一连接电脑,串口2连接esp然后。
第一次画流程图,不知道对不对
usart.c
#include "usart.h"
__IO uint8_t CocheData[2]; //临时数据缓存
/*串口1初始化函数*/
void init_usart1() {
GPIO_InitTypeDef GPIOA_InitStructure; //定义GPIOA初始化结构体变量
USART_InitTypeDef USART_InitStructure; //定义串口初始化结构体变量
NVIC_InitTypeDef NVIC_InitStructure; //定义中断初始化结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//ENABLE THE GPIOA 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//ENABLE USART1 使能串口1时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//ENABLE USART2 使能串口2时钟
GPIOA_InitStructure.GPIO_Pin = (GPIO_Pin_9 | GPIO_Pin_2); //启用GPIOA Pin9引脚 串口发送引脚
GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //工作模式 复用推挽输出
GPIOA_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //工作频率50MHz
GPIO_Init(GPIOA, &GPIOA_InitStructure); //初始化GPIOA
GPIOA_InitStructure.GPIO_Pin = (GPIO_Pin_10 | GPIO_Pin_3); //启用GPIOA Pin10引脚 串口接收引脚
GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //工作模式 悬空输入
GPIO_Init(GPIOA, &GPIOA_InitStructure); //初始化GPIO
USART_InitStructure.USART_BaudRate = 76800; //设置串口1的波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设置数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; //设置停止位为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); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口1中断
USART_ClearFlag(USART1, USART_IT_RXNE); //清除接收缓存非空
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_Cmd(USART2, ENABLE); //使能串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能串口2中断
USART_ClearFlag(USART2, USART_IT_RXNE); //清除接收缓存非空
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //指定串口1的中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断优先级
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //指定串口1的中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //中断优先级
NVIC_Init(&NVIC_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //中断优先级分组
/*发送单个字节*/
void USART1_SendChar(uint8_t dat){
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){ //判断发送缓存区是否为空 TXE是发送缓存区清空标志
}
USART_SendData(USART1,dat);
}
/*发送多个字节*/
void USART1_SendMulti(uint8_t *dat,uint8_t len){
uint8_t i;
for(i=0;i
USART1_SendChar(*dat++);
}
}
/*发送字符串*/
void USART1_SendString(uint8_t *dat) {
while (*dat != '') { //遇到结束符停止发送
USART1_SendChar(*dat++);
}
}
/*串口1中断函数*/
void USART1_IRQHandler(void) {
if (USART_GetFlagStatus(USART1, USART_IT_RXNE)!=RESET) { //判断接收缓冲区是否非空
CocheData[0]=USART_ReceiveData(USART1);
USART_SendData(USART2,CocheData[0]);
}
}
/*串口2中断函数*/
void USART2_IRQHandler(void) {
if (USART_GetFlagStatus(USART2, USART_IT_RXNE)!=RESET) { //判断接收缓冲区是否非空
CocheData[1]=USART_ReceiveData(USART2);
USART_SendData(USART1,CocheData[1]);
}
}
main.c
#include "stm32f10x.h"
#include "usart.h"
int main(void){
init_usart1(); //初始化串口
while(1){
}
}
之前打开串口2时钟我是这样写的:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART2, ENABLE);//ENABLE USART2 使能串口2时钟
因为我之前写过串口1 的调试程序,所以我是直接复制黏贴过来的,然后把RCC_APB2Periph_USART1, ENABLE 改成 RCC_APB2Periph_USART2, ENABLE 然后编辑器立马报错:

然后改成:RCC_APB1Periph_USART2, ENABLE OK通过编译,
但是测试的时候发现串口助手一直收不到数据,
一开始我怀疑是串口1没有配置好然后我就加了段测试代码:
/*´®¿Ú1ÖжϺ¯Êý*/
void USART1_IRQHandler(void) {
USART1_SendChar('a');
if (USART_GetFlagStatus(USART1, USART_IT_RXNE)!=RESET) { //ÅжϽÓÊÕ»º³åÇøÊÇ·ñ·Ç¿Õ
CocheData[0]=USART_ReceiveData(USART1);
USART_SendData(USART2,CocheData[0]);
USART1_SendChar('b');
}
}
结果

发送12 接收到ab ab说明串口1可以进入中断,可以发送数据 这表示串口1 配置没有问题,说明是串口2的问题,思考了下串口1和串口2的配置是一样的,中断还是分开配置的不会有问题,
然后我想可能是线接错了正常是 stm32 TX2对应esp RX0; stm32 RX2对esp TX0,可是我怎么对调都没反应,然后我又把esp 的串口0接到了stm32的串口1上发现串口助手可以接收到数据,这表示不是线路的问题。
通过上面的测试初步判断是串口2的时钟没有开启,而我又找不出问题,所以果断CSDN搜索 stm32f103串口 2配置,一搜索看到别人的代码才恍然大悟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART2, ENABLE);//ENABLE USART2
我居然用ABP1的时钟函数去开启ABP2的时钟。


结束!
串口配置
最近闲来无事,发现以前买的esp 12E开发板在抽屉里躺灰就网上找资料折腾了两三天,结果一顿操作猛如虎,一看是个辣鸡。怎么也烧写不了固件,我怀疑是开发板有问题。所以我又在乐鑫官网买了个新的。然后脑子一热,想用STM32做个串口转发的程序来玩一下串口。
我是这样想的STM32f103串口一连接电脑,串口2连接esp然后。
第一次画流程图,不知道对不对
usart.c
#include "usart.h"
__IO uint8_t CocheData[2]; //临时数据缓存
/*串口1初始化函数*/
void init_usart1() {
GPIO_InitTypeDef GPIOA_InitStructure; //定义GPIOA初始化结构体变量
USART_InitTypeDef USART_InitStructure; //定义串口初始化结构体变量
NVIC_InitTypeDef NVIC_InitStructure; //定义中断初始化结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//ENABLE THE GPIOA 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//ENABLE USART1 使能串口1时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);//ENABLE USART2 使能串口2时钟
GPIOA_InitStructure.GPIO_Pin = (GPIO_Pin_9 | GPIO_Pin_2); //启用GPIOA Pin9引脚 串口发送引脚
GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //工作模式 复用推挽输出
GPIOA_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //工作频率50MHz
GPIO_Init(GPIOA, &GPIOA_InitStructure); //初始化GPIOA
GPIOA_InitStructure.GPIO_Pin = (GPIO_Pin_10 | GPIO_Pin_3); //启用GPIOA Pin10引脚 串口接收引脚
GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //工作模式 悬空输入
GPIO_Init(GPIOA, &GPIOA_InitStructure); //初始化GPIO
USART_InitStructure.USART_BaudRate = 76800; //设置串口1的波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设置数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; //设置停止位为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); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能串口1中断
USART_ClearFlag(USART1, USART_IT_RXNE); //清除接收缓存非空
USART_Init(USART2, &USART_InitStructure); //初始化串口2
USART_Cmd(USART2, ENABLE); //使能串口2
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能串口2中断
USART_ClearFlag(USART2, USART_IT_RXNE); //清除接收缓存非空
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //指定串口1的中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断优先级
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //指定串口1的中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //中断优先级
NVIC_Init(&NVIC_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //中断优先级分组
/*发送单个字节*/
void USART1_SendChar(uint8_t dat){
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){ //判断发送缓存区是否为空 TXE是发送缓存区清空标志
}
USART_SendData(USART1,dat);
}
/*发送多个字节*/
void USART1_SendMulti(uint8_t *dat,uint8_t len){
uint8_t i;
for(i=0;i
USART1_SendChar(*dat++);
}
}
/*发送字符串*/
void USART1_SendString(uint8_t *dat) {
while (*dat != '') { //遇到结束符停止发送
USART1_SendChar(*dat++);
}
}
/*串口1中断函数*/
void USART1_IRQHandler(void) {
if (USART_GetFlagStatus(USART1, USART_IT_RXNE)!=RESET) { //判断接收缓冲区是否非空
CocheData[0]=USART_ReceiveData(USART1);
USART_SendData(USART2,CocheData[0]);
}
}
/*串口2中断函数*/
void USART2_IRQHandler(void) {
if (USART_GetFlagStatus(USART2, USART_IT_RXNE)!=RESET) { //判断接收缓冲区是否非空
CocheData[1]=USART_ReceiveData(USART2);
USART_SendData(USART1,CocheData[1]);
}
}
main.c
#include "stm32f10x.h"
#include "usart.h"
int main(void){
init_usart1(); //初始化串口
while(1){
}
}
之前打开串口2时钟我是这样写的:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART2, ENABLE);//ENABLE USART2 使能串口2时钟
因为我之前写过串口1 的调试程序,所以我是直接复制黏贴过来的,然后把RCC_APB2Periph_USART1, ENABLE 改成 RCC_APB2Periph_USART2, ENABLE 然后编辑器立马报错:

然后改成:RCC_APB1Periph_USART2, ENABLE OK通过编译,
但是测试的时候发现串口助手一直收不到数据,
一开始我怀疑是串口1没有配置好然后我就加了段测试代码:
/*´®¿Ú1ÖжϺ¯Êý*/
void USART1_IRQHandler(void) {
USART1_SendChar('a');
if (USART_GetFlagStatus(USART1, USART_IT_RXNE)!=RESET) { //ÅжϽÓÊÕ»º³åÇøÊÇ·ñ·Ç¿Õ
CocheData[0]=USART_ReceiveData(USART1);
USART_SendData(USART2,CocheData[0]);
USART1_SendChar('b');
}
}
结果

发送12 接收到ab ab说明串口1可以进入中断,可以发送数据 这表示串口1 配置没有问题,说明是串口2的问题,思考了下串口1和串口2的配置是一样的,中断还是分开配置的不会有问题,
然后我想可能是线接错了正常是 stm32 TX2对应esp RX0; stm32 RX2对esp TX0,可是我怎么对调都没反应,然后我又把esp 的串口0接到了stm32的串口1上发现串口助手可以接收到数据,这表示不是线路的问题。
通过上面的测试初步判断是串口2的时钟没有开启,而我又找不出问题,所以果断CSDN搜索 stm32f103串口 2配置,一搜索看到别人的代码才恍然大悟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART2, ENABLE);//ENABLE USART2
我居然用ABP1的时钟函数去开启ABP2的时钟。


结束!
举报