0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32的串口實(shí)驗(yàn)(寄存器操作版本)

dytfki8u8yql ? 來(lái)源:電子技術(shù)控 ? 2023-04-23 10:07 ? 次閱讀
USART—通用同步異步收發(fā)接收器,是一個(gè)串行通信設(shè)備,可以和外部設(shè)備進(jìn)行靈活的全雙工數(shù)據(jù)交換,有別于USART還有一個(gè)UART(在原來(lái)的基礎(chǔ)上裁剪掉了同步通信功能(時(shí)鐘同步)),串行通信一般是以幀格式傳輸數(shù)據(jù),一幀一幀的傳。 協(xié)議層:串口通信的一個(gè)數(shù)據(jù)包包含從起始信號(hào)開(kāi)始,直到停止信號(hào)的結(jié)束起始信號(hào):一個(gè)邏輯0數(shù)據(jù)位表示。停止信號(hào):0.5,1,1.5或2個(gè)邏輯1的數(shù)據(jù)位表示。0.5個(gè)停止位:智能卡模式下的接收數(shù)據(jù)時(shí)使用。1個(gè)停止位:停止位的默認(rèn)數(shù)值1.5個(gè)停止位:智能卡模式下的手法數(shù)據(jù)和接收數(shù)據(jù)時(shí)使用2個(gè)停止位:常規(guī)USART模式,單線模式以及調(diào)制解調(diào)器的模式。有效數(shù)據(jù)的基本長(zhǎng)度被約定為5,6,7,8.奇偶檢驗(yàn)(設(shè)置USART-CR1 的PS位)偶檢驗(yàn):數(shù)據(jù)=00110101,里面數(shù)據(jù)1的個(gè)數(shù)位為偶數(shù)位,檢驗(yàn)位置“0”,當(dāng)數(shù)據(jù)檢驗(yàn)和偶數(shù)相同的時(shí)候,證明沒(méi)有出錯(cuò),反之則錯(cuò)誤奇檢驗(yàn):數(shù)據(jù) = 01110101,里面數(shù)據(jù)1的個(gè)數(shù)為奇檢位,檢驗(yàn)位置“1”,當(dāng)數(shù)據(jù)檢驗(yàn)和奇數(shù)相同,則證明沒(méi)有出錯(cuò),反之錯(cuò)誤。當(dāng)然也會(huì)存在同時(shí)兩個(gè)位一塊出現(xiàn)錯(cuò)誤,導(dǎo)致無(wú)法判斷是否位奇偶檢驗(yàn)的錯(cuò)誤,但發(fā)生的概率很低。 下面這張圖需要重點(diǎn)理解下面是對(duì)代碼的理解:首先先看這個(gè)圖,,可以看出USART_RX_STA類(lèi)似與一個(gè)16位的寄存器,前14位存儲(chǔ)的是數(shù)據(jù),后面兩個(gè)分別檢測(cè)0X0D和0X0A。接下里分析:

	void uart_init(u32 pclk2,u32 bound) { float temp; u16 mantissa; u16 fraction; temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV mantissa=temp; //得到整數(shù)部分 fraction=(temp-mantissa)*16; //得到小數(shù)部分 mantissa<<=4; mantissa+=fraction; RCC->APB2ENR|=1<<2; //使能PORTA口時(shí)鐘 RCC->APB2ENR|=1<<14; //使能串口時(shí)鐘 GPIOA->CRH&=0XFFFFF00F;//IO狀態(tài)設(shè)置 GPIOA->CRH|=0X000008B0;//IO狀態(tài)設(shè)置 RCC->APB2RSTR|=1<<14; //復(fù)位串口1 RCC->APB2RSTR&=~(1<<14);//停止復(fù)位 //波特率設(shè)置 USART1->BRR=mantissa; // 波特率設(shè)置 USART1->CR1|=0X200C; //1位停止,無(wú)校驗(yàn)位. #if EN_USART1_RX //如果使能了接收 //使能接收中斷 USART1->CR1|=1<<5; //接收緩沖區(qū)非空中斷使能 MY_NVIC_Init(3,3,USART1_IRQn,2);//組2,最低優(yōu)先級(jí) #endif }temp=(float)(pclk2*1000000)/(bound*16);這是一個(gè)計(jì)算公式,因?yàn)槭鼓艿氖谴?,而串口1是在APB2ENR寄存器里面(其余串口均在寄存器APB1ENR里面),因?yàn)锳PB2的頻率一般位72M,而APB1的頻率一般位36M。所以這里的pclk2為72M,而bound是你需要設(shè)置的波特率。

	USARTX-BRR:前四位為小數(shù)部分 ,后12位是整數(shù)部分,假設(shè)算出來(lái)的mantissa = 39.5,小數(shù)部分相當(dāng)于把1分成了16份,所以相當(dāng)于把0.5*16轉(zhuǎn)化為二進(jìn)制存入。

	mantissa = temp的作用僅僅是:為了接下來(lái)將小數(shù)部分求出來(lái) fraction=(temp-mantissa)*16; //得到小數(shù)部分 mantissa<<=4;這兩行代碼是為將十進(jìn)制的整數(shù)部分和小數(shù)部分,分別轉(zhuǎn)化為16進(jìn)制。然后存入到波特率寄存器里面。緊接著使能串口1和PORTA時(shí)鐘(串口一對(duì)應(yīng)的IO口是PA9,PA10,需要拿跳帽連接在一起).然后將IO口置零,然后分別進(jìn)行設(shè)置成一個(gè)輸入一個(gè)輸出,

	USART1->CR1|=0X200C; 設(shè)置成使能串口8個(gè)字長(zhǎng)1個(gè)停止位(USART_CR2中[13:12]默認(rèn)為“0”) MY_NVIC_Init(3,3,USART1_IRQn,2)將其分在組2里面,此時(shí)的搶占優(yōu)先級(jí):響應(yīng)優(yōu)先級(jí)為 = 2:2,即(00-11)四種情況,而3:3的安排選擇了組2優(yōu)先級(jí)最小的一種情況。這樣可以先執(zhí)行上面的波特率賦值,以及串口使能等等操作,最后再進(jìn)行這行代碼運(yùn)行。接下來(lái)看下一部分:

	u16 USART_RX_STA=0; //接收狀態(tài)標(biāo)記 void USART1_IRQHandler(void) { u8 res; #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS為真,則需要支持OS. OSIntEnter(); #endif if(USART1->SR&(1<<5)) //接收到數(shù)據(jù) { res=USART1->DR; if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(res!=0x0a)USART_RX_STA=0;//接收錯(cuò)誤,重新開(kāi)始 else USART_RX_STA|=0x8000; //接收完成了 } else //還沒(méi)收到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ò)誤,重新開(kāi)始接收 } } } }起始階段: USART_RX_STA=0,對(duì)接受狀態(tài)的標(biāo)記。先通過(guò)狀態(tài)寄存器SR的RXNE是否為1,是1則接收到了數(shù)據(jù),反之則沒(méi)有。緊接這定義一個(gè)res變量來(lái)接收從數(shù)據(jù)寄存器的一個(gè)字節(jié),然后此時(shí)USART_RX_STA為0,與0X8000進(jìn)行&運(yùn)算,結(jié)果為0,則未接受到,接著繼續(xù)進(jìn)行判斷,0X4000進(jìn)行與運(yùn)算,看是否為0,也是判斷是否接受道路0X0D,如果沒(méi)有接受到,則將這個(gè)res變量存放在數(shù)組里面,此時(shí)的USART_RX_STA為 0 與0X3fff進(jìn)行&運(yùn)算,大家算算會(huì)發(fā)現(xiàn),因?yàn)樗那?4位是數(shù)據(jù)位,所以你會(huì)發(fā)現(xiàn)第一個(gè)變量就會(huì)存放在BUF[0]里面,大概邏輯是這樣的:所以每個(gè)字節(jié)都會(huì)被存放到具體的數(shù)組位上 。if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收數(shù)據(jù)錯(cuò)誤,重新開(kāi)始接收當(dāng)數(shù)組越界的時(shí)候,則會(huì)重新開(kāi)始。接下來(lái)就會(huì)一直循環(huán),當(dāng)數(shù)據(jù)位存滿后,接下來(lái)res里面接受的就是0X0D,先和上面一樣判斷USART_RX_STA是否接受到了0X0A和0X0D。接著執(zhí)行:

	if(res==0x0d)USART_RX_STA|=0x4000;將USART_RX_STA的第十五位變?yōu)?,,接下來(lái)進(jìn)行下一次循環(huán),這一次res接受到的值為0X0A,然后進(jìn)行判斷進(jìn)入到

	if(USART_RX_STA&0x4000)//接收到了0x0d { if(res!=0x0a)USART_RX_STA=0;//接收錯(cuò)誤,重新開(kāi)始 else USART_RX_STA|=0x8000; //接收完成了 }所以執(zhí)行USART_RX_STA|=0x8000,使得USART_RX_STA的第十六位變?yōu)?。接下來(lái)看主函數(shù)部分:

	int main(void) { u8 t; u8 len; u16 times=0; Stm32_Clock_Init(9); //系統(tǒng)時(shí)鐘設(shè)置 delay_init(72); //延時(shí)初始化 uart_init(72,9600); //串口初始化為9600 LED_Init(); //初始化與LED連接的硬件接口 while(1) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//得到此次接收到的數(shù)據(jù)長(zhǎng)度 printf(" 您發(fā)送的消息為: "); for(t=0;tDR=USART_RX_BUF[t]; while((USART1->SR&0X40)==0);//等待發(fā)送結(jié)束 } printf(" ");//插入換行 USART_RX_STA=0; }else { times++; if(times%5000==0) { printf(" ALIENTEK MiniSTM32開(kāi)發(fā)板 串口實(shí)驗(yàn) "); printf("正點(diǎn)原子@ALIENTEK "); } if(times%200==0)printf("請(qǐng)輸入數(shù)據(jù),以回車(chē)鍵結(jié)束 "); if(times%30==0)LED0=!LED0;//閃爍LED,提示系統(tǒng)正在運(yùn)行. delay_ms(10); } } }if(USART_RX_STA&0x8000) 判斷是否接收到了0X0Alen=USART_RX_STA&0x3fff;舉個(gè)簡(jiǎn)單的例子此時(shí)USART_RX_STA為1100000000000011和0X3fff進(jìn)行&運(yùn)算,得到的結(jié)果是3,自然就表示了當(dāng)前數(shù)組的大小。最后階段,重點(diǎn)理解以下兩行代碼:

	USART1->DR=USART_RX_BUF[t]; while((USART1->SR&0X40)==0);//等待發(fā)送結(jié)束分析如下:將每個(gè)組內(nèi)的信息存入到數(shù)據(jù)寄存器,此時(shí)數(shù)據(jù)寄存器將數(shù)據(jù)給TDR,發(fā)送信息的時(shí)候,是一位一位發(fā)送的,每一數(shù)據(jù)幀都有起始位,數(shù)據(jù)位,以及停止位,當(dāng)檢測(cè)到數(shù)據(jù)寄存器的細(xì)信息發(fā)送完了(完全給了TDR),此時(shí)狀態(tài)寄存器的TXE便變?yōu)?,當(dāng)檢測(cè)到TXE為1后,TC也會(huì)變?yōu)?(系統(tǒng)自動(dòng)進(jìn)行)。所以第二行才會(huì)檢測(cè)這個(gè)狀態(tài)寄存器的第6位是否為1來(lái)判斷是否發(fā)送成功了這個(gè)字節(jié)。由此推出,直接判斷TXE也可以判斷發(fā)送是否完成所以代碼可以改為:

	for(t=0;tDR=USART_RX_BUF[t]; while((USART1->SR&0X80)==0);//等待發(fā)送結(jié)束
		


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接收器
    +關(guān)注

    關(guān)注

    14

    文章

    2472

    瀏覽量

    71912
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10900

    瀏覽量

    356041
  • 通信設(shè)備
    +關(guān)注

    關(guān)注

    3

    文章

    337

    瀏覽量

    32055

原文標(biāo)題:老工程師:STM32的串口實(shí)驗(yàn)(寄存器操作版本)

文章出處:【微信號(hào):電子技術(shù)控,微信公眾號(hào):電子技術(shù)控】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    stm32標(biāo)準(zhǔn)例程-寄存器

    stm32標(biāo)準(zhǔn)例程-寄存器版本的源代碼,57個(gè)實(shí)驗(yàn)例程,從跑馬燈到操作系統(tǒng),全方位學(xué)習(xí)stm32
    發(fā)表于 11-26 16:17 ?0次下載

    ALIENTEK_MINISTM32_實(shí)驗(yàn)3_串口實(shí)驗(yàn)

    ALIENTEK MINISTM32 實(shí)驗(yàn)3 串口實(shí)驗(yàn),很好的資料,快來(lái)學(xué)習(xí)吧
    發(fā)表于 02-18 14:58 ?9次下載

    如何通過(guò)STM32串口實(shí)現(xiàn)簡(jiǎn)易脫機(jī)編程

    如何通過(guò)STM32串口實(shí)現(xiàn)簡(jiǎn)易脫機(jī)編程如何通過(guò)STM32串口實(shí)現(xiàn)簡(jiǎn)易脫機(jī)編程如何通過(guò)
    發(fā)表于 04-25 09:38 ?60次下載

    STM32單片機(jī)不完全手冊(cè)之寄存器版本

    STM32單片機(jī)不完全手冊(cè)之寄存器版本
    發(fā)表于 07-31 16:10 ?0次下載

    STM32F1開(kāi)發(fā)指南-寄存器版本_V3.3.pdf(上)

    STM32F1開(kāi)發(fā)指南-寄存器版本_V3.3.pdf(上)
    發(fā)表于 09-28 09:29 ?0次下載

    STM32F1開(kāi)發(fā)指南-寄存器版本_V3.3pdf(下)

    STM32F1開(kāi)發(fā)指南-寄存器版本_V3.3pdf(下)
    發(fā)表于 09-28 09:31 ?0次下載

    STM32寄存器實(shí)現(xiàn)流水燈效果

    一、實(shí)驗(yàn)原理(一)寄存器地址查找STM32給不同的寄存器分配了不同的地址在《STM32中文參考手冊(cè)_V10》的第28頁(yè),有不同
    發(fā)表于 12-07 10:06 ?2次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>寄存器</b>實(shí)現(xiàn)流水燈效果

    STM32寄存器實(shí)現(xiàn)流水燈效果

    一、實(shí)驗(yàn)原理(一)寄存器地址查找STM32給不同的寄存器分配了不同的地址在《STM32中文參考手冊(cè)_V10》的第28頁(yè),有不同
    發(fā)表于 12-07 10:21 ?8次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>寄存器</b>實(shí)現(xiàn)流水燈效果

    STM32寄存器版本】實(shí)例之串口通訊

    以我現(xiàn)在的水平還啥都不了解,所以這次主要說(shuō)的就是通過(guò)USB串口和電腦通信**串口配置**:詳細(xì)配置可以參考STM32開(kāi)發(fā)指南寄存器版本的5.
    發(fā)表于 12-08 17:36 ?0次下載
    【<b class='flag-5'>STM32</b>—<b class='flag-5'>寄存器</b><b class='flag-5'>版本</b>】實(shí)例之<b class='flag-5'>串口</b>通訊

    STM32】基于cubemx+HAL庫(kù)的串口實(shí)驗(yàn)(一)

    stm32串口實(shí)驗(yàn)一、實(shí)驗(yàn)前準(zhǔn)備二、具體項(xiàng)目代碼項(xiàng)目1:printf重定向實(shí)驗(yàn),輪詢方式通信重定向:輪詢方式:中斷方式:項(xiàng)目2:中斷方式的串口
    發(fā)表于 12-09 13:06 ?3次下載
    【<b class='flag-5'>STM32</b>】基于cubemx+HAL庫(kù)的<b class='flag-5'>串口實(shí)驗(yàn)</b>(一)

    STM32的USART串口通訊程序

    文章目錄文章目錄文章目錄寄存器與固態(tài)庫(kù)一、了解串口通信及準(zhǔn)備工作1.串口通信簡(jiǎn)介2.STM32 的 USART 簡(jiǎn)介3.實(shí)驗(yàn)環(huán)境二、USAR
    發(fā)表于 12-16 16:57 ?10次下載
    <b class='flag-5'>STM32</b>的USART<b class='flag-5'>串口</b>通訊程序

    STM32串口通信相關(guān)寄存器和中斷回調(diào)函數(shù)

    STM32串口通信相關(guān)寄存器狀態(tài)寄存器 (USART_SR)數(shù)據(jù)寄存器 (USART_DR)波特率寄存器
    發(fā)表于 12-28 19:11 ?7次下載
    <b class='flag-5'>STM32</b><b class='flag-5'>串口</b>通信相關(guān)<b class='flag-5'>寄存器</b>和中斷回調(diào)函數(shù)

    2021-04-17 STM32串口寄存器庫(kù)函數(shù)配置

    STM32串口寄存器庫(kù)函數(shù)配置方法STM32常用寄存器和庫(kù)函數(shù)串口配置一般步驟(
    發(fā)表于 12-28 19:13 ?7次下載
    2021-04-17  <b class='flag-5'>STM32</b><b class='flag-5'>串口</b><b class='flag-5'>寄存器</b>庫(kù)函數(shù)配置

    STM32寄存器操作

    STM32寄存器操作在使用STM32單片機(jī)編程時(shí)一般都用ST給的庫(kù)函數(shù)編程,庫(kù)函數(shù)編程的底層就是對(duì)單片機(jī)寄存器
    發(fā)表于 01-13 15:43 ?19次下載
    <b class='flag-5'>STM32</b>的<b class='flag-5'>寄存器</b><b class='flag-5'>操作</b>

    STM32F407-雙串口實(shí)驗(yàn)

    STM32F407-雙串口實(shí)驗(yàn),程序?qū)?b class='flag-5'>串口1和串口2全部調(diào)通,可同時(shí)使用
    發(fā)表于 06-13 15:06 ?29次下載