日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]這次講講利用串口收發(fā)中斷來(lái)進(jìn)行串口通訊。STM32 上為每個(gè)串口分配了一個(gè)中斷。也就是說(shuō)無(wú)論是發(fā)送完成還是收到數(shù)據(jù)或是數(shù)據(jù)溢出都產(chǎn)生同一個(gè)中斷。程序需在中斷處理函數(shù)中讀取狀態(tài)寄存器(USART_SR)來(lái)判斷當(dāng)前的是什

這次講講利用串口收發(fā)中斷來(lái)進(jìn)行串口通訊。STM32 上為每個(gè)串口分配了一個(gè)中斷。也就是說(shuō)無(wú)論是發(fā)送完成還是收到數(shù)據(jù)或是數(shù)據(jù)溢出都產(chǎn)生同一個(gè)中斷。程序需在中斷處理函數(shù)中讀取狀態(tài)寄存器(USART_SR)來(lái)判斷當(dāng)前的是什么中斷。下面的中斷映像圖給出了這些中斷源是如何匯合成最終的中斷信號(hào)的。圖中也給出了如何控制每一個(gè)單獨(dú)的中斷源是否起作用。

另外,Cortex-M3內(nèi)核中還有個(gè)NVIC,可以控制這里的中斷信號(hào)是否觸發(fā)中斷處理函數(shù)的執(zhí)行,還有這些外部中斷的級(jí)別。關(guān)于NVIC可以參考《ARM CortexM3權(quán)威指南》,里面講解的非常詳細(xì)。

簡(jiǎn)單的說(shuō),為了開(kāi)啟中斷,我們需要如下的代碼:


NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開(kāi)啟接收中斷

USART_ITConfig(USART1, USART_IT_TXE, ENABLE);// 開(kāi)啟發(fā)送中斷

這里多說(shuō)一句,串口的發(fā)送中斷有兩個(gè),分別是:

l發(fā)送數(shù)據(jù)寄存器空中斷(TXE)

l發(fā)送完成中斷(TC)

一般來(lái)說(shuō)我們會(huì)使用發(fā)送數(shù)據(jù)寄存器空中斷,用這個(gè)中斷發(fā)送的效率會(huì)高一些。

中斷處理函數(shù)的框架如下,如果檢測(cè)到錯(cuò)誤就清除錯(cuò)誤,收到數(shù)了就處理。發(fā)完當(dāng)前數(shù)據(jù)了就發(fā)下一個(gè)。


voidUSART1_IRQHandler(void)

{

unsignedintdata;

if(USART1->SR & 0x0F)

{

// See if we have some kind of error, Clear interrupt

data = USART1->DR;

}

elseif(USART1->SR & USART_FLAG_RXNE)//Receive Data Reg Full Flag

{

data = USART1->DR;

// 對(duì)收到的數(shù)據(jù)進(jìn)行處理,或者干些其他的事

}

elseif(USART1->SR & USART_FLAG_TXE)

{

{// 可以發(fā)送數(shù)據(jù)了,如果沒(méi)有數(shù)據(jù)需要發(fā)送,就在這里關(guān)閉發(fā)送中斷

USART1->DR = something;// Yes, Send character

}

}

}


下面給一個(gè)利用環(huán)形緩沖區(qū)的串口驅(qū)動(dòng)程序。


#ifndef _COM_BUFFERED_H_

#define _COM_BUFFERED_H_

#define COM1 0

#define COM2 1

#define COM_RX_BUF_SIZE 64

#define COM_TX_BUF_SIZE 64

#define COM_NO_ERR 0

#define COM_BAD_CH 1

#define COM_RX_EMPTY 2

#define COM_TX_FULL 3

#define COM_TX_EMPTY 4

unsignedcharCOMGetCharB (unsignedcharch, unsignedchar*err);

unsignedcharCOMPutCharB (unsignedcharport, unsignedcharc);

voidCOMBufferInit (void);

unsignedcharCOMBufferIsEmpty (unsignedcharport);

unsignedcharCOMBufferIsFull (unsignedcharport);

#endif



#include "stm32f10x_usart.h"

#include "com_buffered.h"

#define OS_ENTER_CRITICAL() __set_PRIMASK(1)

#define OS_EXIT_CRITICAL() __set_PRIMASK(0)

staticvoidCOMEnableTxInt(unsignedcharport)

{

staticUSART_TypeDef* map[2] = {USART1, USART2};

USART_ITConfig(map[port], USART_IT_TXE, ENABLE);

}

