當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀] 串口:一. USART_ITConfig(USART1, USART_IT_TXE, ENABLE):只要發(fā)送寄存器為空,就會(huì)一直有中斷,因此,要是不發(fā)送數(shù)據(jù)時(shí),把發(fā)送中斷關(guān)閉,只在開(kāi)始發(fā)送時(shí),才打開(kāi)。二.以下是字符發(fā)送的配置過(guò)程,注

串口

一. USART_ITConfig(USART1, USART_IT_TXE, ENABLE):

只要發(fā)送寄存器為空,就會(huì)一直有中斷,因此,要是不發(fā)送數(shù)據(jù)時(shí),把發(fā)送中斷關(guān)閉,只在開(kāi)始發(fā)送時(shí),才打開(kāi)。

二.

以下是字符發(fā)送的配置過(guò)程,注意第6點(diǎn),在設(shè)置USART_CR1中的TE位時(shí),會(huì)發(fā)送一個(gè)空閑幀作為第一次數(shù)據(jù)發(fā)送,所以即便你執(zhí)行了USART_ClearFlag(USART1, USART_FLAG_TC); (這個(gè)函數(shù)肯定在空閑幀數(shù)據(jù)發(fā)送完成前執(zhí)行),所以當(dāng)空閑幀發(fā)送完后,就進(jìn)入發(fā)送完成中斷。

配置步驟:
1.通過(guò)在USART_CR1寄存器上置位UE位來(lái)激活USART
2.編程USART_CR1的M位來(lái)定義字長(zhǎng)。
3.在USART_CR2中編程停止位的位數(shù)。
4.如果采用多緩沖器通信,配置USART_CR3中的DMA使能位(DMAT)。按多緩沖器通信中
的描述配置DMA寄存器。
5.利用USART_BRR寄存器選擇要求的波特率。
6.設(shè)置USART_CR1中的TE位,發(fā)送一個(gè)空閑幀作為第一次數(shù)據(jù)發(fā)送。
7.把要發(fā)送的數(shù)據(jù)寫進(jìn)USART_DR寄存器(此動(dòng)作清除TXE位)。在只有一個(gè)緩沖器的情況
下,對(duì)每個(gè)待發(fā)送的數(shù)據(jù)重復(fù)步驟7。
8.在USART_DR寄存器中寫入最后一個(gè)數(shù)據(jù)字后,要等待TC=1,它表示最后一個(gè)數(shù)據(jù)幀的
傳輸結(jié)束。當(dāng)需要關(guān)閉USART或需要進(jìn)入停機(jī)模式之前,需要確認(rèn)傳輸結(jié)束,避免破壞
最后一次傳輸。

解決的辦法:
方法一
在執(zhí)行USART_ITConfig(USART1,USART_IT_TC, ENABLE); 之前,
先延時(shí)一段時(shí)間,基本上比一個(gè)字符發(fā)送的時(shí)間長(zhǎng)一點(diǎn)就可以了,然后再執(zhí)行
USART_ClearFlag(USART1, USART_FLAG_TC);

方法二:
在執(zhí)行USART_ITConfig(USART1,USART_IT_TC, ENABLE); 之前,
USART_ClearFlag(USART1, USART_FLAG_TC);

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
{
; //等待空閑幀發(fā)送完成后再清零發(fā)送標(biāo)志
}
USART_ClearFlag(USART1,USART_FLAG_TC);

三.

TXE:發(fā)送緩沖器空閑標(biāo)志

RXNE:接收緩沖區(qū)非空

IAP:

一.

問(wèn):

這幾天在折騰STM32的IAP,參考了兩個(gè)例程,一個(gè)AN2557,然后一個(gè)就是標(biāo)準(zhǔn)外設(shè)庫(kù)內(nèi)的flash例程

總結(jié)IAP:

1.Flash解鎖FLASH_Unlock();

2.清除Flash所有的未完成的標(biāo)志位FLASH_ClearFlag(FLASH_FLAG_BSY|FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);

