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

【GD32F470紫藤派開發(fā)板使用手冊】第十講 USART-中斷串口收發(fā)實驗

發(fā)布者:EnigmaticCharm最新更新時間:2024-12-12 來源: elecfans關(guān)鍵字:USART  中斷  串口收發(fā) 手機看文章 掃描二維碼
隨時隨地手機看文章

10.1實驗內(nèi)容

通過本實驗主要學習以下內(nèi)容:

  • 使用中斷進行串口收發(fā)

10.2實驗原理

10.2.1串口寄存器介紹

串口有幾個非常重要的寄存器需要讀者理解。

數(shù)據(jù)寄存器(USART_DATA)

wKgZomZCzTOAdz_OAAAuTeg2cA0146.png

該寄存器雖然只有一個,但內(nèi)部是映射為發(fā)送和接受兩個寄存器。

發(fā)送時,除了發(fā)送數(shù)據(jù)寄存器,還有一個移位寄存器,當數(shù)據(jù)寫入數(shù)據(jù)寄存器中,移位寄存器空閑的情況下,數(shù)據(jù)從數(shù)據(jù)寄存器中轉(zhuǎn)移到移位寄存器,移位寄存器按照低bit——高bit的順序?qū)?shù)據(jù)移位到IO口上。

接收時,接收到的數(shù)據(jù)保存在數(shù)據(jù)寄存器中,CPU或DMA可以從該寄存器中讀接收到的數(shù)據(jù)。

狀態(tài)寄存器0(USART_STAT0 )

wKgaomZCzUOAbIljAAA9A6YgC4w762.png

我們需要特別理解TBE、TC、RBNE、IDLE、OREE這幾位。

  1. TBE(發(fā)送空):這個位置“1”表示現(xiàn)在可以往數(shù)據(jù)寄存器中寫數(shù)據(jù)了,當移位寄存器空閑時,寫入到數(shù)據(jù)寄存器中的數(shù)據(jù)則會轉(zhuǎn)移到移位寄存器中,串口開始對外發(fā)送數(shù)據(jù);

  2. TC(發(fā)送完成):發(fā)送數(shù)據(jù)時,當數(shù)據(jù)寄存器和移位寄存器都為空時,表示所有的數(shù)據(jù)都已經(jīng)完成了,則TC置“1”,所以當連續(xù)發(fā)數(shù)據(jù)時,最后一個字節(jié)從移位寄存器中發(fā)送完,TC才會置起。

  3. RBNE(接受非空):當串口接受到一個字節(jié)數(shù)據(jù),RBNE置“1”,此時CPU可以去數(shù)據(jù)寄存器中取數(shù)據(jù),當使用了DMA接受,DMA自動將數(shù)據(jù)寄存器中數(shù)據(jù)搬走,當數(shù)據(jù)寄存器數(shù)據(jù)被讀走/搬走,RBNE位自動清“0”;

  4. IDLE(空閑):該標志位用于檢測接受空閑,當串口接受最后一個字節(jié)后,再往后一個字節(jié)時間內(nèi),沒有接受到新的數(shù)據(jù),則該位置“1”;

IDLE一般用于串口DMA接受中,DMA接受中,MCU無法知道發(fā)送方的數(shù)據(jù)個數(shù),所以可以通過判斷IDLE位(或IDLE中斷)來判斷發(fā)送方一幀數(shù)據(jù)發(fā)送結(jié)束了。

5.OREE(溢出錯誤):當RBNE置位的情況,又接收到一個字節(jié)數(shù)據(jù),則OREE位置“1”。

以上就是串口寄存器的介紹。本實驗就是使用TBE中斷和RBNE中斷來實現(xiàn)中斷收發(fā)數(shù)據(jù),實驗原理是RBNE中斷用來接受數(shù)據(jù),IDLE中斷用于判斷發(fā)送方數(shù)據(jù)結(jié)束,TBE中斷用于發(fā)送數(shù)據(jù)。

10.3硬件設(shè)計

本實驗使用P1接口的PA9和PA10實現(xiàn)串口功能,硬件設(shè)計請見上一章。

10.4代碼解析

10.4.1串口中斷發(fā)送函數(shù)

