久久久国产精品视频袁燕,99re久久精品国产,亚洲欧美日韩国产综合v,天天躁夜夜躁狠狠久久,激情五月婷婷激情五月婷婷

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

多個串口的stm32控制

串口是我們常用的一個數(shù)據(jù)傳輸接口,STM32F103系列單片機共有5個串口,其中1-3是通用同步/異步串行接口USART(Universal Synchronous/Asynchronous Receiver/Transmitter),4,、5是通用異步串行接口UART(Universal Asynchronous Receiver/Transmitter)。

配置串口包括三部分內(nèi)容:

1. I/O口配置:TXD配置為復用推挽輸出(GPIO_Mode_AF_PP),RXD配置為浮空輸入(GPIO_Mode_IN_FLOATING);

2. 串口配置:波特率等;

3. 中斷向量配置:一般用中斷方式接收數(shù)據(jù)。

注意事項:

1. USART1是掛在APB2,使能時鐘命令為:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );其他幾個則掛在APB1上,如2口:RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE );

  1. 配置4口和5口的時候,中斷名為UART4、UART5,
  2. 中斷入口分別為UART4_IRQn、UART5_IRQn
  3. 對應(yīng)的中斷服務(wù)函數(shù)為void UART4_IRQHandler(void)和void UART5_IRQHandler(void)。

下面是5個串口的配置函數(shù)和收發(fā)數(shù)據(jù)函數(shù)代碼:

#include "stm32f10x.h"

#include "misc.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_usart.h"

void USART1_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX;

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

GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;

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

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位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; //收發(fā)模式;

USART_Init(USART1, &USART_InitStructure); //配置串口參數(shù);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中斷號;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

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

}

void USART1_Send_Byte(u8 Data) //發(fā)送一個字節(jié);

{

USART_SendData(USART1,Data);

while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );

}

void USART1_Send_String(u8 *Data) //發(fā)送字符串;

{

while(*Data)

USART1_Send_Byte(*Data++);

}

void USART1_IRQHandler(void) //中斷處理函數(shù);

{

u8 res;

if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判斷是否發(fā)生中斷;

{

USART_ClearFlag(USART1, USART_IT_RXNE); //清除標志位;

res=USART_ReceiveData(USART1); //接收數(shù)據(jù);

USART1_Send_Byte(res); //用戶自定義;

}

}

這是串口2

void USART2_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );

RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //USART2 TX;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //USART2 RX;

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

GPIO_Init(GPIOA, &GPIO_InitStructure); //端口A;

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

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位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; //收發(fā)模式;

USART_Init(USART2, &USART_InitStructure); //配置串口參數(shù);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //中斷號;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

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

}

void USART2_Send_Byte(u8 Data) //發(fā)送一個字節(jié);

{

USART_SendData(USART2,Data);

while( USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET );

}

void USART2_Send_String(u8 *Data) //發(fā)送字符串;

{

while(*Data)

USART2_Send_Byte(*Data++);

}

void USART2_IRQHandler(void) //中斷處理函數(shù);

{

u8 res;

if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) //判斷是否發(fā)生中斷;

{

USART_ClearFlag(USART2, USART_IT_RXNE); //清除標志位;

res=USART_ReceiveData(USART2); //接收數(shù)據(jù);

USART2_Send_Byte(res); //用戶自定義;

}

}

這是串口3

void USART3_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );

RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART3 TX;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure); //端口A;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //USART3 RX;

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

GPIO_Init(GPIOB, &GPIO_InitStructure); //端口A;

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

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位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; //收發(fā)模式;

USART_Init(USART3, &USART_InitStructure); //配置串口參數(shù);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //中斷號;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

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

}

void USART3_Send_Byte(u8 Data) //發(fā)送一個字節(jié);

{

USART_SendData(USART3,Data);

while( USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET );

}

void USART3_Send_String(u8 *Data) //發(fā)送字符串;

{

while(*Data)

USART3_Send_Byte(*Data++);

}

