国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

通過串口中斷的方式進(jìn)行ASR-01S模塊與STM32通信(問題與解決)

這篇具有很好參考價(jià)值的文章主要介紹了通過串口中斷的方式進(jìn)行ASR-01S模塊與STM32通信(問題與解決)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言:

最近在做一個(gè)智能家居的項(xiàng)目,需要實(shí)現(xiàn)語音控制的功能,于是我選用了ASR-01S模塊與STM32通信,這個(gè)模塊最大的好處在于有配套的編程軟件和語音庫,不用自己訓(xùn)練且編程簡單(少兒編程的程度)。ASR-01S的代碼架構(gòu)在這不多說,總之在收到語音后它會(huì)通過串口發(fā)送一串命令給STM32,STM32收到后通過串口中斷的方式進(jìn)行一系列操作。但沒想到在這塊看起來很簡單的地方翻車了(太丟人了。。。),經(jīng)過求助之后終于解決了,在這里淺淺記錄一下自己的翻車過程及解決方案。

問題引入

代碼這里偷了一下懶,直接問了GPT,可以直接看我這篇文章:GPT對(duì)話代碼庫——基于STM32F103 1,標(biāo)志位切換模式 & 2,串口的接受和發(fā)送

基礎(chǔ)的就不多說了,主要講一下核心問題,先放一下代碼

#define BUFFER_SIZE 100 // 定義緩沖區(qū)大小為100

char buffer[BUFFER_SIZE]; // 定義一個(gè)緩沖區(qū)數(shù)組用于存儲(chǔ)接收到的數(shù)據(jù)
volatile unsigned int buffer_index = 0; // 聲明一個(gè)用于記錄緩沖區(qū)當(dāng)前索引的變量,使用 volatile 關(guān)鍵字修飾以確保在中斷中的可見性

void USART3_IRQHandler(void) {
    // 檢查是否接收到數(shù)據(jù)
    if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) {
        char data = (char)USART_ReceiveData(USART3); // 讀取接收到的數(shù)據(jù)

        // 簡單的字符串終止判斷(例如以換行結(jié)束)
        if (data != '\n' && buffer_index < BUFFER_SIZE - 1) { // 如果接收到的數(shù)據(jù)不是換行符且緩沖區(qū)未滿
            buffer[buffer_index++] = data; // 將接收到的數(shù)據(jù)存儲(chǔ)到緩沖區(qū)中
        } else { // 如果接收到換行符或者緩沖區(qū)已滿
            buffer[buffer_index] = '\0'; // 確保字符串結(jié)束,即在緩沖區(qū)末尾添加字符串結(jié)束符'\0'

            // 檢查接收到的命令
            if (strcmp(buffer, "led on") == 0) { // 如果接收到的命令是"led on"
                GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 點(diǎn)亮LED
                char *msg = "已打開\n"; // 定義提示消息
                while (*msg) { // 循環(huán)發(fā)送消息中的每個(gè)字符
                    USART3_SendChar(*msg++); // 通過串口發(fā)送字符
                }
            }

            // 重置索引,準(zhǔn)備下一次接收
            buffer_index = 0; // 重置緩沖區(qū)索引,準(zhǔn)備接收下一條指令
        }

        USART_ClearITPendingBit(USART3, USART_IT_RXNE); // 清除接收中斷標(biāo)志位
    }
}

按照我原本的想法是先通過 USART3 接收中斷判斷是否接收到數(shù)據(jù),然后讀取接收到的數(shù)據(jù)并存儲(chǔ)到緩沖區(qū)中。當(dāng)接收到換行符或者緩沖區(qū)已滿時(shí),將緩沖區(qū)末尾添加字符串結(jié)束符'\0',然后檢查接收到的命令,如果是"led on"則點(diǎn)亮LED,并通過串口發(fā)送提示消息"已打開\n",最后重置緩沖區(qū)索引,準(zhǔn)備接收下一條指令。乍一看沒啥毛病,但發(fā)現(xiàn)雖然buffer[]這個(gè)數(shù)組接收到了來自data的信息,最后經(jīng)過仿真調(diào)試發(fā)現(xiàn)是在代碼實(shí)現(xiàn)的時(shí)候給自己埋了雷。