typedefstruct{

shortRingBufRxCtr;

unsignedchar*RingBufRxInPtr;

unsignedchar*RingBufRxOutPtr;

unsignedcharRingBufRx[COM_RX_BUF_SIZE];

shortRingBufTxCtr;

unsignedchar*RingBufTxInPtr;

unsignedchar*RingBufTxOutPtr;

unsignedcharRingBufTx[COM_TX_BUF_SIZE];

} COM_RING_BUF;

COM_RING_BUF COM1Buf;

COM_RING_BUF COM2Buf;

unsignedcharCOMGetCharB (unsignedcharport, unsignedchar*err)

{

// unsigned char cpu_sr;

unsignedcharc;

COM_RING_BUF *pbuf;

switch(port)

{

caseCOM1:

pbuf = &COM1Buf;

break;

caseCOM2:

pbuf = &COM2Buf;

break;

default:

*err = COM_BAD_CH;

return(0);

}

OS_ENTER_CRITICAL();

if(pbuf->RingBufRxCtr > 0)

{

pbuf->RingBufRxCtr--;

c = *pbuf->RingBufRxOutPtr++;

if(pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE])

{

pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];

}

OS_EXIT_CRITICAL();

*err = COM_NO_ERR;

return(c);

}else{

OS_EXIT_CRITICAL();

*err = COM_RX_EMPTY;

c = 0;

return(c);

}

}

unsignedcharCOMPutCharB (unsignedcharport, unsignedcharc)

{

// unsigned char cpu_sr;

COM_RING_BUF *pbuf;

switch(port)

{

caseCOM1:

pbuf = &COM1Buf;

break;

caseCOM2:

pbuf = &COM2Buf;

break;

default:

return(COM_BAD_CH);

}

OS_ENTER_CRITICAL();

if(pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {

pbuf->RingBufTxCtr++;

*pbuf->RingBufTxInPtr++ = c;

if(pbuf->RingBufTxInPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE]) {

pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];

}

if(pbuf->RingBufTxCtr == 1) {

COMEnableTxInt(port);

OS_EXIT_CRITICAL();

}else{

OS_EXIT_CRITICAL();

}

return(COM_NO_ERR);

}else{

OS_EXIT_CRITICAL();

return(COM_TX_FULL);

}

}

voidCOMBufferInit (void)

{

COM_RING_BUF *pbuf;

pbuf = &COM1Buf;

pbuf->RingBufRxCtr = 0;

pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];

pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];

pbuf->RingBufTxCtr = 0;

pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];

pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

pbuf = &COM2Buf;

pbuf->RingBufRxCtr = 0;

pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];

pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];

pbuf->RingBufTxCtr = 0;

pbuf->RingBufTxInPtr = &pbuf->RingBufTx[0];

pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

}

unsignedcharCOMBufferIsEmpty (unsignedcharport)

{

// unsigned char cpu_sr;

unsignedcharempty;

COM_RING_BUF *pbuf;

switch(port)

{

caseCOM1:

pbuf = &COM1Buf;

break;

caseCOM2:

pbuf = &COM2Buf;

break;

default:

return(1);

}

OS_ENTER_CRITICAL();

if(pbuf->RingBufRxCtr > 0)

{

empty = 0;

}

else

{

empty = 1;

}

OS_EXIT_CRITICAL();

return(empty);

}

unsignedcharCOMBufferIsFull (unsignedcharport)

{

// unsigned char cpu_sr;

charfull;

COM_RING_BUF *pbuf;

switch(port)

{

caseCOM1:

pbuf = &COM1Buf;

break;

caseCOM2:

pbuf = &COM2Buf;

break;

default:

return(1);

}

OS_ENTER_CRITICAL();

if(pbuf->RingBufTxCtr < COM_TX_BUF_SIZE) {

full = 0;

}else{

full = 1;

}

OS_EXIT_CRITICAL();

return(full);

}

// This function is called by the Rx ISR to insert a character into the receive ring buffer.

staticvoidCOMPutRxChar (unsignedcharport, unsignedcharc)

{

COM_RING_BUF *pbuf;

switch(port)

{

caseCOM1:

pbuf = &COM1Buf;

break;

caseCOM2:

pbuf = &COM2Buf;

break;

default:

return;

}

if(pbuf->RingBufRxCtr < COM_RX_BUF_SIZE) {

pbuf->RingBufRxCtr++;

*pbuf->RingBufRxInPtr++ = c;

if(pbuf->RingBufRxInPtr == &pbuf->RingBufRx[COM_RX_BUF_SIZE]) {

pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];

}

}

}

// This function is called by the Tx ISR to extract the next character from the Tx buffer.