void USART3_IRQHandler(void) //中斷處理函數(shù);

{

u8 res;

if(USART_GetITStatus(USART3, USART_IT_RXNE) == SET) //判斷是否發(fā)生中斷;

{

USART_ClearFlag(USART3, USART_IT_RXNE); //清除標志位;

res=USART_ReceiveData(USART3); //接收數(shù)據(jù);

USART3_Send_Byte(res); //用戶自定義;

}

}

這是串口4

void USART4_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART4, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART4 TX;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure); //端口A;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //USART4 RX;

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

GPIO_Init(GPIOC, &GPIO_InitStructure); //端口A;

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

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位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; //收發(fā)模式;

USART_Init(USART4, &USART_InitStructure); //配置串口參數(shù);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannel = USART4_IRQn; //中斷號;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);

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

}

void USART4_Send_Byte(u8 Data) //發(fā)送一個字節(jié);

{

USART_SendData(USART4,Data);

while( USART_GetFlagStatus(USART4, USART_FLAG_TC) == RESET );

}

void USART4_Send_String(u8 *Data) //發(fā)送字符串;

{

while(*Data)

USART4_Send_Byte(*Data++);

}

void USART4_IRQHandler(void) //中斷處理函數(shù);

{

u8 res;

if(USART_GetITStatus(USART4, USART_IT_RXNE) == SET) //判斷是否發(fā)生中斷;

{

USART_ClearFlag(USART4, USART_IT_RXNE); //清除標志位;

res=USART_ReceiveData(USART4); //接收數(shù)據(jù);

USART4_Send_Byte(res); //用戶自定義;

}

}

這是串口5

void USART5_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE );

RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //USART5 TX;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure); //端口A;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //USART5 RX;

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

GPIO_Init(GPIOD, &GPIO_InitStructure); //端口A;

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

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位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; //收發(fā)模式;

USART_Init(USART5, &USART_InitStructure); //配置串口參數(shù);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannel = USART5_IRQn; //中斷號;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應(yīng)優(yōu)先級;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(USART5, USART_IT_RXNE, ENABLE);

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

}

void USART5_Send_Byte(u8 Data) //發(fā)送一個字節(jié);

{

USART_SendData(USART5,Data);

while( USART_GetFlagStatus(USART5, USART_FLAG_TC) == RESET );

}

void USART5_Send_String(u8 *Data) //發(fā)送字符串;

{

while(*Data)

USART5_Send_Byte(*Data++);

}

void USART5_IRQHandler(void) //中斷處理函數(shù);

{

u8 res;

if(USART_GetITStatus(USART5, USART_IT_RXNE) == SET) //判斷是否發(fā)生中斷;

{

USART_ClearFlag(USART5, USART_IT_RXNE); //清除標志位;

res=USART_ReceiveData(USART5); //接收數(shù)據(jù);

USART5_Send_Byte(res); //用戶自定義;

}

}

全部回復(21)
正序查看
倒序查看
2021-03-23 12:24
STM32確實很強大,5個串口這在51單 片 機時代想都不感想,合理運用串口采集不同的數(shù)據(jù),現(xiàn)在為了方便,屏幕都用了串口屏,再加上位機通迅,數(shù)據(jù)采集也用串口,51單 串口無法滿足,只能強大的STM32能滿足,而且現(xiàn)在價格也下降了不少,性價比較高。
0
回復
2021-03-23 12:46
@ZH電子達人
STM32確實很強大,5個串口這在51單片機時代想都不感想,合理運用串口采集不同的數(shù)據(jù),現(xiàn)在為了方便,屏幕都用了串口屏,再加上位機通迅,數(shù)據(jù)采集也用串口,51單串口無法滿足,只能強大的STM32能滿足,而且現(xiàn)在價格也下降了不少,性價比較高。
是的,多串口多任務(wù)
0
回復
dog41
LV.6
4
2021-03-23 16:25
厲害
0
回復
熒火
LV.4
5
2021-03-23 16:55
兄弟,碼太亂了。
0
回復
2021-03-23 21:53
分享的東西不錯,代碼有點亂了。。。
0
回復
JacobL
LV.4
7
2021-03-23 23:07
現(xiàn)在32太貴了
0
回復
飛翔2004
LV.10
8
2021-03-24 13:49
現(xiàn)在STM32貴了不少,是用HAL庫寫的嗎?多串口是同時工作的?講講原理?
0
回復
boy59
LV.9
9
2021-03-24 16:06