strcmp這個(gè)函數(shù)用于比較兩個(gè)字符串是否相等,函數(shù)原型:

int strcmp(const char *str1, const char *str2);

strcmp函數(shù)接受兩個(gè)參數(shù),分別是要比較的兩個(gè)字符串 str1str2。它會(huì)按照字典順序逐個(gè)比較兩個(gè)字符串中的字符,直到遇到不相等的字符或者到達(dá)字符串結(jié)尾(即遇到 '\0' 終止符)。

如果兩個(gè)字符串相等,則返回值為0;如果第一個(gè)字符串小于第二個(gè)字符串,則返回值為負(fù)數(shù);如果第一個(gè)字符串大于第二個(gè)字符串,則返回值為正數(shù)。

GPT在這里是這樣寫的:

if (strcmp(buffer, "led on") == 0)  // 如果接收到的命令是"led on"

也就是要求我發(fā)送的字符串完全等于?"led on"才能進(jìn)入,但在串口助手中卻選擇了“發(fā)送新行”這個(gè)選項(xiàng),就相當(dāng)于每次發(fā)送的都是"led on\n",由于strcmp函數(shù)的作用自然不會(huì)讓我們進(jìn)入邏輯,而且這段代碼中并沒有清空緩沖區(qū)數(shù)據(jù)的操作,也就是說就算沒有發(fā)送新行,在第一次發(fā)送結(jié)束之后buffer[]中的數(shù)據(jù)就是“l(fā)ed onled onled on...”這種,所以需要使用memset函數(shù)在每次接收后清空緩沖區(qū)數(shù)據(jù),并且最好將strcmp函數(shù)換成strstr函數(shù),strstr作用和strcmp很相似,但更適合這個(gè)場景,簡單來說使用strstr就是只要buffer[]這個(gè)數(shù)組中出現(xiàn)“l(fā)ed on”就能進(jìn)入邏輯,只要在每次接收完數(shù)據(jù)后清空緩沖區(qū)數(shù)據(jù)就行。下面看我修正優(yōu)化過的正確代碼。

注:

1,strstr 函數(shù)是 C 標(biāo)準(zhǔn)庫中的一個(gè)字符串查找函數(shù),用于在一個(gè)字符串中查找另一個(gè)子字符串的第一次出現(xiàn)位置。其函數(shù)原型為:

char *strstr(const char *haystack, const char *needle);

strstr 函數(shù)接受兩個(gè)參數(shù),分別是要搜索的主字符串 haystack 和要查找的子字符串 needle。它會(huì)在主字符串中從頭開始逐個(gè)字符地搜索子字符串,直到找到子字符串的第一次出現(xiàn)或者到達(dá)主字符串的結(jié)尾。如果找到子字符串,則返回指向該子字符串在主字符串中第一次出現(xiàn)位置的指針;如果沒有找到子字符串,則返回 NULL。

2,memset 函數(shù)是 C 標(biāo)準(zhǔn)庫中的一個(gè)函數(shù),用于將一段內(nèi)存塊的內(nèi)容設(shè)置為指定的值。其函數(shù)原型為:

void *memset(void *ptr, int value, size_t num);

memset 函數(shù)接受三個(gè)參數(shù),分別是指向要設(shè)置的內(nèi)存塊的指針 ptr、要設(shè)置的值 value、以及要設(shè)置的字節(jié)數(shù) num。