3.根據(jù)文件大小擦除Flash
for(EraseCounter=0;(EraseCounter{
FLASHStatus=FLASH_ErasePage(StartAddr+(FLASH_PAGE_SIZE*EraseCounter));
}

4.編程Flash
while((Address{
FLASHStatus=FLASH_ProgramWord(Address,Data);
Address=Address+4;
}

5.檢驗(yàn)編入數(shù)據(jù)的正確性
while((Address{
if((*(__IOuint32_t*)Address)!=Data)
{
MemoryProgramStatus=FAILED;
}
Address+=4;
}

在以上幾步中,如果上面沒(méi)有問(wèn)題的話,提出下面幾個(gè)疑問(wèn)

1.假如我的應(yīng)用程序的地址應(yīng)該從0x8003000開(kāi)始,那么我把后面的頁(yè)全部擦除是否可以?雖然我的程序可能只占到0x8003000-0x8005000那么這之后的頁(yè)是否也可以一并擦除?

2.在編程的時(shí)候有個(gè)很小的問(wèn)題,因我的數(shù)據(jù)都是以字節(jié)(byte)的形式儲(chǔ)存的,在寫的時(shí)候因?yàn)橹荒芤园胱?16位)或一個(gè)字(32位)的方式編程,那么如果我的bin
文件的最后一個(gè)字節(jié)并不夠兩個(gè)字節(jié),怎么辦?舉例:我的bin文件的大小是501個(gè)字節(jié)(8位),我的寫入方法是這樣的:
data[501]={X,X,X...}//應(yīng)用程序bin文件內(nèi)容
temp=data[0];
temp=temp<<8;
temp|=data[1];
temp=temp<<8;
temp|=data[2];
teme=temp<<8;
teme|=data[3];//待寫入得數(shù)據(jù)

FLASHStatus=FLASH_ProgramWord(Address,temp);//寫入flash

如果像這樣的話,那么不能被4整除的那一個(gè)字節(jié)怎么辦?

3.IAP程序中有一處一直很迷惑,不能理解
/*Testifusercodeisprogrammedstartingfromaddress"ApplicationAddress"*/
if(((*(__IOuint32_t*)ApplicationAddress)&0x2FFE0000)==0x20000000)
{/*Jumptouserapplication*/
JumpAddress=*(__IOuint32_t*)(ApplicationAddress+4);
Jump_To_Application=(pFunction)JumpAddress;
/*Initializeuserapplication'sStackPointer*/
__set_MSP(*(__IOuint32_t*)ApplicationAddress);
Jump_To_Application();
}
程序的整體是要跳出IAP引導(dǎo)區(qū)跳到應(yīng)用程序區(qū).那么這句判斷的依據(jù)是什么?if(((*(__IOuint32_t*)ApplicationAddress)&0x2FFE0000)==0x20000000)
倘若我今天的程序是重0x8003000處開(kāi)始,那么明天我升級(jí)一個(gè)程序,他的開(kāi)始是0x80080000呢?這里需要改嗎?

0x2FFE00000x20000000這兩個(gè)數(shù)我在AN2557的例子代碼里反復(fù)尋找,并沒(méi)有哪里出現(xiàn),那么又是怎么跟用戶的應(yīng)用程序關(guān)聯(lián)的呢?

還有如果將上面的例子直接這樣更改,是否可以達(dá)到跳轉(zhuǎn)到應(yīng)用程序區(qū)的目的呢?
/*Jumptouserapplication*/
JumpAddress=*(__IOuint32_t*)(ApplicationAddress+4);//這里為何要+4?+了4不就跳過(guò)出應(yīng)用程序的入口了嗎?
Jump_To_Application=(pFunction)JumpAddress;
/*Initializeuserapplication'sStackPointer*/
__set_MSP(*(__IOuint32_t*)ApplicationAddress);
Jump_To_Application();

4.關(guān)于Flash的寫保護(hù)問(wèn)題,在3.0標(biāo)準(zhǔn)外設(shè)庫(kù)中Flash還有另外一個(gè)例子,就是關(guān)于保護(hù)的
無(wú)疑flash的保護(hù)是對(duì)程序的一個(gè)安全保障,但目前我買的新片子(未進(jìn)行過(guò)任何保護(hù)方面的操作)中,是否不需要考慮這些問(wèn)題,直接擦除,然后編程即可?

5.有什么理由要“今天的程序是重0x8003000處開(kāi)始,明天又升級(jí)一個(gè)程序,他的開(kāi)始是呢”?第1沒(méi)有必要,第2是自尋煩惱。開(kāi)始地址是你自己定的,為什么要自己為難自己?

這個(gè)問(wèn)題怪我沒(méi)說(shuō)清楚,其實(shí)我是想說(shuō),我現(xiàn)在的引導(dǎo)區(qū)這樣定義的#ApplicationAddress0x80030000我只能啟動(dòng)起始地址在0x08003000處的應(yīng)用程序,那么這段代碼是可以成功啟動(dòng)的(我驗(yàn)證過(guò)):
/*Testifusercodeisprogrammedstartingfromaddress"ApplicationAddress"*/
if(((*(__IOuint32_t*)ApplicationAddress)&0x2FFE0000)==0x20000000)
{/*Jumptouserapplication*/
JumpAddress=*(__IOuint32_t*)(ApplicationAddress+4);
Jump_To_Application=(pFunction)JumpAddress;
/*Initializeuserapplication'sStackPointer*/
__set_MSP(*(__IOuint32_t*)ApplicationAddress);
Jump_To_Application();
}

那如果我現(xiàn)在想引導(dǎo)啟動(dòng)地址在0x80080000的應(yīng)用程序,是否只要更改#ApplicationAddress0x80080000這句就好?上面那串代碼就不需要更改了吧?

我還是想理解了上面的那串代碼到底是為什么?希望香版能仔細(xì)幫我解釋下,(當(dāng)我白癡好了,呵呵)!

答:

1.可以,只要不影響功能就行
2.比較好的解決方法,先讀一頁(yè)出來(lái)到RAM,擦掉這一頁(yè)Flash,在RAM中修改相應(yīng)的Bytes,再將整頁(yè)寫回去?!∫话愕慕鉀Q方法,后面不足一個(gè)WORD/DWORD的補(bǔ)0xff或0x00,補(bǔ)齊一個(gè)WORD或DWORD

3.ApplicationAddress對(duì)應(yīng)著你的應(yīng)用程序"stm32f10x_vector.c"這個(gè)文件中的__vector_table
*(__IOuint32_t*)ApplicationAddress與__vector_table[0]是一樣的
*(__IOuint32_t*)(ApplicationAddress+4)與__vector_table[1]是一樣的
__vector_table[0]是應(yīng)用程序棧的頂
__vector_table[1]是應(yīng)用程序的啟動(dòng)地址
這里有討論過(guò)
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=1600156&bbs_page_no=3&bbs_id=3020

(X&0x2FFE0000)==0x20000000意思是說(shuō)X是不是在0x20000000與0x2001FFFF之間,即棧頂是不是在以0x20000000開(kāi)始的128K

的范圍內(nèi),這里便是STM32的RAM區(qū)域,雖然現(xiàn)在最大的只有64k

如果你的bootloader只能啟動(dòng)0x08003000的應(yīng)用程序,那么你寫一個(gè)起始地址在0x08008000的程序他將不能啟動(dòng)
你要寫一個(gè)在0x080003000的啟動(dòng)程序來(lái)啟動(dòng)0x08008000的應(yīng)用程序,或者把0x08008000前八字節(jié)的內(nèi)容放到0x08003000中

4.是的,買回來(lái)的可以直接寫,出廠時(shí)芯片的Flash都沒(méi)有設(shè)置保護(hù)。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