娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年06月13日(星期五)

2019年06月13日 | STM32自打包的UART串口通訊編程方法

發(fā)布者:sunyouz1 來(lái)源: eefocus關(guān)鍵字:STM32  UART  串口通訊  編程方法 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

    在對(duì)通訊時(shí)間要求比較高的時(shí)候,就需要自己對(duì)UART的通訊底層直接進(jìn)行操作。我以STM32單片機(jī)為例,講一下比較快速的UART編程方法。——其實(shí)不止是STM32這么處理,我以前使用過(guò)51的單片機(jī),TI的MSP單片機(jī),三菱的16位單片機(jī),都可以采用這種方法。


    基本的處理思路如下:


    1. UART接收的處理方法


        打開(kāi)UART的接收中斷,每收到一個(gè)字節(jié)就放到接收緩沖區(qū),同時(shí)更新接收指針。當(dāng)連續(xù)100ms沒(méi)有收到接收字符,則認(rèn)為本次幀接收完畢,置位幀接收完成標(biāo)志,由主程序進(jìn)行處理。


    2. UART發(fā)送的處理方法


        將需要發(fā)送的數(shù)據(jù)放到發(fā)送緩沖區(qū),設(shè)置發(fā)送長(zhǎng)度。然后發(fā)送第一個(gè)字節(jié),并打開(kāi)發(fā)送中斷。在發(fā)送中斷中判斷是否已經(jīng)發(fā)送了指定長(zhǎng)度的數(shù)據(jù)。如果沒(méi)有發(fā)送完成,則繼續(xù)發(fā)送;發(fā)送完成,則關(guān)閉發(fā)送中斷。


     以上方法,說(shuō)起來(lái)比較簡(jiǎn)單,主要是容錯(cuò)的處理,以及細(xì)節(jié)的考慮。以下我以STM32單片機(jī)為例進(jìn)行說(shuō)明。


    1. 定義需要的變量


uint8_t gcRXDBuffer[50], gcRXDPointer, gcRXDLength;    //接收的緩沖區(qū)、接收指針、接收的幀長(zhǎng)度

uint8_t gcTXDBuffer[50], gcTXDPointer, gcTXDLength;    //發(fā)送的緩沖區(qū),發(fā)送指針,發(fā)送的長(zhǎng)度

uint8_t gcInRXDMode, gcInTXDMode;                //是否處于接收或發(fā)送的狀態(tài)標(biāo)志,在需要切入低功耗模式,或關(guān)閉其他功能時(shí)需要

    2. 初始化UART寄存器,以LL庫(kù)為例,HAL庫(kù)也可以。其實(shí)這部分功能使用STM32CUBEMX自己生成就行,不用給自己編寫。


/* USART2 init function */

static void MX_USART2_UART_Init(void)

{

  LL_USART_InitTypeDef USART_InitStruct;

  LL_GPIO_InitTypeDef GPIO_InitStruct;

 

  /* Peripheral clock enable */

  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);

  

  /**USART2 GPIO Configuration  

  PA9   ------> USART2_TX

  PA10   ------> USART2_RX 

  */

  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;

  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;

  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

  GPIO_InitStruct.Alternate = LL_GPIO_AF_4;

  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;

  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;

  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;

  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;

  GPIO_InitStruct.Alternate = LL_GPIO_AF_4;

  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

  /* USART2 interrupt Init */

  NVIC_SetPriority(USART2_IRQn, 0);

  NVIC_EnableIRQ(USART2_IRQn);

 

  USART_InitStruct.BaudRate = 9600;

  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;

  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;

  USART_InitStruct.Parity = LL_USART_PARITY_NONE;

  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;

  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;

  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;

  LL_USART_Init(USART2, &USART_InitStruct);

  LL_USART_DisableOverrunDetect(USART2);

  LL_USART_ConfigAsyncMode(USART2);

  LL_USART_Enable(USART2);

 

}

    3. 自己增加的初始化,初始化變量,并打開(kāi)接收中斷,注意此時(shí)不要打開(kāi)發(fā)送中斷。


/************************************

*不帶流控的USART2函數(shù)****************

*/

void uart2Init(void)