#include "stm32f10x.h"
#include "misc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h" 

void USART1_Configuration(void)
{ 
  GPIO_InitTypeDef GPIO_InitStructure;   
  USART_InitTypeDef USART_InitStructure;   
  NVIC_InitTypeDef NVIC_InitStructure;        
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;             //USART1 TX;  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       //復用推挽輸出;   
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  GPIO_Init(GPIOA, &GPIO_InitStructure);                //端口A;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            //USART1 RX;   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入;  
  GPIO_Init(GPIOA, &GPIO_InitStructure);                //端口A;
  USART_InitStructure.USART_BaudRate = 9600;           //波特率;   
  USART_InitStructure.USART_WordLength = USART_WordLength_8b; //數(shù)據(jù)位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;      //收發(fā)模式;   
  USART_Init(USART1, &USART_InitStructure);                //配置串口參數(shù);
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);       //設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;          //中斷號;   
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級;   
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     //響應(yīng)優(yōu)先級;   
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
  NVIC_Init(&NVIC_InitStructure);
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);   
  USART_Cmd(USART1, ENABLE);                             //使能串口;
}

void USART1_Send_Byte(u8 Data) //發(fā)送一個字節(jié);
{  
 USART_SendData(USART1,Data);   
 while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );
}

void USART1_Send_String(u8 *Data) //發(fā)送字符串;
{   
  while(*Data)    
  USART1_Send_Byte(*Data++);
}

void USART1_IRQHandler(void) //中斷處理函數(shù);
{ 
  u8 res;       
 if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判斷是否發(fā)生中斷;   
 {  
    USART_ClearFlag(USART1, USART_IT_RXNE);         //清除標志位;        
    res=USART_ReceiveData(USART1);                  //接收數(shù)據(jù);           
    USART1_Send_Byte(res);                          //用戶自定義;   
  }  
}
右上角有個插入程序代碼的,似乎可以保留原書寫格式。 
0
回復
k6666
LV.9
10
2021-03-24 16:20
@boy59
#include"stm32f10x.h"#include"misc.h"#include"stm32f10x_gpio.h"#include"stm32f10x_usart.h"voidUSART1_Configuration(void){GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure;NVIC_InitTypeDefNVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//USART1TX;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//端口A;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//USART1RX;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空輸入;GPIO_Init(GPIOA,&GPIO_InitStructure);//端口A;USART_InitStructure.USART_BaudRate=9600;//波特率;USART_InitStructure.USART_WordLength=USART_WordLength_8b;//數(shù)據(jù)位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;//收發(fā)模式;USART_Init(USART1,&USART_InitStructure);//配置串口參數(shù);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷號;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優(yōu)先級;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//響應(yīng)優(yōu)先級;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);//使能串口;}voidUSART1_Send_Byte(u8Data)//發(fā)送一個字節(jié);{USART_SendData(USART1,Data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}voidUSART1_Send_String(u8*Data)//發(fā)送字符串;{while(*Data)USART1_Send_Byte(*Data++);}voidUSART1_IRQHandler(void)//中斷處理函數(shù);{u8res;if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//判斷是否發(fā)生中斷;{USART_ClearFlag(USART1,USART_IT_RXNE);//清除標志位;res=USART_ReceiveData(USART1);//接收數(shù)據(jù);USART1_Send_Byte(res);//用戶自定義;}}右上角有個插入程序代碼的,似乎可以保留原書寫格式。
樓主這個代碼注釋比較少,看著比較規(guī)范。成熟的函數(shù)配置模塊。
0
回復
yujunice
LV.5
11
2021-03-24 17:35