具體來說,ptr 是要設(shè)置的內(nèi)存塊的起始地址,value 是要設(shè)置的值(通常是一個(gè)字節(jié)的值,即 0 到 255 之間的整數(shù)),num 是要設(shè)置的字節(jié)數(shù)。函數(shù)會(huì)將 ptr 指向的內(nèi)存塊中的前 num 個(gè)字節(jié)的內(nèi)容都設(shè)置為 value。

代碼講解

串口的頭文件

#ifndef __USART_H
#define	__USART_H


#include "stm32f10x.h"
#include <stdio.h>

// 串口3-USART3
#define  DEBUG_USARTx                   USART3
#define  BUFFER_SIZE                    100

void USART3_Config(u32 BAUD);
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch);
void Usart_SendString( USART_TypeDef * pUSARTx, char *str);
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch);
uint8_t Check_devices(void);
uint8_t Control_devices(void);

#endif /* __USART_H */

USART3配置及其中斷配置

void USART3_Config(u32 BAUD) 
{
    // GPIO端口設(shè)置
    GPIO_InitTypeDef GPIO_InitStructure; // 聲明GPIO初始化結(jié)構(gòu)體變量
    USART_InitTypeDef USART_InitStructure; // 聲明USART初始化結(jié)構(gòu)體變量
    NVIC_InitTypeDef NVIC_InitStructure; // 聲明中斷向量表初始化結(jié)構(gòu)體變量

    // 使能GPIOB時(shí)鐘和USART3時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB時(shí)鐘
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); // 使能USART3時(shí)鐘

    // USART3 TX -> PB10,RX -> PB11
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // 配置GPIOB的引腳10(USART3的TX引腳)
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 設(shè)置為復(fù)用推挽輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 設(shè)置輸出速度為50MHz
    GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB的引腳10

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; // 配置GPIOB的引腳11(USART3的RX引腳)
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 設(shè)置為浮空輸入
    GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB的引腳11

    // USART3配置
    USART_InitStructure.USART_BaudRate = BAUD; // 設(shè)置波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 設(shè)置數(shù)據(jù)位長度為8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1; // 設(shè)置停止位為1位
    USART_InitStructure.USART_Parity = USART_Parity_No; // 設(shè)置奇偶校驗(yàn)位為無校驗(yàn)
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 設(shè)置硬件流控制為無
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 設(shè)置USART模式為收發(fā)模式
    USART_Init(USART3, &USART_InitStructure); // 根據(jù)USART_InitStruct中指定的參數(shù)初始化USARTx寄存器

    // 配置USART3中斷
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; // 設(shè)置USART3中斷通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 設(shè)置搶占優(yōu)先級(jí)
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 設(shè)置響應(yīng)優(yōu)先級(jí)
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中斷通道
    NVIC_Init(&NVIC_InitStructure); // 根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
    
    // 使能USART3的接收中斷
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 使能USART3的接收中斷
    
    // 使能USART3
    USART_Cmd(USART3, ENABLE); // 使能USART3
}

這個(gè)沒什么好說的,直接復(fù)制就行,注意自己頭文件的引用

串口發(fā)送函數(shù)及printf和scanf的重定向

/*****************  發(fā)送一個(gè)字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
	/* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到USART */
	USART_SendData(pUSARTx,ch);
		
	/* 等待發(fā)送數(shù)據(jù)寄存器為空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

/*****************  發(fā)送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
	unsigned int k=0;
  do 
  {
      Usart_SendByte( pUSARTx, *(str + k) );
      k++;
  } while(*(str + k)!='\0');
  
  /* 等待發(fā)送完成 */
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  {}
}

/*****************  發(fā)送一個(gè)16位數(shù) **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
	uint8_t temp_h, temp_l;
	
	/* 取出高八位 */
	temp_h = (ch&0XFF00)>>8;
	/* 取出低八位 */
	temp_l = ch&0XFF;
	
	/* 發(fā)送高八位 */
	USART_SendData(pUSARTx,temp_h);	
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
	/* 發(fā)送低八位 */
	USART_SendData(pUSARTx,temp_l);	
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

