99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

  • 回復
  • 收藏
  • 點贊
  • 分享
  • 發新帖

多個串口的stm32控制

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

配置串口包括三部分內容:

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

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

3. 中斷向量配置:一般用中斷方式接收數據。

注意事項:

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. 對應的中斷服務函數為void UART4_IRQHandler(void)和void UART5_IRQHandler(void)。

下面是5個串口的配置函數和收發數據函數代碼:

#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; //數據位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; //收發模式;

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

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置中斷組,4位搶占優先級,4位響應優先級;

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

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應優先級;

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) //發送一個字節;

{

USART_SendData(USART1,Data);

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

}

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

{

while(*Data)

USART1_Send_Byte(*Data++);

}

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

{

u8 res;

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

{

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

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

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; //數據位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; //收發模式;

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

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置中斷組,4位搶占優先級,4位響應優先級;

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

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應優先級;

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) //發送一個字節;

{

USART_SendData(USART2,Data);

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

}

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

{

while(*Data)

USART2_Send_Byte(*Data++);

}

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

{

u8 res;

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

{

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

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

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; //數據位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; //收發模式;

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

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置中斷組,4位搶占優先級,4位響應優先級;

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

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應優先級;

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) //發送一個字節;

{

USART_SendData(USART3,Data);

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

}

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

{

while(*Data)

USART3_Send_Byte(*Data++);

}

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

{

u8 res;

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

{

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

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

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; //數據位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; //收發模式;

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

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置中斷組,4位搶占優先級,4位響應優先級;

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

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應優先級;

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) //發送一個字節;

{

USART_SendData(USART4,Data);

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

}

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

{

while(*Data)

USART4_Send_Byte(*Data++);

}

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

{

u8 res;

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

{

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

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

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; //數據位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; //收發模式;

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

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設置中斷組,4位搶占優先級,4位響應優先級;

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

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應優先級;

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) //發送一個字節;

{

USART_SendData(USART5,Data);

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

}

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

{

while(*Data)

USART5_Send_Byte(*Data++);

}

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

{

u8 res;

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

{

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

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

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

}

}

全部回復(21)
正序查看
倒序查看
2021-03-23 12:24
STM32確實很強大,5個串口這在51單 片 機時代想都不感想,合理運用串口采集不同的數據,現在為了方便,屏幕都用了串口屏,再加上位機通迅,數據采集也用串口,51單 串口無法滿足,只能強大的STM32能滿足,而且現在價格也下降了不少,性價比較高。
0
回復
2021-03-23 12:46
@ZH電子達人
STM32確實很強大,5個串口這在51單片機時代想都不感想,合理運用串口采集不同的數據,現在為了方便,屏幕都用了串口屏,再加上位機通迅,數據采集也用串口,51單串口無法滿足,只能強大的STM32能滿足,而且現在價格也下降了不少,性價比較高。
是的,多串口多任務
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
現在32太貴了
0
回復
飛翔2004
LV.10
8
2021-03-24 13:49
現在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; //數據位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;      //收發模式;   
  USART_Init(USART1, &USART_InitStructure);                //配置串口參數;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);       //設置中斷組,4位搶占優先級,4位響應優先級;
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;          //中斷號;   
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級;   
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     //響應優先級;   
  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) //發送一個字節;
{  
 USART_SendData(USART1,Data);   
 while( USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET );
}

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

void USART1_IRQHandler(void) //中斷處理函數;
{ 
  u8 res;       
 if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET) //判斷是否發生中斷;   
 {  
    USART_ClearFlag(USART1, USART_IT_RXNE);         //清除標志位;        
    res=USART_ReceiveData(USART1);                  //接收數據;           
    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;//數據位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;//收發模式;USART_Init(USART1,&USART_InitStructure);//配置串口參數;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷組,4位搶占優先級,4位響應優先級;NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷號;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優先級;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//響應優先級;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);//使能串口;}voidUSART1_Send_Byte(u8Data)//發送一個字節;{USART_SendData(USART1,Data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}voidUSART1_Send_String(u8*Data)//發送字符串;{while(*Data)USART1_Send_Byte(*Data++);}voidUSART1_IRQHandler(void)//中斷處理函數;{u8res;if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//判斷是否發生中斷;{USART_ClearFlag(USART1,USART_IT_RXNE);//清除標志位;res=USART_ReceiveData(USART1);//接收數據;USART1_Send_Byte(res);//用戶自定義;}}右上角有個插入程序代碼的,似乎可以保留原書寫格式。
樓主這個代碼注釋比較少,看著比較規范。成熟的函數配置模塊。
0
回復
yujunice
LV.5
11
2021-03-24 17:35

串口設置的一般步驟可以總結為如下幾個步驟:

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

2)串口復位

3) GPIO端口模式設置

4)串口參數初始化

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

6)使能串口

