日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STM32】串口收发主要程序代码分析

發(fā)布時(shí)間:2025/4/5 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STM32】串口收发主要程序代码分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 數(shù)據(jù)發(fā)送與接收
  • 串口狀態(tài)
  • 開啟串口響應(yīng)中斷
  • 獲取相應(yīng)中斷狀態(tài)
  • main.c
  • usart.c
  • usart.h

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

  • 串口時(shí)鐘使能,GPIO 時(shí)鐘使能
  • 串口復(fù)位
  • GPIO 端口模式設(shè)置
  • 串口參數(shù)初始化
  • 開啟中斷并且初始化 NVIC (如果需要開啟中斷才需要這個(gè)步驟)
  • 使能串口
  • 編寫中斷處理函數(shù)
  • 下表為幾個(gè)與串口基本配置直接相關(guān)的幾個(gè)固件庫函數(shù),這些函數(shù)和定義主要分布在 stm32f10x_usart.h 和 stm32f10x_usart.c 文件中。

    功能函數(shù)
    1. 串口時(shí)鐘使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1)
    2. 串口復(fù)位void USART_DeInit(USART_TypeDef* USARTx); // 串口復(fù)位
    USART_DeInit(USART1); // 復(fù)位串口 1
    3. 串口參數(shù)初始化void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
    4. 數(shù)據(jù)發(fā)送與接收(發(fā)送)void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
    4. 數(shù)據(jù)發(fā)送與接收(接收)uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
    5. 串口狀態(tài)FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
    USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
    USART_GetFlagStatus(USART1, USART_FLAG_TC);
    6. 串口使能USART_Cmd(USART1, ENABLE); //使能串口
    7. 開啟串口響應(yīng)中斷void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //開啟中斷,接收到數(shù)據(jù)中斷
    USART_ITConfig(USART1,USART_IT_TC,ENABLE);
    8. 獲取相應(yīng)中斷狀態(tài)ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
    USART_GetITStatus(USART1, USART_IT_TC)

    數(shù)據(jù)發(fā)送與接收

    STM32 的發(fā)送與接收是通過數(shù)據(jù)寄存器 USART_DR 來實(shí)現(xiàn)的,這是一個(gè)雙寄存器,包含了 TDR 和 RDR。當(dāng)向該寄存器寫數(shù)據(jù)的時(shí)候,串口就會(huì)自動(dòng)發(fā)送,當(dāng)收到數(shù)據(jù)的時(shí)候,也是存在該寄存器內(nèi)。

    STM32 庫函數(shù)操作 USART_DR 寄存器發(fā)送數(shù)據(jù)的函數(shù)是:void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); 通過該函數(shù)向串口寄存器 USART_DR 寫入一個(gè)數(shù)據(jù)。

    STM32 庫函數(shù)操作 USART_DR 寄存器讀取串口接收到的數(shù)據(jù)的函數(shù)是:uint16_t USART_ReceiveData(USART_TypeDef* USARTx); 通過該函數(shù)可以讀取串口接收到的數(shù)據(jù)。

    串口狀態(tài)

    串口的狀態(tài)可以通過狀態(tài)寄存器 USART_SR 讀取。狀態(tài)寄存器 USART_SR 的各位描述如下圖:

    RXNE(讀數(shù)據(jù)寄存器非空)。當(dāng)該位被置 1 的時(shí)候,就是提示已經(jīng)有數(shù)據(jù)被接收到了,并且可以讀出來了。這時(shí)候我們要做的就是盡快去讀取 USART_DR,通過讀 USART_DR 可以將該位清零,也可以向該位寫 0,直接清除。

    TC(發(fā)送完成)。當(dāng)該位被置位的時(shí)候,表示 USART_DR 內(nèi)的數(shù)據(jù)已經(jīng)被發(fā)送完成了。如果設(shè)置了這個(gè)位的中斷, 則會(huì)產(chǎn)生中斷。 該位也有兩種清零方式: 1 )讀 USART_SR , 寫USART_DR。2)直接向該位寫 0。

    在我們固件庫函數(shù)里面,讀取串口狀態(tài)的函數(shù)是FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); 這里第二個(gè)入口參數(shù)非常關(guān)鍵,它是標(biāo)示我們要查看串口的哪種狀態(tài)。

    例如我們要判斷讀寄存器是否非空(RXNE),操作庫函數(shù)的方法為:
    USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
    判斷發(fā)送是否完成(TC),操作庫函數(shù)的方法為:
    USART_GetFlagStatus(USART1, USART_FLAG_TC);

    開啟串口響應(yīng)中斷

    有時(shí)候我們還需要開啟串口中斷,那么我們還需要使能串口中斷,使能串口中斷的函數(shù)是:void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState); 這個(gè)函數(shù)的第二個(gè)入口參數(shù)是標(biāo)示使能串口的類型,也就是使能哪種中斷,因?yàn)榇诘闹袛囝愋陀泻芏喾N。

    比如我們?cè)诮邮盏綌?shù)據(jù)的時(shí)候(RXNE讀數(shù)據(jù)寄存器非空),我們要產(chǎn)生中斷,那么我們開啟中斷的方法是:USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 開啟中斷,接收到數(shù)據(jù)中斷
    要在發(fā)送數(shù)據(jù)結(jié)束的時(shí)候(TC,發(fā)送完成)產(chǎn)生中斷的方法是:USART_ITConfig(USART1, USART_IT_TC, ENABLE);

    獲取相應(yīng)中斷狀態(tài)

    當(dāng)我們使能了某個(gè)中斷的時(shí)候,當(dāng)改中斷發(fā)生了,就會(huì)設(shè)置狀態(tài)寄存器中的某個(gè)標(biāo)志位。經(jīng)常我們?cè)谥袛嗵幚砗瘮?shù)中,要判斷該中斷是哪種中斷,使用的函數(shù)是:ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

    比如我們使能了串口發(fā)送完成中斷,那么當(dāng)中斷發(fā)生了,我們便可以在中斷處理函數(shù)中調(diào)用這個(gè)函數(shù)來判斷到底是否是串口發(fā)送完成中斷,方法是:USART_GetITStatus(USART1, USART_IT_TC); 返回值是 SET,說明是串口發(fā)送完成中斷發(fā)生。

    main.c

    #include "sys.h" #include "usart.h" #include "delay.h" #include "led.h" int main(void) {u8 t; u8 len;u16 times=0;delay_init(); //延時(shí)函數(shù)初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置中斷分組uart_init(9600); //串口初始化為 9600LED_Init(); //初始化與 LED 連接的硬件接口while(1){if(USART_RX_STA&0x8000){len=USART_RX_STA&0x3fff; //得到此次接收到的數(shù)據(jù)長度printf("\r\n 您發(fā)送的消息為:\r\n");for(t=0;t<len;t++){USART1->DR=USART_RX_BUF[t];while((USART1->SR&0X40)==0); //等待發(fā)送結(jié)束}printf("\r\n\r\n");//插入換行USART_RX_STA=0;}else{times++;if(times%5000==0){printf("\r\nALIENTEK MiniSTM32 開發(fā)板 串口實(shí)驗(yàn)\r\n");printf("正點(diǎn)原子@ALIENTEK\r\n\r\n\r\n");}if(times%200==0)printf("請(qǐng)輸入數(shù)據(jù),以回車鍵結(jié)束\r\n");if(times%30==0)LED0=!LED0; //閃爍 LED,提示系統(tǒng)正在運(yùn)行.delay_ms(10);}} }

    usart.c

    #include "sys.h" #include "usart.h" #if EN_USART1_RX //如果使能了接收 //串口1中斷服務(wù)程序 //注意,讀取USARTx->SR能避免莫名其妙的錯(cuò)誤 u8 USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個(gè)字節(jié). //接收狀態(tài) //bit15, 接收完成標(biāo)志 //bit14, 接收到0x0d //bit13~0, 接收到的有效字節(jié)數(shù)目 u16 USART_RX_STA=0; //接收狀態(tài)標(biāo)記 void uart_init(u32 bound){//GPIO端口設(shè)置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA時(shí)鐘//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//搶占優(yōu)先級(jí)3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子優(yōu)先級(jí)3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根據(jù)指定的參數(shù)初始化VIC寄存器//USART 初始化設(shè)置USART_InitStructure.USART_BaudRate = bound; //串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字長為8位數(shù)據(jù)格式USART_InitStructure.USART_StopBits = USART_StopBits_1; //一個(gè)停止位USART_InitStructure.USART_Parity = USART_Parity_No; //無奇偶校驗(yàn)位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //無硬件數(shù)據(jù)流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發(fā)模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //開啟串口接受中斷USART_Cmd(USART1, ENABLE); //使能串口1 }void USART1_IRQHandler(void) //串口1中斷服務(wù)程序{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷(接收到的數(shù)據(jù)必須是0x0d 0x0a結(jié)尾){Res = USART_ReceiveData(USART1); //讀取接收到的數(shù)據(jù)if((USART_RX_STA&0x8000)==0) //接收未完成{if(USART_RX_STA&0x4000) //接收到了0x0d{if(Res!=0x0a)USART_RX_STA=0; //接收錯(cuò)誤,重新開始else USART_RX_STA|=0x8000; //接收完成了 }else //還沒收到0X0D{ if(Res==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開始接收 } }} } } #endif

    查看手冊(cè)得知,配置全雙工的串口 1,那么 TX(PA9) 管腳需要配置為推挽復(fù)用輸出,RX(PA10)管腳配置為浮空輸入或者帶上拉輸入。

    這里需要注意一點(diǎn), 因?yàn)槲覀兪褂玫搅舜诘闹袛嘟邮?#xff0c; 必須在 usart.h 里面設(shè)置 EN_USART1_RX 為 1(默認(rèn)設(shè)置就是 1 的) 。該函數(shù)才會(huì)配置中斷使能,以及開啟串口 1 的 NVIC 中斷。

    我們之前進(jìn)行了開啟串口響應(yīng)中斷,接下來還要編寫中斷服務(wù)函數(shù)。

    串口 1 的中斷服務(wù)函數(shù)為 USART1_IRQHandler。之前已講過,在【STM32】SYSTEM文件夾介紹,delay,sys,usart。從之前的代碼可以看出,其初始化串口的過程,先計(jì)算得到 USART1->BRR 的內(nèi)容,然后開始初始化串口引腳,接著把 USART1 復(fù)位,之后設(shè)置波特率和奇偶校驗(yàn)等。

    重點(diǎn)看一下兩句函數(shù):

    USART_SendData(USART1, USART_RX_BUF[t]); // 向串口 1 發(fā)送數(shù)據(jù) while(USART_GetFlagStatus(USART1, USART_FLAG_TC)!=SET);

    第一句,其實(shí)就是發(fā)送一個(gè)字節(jié)到串口。
    第二句,就是我們?cè)诎l(fā)送一個(gè)數(shù)據(jù)到串口之后,要檢測(cè)這個(gè)數(shù)據(jù)是否已經(jīng)被發(fā)送完成了。
    USART_FLAG_TC 是宏定義的數(shù)據(jù)發(fā)送完成標(biāo)識(shí)符。

    usart.h

    #ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收 #define USART_REC_LEN 200 //定義最大接收字節(jié)數(shù) 200extern u8 USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個(gè)字節(jié).末字節(jié)為換行符 extern u16 USART_RX_STA; //接收狀態(tài)標(biāo)記 //如果想串口中斷接收,請(qǐng)不要注釋以下宏定義 void uart_init(u32 bound); #endif

    總結(jié)

    以上是生活随笔為你收集整理的【STM32】串口收发主要程序代码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 天天躁夜夜躁狠狠躁 | 色视频网站 | 欧美日韩综合网 | 国产二区精品 | 黑鬼巨鞭白妞冒白浆 | а√天堂资源官网在线资源 | 伊人色综合网 | 熟女高潮一区二区三区 | 欧美另类色| 在线观看色视频 | 亚洲区国产区 | 日日干影院| 欧美精品久久久久久久久久 | 粉嫩av一区二区三区四区五区 | 青草超碰 | 91超碰人人 | 色小说香蕉 | 夜夜骑夜夜 | 欧美性aaa | 久久网中文字幕 | 夜夜艹天天干 | 欧美日韩成人精品 | 最好看的mv中文字幕国语电影 | 伊人3| 特级免费毛片 | 自拍偷拍综合 | 五月婷婷亚洲综合 | 日啪| 久久久精品免费看 | 可以免费看av | 久久国语 | 多男调教一女折磨高潮高h 国内毛片毛片毛片毛片毛片 | 精品国产成人 | 小镇姑娘国语版在线观看免费 | 日本精品中文字幕 | 久久网页| xx视频在线观看 | 人妻内射一区二区在线视频 | 亚洲插 | www.日韩在线| 亚洲综合网在线观看 | 亚a在线| 日本一区二区高清不卡 | 日韩电影三级 | 中文字幕乱码亚洲无线三区 | 亚洲成人黄色小说 | 成人高潮视频 | 2019国产在线 | 97超碰人人模人人人爽人人爱 | 91在线小视频 | 国产精品久久久久一区二区三区 | 露胸app| 国模视频在线 | 国模叶桐尿喷337p人体 | 色婷婷综合在线 | 国产精品视频播放 | 色草在线 | 九九热精 | 动漫一区二区 | 最好看的电影2019中文字幕 | 欧美日韩六区 | 黄网站免费视频 | 精品人妻一区二区免费视频 | 超碰在线播放97 | 日韩欧美不卡 | 日韩片在线 | 亚洲综合图 | 中文字幕三级电影 | 日韩亚洲视频在线观看 | 国产乱视频 | 精品一区二区不卡 | 一级黄色片a | 成人综合在线观看 | 高清av一区 | 日韩黄色在线视频 | 少妇一区二区三区四区 | 色老头一区二区 | 少妇偷人精品无码人妻 | 国产精品影院在线观看 | 国产视频精品在线 | 自拍偷拍2019 | 极品少妇xxxx精品少妇 | 国产成人91精品 | 制服丝袜一区在线 | 免费看成人av | 97国产精东麻豆人妻电影 | 自拍偷拍p| 久久久男人的天堂 | 欧美福利网站 | 国产天堂精品 | 亚洲情涩 | 91热久久| 久色在线| 伊人自拍视频 | 日本免费一区二区三区最新 | 男人天堂欧美 | 国产精品久久777777 | 黄色短视频在线播放 | 91av视频在线|