性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

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

多個(gè)串口的stm32控制

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

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

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

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

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

注意事項(xiàng):

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

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

下面是5個(gè)串口的配置函數(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; //復(fù)用推挽輸出;

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 ; //無(wú)校驗(yàn)位;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無(wú)硬件流控;

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)先級(jí),4位響應(yīng)優(yōu)先級(jí);

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中斷號(hào);

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

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

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ā)送一個(gè)字節(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); //清除標(biāo)志位;

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

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

}

}

這是串口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; //復(fù)用推挽輸出;

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 ; //無(wú)校驗(yàn)位;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無(wú)硬件流控;

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)先級(jí),4位響應(yīng)優(yōu)先級(jí);

NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //中斷號(hào);

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

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

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ā)送一個(gè)字節(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); //清除標(biāo)志位;

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

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

}

}

這是串口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; //復(fù)用推挽輸出;

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 ; //無(wú)校驗(yàn)位;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無(wú)硬件流控;

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)先級(jí),4位響應(yīng)優(yōu)先級(jí);

NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //中斷號(hào);

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

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

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ā)送一個(gè)字節(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); //清除標(biāo)志位;

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

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

}

}

這是串口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; //復(fù)用推挽輸出;

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 ; //無(wú)校驗(yàn)位;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無(wú)硬件流控;

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)先級(jí),4位響應(yīng)優(yōu)先級(jí);

NVIC_InitStructure.NVIC_IRQChannel = USART4_IRQn; //中斷號(hào);

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

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

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ā)送一個(gè)字節(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); //清除標(biāo)志位;

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

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

}

}

這是串口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; //復(fù)用推挽輸出;

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 ; //無(wú)校驗(yàn)位;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無(wú)硬件流控;

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)先級(jí),4位響應(yīng)優(yōu)先級(jí);

NVIC_InitStructure.NVIC_IRQChannel = USART5_IRQn; //中斷號(hào);

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

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

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ā)送一個(gè)字節(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); //清除標(biāo)志位;

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

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

}

}

全部回復(fù)(21)
正序查看
倒序查看
2021-03-23 12:24
STM32確實(shí)很強(qiáng)大,5個(gè)串口這在51單 片 機(jī)時(shí)代想都不感想,合理運(yùn)用串口采集不同的數(shù)據(jù),現(xiàn)在為了方便,屏幕都用了串口屏,再加上位機(jī)通迅,數(shù)據(jù)采集也用串口,51單 串口無(wú)法滿(mǎn)足,只能強(qiáng)大的STM32能滿(mǎn)足,而且現(xiàn)在價(jià)格也下降了不少,性?xún)r(jià)比較高。
0
回復(fù)
2021-03-23 12:46
@ZH電子達(dá)人
STM32確實(shí)很強(qiáng)大,5個(gè)串口這在51單片機(jī)時(shí)代想都不感想,合理運(yùn)用串口采集不同的數(shù)據(jù),現(xiàn)在為了方便,屏幕都用了串口屏,再加上位機(jī)通迅,數(shù)據(jù)采集也用串口,51單串口無(wú)法滿(mǎn)足,只能強(qiáng)大的STM32能滿(mǎn)足,而且現(xiàn)在價(jià)格也下降了不少,性?xún)r(jià)比較高。
是的,多串口多任務(wù)
0
回復(fù)
dog41
LV.6
4
2021-03-23 16:25
厲害
0
回復(fù)
熒火
LV.4
5
2021-03-23 16:55
兄弟,碼太亂了。
0
回復(fù)
2021-03-23 21:53
分享的東西不錯(cuò),代碼有點(diǎn)亂了。。。
0
回復(fù)
JacobL
LV.4
7
2021-03-23 23:07
現(xiàn)在32太貴了
0
回復(fù)
飛翔2004
LV.10
8
2021-03-24 13:49
現(xiàn)在STM32貴了不少,是用HAL庫(kù)寫(xiě)的嗎?多串口是同時(shí)工作的?講講原理?
0
回復(fù)
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;       //復(fù)用推挽輸出;   
  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 ;      //無(wú)校驗(yàn)位;   
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //無(wú)硬件流控;   
  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)先級(jí),4位響應(yīng)優(yōu)先級(jí);
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;          //中斷號(hào);   
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級(jí);   
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     //響應(yīng)優(yōu)先級(jí);   
  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ā)送一個(gè)字節(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);         //清除標(biāo)志位;        
    res=USART_ReceiveData(USART1);                  //接收數(shù)據(jù);           
    USART1_Send_Byte(res);                          //用戶(hù)自定義;   
  }  
}
右上角有個(gè)插入程序代碼的,似乎可以保留原書(shū)寫(xiě)格式。 
0
回復(fù)
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;//復(fù)用推挽輸出;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;//無(wú)校驗(yàn)位;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無(wú)硬件流控;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)先級(jí),4位響應(yīng)優(yōu)先級(jí);NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷號(hào);NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優(yōu)先級(jí);NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//響應(yīng)優(yōu)先級(jí);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ā)送一個(gè)字節(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);//清除標(biāo)志位;res=USART_ReceiveData(USART1);//接收數(shù)據(jù);USART1_Send_Byte(res);//用戶(hù)自定義;}}右上角有個(gè)插入程序代碼的,似乎可以保留原書(shū)寫(xiě)格式。
樓主這個(gè)代碼注釋比較少,看著比較規(guī)范。成熟的函數(shù)配置模塊。
0
回復(fù)
yujunice
LV.5
11
2021-03-24 17:35

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