7)編寫中斷處理函數

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

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;//數據位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;//收發模式;USART_Init(USART1,&USART_InitStructure);//配置串口參數;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷組,4位搶占優先級,4位響應優先級;NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷號;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優先級;NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//響應優先級;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_Cmd(USART1,ENABLE);//使能串口;}voidUSART1_Send_Byte(u8Data)//發送一個字節;{USART_SendData(USART1,Data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}voidUSART1_Send_String(u8*Data)//發送字符串;{while(*Data)USART1_Send_Byte(*Data++);}voidUSART1_IRQHandler(void)//中斷處理函數;{u8res;if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)//判斷是否發生中斷;{USART_ClearFlag(USART1,USART_IT_RXNE);//清除標志位;res=USART_ReceiveData(USART1);//接收數據;USART1_Send_Byte(res);//用戶自定義;}}右上角有個插入程序代碼的,似乎可以保留原書寫格式。
我弄了幾次一直亂碼,我再試試
0
回復
2021-03-25 10:38
@飛翔2004
現在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
串口設置的一般步驟可以總結為如下幾個步驟:1)串口時鐘使能,GPIO時鐘使能2)串口復位3)GPIO端口模式設置4)串口參數初始化5)開啟中斷并且初始化NVIC(如果需要開啟中斷才需要這個步驟)6)使能串口7)編寫中斷處理函數注:對于復用功能的IO,我們首先要使能GPIO時鐘,然后使能復用功能時鐘,同時要把GPIO模式設置為復用功能對應的模式。
非常不錯
0
回復
2021-03-25 13:35
@fjfhjmh
厲害了,兄弟

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

下面主要說實戰中串口如何接受

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


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

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


簡單總結

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



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


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

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