在driver_uart.c中定義了串口中斷發(fā)送函數(shù):

C
Drv_Err driver_uart_int_transmit(typdef_uart_struct *uartx,uint8_t *pbuff,uint16_t length)
{
uint64_t timeout = driver_tick;
while(uartx->uart_control.Com_Flag.Bits.SendState==1){
if((timeout+UART_TIMEOUT_MS) <= driver_tick) {              
uartx->uart_control.Com_Flag.Bits.SendState=0;
return DRV_ERROR;
}
}

uartx->uart_control.Com_Flag.Bits.SendSucess=0;
uartx->uart_control.Com_Flag.Bits.SendState=1;
uartx->uart_control.p_Send=pbuff;
uartx->uart_control.SendSize=length;
uartx->uart_control.SendCount=0;

usart_flag_clear(uartx->uart_x,USART_FLAG_TC);
usart_interrupt_enable(uartx->uart_x,USART_INT_TBE);

return DRV_SUCCESS;
}

10.4.2串口中斷接受函數(shù)

在driver_uart.c中定義了串口中斷接受函數(shù):

C
Drv_Err driver_uart_int_receive(typdef_uart_struct *uartx,uint8_t *pbuff,uint16_t length)
{
uint64_t timeout = driver_tick;
while(uartx->uart_control.Com_Flag.Bits.RecState==1){
if((timeout+UART_TIMEOUT_MS) <= driver_tick) {              
uartx->uart_control.Com_Flag.Bits.RecState=0;
return DRV_ERROR;
}
}

if(usart_flag_get(uartx->uart_x,USART_FLAG_ORERR))
{
usart_flag_clear(uartx->uart_x,USART_FLAG_ORERR);
USART_STAT0(uartx->uart_x);
USART_DATA(uartx->uart_x);
}

uartx->uart_control.Com_Flag.Bits.RecSuccess=0;
uartx->uart_control.Com_Flag.Bits.RecState=1;
uartx->uart_control.p_Rec=pbuff;
uartx->uart_control.RecSize=length;
uartx->uart_control.RecCount=0;

usart_flag_clear(uartx->uart_x,USART_FLAG_IDLE);
USART_STAT0(uartx->uart_x);
USART_DATA(uartx->uart_x);

usart_interrupt_enable(uartx->uart_x,USART_INT_RBNE);
usart_interrupt_enable(uartx->uart_x,USART_INT_IDLE);

return DRV_SUCCESS;
}

10.4.3main函數(shù)實現(xiàn)

以下為main函數(shù)代碼:

C
int main(void)
{
//延時、共用驅(qū)動部分初始化
driver_init();

//初始化UART為中斷模式,注冊接受完成(IDLE)回調(diào)函數(shù)
BOARD_UART.uart_mode_tx=MODE_INT;
BOARD_UART.uart_mode_rx=MODE_INT;
BOARD_UART.uart_idle_callback=user_receive_complete_callback;
bsp_uart_init(&BOARD_UART);

bsp_led_init(&LED2);
bsp_led_init(&LED1);
bsp_led_on(&LED2);
bsp_led_off(&LED1);

//使能UART中斷
nvic_irq_enable(USART0_IRQn,2,0);

delay_ms(100);
printf_log('uart interrupt mode sends and receives loopback packets of indefinite length.rn');

//啟動UART中斷接受,最長100byte
driver_uart_int_receive(&BOARD_UART,uart_rec_buff,100);

while (1)
{
//查詢到接受完成回調(diào)函數(shù)標志
if(uart_receive_complete_flag==SET)
{
uart_receive_complete_flag=RESET;

//啟動中斷方式發(fā)送剛接受到的數(shù)據(jù)
driver_uart_int_transmit(&BOARD_UART,uart_send_buff,uart_receive_count);
bsp_lcd_printf('%s',uart_send_buff);
}
}
}