// The function returns FALSE if the buffer is empty after the character is extracted from

// the buffer. This is done to signal the Tx ISR to disable interrupts because this is the

// last character to send.

staticunsignedcharCOMGetTxChar (unsignedcharport, unsignedchar*err)

{

unsignedcharc;

COM_RING_BUF *pbuf;

switch(port)

{

caseCOM1:

pbuf = &COM1Buf;

break;

caseCOM2:

pbuf = &COM2Buf;

break;

default:

*err = COM_BAD_CH;

return(0);

}

if(pbuf->RingBufTxCtr > 0) {

pbuf->RingBufTxCtr--;

c = *pbuf->RingBufTxOutPtr++;

if(pbuf->RingBufTxOutPtr == &pbuf->RingBufTx[COM_TX_BUF_SIZE])

{

pbuf->RingBufTxOutPtr = &pbuf->RingBufTx[0];

}

*err = COM_NO_ERR;

return(c);

}else{

*err = COM_TX_EMPTY;

return(0);

}

}

voidUSART1_IRQHandler(void)

{

unsignedintdata;

unsignedcharerr;

if(USART1->SR & 0x0F)

{

// See if we have some kind of error

// Clear interrupt (do nothing about it!)

data = USART1->DR;

}

elseif(USART1->SR & USART_FLAG_RXNE)//Receive Data Reg Full Flag

{

data = USART1->DR;

COMPutRxChar(COM1, data);// Insert received character into buffer

}

elseif(USART1->SR & USART_FLAG_TXE)

{

data = COMGetTxChar(COM1, &err);// Get next character to send.

if(err == COM_TX_EMPTY)

{// Do we have anymore characters to send ?

// No, Disable Tx interrupts

//USART_ITConfig(USART1, USART_IT_TXE| USART_IT_TC, ENABLE);

USART1->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;

}

else

{

USART1->DR = data;// Yes, Send character

}

}

}

voidUSART2_IRQHandler(void)

{

unsignedintdata;

unsignedcharerr;

if(USART2->SR & 0x0F)

{

// See if we have some kind of error

// Clear interrupt (do nothing about it!)

data = USART2->DR;

}

elseif(USART2->SR & USART_FLAG_RXNE)//Receive Data Reg Full Flag

{

data = USART2->DR;

COMPutRxChar(COM2, data);// Insert received character into buffer

}

elseif(USART2->SR & USART_FLAG_TXE)

{

data = COMGetTxChar(COM2, &err);// Get next character to send.

if(err == COM_TX_EMPTY)

{// Do we have anymore characters to send ?

// No, Disable Tx interrupts

//USART_ITConfig(USART2, USART_IT_TXE| USART_IT_TC, ENABLE);

USART2->CR1 &= ~USART_FLAG_TXE | USART_FLAG_TC;

}

else

{

USART2->DR = data;// Yes, Send character

}

}

}


下面給個(gè)例子主程序,來(lái)演示如何使用上面的串口驅(qū)動(dòng)代碼。


#include "misc.h"

#include "stm32f10x.h"

#include "com_buffered.h"

voidUART_PutStrB (unsignedcharport, uint8_t *str)

{

while(0 != *str)

{

COMPutCharB(port, *str);

str++;

}

}

voidUSART1_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GP

本站聲明: 本文章由作者或相關(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)系本站刪除。
換一批
延伸閱讀

在嵌入式開(kāi)發(fā)中,STM32的時(shí)鐘系統(tǒng)因其靈活性和復(fù)雜性成為開(kāi)發(fā)者關(guān)注的焦點(diǎn)。然而,看似簡(jiǎn)單的時(shí)鐘配置背后,隱藏著諸多易被忽視的陷阱,輕則導(dǎo)致系統(tǒng)不穩(wěn)定,重則引發(fā)硬件損壞。本文從時(shí)鐘源選擇、PLL配置、總線時(shí)鐘分配等關(guān)鍵環(huán)...

關(guān)鍵字: STM32 時(shí)鐘系統(tǒng)

在嵌入式系統(tǒng)開(kāi)發(fā)中,STM32系列微控制器的內(nèi)部溫度傳感器因其低成本、高集成度特性,廣泛應(yīng)用于設(shè)備自檢、環(huán)境監(jiān)測(cè)等場(chǎng)景。然而,受芯片工藝差異和電源噪聲影響,其原始數(shù)據(jù)存在±1.5℃的固有誤差。本文從硬件配置、校準(zhǔn)算法、軟...

關(guān)鍵字: STM32 溫度傳感器