///重定向c庫函數(shù)printf到串口,重定向后可使用printf函數(shù)
int fputc(int ch, FILE *f)
{
		/* 發(fā)送一個(gè)字節(jié)數(shù)據(jù)到串口 */
		USART_SendData(DEBUG_USARTx, (uint8_t) ch);
		
		/* 等待發(fā)送完畢 */
		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

///重定向c庫函數(shù)scanf到串口,重寫向后可使用scanf、getchar等函數(shù)
int fgetc(FILE *f)
{
		/* 等待串口輸入數(shù)據(jù) */
		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(DEBUG_USARTx);
}

重頭戲來了,編寫中斷服務(wù)函數(shù)來存放PC端發(fā)送的數(shù)據(jù)

char buffer[BUFFER_SIZE];
// 定義一個(gè)大小為 BUFFER_SIZE 的字符數(shù)組 buffer,用于存儲(chǔ)接收到的數(shù)據(jù)。

volatile unsigned int buffer_index = 0;
// 定義一個(gè)無符號(hào)整數(shù)變量 buffer_index,表示當(dāng)前接收到的數(shù)據(jù)在 buffer 中的索引。
// volatile 修飾表示該變量可能會(huì)被中斷修改,編譯器不會(huì)對(duì)其進(jìn)行優(yōu)化。

uint8_t buffer_ready = 0;
// 定義一個(gè)無符號(hào) 8 位整數(shù)變量 buffer_ready,表示緩沖區(qū)是否準(zhǔn)備好。
// 0 表示未準(zhǔn)備好,1 表示準(zhǔn)備好。

void USART3_IRQHandler(void) 
{
    // 進(jìn)入 USART3 的中斷服務(wù)程序

    // 檢查是否接收到數(shù)據(jù)
    if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) 
    {
        char data = (char)USART_ReceiveData(USART3); // 讀取接收到的數(shù)據(jù)并存儲(chǔ)在 data 中

        buffer[buffer_index++] = data;
        // 將接收到的數(shù)據(jù)存儲(chǔ)在 buffer 數(shù)組中,并將 buffer_index 索引遞增
        
        buffer_ready = 1;
        // 設(shè)置 buffer_ready 標(biāo)志為 1,表示緩沖區(qū)已經(jīng)準(zhǔn)備好了
        
        if (buffer_index > BUFFER_SIZE - 1) 
            memset(buffer, 0, 100);
        // 如果 buffer_index 大于等于 BUFFER_SIZE - 1,則清空 buffer 數(shù)組中的內(nèi)容,大小為 100 字節(jié)
    }	

    USART_ClearITPendingBit(USART3, USART_IT_RXNE);
    // 清除接收中斷標(biāo)志位,以便下一次接收
}

簡單來說,當(dāng) USART3 接收到數(shù)據(jù)時(shí),將數(shù)據(jù)存儲(chǔ)到 buffer 數(shù)組中,并設(shè)置 buffer_ready 標(biāo)志為 1 表示緩沖區(qū)已經(jīng)準(zhǔn)備好。如果 buffer_index 超出緩沖區(qū)大小,則通過 memset 函數(shù)將 buffer 數(shù)組清空。最后,清除 USART3 的接收中斷標(biāo)志位,以便下一次接收。

編寫串口接收檢查函數(shù)來判斷PC端發(fā)送的數(shù)據(jù),并返回相應(yīng)的返回值