本例程main函數(shù)首先進行了延時函數(shù)初始化,再初始化UART為中斷模式,接著配置串口BOARD_UART,開啟串口中斷NVIC,這里使用到了IDLE中斷,TBE中斷和RBNE中斷,然后配置串口D中斷接受,最長100個字節(jié),所以我們可以給串口發(fā)送100個字節(jié)以下長度的數(shù)據(jù)。在while(1)循環(huán)中循環(huán)查詢uart_receive_complete_flag標志位,當該標志位為“SET”時,表示IDLE中斷被觸發(fā),一幀數(shù)據(jù)接受完,最后將接收到的幀數(shù)據(jù)通過中斷發(fā)送方式原封不動發(fā)送到串口上。

10.4.4中斷函數(shù)

在bsp_uart.c中定義了串口中斷處理函數(shù)

C
void USART0_IRQHandler(void)
{
driver_uart_int_handler(&BOARD_UART);
}

在driver_uart.c中定義了driver_uart_int_handler函數(shù):

C
Drv_Err driver_uart_int_handler(typdef_uart_struct *uartx)
{
Drv_Err uart_state=DRV_SUCCESS;
if(usart_interrupt_flag_get(uartx->uart_x,USART_INT_FLAG_RBNE)!=RESET)
{
if(uartx->uart_control.RecCount < uartx->uart_control.RecSize){
uartx->uart_control.p_Rec[uartx->uart_control.RecCount]=usart_data_receive(uartx->uart_x);
uartx->uart_control.RecCount++;
}
else{
usart_data_receive(uartx->uart_x);
uart_state=DRV_ERROR;
//err 溢出
}
if(uartx->uart_rbne_callback!=NULL){
uartx->uart_rbne_callback(uartx);
}
//callback
if(uartx->uart_control.RecCount == uartx->uart_control.RecSize){
uartx->uart_control.Com_Flag.Bits.RecSuccess=1;
uartx->uart_control.Com_Flag.Bits.RecState=0;
uartx->uart_control.RecCount=0;
}
}
if(usart_interrupt_flag_get(uartx->uart_x,USART_INT_FLAG_IDLE)!=RESET)
{
usart_interrupt_flag_clear(uartx->uart_x,USART_INT_FLAG_IDLE);
USART_STAT0(uartx->uart_x);
USART_DATA(uartx->uart_x);

if( (uartx->uart_mode_rx==MODE_INT && uartx->uart_control.RecCount>0)
||(uartx->uart_mode_rx==MODE_DMA && dma_transfer_number_get(uartx->uart_rx_dma->dmax,uartx->uart_rx_dma->dma_chx)!=uartx->uart_control.RecSize))
{
uartx->uart_control.Com_Flag.Bits.RecSuccess=1;
uartx->uart_control.Com_Flag.Bits.RecState=0;

if(uartx->uart_mode_rx==MODE_DMA){
uartx->uart_control.RecCount=uartx->uart_control.RecSize-dma_transfer_number_get(uartx->uart_rx_dma->dmax,uartx->uart_rx_dma->dma_chx);
}
//callback
if(uartx->uart_idle_callback!=NULL){
uartx->uart_idle_callback(uartx);
}
}

}

if(usart_interrupt_flag_get(uartx->uart_x,USART_INT_FLAG_TBE)!=RESET)
{
usart_data_transmit(uartx->uart_x,uartx->uart_control.p_Send[uartx->uart_control.SendCount]);
uartx->uart_control.SendCount++;

if(uartx->uart_tbe_callback!=NULL){
uartx->uart_tbe_callback(uartx);
}

if(uartx->uart_control.SendCount >= uartx->uart_control.SendSize)
{
uartx->uart_control.SendCount=0;
usart_interrupt_disable(uartx->uart_x, USART_INT_TBE);
usart_interrupt_enable(uartx->uart_x, USART_INT_TC);
}
}

if(usart_interrupt_flag_get(uartx->uart_x,USART_INT_FLAG_TC)!=RESET)
{
usart_interrupt_disable(uartx->uart_x, USART_INT_TC);
usart_flag_clear(uartx->uart_x,USART_FLAG_TC);

if( !(uartx->uart_mode_rx==MODE_DMA && dma_transfer_number_get(uartx->uart_tx_dma->dmax,uartx->uart_tx_dma->dma_chx)!=0) )
{
uartx->uart_control.Com_Flag.Bits.SendSucess=1;
uartx->uart_control.Com_Flag.Bits.SendState=0;

if(uartx->uart_tc_callback!=NULL){
uartx->uart_tc_callback(uartx);
}

uartx->uart_control.SendCount=0;
}
}

if(usart_flag_get(uartx->uart_x,USART_FLAG_ORERR)==SET)
{
usart_flag_clear(uartx->uart_x,USART_FLAG_ORERR);
USART_STAT0(uartx->uart_x);
USART_DATA(uartx->uart_x);
uart_state=DRV_ERROR;
}

return uart_state;

}