串口設(shè)置的一般步驟可以總結(jié)為如下幾個步驟:

1)串口時鐘使能,GPIO時鐘使能

2)串口復位

3) GPIO端口模式設(shè)置

4)串口參數(shù)初始化

5)開啟中斷并且初始化NVIC(如果需要開啟中斷才需要這個步驟)

6)使能串口

7)編寫中斷處理函數(shù)

注:對于復用功能的IO,我們首先要使能GPIO時鐘,然后使能復用功能時鐘,同時要把GPIO模式設(shè)置為復用功能對應(yīng)的模式。

0
回復
2021-03-25 10:22
@boy59
#include"stm32f10x.h"#include"misc.h"#include"stm32f10x_gpio.h"#include"stm32f10x_usart.h"voidUSART1_Configuration(void){GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure;NVIC_InitTypeDefNVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//USART1TX;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//端口A;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//USART1RX;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空輸入;GPIO_Init(GPIOA,&GPIO_InitStructure);//端口A;USART_InitStructure.USART_BaudRate=9600;//波特率;USART_InitStructure.USART_WordLength=USART_WordLength_8b;//數(shù)據(jù)位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;//收發(fā)模式;USART_Init(USART1,&USART_InitStructure);//配置串口參數(shù);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷組,4位搶占優(yōu)先級,4位響應(yīng)優(yōu)先級;NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷號;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優(yōu)先級;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//響應(yīng)優(yōu)先級;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);//使能串口;}voidUSART1_Send_Byte(u8Data)//發(fā)送一個字節(jié);{USART_SendData(USART1,Data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}voidUSART1_Send_String(u8*Data)//發(fā)送字符串;{while(*Data)USART1_Send_Byte(*Data++);}voidUSART1_IRQHandler(void)//中斷處理函數(shù);{u8res;if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//判斷是否發(fā)生中斷;{USART_ClearFlag(USART1,USART_IT_RXNE);//清除標志位;res=USART_ReceiveData(USART1);//接收數(shù)據(jù);USART1_Send_Byte(res);//用戶自定義;}}右上角有個插入程序代碼的,似乎可以保留原書寫格式。
我弄了幾次一直亂碼,我再試試
0
回復
2021-03-25 10:38
@飛翔2004
現(xiàn)在STM32貴了不少,是用HAL庫寫的嗎?多串口是同時工作的?講講原理?
標準庫
0
回復
2021-03-25 11:27
@熒火
兄弟,碼太亂了。
代碼這塊,已非常完整,可以直接移植
0
回復
2021-03-25 11:27
@zhanceshen
分享的東西不錯,代碼有點亂了。。。
代碼這塊,已非常完整,可以直接移植
0
回復
fjfhjmh
LV.9
16
2021-03-25 11:45
厲害了,兄弟
0
回復
2021-03-25 13:13
@yujunice
串口設(shè)置的一般步驟可以總結(jié)為如下幾個步驟:1)串口時鐘使能,GPIO時鐘使能2)串口復位3)GPIO端口模式設(shè)置4)串口參數(shù)初始化5)開啟中斷并且初始化NVIC(如果需要開啟中斷才需要這個步驟)6)使能串口7)編寫中斷處理函數(shù)注:對于復用功能的IO,我們首先要使能GPIO時鐘,然后使能復用功能時鐘,同時要把GPIO模式設(shè)置為復用功能對應(yīng)的模式。
非常不錯
0
回復
2021-03-25 13:35
@fjfhjmh
厲害了,兄弟

上面是5個串口的基本配置

下面主要說實戰(zhàn)中串口如何接受