在能源效率與智能化需求雙重驅(qū)動(dòng)下,AC-DC轉(zhuǎn)換器的數(shù)字控制技術(shù)正經(jīng)歷從傳統(tǒng)模擬方案向全數(shù)字架構(gòu)的深刻變革。基于STM32微控制器的PFM(脈沖頻率調(diào)制)+PWM(脈沖寬度調(diào)制)混合調(diào)制策略,結(jié)合動(dòng)態(tài)電壓調(diào)整(Dynam...

關(guān)鍵字: AC-DC STM32

當(dāng)前智能家居產(chǎn)品需求不斷增長(zhǎng) ,在這一背景下 ,對(duì)現(xiàn)有澆花裝置缺陷進(jìn)行了改進(jìn) ,設(shè)計(jì)出基于STM32單片機(jī)的全 自動(dòng)家用澆花機(jī)器人。該設(shè)計(jì)主要由機(jī)械結(jié)構(gòu)和控制系統(tǒng)構(gòu)成 ,機(jī)械結(jié)構(gòu)通過(guò)麥克納姆輪底盤(pán)與噴灑裝置的結(jié)合實(shí)現(xiàn)機(jī)器...

關(guān)鍵字: STM32 麥克納姆輪 安全可靠 通過(guò)性強(qiáng)

用c++編程似乎是讓你的Arduino項(xiàng)目起步的障礙嗎?您想要一種更直觀的微控制器編程方式嗎?那你需要了解一下Visuino!這個(gè)圖形化編程平臺(tái)將復(fù)雜電子項(xiàng)目的創(chuàng)建變成了拖動(dòng)和連接塊的簡(jiǎn)單任務(wù)。在本文中,我們將帶您完成使...

關(guān)鍵字: Visuino Arduino ESP32 STM32

基于STM32與LoRa技術(shù)的無(wú)線傳感網(wǎng)絡(luò)憑借其低功耗、廣覆蓋、抗干擾等特性,成為環(huán)境監(jiān)測(cè)、工業(yè)自動(dòng)化等場(chǎng)景的核心解決方案。然而,如何在復(fù)雜電磁環(huán)境中實(shí)現(xiàn)高效休眠調(diào)度與動(dòng)態(tài)信道優(yōu)化,成為提升網(wǎng)絡(luò)能效與可靠性的關(guān)鍵挑戰(zhàn)。本...

關(guān)鍵字: STM32 LoRa

在實(shí)時(shí)控制系統(tǒng)、高速通信協(xié)議處理及高精度數(shù)據(jù)采集等對(duì)時(shí)間敏感的應(yīng)用場(chǎng)景中,中斷響應(yīng)延遲的優(yōu)化直接決定了系統(tǒng)的可靠性與性能上限。STM32系列微控制器憑借其靈活的嵌套向量中斷控制器(NVIC)、多通道直接內(nèi)存訪問(wèn)(DMA)...

關(guān)鍵字: STM32 DMA

數(shù)字電源技術(shù)向高功率密度、高效率與高動(dòng)態(tài)響應(yīng)方向加速演進(jìn),STM32微控制器憑借其基于DSP庫(kù)的算法加速能力與對(duì)LLC諧振變換器的精準(zhǔn)控制架構(gòu),成為優(yōu)化電源動(dòng)態(tài)性能的核心平臺(tái)。相較于傳統(tǒng)模擬控制或通用型數(shù)字控制器,STM...

關(guān)鍵字: STM32 數(shù)字電源

STM32微控制器憑借其針對(duì)電機(jī)控制場(chǎng)景的深度優(yōu)化,成為高精度、高可靠性驅(qū)動(dòng)系統(tǒng)的核心選擇。相較于通用型MCU,STM32在電機(jī)控制領(lǐng)域的核心優(yōu)勢(shì)集中體現(xiàn)在FOC(磁場(chǎng)定向控制)算法的硬件加速引擎與PWM死區(qū)時(shí)間的動(dòng)態(tài)補(bǔ)...

關(guān)鍵字: STM32 電機(jī)控制

無(wú)線充電技術(shù)加速滲透消費(fèi)電子與汽車電子領(lǐng)域,基于Qi協(xié)議的無(wú)線充電發(fā)射端開(kāi)發(fā)成為智能設(shè)備能量補(bǔ)給的核心課題。傳統(tǒng)模擬控制方案存在響應(yīng)滯后、參數(shù)調(diào)整困難等問(wèn)題,而基于STM32的數(shù)字PID控制結(jié)合FOD(Foreign O...

關(guān)鍵字: STM32 無(wú)線充電
關(guān)閉