{

gcRXDPointer=0;

gcRXDLength=0;

gcTXDPointer=0;

gcTXDLength=0;

gcInRXDMode=0;

gcInTXDMode=0;

LL_USART_EnableIT_RXNE(USART2);

//LL_USART_EnableIT_TXE(USART2);

}

    4. 以上的初始化就完成了,下面看中斷處理函數(shù)的編程方法。


void USART2_IRQHandler(void)

{

uint8_t ucTemp;

 

if(LL_USART_IsActiveFlag_RXNE(USART2))

{    //如果是接收中斷

gcUartCounter=0;    //全局變量,每次收到一個(gè)自己就清零,到100ms沒(méi)有更新認(rèn)為接收完成。       

ucTemp=LL_USART_ReceiveData8(USART2);

gcRXDBuffer[gcRXDPointer++]=ucTemp;    //接收到的數(shù)據(jù)放入緩沖區(qū)

gcInRXDMode=1;                         //當(dāng)前在接收模式

}

else if(LL_USART_IsActiveFlag_TXE(USART2))

{     //如果是發(fā)送中斷

gcTXDPointer++;

if(gcTXDPointer {   //還沒(méi)有發(fā)送完成,繼續(xù)發(fā)送

LL_USART_TransmitData8(USART2, gcTXDBuffer[gcTXDPointer]);

}

else

{    //發(fā)送完成了,復(fù)位發(fā)送的變量

gcTXDLength=0;

gcTXDPointer=0;

LL_USART_DisableIT_TXE(USART2);  //關(guān)閉發(fā)送中斷

gcInTXDMode=0;  //退出發(fā)送模式

delayms(1);     //有流控時(shí)需要延時(shí)關(guān)閉流控,比如RTS,或者485中斷的發(fā)送引腳。

RTS_HIGH();

}

}

}

    5. 在系統(tǒng)的1ms SysTick中斷中,判斷是否100ms沒(méi)有收到數(shù)據(jù)了。


gcUartCounter++;   //這個(gè)變量在接收中斷中不斷清零

if(gcUartCounter>=100)

{   //100ms沒(méi)有收到數(shù)據(jù)了,如果有數(shù)據(jù),則打包幀

gcUartCounter=100;

gcInRXDMode=0;  //退出接收模式

if(gcRXDPointer>=3)

{  //根據(jù)協(xié)議長(zhǎng)度,3是可以改動(dòng)的。

gcRXDLength=gcRXDPointer;  //將長(zhǎng)度放入gcRXDLength,由主程序處理

gcRXDPointer=0;

}}

    6. 以上程序中,接收數(shù)據(jù)部分就完成了。在主程序,或主業(yè)務(wù)中,判斷gcRXDLength就知道是否有數(shù)據(jù)需要處理。


    7. 在需要發(fā)送數(shù)據(jù)的時(shí)候:


/************************************

清空發(fā)送緩沖區(qū)的函數(shù),需要重新組織發(fā)送時(shí)調(diào)用。*/

void TxdClearBuff(void)

{

gcTXDPointer=0;

gcTXDLength=0;

}

 

/************************************

如果需要多次組織數(shù)據(jù),就一次次調(diào)用Push函數(shù),將發(fā)送數(shù)據(jù)送入發(fā)送緩沖區(qū)。*/

void TxdPushToBuff(uint8_t *buffer, unsigned int length)

{

memcpy(gcTXDBuffer+gcTXDLength, buffer, length);

gcTXDLength+=length;

}

 

/************************************

組織完數(shù)據(jù)后,調(diào)用TxdSend,進(jìn)行發(fā)送。*/

void TxdSend(void)

{

LL_USART_TransmitData8(USART2, gcTXDBuffer[0]);

gcTXDPointer=0;    

LL_USART_EnableIT_TXE(USART2);   //打開(kāi)發(fā)送中斷。

gcInTXDMode=1;                   //進(jìn)入發(fā)送模式。

}

    以上發(fā)送需要使用3個(gè)函數(shù),有些復(fù)雜。如果你一次就能將數(shù)據(jù)組織完成,就可以寫簡(jiǎn)單點(diǎn)。


   在對(duì)實(shí)時(shí)處理要求更嚴(yán)格的時(shí)候,會(huì)在接收中斷中直接處理幀頭的判斷(是否是正確的幀頭,不是則接收指針直接清零),并根據(jù)幀長(zhǎng)度字節(jié),判斷接收是否完成,然后直接調(diào)用通訊處理函數(shù)。這樣的處理方法最快速,但封裝不好,不易維護(hù)。不是必須的時(shí)候,不建議這么使用。


關(guān)鍵字:STM32  UART  串口通訊  編程方法 引用地址:STM32自打包的UART串口通訊編程方法

上一篇:STM32單片機(jī)學(xué)習(xí)筆記——USART串口通信
下一篇:STM32-串口通訊工作原理

推薦閱讀

? ? 隨著各大互聯(lián)網(wǎng)廠商紛紛推出流量卡,以及運(yùn)營(yíng)商自身的改革,“無(wú)限流量套餐”已經(jīng)越來(lái)越多,但沒(méi)有一個(gè)是真正的無(wú)限流量,都有各自的限制條款。  其實(shí),真正的無(wú)限流量套餐并不現(xiàn)實(shí),加入限制也是可以理解的,但問(wèn)題在于很多規(guī)定條款要么十分模糊,要么隱藏很深,一般用戶很難注意到,或者很難理解,就造成了不少尷尬事,比如用著用著就被限速甚...
一、什么是IAP,為什么要IAP IAP即為In Application Programming(在應(yīng)用中編程),一般情況下,以STM32F10x系列芯片為主控制器的設(shè)備在出廠時(shí)就已經(jīng)使用J-Link仿真器將應(yīng)用代碼燒錄了,如果在設(shè)備使用過(guò)程中需要進(jìn)行應(yīng)用代碼的更換、升級(jí)等操作的話,則可能需要將設(shè)備返回原廠并拆解出來(lái)再使用J-Link重新燒錄代碼,這就增加了很多不必要的麻煩。站在...
在實(shí)現(xiàn)流水燈之前,我們有必要提一點(diǎn),C51代碼在寫之前,要參考電路圖來(lái)寫。拿流水燈來(lái)說(shuō),我們來(lái)看圖二,LED燈,也就是二極管,八只LED的正極通過(guò)一根總線接在+5V的電壓上,再看圖一,可知八只LED燈的負(fù)極接在LED、P2的8個(gè)I/O口上。根據(jù)二極管的導(dǎo)通條件可知,在單片機(jī)的IO口輸出低電平時(shí),才能點(diǎn)亮LED燈。下面貼上代碼:#include<reg52.h> #define uch...
前不久,小米正式公布了全新一代的快充技術(shù),首次在業(yè)內(nèi)實(shí)現(xiàn)了200W有線快充+120W無(wú)線快充的規(guī)格,將手機(jī)充電時(shí)間帶到8分鐘。  上周,小米官方征集了米粉關(guān)于200W有線快充+120W無(wú)線快充的問(wèn)題,并邀請(qǐng)米粉代表當(dāng)面詢問(wèn)小米工程師。  今天上午,小米手機(jī)官微公布了此次溝通的部分視頻,其中展示了小米工程師對(duì)快充的一些解答。  對(duì)于大家關(guān)注...

史海拾趣

問(wèn)答坊 | AI 解惑

請(qǐng)教~

為什么我下載的時(shí)候會(huì)彈出一個(gè)窗口,上面寫著:下載會(huì)導(dǎo)致你的芯幣低于0,請(qǐng)修正后再下載,這是怎么回事?…

查看全部問(wèn)答∨

全國(guó)大學(xué)生電子設(shè)計(jì)競(jìng)賽訓(xùn)練教程

群里朋友傳的 共享下 本書是針對(duì)全國(guó)大學(xué)生電子設(shè)計(jì)競(jìng)賽特點(diǎn)和需要,為高等院校電子信息工程、通信工程、自動(dòng)化、電氣控制類專業(yè)學(xué)生編寫的培訓(xùn)教材。全書共分8章,內(nèi)容包括: 電子設(shè)計(jì)競(jìng)賽題目分析,電子設(shè)計(jì)競(jìng)賽基礎(chǔ)訓(xùn)練,單元電子電路訓(xùn)練,單 ...…

查看全部問(wèn)答∨

TTL和CMOS門電路的區(qū)別.doc

TTL和CMOS門電路 的區(qū)別.doc…

查看全部問(wèn)答∨

《家庭電子小制作》高清晰PDF

內(nèi)容簡(jiǎn)介 本書介紹的家庭電子小制作,適合于業(yè)余條件下制作。這些經(jīng)精選的電子小裝置具有較強(qiáng)的趣味性和實(shí)用性,且與日常生活密切相關(guān),如彩燈鏈、照明控制器、溫控器、電扇調(diào)整器、延時(shí)電路、電子門鈴、報(bào)警器、防盜器等。為了便于電子愛(ài)好者學(xué)習(xí) ...…

查看全部問(wèn)答∨

嵌入式人才的發(fā)展方向,給從事嵌入式開(kāi)發(fā)的同學(xué)指路(轉(zhuǎn))

     嵌入式系統(tǒng)無(wú)疑是當(dāng)前最熱門最有發(fā)展前途的IT應(yīng)用領(lǐng)域之一。嵌入式系統(tǒng)用在一些特定專用設(shè)備上,通常這些設(shè)備的硬件資源(如處理器、存儲(chǔ)器等)非常有限,并且對(duì)成本很敏感,有時(shí)對(duì)實(shí)時(shí)響應(yīng)要求很高等。特別是隨著消費(fèi)家 ...…

查看全部問(wèn)答∨

關(guān)于在wince初始化中端口的問(wèn)題

大家好,小弟想問(wèn)一下, 在wince os跑起來(lái)后能否初始化INT0? 因我用讀GPIO口的方式將INT0作為普通的I/O口來(lái)讀取其狀態(tài)(因?yàn)镮NT0與GPF0口復(fù)用), 讀取完之后,我想把INT0設(shè)置為中斷口? 想請(qǐng)教一下如何大家,如何在wince下初始化中端口? ( ...…

查看全部問(wèn)答∨

物聯(lián)網(wǎng)智能家居--如何往zigbee模塊(CC2530)里下載程序

第一步:首先要打開(kāi)針對(duì)C8051的IAR軟件: 在file選項(xiàng)里找到open——workspace,接著根據(jù)你放協(xié)議棧的路徑找到你需要的工程。 在上述圖片中,你需要的工程在Projects中,打開(kāi)后在zstack中找到Utilities , 在Utilities中找到SerialApp,這個(gè)文件夾 ...…

查看全部問(wèn)答∨

430F149下載器

如果用TI的LM3S811板子或者是MSP430 LaunchPad,它的仿真器能用于430F149下載嗎?如果可以,是怎么用呢…

查看全部問(wèn)答∨

raw lwip 拔掉網(wǎng)線后再插上網(wǎng)線就連接不上了?

在學(xué)習(xí)raw lwip時(shí),遇到以下幾個(gè)問(wèn)題: lm3s9b96作為服務(wù)器,拔掉網(wǎng)線后,pc機(jī)作為客戶端就連接不上開(kāi)發(fā)板了;lm3s9b96需重新上電后,pc機(jī)才能連接上。lm3s9b96作為客戶端,pc機(jī)作為服務(wù)器時(shí),開(kāi)發(fā)板連續(xù)調(diào)用tcp_write,只有第一個(gè)能發(fā)送到pc機(jī), ...…

查看全部問(wèn)答∨
小廣播
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開(kāi)發(fā)圈

 
機(jī)器人開(kāi)發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 木里| 麦盖提县| 荣成市| 贺州市| 龙门县| 克山县| 广东省| 鄂州市| 醴陵市| 益阳市| 崇礼县| 嘉善县| 富顺县| 开远市| 城步| 城市| 邢台市| 和龙市| 乳山市| 曲阳县| 微博| 芦山县| 涡阳县| 东乌珠穆沁旗| 府谷县| 越西县| 汉中市| 健康| 黔西| 托里县| 平遥县| 左贡县| 永宁县| 翁牛特旗| 新竹市| 东辽县| 乌拉特前旗| 连山| 方正县| 凌源市| 尼木县|