在嵌入式應(yīng)用中,串口通訊應(yīng)用幾乎是必須的,非常常用,好多事件都是和串口有關(guān),做好串口的數(shù)據(jù)處理是非常關(guān)鍵的一步,這里再分享一下如何在裸機中對串口數(shù)據(jù)的有效處理,比如一包數(shù)據(jù)0xaa,0x55,0xXX,0xXX,0x0a,0x0d,簡單介紹串口處理的方法


一.直接在接受中斷中判斷數(shù)據(jù)
先定義一個uint8_t Buff和一個uint8_t Table[10];
在接收中斷函數(shù)里用HAL_UART_Receive_IT(&UART1_Handler, &Buff, 1)這個函數(shù),
每次在中斷里面都判斷Buff是不是0xaa,如果是則將數(shù)據(jù)存入到Table[0]中且繼續(xù)接收下面的數(shù)據(jù),都存入到Table的數(shù)組中,如果不是則繼續(xù)進行判斷。然后對Table進行判斷,首先判斷Table[0]和Table[1]分別為0xaa,0x55后,在進行判斷Table[4]和Table[5]分別為0x0a,0x0d。在進行判斷校驗是否正確,正確后取出Table[2]的數(shù)據(jù)進行處理。
這種方法在數(shù)據(jù)傳輸慢的情況下,比較簡單方便,還可以,但是在數(shù)據(jù)快的時候,非常容易造成數(shù)據(jù)的丟失,還有就是要是第一次數(shù)據(jù)接收錯誤,回不到初始化狀態(tài),必須復位操作
二.FIFO方式 超時接受
接收中斷函數(shù)里用HAL_UART_Receive_IT(&UART1_Handler, &Buff, 1)這個函數(shù)
接收數(shù)據(jù)的時候不要做數(shù)據(jù)處理,而是忠實地接收原始字節(jié)流,只管接受入列,就是接受完數(shù)據(jù)0xaa,0x55,0xXX,0xXX,0x0a,0x0d后,超時時間RxTimeOut3到以后再對數(shù)據(jù)處理
/* 數(shù)據(jù)入隊 */
chfifo_in(&RxFifo, &Buff);
/* 清零超時 */
RxTimeOut3 = 0;
三.DMA+空閑中斷
0、開啟串口DMA接收
1、串口收到數(shù)據(jù),DMA不斷傳輸數(shù)據(jù)到存儲buf
2、一幀數(shù)據(jù)發(fā)送完畢,串口暫時空閑,觸發(fā)串口空閑中斷
3、在中斷服務(wù)函數(shù)中,可以計算剛才收到了多少個字節(jié)的數(shù)據(jù)
4、解碼存儲buf,清除標志位,開始下一幀接收

就是接收到一幀數(shù)據(jù)0xaa,0x55,0xXX,0xXX,0x0a,0x0d后才觸發(fā)中斷接受,處理數(shù)據(jù)非常高效。


簡單總結(jié)

健壯的串口接受程序注意幾點



1.對于沒有dma和空閑中斷功能的單片機,最好采用環(huán)形隊列+超時的方法,保證不會出現(xiàn)丟幀等串口問題,對于那種串口接受,比如接受數(shù)據(jù)的同時判斷解析數(shù)據(jù)的話,肯定會出問題的


2.對于具備dma和空閑中斷功能的單片機,建議采用DMA+空閑中斷的方法,幀接受中斷,效率非常高,對于不等長的數(shù)據(jù)非常方便。

3.對于串口設(shè)備初始化后最好延時一段時間,時間具體情況而定