// 串口接收檢查函數(shù)
uint8_t Check_devices(void)
{
    if (buffer_ready) // 檢查緩沖區(qū)是否已準(zhǔn)備好
    {
        buffer_ready = 0; // 清除緩沖區(qū)準(zhǔn)備好的標(biāo)志位

        // 判斷接收到的命令
        if (strstr((const char*)buffer, "UVC on") != 0) 
        {
            buffer_index = 0; // 重置緩沖區(qū)索引,準(zhǔn)備下一次接收
            memset(buffer, 0, 100); // 清空緩沖區(qū)數(shù)據(jù)
            return 1; // 返回命令標(biāo)識(shí)
        }
        // 判斷接收到的命令
        if (strstr((const char*)buffer, "UVC off") != 0)
        {
            buffer_index = 0; // 重置緩沖區(qū)索引,準(zhǔn)備下一次接收
            memset(buffer, 0, 100); // 清空緩沖區(qū)數(shù)據(jù)
            return 2; // 返回命令標(biāo)識(shí)
        }
        // 判斷接收到的命令
        if (strstr((const char*)buffer, "fan on") != 0)
        {
            buffer_index = 0; // 重置緩沖區(qū)索引,準(zhǔn)備下一次接收
            memset(buffer, 0, 100); // 清空緩沖區(qū)數(shù)據(jù)
            return 3; // 返回命令標(biāo)識(shí)
        }
        // 判斷接收到的命令
        if (strstr((const char*)buffer, "fan off") != 0)
        {
            buffer_index = 0; // 重置緩沖區(qū)索引,準(zhǔn)備下一次接收
            memset(buffer, 0, 100); // 清空緩沖區(qū)數(shù)據(jù)
            return 4; // 返回命令標(biāo)識(shí)
        }
    }
}

編寫串口控制設(shè)備函數(shù),并且根據(jù)接收檢查函數(shù)的返回值來執(zhí)行相應(yīng)的邏輯

// 串口控制設(shè)備函數(shù)
uint8_t Control_devices(void)
{	
    if (Check_devices() == 1)
    {		
        GPIO_ResetBits(GPIOC, GPIO_Pin_13); // 點(diǎn)亮LED
        Usart_SendString(USART3, "消毒燈已開啟\n\r"); // 發(fā)送消息到串口
    }
				
    if (Check_devices() == 2)
    {
        GPIO_SetBits(GPIOC, GPIO_Pin_13); // 熄滅LED
        Usart_SendString(USART3, "消毒燈已關(guān)閉\n\r"); // 發(fā)送消息到串口
    }

    if (Check_devices() == 3)
    {
        GPIO_ResetBits(GPIOC, GPIO_Pin_13); // 點(diǎn)亮LED
        Usart_SendString(USART3, "通風(fēng)扇已打開\n\r"); // 發(fā)送消息到串口
    }

    if (Check_devices() == 4)
    {
        GPIO_SetBits(GPIOC, GPIO_Pin_13); // 熄滅LED
        Usart_SendString(USART3, "通風(fēng)扇已關(guān)閉\n\r"); // 發(fā)送消息到串口
    }
}

總的來說,通過上面三段代碼實(shí)現(xiàn)了一個(gè)通過 USART3 接收指令并控制設(shè)備的功能。

首先,通過 USART3 接收中斷函數(shù) USART3_IRQHandler 接收數(shù)據(jù)并存儲(chǔ)到 buffer 緩沖區(qū)中。

然后,通過 Check_devices 函數(shù)檢查緩沖區(qū)中是否有指令,根據(jù)指令執(zhí)行相應(yīng)的操作,并通過串口發(fā)送反饋信息。

Control_devices 函數(shù)根據(jù) Check_devices 的返回值執(zhí)行相應(yīng)的設(shè)備控制操作。

總結(jié):

通過這個(gè)問題,我熟悉了使用串口中斷實(shí)現(xiàn)單片機(jī)與STM32之間的高效通信,同時(shí)也加深了對(duì)于串口通信的理解和掌握。希望這篇博客能夠幫助到有類似學(xué)習(xí)目標(biāo)的讀者,也歡迎大家分享自己的經(jīng)驗(yàn)和觀點(diǎn)。

參考鏈接:

STM32串口通信—串口的接收和發(fā)送詳解文章來源地址http://www.zghlxwxcb.cn/news/detail-855593.html