10.5實驗結(jié)果

使用串口調(diào)試助手發(fā)送一幀數(shù)據(jù)到MCU,MCU會將這幀數(shù)據(jù)回發(fā)到串口調(diào)試助手中。

wKgZomZCzhqAd1-uAAAEQNN_QRI502.pngwKgZomZCziKAWcJsAAAIXPeWoWw536.png

關(guān)鍵字:USART  中斷  串口收發(fā) 引用地址:【GD32F470紫藤派開發(fā)板使用手冊】第十講 USART-中斷串口收發(fā)實驗

上一篇:【GD32F303紅楓派開發(fā)板使用手冊】第十三講 ADC-內(nèi)部溫度傳感器和參考電壓采樣實驗
下一篇:【GD32H757Z海棠派開發(fā)板使用手冊】第三講 EXTI-按鍵中斷檢測實驗

推薦閱讀最新更新時間:2025-05-15 12:27

STM32入門學習之USART中斷(STM32F030F4P6基于CooCox IDE)
#include stm32f0xx.h #include stm32_lib/inc/stm32f0xx_rcc.h #include stm32_lib/inc/stm32f0xx_gpio.h #include stm32_lib/inc/stm32f0xx_usart.h #include stm32_lib/inc/stm32f0xx_misc.h #include delay.h int main(void) { //1、使能時鐘 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2
[單片機]
STM32 HAL庫串口收發(fā)如何使用
前言 對于 STM32 串口的使用,確實很簡單使用 STM32CubeMX 做好初始化,就可以直接使用了。 但是最近在某些產(chǎn)品上使用串口同時收發(fā)的時候,發(fā)現(xiàn)有時候串口會收不到數(shù)據(jù)了,但是發(fā)送正常,而且這個問題再數(shù)據(jù)量大的時候很容易出現(xiàn),于是乎進行了好幾天的問題測試…… 一、 HAL 庫串口收發(fā) 先簡單回顧一下 STM32 HAL庫串口收發(fā)是如何使用的。 1.1 串口發(fā)送 對于 STM32 來說,串口發(fā)送有3中方式: 輪詢發(fā)送; 中斷發(fā)送; DMA發(fā)送; 在實際產(chǎn)品上,大部分項目中都用的是 輪詢 方式發(fā)送,本次出現(xiàn)接收卡死的問題的產(chǎn)品也是采用的輪詢發(fā)送,所以我簡單的說明一下輪詢發(fā)送,其他兩種方式為 STM32 學習的基礎(chǔ)
[單片機]
STM32 HAL庫<font color='red'>串口</font><font color='red'>收發(fā)</font>如何使用
STM32 USART簡介-串口通訊協(xié)議簡介01
通訊的方式分類: 1.并行通信:是指數(shù)據(jù)的各位同時在多根數(shù)據(jù)線上發(fā)送或接收。如下圖 并行通信的特點:控制簡單,傳輸速度快;由于傳輸線較多,適用于短距離通信。 2.串行通信:是指數(shù)據(jù)的各位在同一根數(shù)據(jù)線上逐位發(fā)送和接收。如下圖 串行通信的特點:控制復(fù)雜,傳輸速度慢;只需要一根數(shù)據(jù)線,適用于遠距離通信。 串行通信方式分類 在串行通信中,根據(jù)對數(shù)據(jù)流的分界、定時以及同步方案方法不同,可分為和同步串行通信方式和異步通信方式。 同步通信 同步通信是指發(fā)送端和接收端必須使用同一時鐘,是一種連續(xù)傳送數(shù)據(jù)的通信方式,一次通訊傳送多個字符數(shù)據(jù)(一幀數(shù)據(jù))。下圖是同步串行通信幀格式: 同步串行通信方式:把許多字符組成一個信息組
[單片機]
STM32 <font color='red'>USART</font>簡介-<font color='red'>串口</font>通訊協(xié)議簡介01
【STM32Cube_06】使用USART發(fā)送和接收數(shù)據(jù)(查詢模式)
1. 準備工作 硬件準備 首先需要準備一個開發(fā)板,這里我準備的是STM32L4的開發(fā)板(BearPi): 軟件準備 需要安裝好Keil - MDK及芯片對應(yīng)的包,以便編譯和下載生成的代碼; 準備一個串口調(diào)試助手,這里我使用的是Serial Port Utility; 2.生成MDK工程 選擇芯片型號 打開STM32CubeMX,打開MCU選擇器: 搜索并選中芯片STM32L431RCT6: 配置時鐘源 如果選擇使用外部高速時鐘(HSE),則需要在System Core中配置RCC; 如果使用默認內(nèi)部時鐘(HSI),這一步可以略過; 這里我都使用外部時鐘: 配置串口 小熊派開發(fā)板板載ST-Lin
[單片機]
【STM32Cube_06】使用<font color='red'>USART</font>發(fā)送和接收數(shù)據(jù)(查詢模式)
【stm32f103】USART RX實現(xiàn)(寄存器版)
本講主要實現(xiàn)usart RX的實現(xiàn),主要分幾部分的應(yīng)用 1.USART 1 RX polling的實現(xiàn) 2.USART1 RX DMA的實現(xiàn) 3.USART1 RX DMA中斷的實現(xiàn) 4.配合著TIMER進行RX DMA中斷實現(xiàn)實現(xiàn)(用途很大) 本文章不在對寄存器貼圖,直接上代碼以及運行圖,有興趣的可以去調(diào)試下看看寄存器,以下歷程都必須調(diào)用Init函數(shù),Init函數(shù)源碼 void USART1_Init() { /* 1. ENABLE USART1 GPIOA CLOCK */ RCC- APB2ENR |= RCC_APB2ENR_IOPAEN; /* 2. ENABLE USART1 IN A
[單片機]
【stm32f103】<font color='red'>USART</font> RX實現(xiàn)(寄存器版)
STM32之USART配置
//USART void UART2_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_5
[單片機]
s3c6410_中斷
參考: 1)《USER'S MANUAL-S3C6410X》Chapter 10 GPIO, Chapter 12 VECTORED INTERRUPT CONTROLLER 2)《ARM1176 JZF-S Technical Reference Manual》Chapter 2 Programmer's Model, Chapter 12 Vectored Interrupt Controller Port 3)《ARM Architecture Reference Manual》Chapter A2 Programmers' Model, 4)u-boot源碼: u-boot-x.x.x/cpu/s3
[單片機]
s3c6410_<font color='red'>中斷</font>
外部中斷的理解
使用 IO 口外部中斷的一般步驟: 1)初始化 IO 口為輸入。 2)開啟 IO 口復(fù)用時鐘,設(shè)置 IO 口與中斷線的映射關(guān)系。 3)初始化線上中斷,設(shè)置觸發(fā)條件等。 4)配置中斷分組(NVIC),并使能中斷。 5)編寫中斷服務(wù)函數(shù)。 //初始化 EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //開啟復(fù)用時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //外部中斷,需要使能 AFIO 時鐘 KEY_Init();//初始化按鍵對應(yīng) io 模式 //初始化線上
[單片機]
外部<font color='red'>中斷</font>的理解
小廣播
設(shè)計資源 培訓 開發(fā)板 精華推薦

最新單片機文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 寿宁县| 沂源县| 团风县| 正阳县| 云和县| 多伦县| 北碚区| 三亚市| 广水市| 任丘市| 沅陵县| 盐山县| 浦江县| 牟定县| 大宁县| 恩平市| 华池县| 石门县| 宝坻区| 万年县| 兴和县| 穆棱市| 南郑县| 汉沽区| 汉寿县| 张家港市| 梁山县| 宁都县| 康保县| 崇礼县| 乡宁县| 新巴尔虎左旗| 岱山县| 华池县| 永善县| 绥德县| 潜江市| 安溪县| 武平县| 常州市| 江西省|