0
回復
1260086278
LV.2
19
2021-04-01 16:59
我做通訊一般都加上校驗,加和或者CRC校驗,不然用起來不放心
0
回復
dy-blNlwnWV
LV.1
20
2021-04-03 09:23
@lihui710884923
上面是5個串口的基本配置下面主要說實戰(zhàn)中串口如何接受在嵌入式應(yīng)用中,串口通訊應(yīng)用幾乎是必須的,非常常用,好多事件都是和串口有關(guān),做好串口的數(shù)據(jù)處理是非常關(guān)鍵的一步,這里再分享一下如何在裸機中對串口數(shù)據(jù)的有效處理,比如一包數(shù)據(jù)0xaa,0x55,0xXX,0xXX,0x0a,0x0d,簡單介紹串口處理的方法一.直接在接受中斷中判斷數(shù)據(jù)先定義一個uint8_tBuff和一個uint8_tTable[10];在接收中斷函數(shù)里用HAL_UART_Receive_IT(&UART1_Handler,&Buff,1)這個函數(shù),每次在中斷里面都判斷Buff是不是0xaa,如果是則將數(shù)據(jù)存入到Table[0]中且繼續(xù)接收下面的數(shù)據(jù),都存入到Table的數(shù)組中,如果不是則繼續(xù)進行判斷。然后對Table進行判斷,首先判斷Table[0]和Table[1]分別為0xaa,0x55后,在進行判斷Table[4]和Table[5]分別為0x0a,0x0d。在進行判斷校驗是否正確,正確后取出Table[2]的數(shù)據(jù)進行處理。這種方法在數(shù)據(jù)傳輸慢的情況下,比較簡單方便,還可以,但是在數(shù)據(jù)快的時候,非常容易造成數(shù)據(jù)的丟失,還有就是要是第一次數(shù)據(jù)接收錯誤,回不到初始化狀態(tài),必須復位操作二.FIFO方式超時接受接收中斷函數(shù)里用HAL_UART_Receive_IT(&UART1_Handler,&Buff,1)這個函數(shù)接收數(shù)據(jù)的時候不要做數(shù)據(jù)處理,而是忠實地接收原始字節(jié)流,只管接受入列,就是接受完數(shù)據(jù)0xaa,0x55,0xXX,0xXX,0x0a,0x0d后,超時時間RxTimeOut3到以后再對數(shù)據(jù)處理/*數(shù)據(jù)入隊*/chfifo_in(&RxFifo,&Buff);/*清零超時*/RxTimeOut3=0;三.DMA+空閑中斷0、開啟串口DMA接收1、串口收到數(shù)據(jù),DMA不斷傳輸數(shù)據(jù)到存儲buf2、一幀數(shù)據(jù)發(fā)送完畢,串口暫時空閑,觸發(fā)串口空閑中斷3、在中斷服務(wù)函數(shù)中,可以計算剛才收到了多少個字節(jié)的數(shù)據(jù)4、解碼存儲buf,清除標志位,開始下一幀接收就是接收到一幀數(shù)據(jù)0xaa,0x55,0xXX,0xXX,0x0a,0x0d后才觸發(fā)中斷接受,處理數(shù)據(jù)非常高效。簡單總結(jié)健壯的串口接受程序注意幾點1.對于沒有dma和空閑中斷功能的單片機,最好采用環(huán)形隊列+超時的方法,保證不會出現(xiàn)丟幀等串口問題,對于那種串口接受,比如接受數(shù)據(jù)的同時判斷解析數(shù)據(jù)的話,肯定會出問題的2.對于具備dma和空閑中斷功能的單片機,建議采用DMA+空閑中斷的方法,幀接受中斷,效率非常高,對于不等長的數(shù)據(jù)非常方便。3.對于串口設(shè)備初始化后最好延時一段時間,時間具體情況而定
這才是串口通訊實戰(zhàn)的經(jīng)驗總結(jié),非常感謝
0
回復
2021-04-07 11:25
@1260086278
我做通訊一般都加上校驗,加和或者CRC校驗,不然用起來不放心
校驗是通信協(xié)議這塊,現(xiàn)在主要分析如何讓接受這塊
0
回復
2021-04-07 11:30
@飛翔2004
現(xiàn)在STM32貴了不少,是用HAL庫寫的嗎?多串口是同時工作的?講講原理?
多串口工作,一是中斷,二是時間輪詢,三是實時操作系統(tǒng)
0
回復
發(fā)