到了這里,關(guān)于通過串口中斷的方式進(jìn)行ASR-01S模塊與STM32通信(問題與解決)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • STM32使用三種方式(阻塞、中斷、DMA)實(shí)現(xiàn)串口發(fā)送和接收數(shù)據(jù)

    STM32使用三種方式(阻塞、中斷、DMA)實(shí)現(xiàn)串口發(fā)送和接收數(shù)據(jù)

    記錄下學(xué)習(xí)STM32開發(fā)板的心得的和遇見的問題。 板卡型號(hào):STM32F405RGT6 軟件:STM32CubeMX、IAR STM32串口外設(shè)提供了3種接收和發(fā)送方式:阻塞、中斷、DMA,主要給大家分享中斷方式接收不定長數(shù)據(jù)和DMA使用空閑中斷接收不定長數(shù)據(jù)。 阻塞發(fā)送: 阻塞接收: 兩個(gè)函數(shù)需要注意的就

    2024年02月03日
    瀏覽(26)
  • Arduino與LU-ASR01語音識(shí)別模塊的雙向串口通信實(shí)現(xiàn)

    Arduino與LU-ASR01語音識(shí)別模塊的雙向串口通信實(shí)現(xiàn)

    ? ? 之前我寫了一篇《Arduino的智能語言輸入實(shí)現(xiàn)》,討論了Arduino與LU-ASR01之間通過串口通信實(shí)現(xiàn)Arduino的中文語音輸入,不過那個(gè)通信是不完整的,因?yàn)長U-ASR01的串口只有一個(gè)發(fā)送端口TX,而沒有接收端口RX。其實(shí)在真正的應(yīng)用中,LU-ASR01通常也需要接收上位機(jī)的數(shù)據(jù),例如為確

    2024年02月05日
    瀏覽(321)
  • 嵌入式開發(fā)--STM32用DMA+IDLE中斷方式串口接收不定長數(shù)據(jù)

    嵌入式開發(fā)--STM32用DMA+IDLE中斷方式串口接收不定長數(shù)據(jù)

    之前講過用 利用IDLE空閑中斷來接收不定長數(shù)據(jù) ,但是沒有用到DMA,其實(shí)用DMA會(huì)更加的高效,MCU也可以騰出更多的性能去處理應(yīng)該做的事情。 IDLE顧名思義,就是空閑的意思,即當(dāng)監(jiān)測(cè)到串口空閑超過1個(gè)串口的數(shù)據(jù)幀時(shí),會(huì)使?fàn)顟B(tài)寄存器(SR或ISR)的IDLE位置位,如果此時(shí)控制

    2024年04月17日
    瀏覽(39)
  • STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號(hào)

    STM32-HAL庫串口DMA空閑中斷的正確使用方式+解析SBUS信號(hào)

    能夠點(diǎn)進(jìn)這篇文章的小伙伴肯定是對(duì)STM32串口DMA空閑中斷接收數(shù)據(jù)感興趣的啦,今天用這一功能實(shí)現(xiàn)串口解析航模遙控器sbus信號(hào)時(shí),查閱了很多網(wǎng)友發(fā)布的文章(勤勞的搬運(yùn)工~),包括自己之前寫過一篇博客 STM32_HAL庫_CubeMx串口DMA通信(DMA發(fā)送+DMA空閑接收不定長數(shù)據(jù))。本文

    2024年02月09日
    瀏覽(24)
  • STM32通過DMA方式實(shí)現(xiàn)串口通信

    目錄 一、DMA工作原理 ?二、創(chuàng)建工程項(xiàng)目 三、編寫代碼 1.在main.c寫入以下函數(shù) 2.main函數(shù)中的while循環(huán)中寫入以下代碼

    2024年02月15日
    瀏覽(31)
  • STM32F4_HAL庫_串口阻塞/中斷/DMA三種方式發(fā)送數(shù)據(jù)的配置

    串口阻塞發(fā)送的意思就是,發(fā)送一段數(shù)據(jù),在沒有發(fā)送完所有數(shù)據(jù)之前,一直停留在此發(fā)送函數(shù)(可設(shè)定阻塞時(shí)間),這個(gè)過程中會(huì)阻塞別的程序運(yùn)行; HAL庫的配置分為兩個(gè)層次,一個(gè)是HAL庫內(nèi)部調(diào)用的、與MCU硬件相關(guān)的初始化xxx_MspInit,一個(gè)是我們外部調(diào)用的初始化xxx_In

    2023年04月25日
    瀏覽(32)
  • STM32通過串口2使用ESP8266WIFI模塊連接新大陸云平臺(tái)

    STM32通過串口2使用ESP8266WIFI模塊連接新大陸云平臺(tái)

    目錄 使用硬件: 分步驟:配置TCP連接,連接WIFI 1.使用ESP8266的復(fù)位引腳進(jìn)行復(fù)位 2.發(fā)送基本AT指令 3.連接新大陸 4.新大陸云平臺(tái)顯示在線及上傳數(shù)據(jù)測(cè)試成功 5.串口顯示 5.涉及的函數(shù) 發(fā)生AT檢測(cè)WIFI模塊錯(cuò)誤,如圖,代碼運(yùn)行停留在了.AT,在while中一直循環(huán),沒有往下跑了,這種

    2024年04月24日
    瀏覽(33)
  • STM32 IAP應(yīng)用開發(fā)——通過串口/RS485實(shí)現(xiàn)固件升級(jí)(方式2)

    STM32 IAP應(yīng)用開發(fā)——通過串口/RS485實(shí)現(xiàn)固件升級(jí)(方式2)

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系統(tǒng)中獲取新代碼并對(duì)自己重新編程,即可用程序來改變程序。在應(yīng)用編程(IAP)是用戶的應(yīng)用代碼對(duì)片內(nèi)Flash存儲(chǔ)器進(jìn)行擦除/編程的方法。這種方式的典型應(yīng)用就是用一小段代碼來實(shí)現(xiàn)程序的下載,實(shí)際上單片機(jī)的ISP功能就

    2024年02月14日
    瀏覽(24)
  • STM32 IAP應(yīng)用開發(fā)——通過串口/RS485實(shí)現(xiàn)固件升級(jí)(方式1)

    STM32 IAP應(yīng)用開發(fā)——通過串口/RS485實(shí)現(xiàn)固件升級(jí)(方式1)

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系統(tǒng)中獲取新代碼并對(duì)自己重新編程,即可用程序來改變程序。在應(yīng)用編程(IAP)是用戶的應(yīng)用代碼對(duì)片內(nèi)Flash存儲(chǔ)器進(jìn)行擦除/編程的方法。這種方式的典型應(yīng)用就是用一小段代碼來實(shí)現(xiàn)程序的下載,實(shí)際上單片機(jī)的ISP功能就

    2024年02月10日
    瀏覽(19)
  • STM32(HAL庫)驅(qū)動(dòng)SHT30溫濕度傳感器通過串口進(jìn)行打印

    STM32(HAL庫)驅(qū)動(dòng)SHT30溫濕度傳感器通過串口進(jìn)行打印

    目錄 1、簡介 2、CubeMX初始化配置 2.1 基礎(chǔ)配置 2.1.1 SYS配置 ?2.1.2 RCC配置 2.2 軟件IIC引腳配置 2.3?串口外設(shè)配置 ?2.4 項(xiàng)目生成 ?3、KEIL端程序整合 3.1 串口重映射 3.2 SHT30驅(qū)動(dòng)添加 3.3 主函數(shù)代 3.4 效果展示 本文通過STM32F103C8T6單片機(jī)通過HAL庫方式對(duì)SHT30傳感器進(jìn)行數(shù)據(jù)的讀取,并

    2024年02月16日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包