五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

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

菜喵のSTM32F4學(xué)習(xí)筆記(1)USART

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

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

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

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

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


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

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

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

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


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

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

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

GPIO 均掛載在AHB1時(shí)鐘上
USART1 掛載在APB2時(shí)鐘上

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

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

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


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

????????不過這里我在想,?如果你足夠巨佬也足夠頑皮,你可以考慮修改一下庫函數(shù)的內(nèi)容(笑),比如把GPIO_PinAFConfig中的內(nèi)容改寫到GPIO_Init()當(dāng)中,然后修改一下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í)候直接設(shè)置為GPIO_AF_USART1就好。

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

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

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

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

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

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

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

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

debug1:

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

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

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

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

3、所以講道理除了延時(shí)應(yīng)該還有一個(gè)辦法:等待發(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時(shí)鐘

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


//開啟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); //配置串口中斷標(biāo)志位(接收觸發(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); //延時(shí)初始化


????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);

?????????}

????}

}

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

可以,它換行了。

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

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

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

實(shí)驗(yàn)結(jié)果:

可以,破壞了?。??)

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

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


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

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


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

分享到微博請遵守國家法律
车险| 凌云县| 玛曲县| 静宁县| 玉屏| 高台县| 白水县| 桃园县| 新乐市| 阿鲁科尔沁旗| 徐水县| 拜泉县| 连云港市| 安国市| 洞口县| 海阳市| 南投县| 太和县| 唐海县| 搜索| 建平县| 勃利县| 昭平县| 健康| 新和县| 加查县| 开阳县| 晴隆县| 保德县| 宜兰市| 互助| 苏尼特右旗| 天门市| 濉溪县| 固安县| 秀山| 东安县| 苏尼特左旗| 获嘉县| 沛县| 静乐县|