国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

菜喵のSTM32F4學習筆記(1)USART

2020-08-25 12:50 作者:竹之武  | 我要投稿

????這個系列的文章幾乎沒有怎么潤色,大約保留了自己學習過程中的原始筆記和debug記錄,部分內(nèi)容甚至很基礎(chǔ),bug出的也很沒水平,大家笑一笑就好2333。 ?

? 注1:本系列筆記中使用STM32F407ZGT6,利用STM32庫函數(shù)進行開發(fā); ?

??注2:個人筆記,記錄的是零散的知識,不對涉及到的背景知識進行的鋪開介紹(換句話說這不是一個成體系的可以視作學習用的教材的筆記,不過可以做交流參考~); ????

? 注3:啥時候B站專欄有代碼塊和公式啊qwq(每篇一問(笑))


????? ? 寫在筆記前:

????????關(guān)于STM32配置操作的部分內(nèi)容,個人感覺在了解了GPIO以及各個外設(shè)涉及到的寄存器之后,再來看各種庫函數(shù)會有一種啟明的感覺23333。

????????此時通過“到定義”的方式查看各個函數(shù)的實現(xiàn)也能比較容易地了解到這些亂七八糟的函數(shù)到底都在動那些寄存器、又干了些啥(筆記Note1中記錄的就是這樣的過程)。

????????稍微熟悉一點之后你甚至可以主動探索了:或者從各個外設(shè)的功能出發(fā),看對應(yīng)文件下定義的函數(shù)以及其中操作的寄存器;或者從文件出發(fā),通過看函數(shù)和寄存器反推這個外設(shè)在干嘛23333。


Note1:(這部分在研究GPIO復(fù)用操作(有點細過頭了2333))

?? ?首先,外設(shè)和GPIO不一定掛載在同一個時鐘上,所以可能要分別使能相關(guān)時鐘總線。STM32F4給了五個外設(shè)時鐘使能函數(shù):

一番搜索不難發(fā)現(xiàn)(stm32f4xx_rcc.h):

GPIO 均掛載在AHB1時鐘上
USART1 掛載在APB2時鐘上

????????之后,注意到GPIO結(jié)構(gòu)體沒有涉及到對于AFRL &AFRH寄存器的操作,也就是說即使MODER寄存器里面選擇了復(fù)用功能,復(fù)用器也沒有配置。

GPIO_InitTypeDef結(jié)構(gòu)體,沒有AFR寄存器的事r

????????查看GPIO_PinAFConfig函數(shù)定義(在stm32f4xx_gpio.c文件中 )可知,關(guān)于每一個GPIO口的復(fù)用器設(shè)置,還是需要用函數(shù)單獨操作一下的(GPIOx->AFR)


????????或者換句話說,你看完之后就知道為啥GPIO復(fù)用的時候還要用這樣一個函數(shù)了,而不是在GPIO_Init()中完成所有的定義(前提:你知道STM32F4當中都有哪些寄存器,分別有什么功能)。

????????不過這里我在想,?如果你足夠巨佬也足夠頑皮,你可以考慮修改一下庫函數(shù)的內(nèi)容(笑),比如把GPIO_PinAFConfig中的內(nèi)容改寫到GPIO_Init()當中,然后修改一下GPIO_InitTypeDef結(jié)構(gòu)體啥的(x),這樣你就可以少寫一兩行GPIO復(fù)用的代碼了,是不是很方便23333(x)。


????????對于GPIO_PinAFConfig()中可選用的GPIO_AF,在stm32f4xx_gpio.h中有定義(我用的是STM32F407,故而是這一段)


????????可以看到,串口USART、UART都在,不區(qū)分TX、RX;所以復(fù)用的時候直接設(shè)置為GPIO_AF_USART1就好。

? ? ????查閱芯片數(shù)據(jù)手冊得PA9、PA10 可擔當串口復(fù)用大任:

????????故最后GPIO復(fù)用如下:

????????這里就完成了將特定一組GPIO中的特定的IO口通過復(fù)用器連接到其對應(yīng)復(fù)用功能上的操作了。

試驗1:含中斷的串口發(fā)送試驗

????????第一次寫的主程序如下(Usart_Init();為串口初始化代碼,對串口1?進行初始化操作,后文有說明)

data遞增,準備打印
程序運行時候的串口監(jiān)視器(笑)

????????打印的應(yīng)該是ASCII碼,不過看起來,ASCII碼中確實不是所有的字符都是可打印的。

圖源百度百科ASCII碼條目。由圖易知,從十進制32 - 十進制127的符號是可被打印的

debug1:

????????看起來直接發(fā)送數(shù)據(jù)不太現(xiàn)實(或者我沒了解到),所以試著用字符串來實現(xiàn)收發(fā):

1、關(guān)于這里的字符串結(jié)尾,似乎必須寫成\r\n才能實現(xiàn)換行,單獨的\n不行

2、在輪詢發(fā)送data字符串的時候,有一個2ms的延時,如果這個延時沒有的話,運行效果是這個樣子的:

目測是因為DR寫入的太快,有些數(shù)據(jù)沒發(fā)出去就被覆蓋了。
手動@一下F4的USART結(jié)構(gòu)圖 DR寄存器部分(不過,@這兒似乎不是很能說明問題):

3、所以講道理除了延時應(yīng)該還有一個辦法:等待發(fā)送完成。故代碼應(yīng)該可以改成如下內(nèi)容:

附一張完成的串口結(jié)構(gòu)圖,在ST官方的中文參考手冊上可查

bug修復(fù)!

Code1:

#include "stm32f4xx.h"

#include "delay.h"


void Usart_Init()

{

GPIO_InitTypeDef? GPIO_Struct;

USART_InitTypeDef USART_Struct;

NVIC_InitTypeDef NVIC_Struct;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //初始化USART時鐘

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //初始化GPIO時鐘


//開啟GPIO復(fù)用

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);?


GPIO_Struct.GPIO_Mode = GPIO_Mode_AF;

GPIO_Struct.GPIO_OType = GPIO_OType_PP;

GPIO_Struct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;

GPIO_Struct.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;


//初始化GPIO

GPIO_Init(GPIOA,&GPIO_Struct);?


USART_Struct.USART_BaudRate = 9600;

USART_Struct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;

USART_Struct.USART_Parity = USART_Parity_No;

USART_Struct.USART_StopBits = USART_StopBits_1;

USART_Struct.USART_WordLength = USART_WordLength_8b;

USART_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;


USART_Init(USART1,&USART_Struct);

USART_Cmd(USART1,ENABLE); //咋那么多使能2333


NVIC_Struct.NVIC_IRQChannel = USART1_IRQn;

NVIC_Struct.NVIC_IRQChannelCmd = ENABLE;

NVIC_Struct.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_Struct.NVIC_IRQChannelSubPriority = 2;

NVIC_Init(&NVIC_Struct); // 初始化中斷


USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //配置串口中斷標志位(接收觸發(fā))

}


//串口1 中斷服務(wù)函數(shù)

void USART1_IRQHandler(void)

{

????u8 res;

???? if(USART_GetITStatus(USART1,USART_IT_RXNE))

???? {

???????? res = USART_ReceiveData(USART1);

???????? USART_SendData(USART1,res);

???? }

}


//字符串長度獲取函數(shù)

int len(char * strdata)

{

???? char * point? = strdata;

???? int counter = 0;

???? while(*point!='\0')

???? {

???????? counter++;

???????? point++;

???? }

???? return counter;

}

//主函數(shù)

int main()

{

????char *data="Please Input Something\r\n";

????char *point;

????NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

????delay_init(168); //延時初始化


????Usart_Init();

????while(1)

????{

???? point = data;

???? delay_ms(1000);

???????? while(*point != data[len(data)])

???????? {

???????????? USART_SendData(USART1,*point);

???????????? point++;

???????????? while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);

?????????}

????}

}

運行結(jié)果如下所示:

可以,它換行了。

????????然后既然初始化了中斷,我們就稍微皮一下。

劃重點:發(fā)送周期1ms

????????發(fā)送數(shù)據(jù),周期設(shè)置為1ms,看看能不能破壞輪詢中向PC端發(fā)送的數(shù)據(jù)。

實驗結(jié)果:

可以,破壞了!(?)

????????這里應(yīng)該有兩次STM32發(fā)送給PC的信息"Please Input Something\r\n",第一次應(yīng)該是丟失了'P'、"\r\n";第二次應(yīng)該是丟失了'P' 't'?兩個字符。

????????也就是說,如果中斷和輪詢都要用到串口的話,是可能產(chǎn)生兩個發(fā)送信息交叉影響的結(jié)果的。所以如果之后用到遙控器或者別的通訊、特別是用同一個串口(或者別的信道)的時候,小心一點。


????????#MARK一下,這里我打算之后試一試在中斷服務(wù)函數(shù)中判斷SR寄存器,看看能不能做到兩個發(fā)送信息不沖突(起碼,不要丟失字符,哪怕兩條信息混在一起呢)

????????今天先不寫了,先去啃PWM的內(nèi)容233333 。


菜喵のSTM32F4學習筆記(1)USART的評論 (共 條)

分享到微博請遵守國家法律
博爱县| 库尔勒市| 西林县| 柘城县| 台南市| 霍林郭勒市| 海宁市| 简阳市| 城口县| 太康县| 建瓯市| 外汇| 尼木县| 临潭县| 宜宾县| 阆中市| 临桂县| 枞阳县| 徐水县| 玉溪市| 黑龙江省| 达拉特旗| 汉寿县| 育儿| 鄂州市| 南宁市| 军事| 金昌市| 仙游县| 内丘县| 老河口市| 林芝县| 鹤峰县| 南涧| 大连市| 漳平市| 江源县| 宜春市| 泸定县| 巴塘县| 稻城县|