1)串口時(shí)鐘使能,GPIO時(shí)鐘使能

2)串口復(fù)位

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

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

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

6)使能串口

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

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

0
回復(fù)
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;//復(fù)用推挽輸出;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;//無(wú)校驗(yàn)位;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無(wú)硬件流控;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)先級(jí),4位響應(yīng)優(yōu)先級(jí);NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中斷號(hào);NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//搶占優(yōu)先級(jí);NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//響應(yīng)優(yōu)先級(jí);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ā)送一個(gè)字節(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);//清除標(biāo)志位;res=USART_ReceiveData(USART1);//接收數(shù)據(jù);USART1_Send_Byte(res);//用戶(hù)自定義;}}右上角有個(gè)插入程序代碼的,似乎可以保留原書(shū)寫(xiě)格式。
我弄了幾次一直亂碼,我再試試
0
回復(fù)
2021-03-25 10:38
@飛翔2004
現(xiàn)在STM32貴了不少,是用HAL庫(kù)寫(xiě)的嗎?多串口是同時(shí)工作的?講講原理?
標(biāo)準(zhǔn)庫(kù)
0
回復(fù)
2021-03-25 11:27
@熒火
兄弟,碼太亂了。
代碼這塊,已非常完整,可以直接移植
0
回復(fù)
2021-03-25 11:27
@zhanceshen
分享的東西不錯(cuò),代碼有點(diǎn)亂了。。。
代碼這塊,已非常完整,可以直接移植
0
回復(fù)
fjfhjmh
LV.9
16
2021-03-25 11:45
厲害了,兄弟
0
回復(fù)
2021-03-25 13:13
@yujunice
串口設(shè)置的一般步驟可以總結(jié)為如下幾個(gè)步驟:1)串口時(shí)鐘使能,GPIO時(shí)鐘使能2)串口復(fù)位3)GPIO端口模式設(shè)置4)串口參數(shù)初始化5)開(kāi)啟中斷并且初始化NVIC(如果需要開(kāi)啟中斷才需要這個(gè)步驟)6)使能串口7)編寫(xiě)中斷處理函數(shù)注:對(duì)于復(fù)用功能的IO,我們首先要使能GPIO時(shí)鐘,然后使能復(fù)用功能時(shí)鐘,同時(shí)要把GPIO模式設(shè)置為復(fù)用功能對(duì)應(yīng)的模式。
非常不錯(cuò)
0
回復(fù)
2021-03-25 13:35
@fjfhjmh
厲害了,兄弟

上面是5個(gè)串口的基本配置

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

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


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

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


簡(jiǎn)單總結(jié)

健壯的串口接受程序注意幾點(diǎn)



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


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

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

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