0
回復
1260086278
LV.2
19
2021-04-01 16:59
我做通訊一般都加上校驗,加和或者CRC校驗,不然用起來不放心
0
回復
dy-blNlwnWV
LV.1
20
2021-04-03 09:23
@lihui710884923
上面是5個串口的基本配置下面主要說實戰中串口如何接受在嵌入式應用中,串口通訊應用幾乎是必須的,非常常用,好多事件都是和串口有關,做好串口的數據處理是非常關鍵的一步,這里再分享一下如何在裸機中對串口數據的有效處理,比如一包數據0xaa,0x55,0xXX,0xXX,0x0a,0x0d,簡單介紹串口處理的方法一.直接在接受中斷中判斷數據先定義一個uint8_tBuff和一個uint8_tTable[10];在接收中斷函數里用HAL_UART_Receive_IT(&UART1_Handler,&Buff,1)這個函數,每次在中斷里面都判斷Buff是不是0xaa,如果是則將數據存入到Table[0]中且繼續接收下面的數據,都存入到Table的數組中,如果不是則繼續進行判斷。然后對Table進行判斷,首先判斷Table[0]和Table[1]分別為0xaa,0x55后,在進行判斷Table[4]和Table[5]分別為0x0a,0x0d。在進行判斷校驗是否正確,正確后取出Table[2]的數據進行處理。這種方法在數據傳輸慢的情況下,比較簡單方便,還可以,但是在數據快的時候,非常容易造成數據的丟失,還有就是要是第一次數據接收錯誤,回不到初始化狀態,必須復位操作二.FIFO方式超時接受接收中斷函數里用HAL_UART_Receive_IT(&UART1_Handler,&Buff,1)這個函數接收數據的時候不要做數據處理,而是忠實地接收原始字節流,只管接受入列,就是接受完數據0xaa,0x55,0xXX,0xXX,0x0a,0x0d后,超時時間RxTimeOut3到以后再對數據處理/*數據入隊*/chfifo_in(&RxFifo,&Buff);/*清零超時*/RxTimeOut3=0;三.DMA+空閑中斷0、開啟串口DMA接收1、串口收到數據,DMA不斷傳輸數據到存儲buf2、一幀數據發送完畢,串口暫時空閑,觸發串口空閑中斷3、在中斷服務函數中,可以計算剛才收到了多少個字節的數據4、解碼存儲buf,清除標志位,開始下一幀接收就是接收到一幀數據0xaa,0x55,0xXX,0xXX,0x0a,0x0d后才觸發中斷接受,處理數據非常高效。簡單總結健壯的串口接受程序注意幾點1.對于沒有dma和空閑中斷功能的單片機,最好采用環形隊列+超時的方法,保證不會出現丟幀等串口問題,對于那種串口接受,比如接受數據的同時判斷解析數據的話,肯定會出問題的2.對于具備dma和空閑中斷功能的單片機,建議采用DMA+空閑中斷的方法,幀接受中斷,效率非常高,對于不等長的數據非常方便。3.對于串口設備初始化后最好延時一段時間,時間具體情況而定
這才是串口通訊實戰的經驗總結,非常感謝
0
回復
2021-04-07 11:25
@1260086278
我做通訊一般都加上校驗,加和或者CRC校驗,不然用起來不放心
校驗是通信協議這塊,現在主要分析如何讓接受這塊
0
回復
2021-04-07 11:30
@飛翔2004
現在STM32貴了不少,是用HAL庫寫的嗎?多串口是同時工作的?講講原理?
多串口工作,一是中斷,二是時間輪詢,三是實時操作系統
0
回復
主站蜘蛛池模板: 国产午夜精品片一区二区三区 | 91无限观看 | 国产精品色区 | 痉挛高潮喷水av无码免费 | 91伦理片在线观看 | 久久精品欧洲AV无码四区 | 99久久免费精品国产72精品九九 | 黄色毛片一级视频 | 国产在线视频不卡一区二区 | 四虎四虎 | hd法国xxxxhdvideos| 亚洲精品亚洲人成在线观看麻豆 | 国产精品高潮呻吟av久久4虎 | 在线观看免费视频国产 | 性高爱久久久久久久久久久dj | 毛茸茸xxxxx 中文字幕亚洲码在线观看 99国产免费网址 | 中文字字幕在线中文乱码范文 | 色视频网站在线观看 | 日本一区二区福利视频 | 91在线观看网站 | 免费一级好看的国产 | 白丝美女被操黄色视频国产免费 | 中文字幕无码AV激情不卡 | 一区二区三区日韩在线观看 | 蜜桃av网站 | 免费大片AV手机看片高清 | 狠狠躁天天躁夜夜躁婷婷 | 精品国产综合乱码久久久久久 | www.5xpxp.com毛片 日韩精品免费一区二区三区竹菊 | 国产精品裸体一区二区三区 | 啊灬啊灬啊灬快灬深高潮了 | 女女女女bbbb毛片免费视频 | 美女精品国产 | 4hu44四虎www在线影院麻豆 | 日韩中文字幕亚洲一区二区va在线 | 成人免费视频软件网站 | 91成品视频| 美女高潮无遮挡喷水视频 | 国产无遮挡色视频免费观看性色 | 日韩精品欧美在线成人 | japanese乱人伦精品 |