stm32-c8t6实现语音识别(LD3320)
目录
LD3320介绍:
功能引脚
主要特色功能
通信协议
端口信息
开发流程
stm32c8t6代码
LD3320驱动代码:
LD3320介绍:
- 内置单声道mono 16-bit A/D 模数转换
- 内置双声道stereo 16-bit D/A 数模转换
- 内置 20mW 双声道耳机放大器输出
- 内置 550mW 单声道扬声器放大器输出
- 支持并行接口或者 SPI 接口
- 内置锁相电路 PLL,输入主控时钟频率为 2MHz - 34MHz
- 工作电压:(VDD: for internal core) 3.3V
- 48pin 的 QFN 7*7 标准封装
- 省电模式耗电:1uA
功能引脚
功能引脚 | 描述 |
3.3V | 3.3V电源正 |
GND | 电源地 |
MISO | SPI数据输出 |
MOSI | SPI数据输入 |
SCK | SPI时钟输入 |
NSS | 片选,低电平有效 |
NC | 悬空 |
RST | 复位 |
WR | 写允许,低电平有效 |
IRQ | 中断输出,输出下降沿 |
主要特色功能
LD3320 是一颗基于非特定人语音识别(SI-ASR:Speaker-Independent Automatic Speech Recognition)技术的语音识别/声控芯片。提供了真正的单芯片语音识别解决方案。LD3320 芯片上集成了高精度的 A/D 和 D/A 接口,不再需要外接辅助的 Flash 和 RAM,即可以实现语音识别/声控/人机对话功能。并且,识别的关键词语列表是可以动态编辑的。基于 LD3320,可以在任何的电子产品中,甚至包括最简单的 51 作为主控芯片的系统中,轻松实现语音识别/声控/人机对话功能。为所有的电子产品增加 VUI(Voice User Interface)语音用户操作界面。
- 高准确度和实用的语音识别效果。
- 非特定人语音识别技术:不需要用户进行录音训练。
- 真正单芯片解决方案:不需要任何外接的辅助 Flash 和 RAM,真正降低系统成本。
- 内置高精度 A/D和D/A通道:不需要外接 AD 芯片,只需要把麦克风接在芯片的AD 引脚上;可以播放声音文件,并提供 550mW 的内置放大器。
- 支持用户自由编辑 50 条关键词语条:在同一时刻,最多在 50 条关键词语中进行识别,终端用户可以根据场景需要,随时编辑和更新这 50 条关键词语的内容。
- 可动态编辑的识别关键词语列表:只需要把识别的关键词语以字符串的形式传送进芯片,即可以在下次识别中立即生效。比如,用户在 51 等 MCU 的编程中,简单地通过设置芯片的寄存器,把诸如“你好”这样的识别关键词的内容动态地传入芯片中,芯片就可以识别这样设定的关键词语了。
通信协议
读数据:
写数据:
SCS为从机片选, 仅当SCS为低电平时,芯片才会被使能。
SDI主设备数据输出,从设备数据输入(本模块为从设备)。
SDO为主设备数据输入,从设备数据输出(本模块为从设备)。
SDCK为SPI通信时钟。
对于SPI通信而言,数据是有传输时序的,即数据的捕获需要时钟信号的某个边沿触发,而这个边沿就是由时钟极性(CPOL)与时钟相位(CPHA)的组合决定的:
CPOL的高低决定串行同步时钟的空闲状态电平,CPOL = 0,为低电平;CPOL = 1,为高电平。
CPHA的高低决定串行同步时钟是在第一时钟跳变沿还是第二个时钟跳变沿数据被采集,当CPHA = 0,在第一个跳变沿进行数据采集;CPHA = 1,在第二个跳变沿进行数据采集。
从图中可以看出本模块的SPI传输规则:SDCK空闲时是高电平在第一个边沿时开始传输数据,即传输模式为模式二(0x10);8bit数据;按位传输,高位在前(MSB);另外,本模块的SPI速度建议小于1.5MHz
- 非特定人识别
- 无需用户预先录音训练,可直接识别语音指令。
- 动态关键词列表
- 支持动态编辑最多50条关键词(如“开灯”“关灯”),关键词以字符串形式传入芯片即可生效。
- 关键词长度限制:不超过10个汉字或79字节拼音串。
- 硬件集成度高
- 内置高精度A/D和D/A转换器,无需外接Flash、RAM或AD芯片,麦克风直连即可使用。
- 提供550mW内置音频放大器,支持声音播放功能。
- 多种工作模式
- 口令模式:需唤醒词(如“小呆”)触发后续指令,抗环境干扰能力强。
- 普通模式/按键模式:直接识别或通过按键触发识别。
- 硬件连接
- 典型接口:
WR
(写使能)、IRQ
(中断输出)等控制引脚3。 - 示例:Arduino通过D8引脚控制LED,识别“开灯/关灯”指令10。
- 典型接口:
- 软件配置
-
- 关键词添加:通过寄存器动态写入关键词拼音(如
"kai deng"
)310。 - 代码库支持:提供STM32/Arduino驱动库及示例代码(如
Voice.addCommand()
函数)
- 关键词添加:通过寄存器动态写入关键词拼音(如
端口信息
/*************端口信息********************
* 接线说明
LD3320接口 STM32接口
* RST PB6
* CS PB8
* WR/SPIS PB9
* P2/SDCK PB13
* P1/SDO PB14
* P0/SDI PB15
* IRQ PA3
* A0 PB7
* RD PA0
*****************************************/
LED PB12
#define LED_KT PBout(12) //客厅灯引脚口
#define LED_WS PBout(0) //卧室灯引脚口
#define JDY_FS PBout(1) //控制继电器风扇引脚口
开发流程
// Arduino示例(控制LED)
#include <ld3320.h>
VoiceRecognition Voice;
#define Led 8 void setup() { pinMode(Led, OUTPUT); Voice.init(); Voice.addCommand("kai deng", 0); // 添加指令"开灯",标签0 Voice.addCommand("guan deng", 1); // 添加指令"关灯",标签1 Voice.start();
} void loop() { switch(Voice.read()) { case 0: digitalWrite(Led, HIGH); break; // 开灯 case 1: digitalWrite(Led, LOW); break; // 关灯 }
}
stm32c8t6代码
/*************¶Ë¿ÚÐÅÏ¢********************* ½ÓÏß˵Ã÷LD3320½Ó¿Ú STM32½Ó¿Ú* RST PB6* CS PB8* WR/SPIS PB9* P2/SDCK PB13* P1/SDO PB14* P0/SDI PB15* IRQ PA3 * A0 PB7* RD PA0#define LED_KT PBout(12) //¿ÍÌüµÆÒý½Å¿Ú
#define LED_WS PBout(0) //ÎÔÊÒµÆÒý½Å¿Ú
#define JDY_FS PBout(1) //¿ØÖƼ̵çÆ÷·çÉÈÒý½Å¿Ú*****************************************/#include "system.h"
#include "SysTick.h"
#include "variable.h"
#include "usart.h"
#include "spi.h"
#include "led.h"
#include "timer.h"
#include "LDchip.h"
#include <stdio.h>volatile float mm=0; extern void LD3320_main(void);
int main()
{ Systick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);USART1_Init(115200);//TIM3_Int_Init(5000-1,72-1);TIM4_Int_Init(999,72-1);LED_Init();//TIM_Cmd(TIM3,ENABLE);TIM_Cmd(TIM4,ENABLE);printf("³õʼ»¯Íê³É\r\n");LD3320_main(); //LD3320 Ö÷º¯Êýº¯Êýwhile(1){TimerTreat();ledshow();}
}
LD3320驱动代码:
#include "LDchip.h"
#include "Reg_RW.h"
#include "system.h"
#include "SysTick.h"
#include "usart.h"
#include <stdio.h>
#include "led.h"
/*************¶Ë¿ÚÐÅÏ¢********************* ½ÓÏß˵Ã÷LD3320½Ó¿Ú STM32½Ó¿Ú* RST PB6* CS PB8* WR/SPIS PB9* P2/SDCK PB13* P1/SDO PB14* P0/SDI PB15* IRQ PA3* A0 PB7* RD PA0*****************************************//************************************************************************************
// nAsrStatus ÓÃÀ´ÔÚmainÖ÷³ÌÐòÖбíʾ³ÌÐòÔËÐеÄ״̬£¬²»ÊÇLD3320оƬÄÚ²¿µÄ״̬¼Ä´æÆ÷
// LD_ASR_NONE: ±íʾûÓÐÔÚ×÷ASRʶ±ð
// LD_ASR_RUNING£º ±íʾLD3320ÕýÔÚ×÷ASRʶ±ðÖÐ
// LD_ASR_FOUNDOK: ±íʾһ´Îʶ±ðÁ÷³Ì½áÊøºó£¬ÓÐÒ»¸öʶ±ð½á¹û
// LD_ASR_FOUNDZERO: ±íʾһ´Îʶ±ðÁ÷³Ì½áÊøºó£¬Ã»ÓÐʶ±ð½á¹û
// LD_ASR_ERROR: ±íʾһ´Îʶ±ðÁ÷³ÌÖÐLD3320оƬÄÚ²¿³öÏÖ²»ÕýÈ·µÄ״̬
*********************************************************************************/uint8 nAsrStatus=0;
void LD3320_Init(void);
uint8 RunASR(void);
void ProcessInt0(void);
void LD3320_EXTI_Cfg(void);
void LD3320_Spi_cfg(void);
void LD3320_GPIO_Cfg(void);
void LED_gpio_cfg(void);
static void Board_text(uint8 Code_Val);
extern void PrintComBit(USART_TypeDef* USARTx, uint8_t Data);
/***********************************************************
* Ãû ³Æ£º LD3320_main(void)
* ¹¦ ÄÜ£º Ö÷º¯ÊýLD3320³ÌÐòÈë¿Ú
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void LD3320_main(void)
{uint8 nAsrRes=0;LD3320_Init(); while(1){switch(nAsrStatus){case LD_ASR_RUNING:case LD_ASR_ERROR: break;case LD_ASR_NONE:nAsrStatus=LD_ASR_RUNING;if (RunASR()==0) // Æô¶¯Ò»´ÎASRʶ±ðÁ÷³Ì£ºASR³õʼ»¯£¬ASRÌí¼Ó¹Ø¼ü´ÊÓÆô¶¯ASRÔËËã{ nAsrStatus = LD_ASR_ERROR;}break;case LD_ASR_FOUNDOK:nAsrRes = LD_GetResult( ); //ʶ±ð³É¹¦×Ô¶¯ »ñȡʶ±ðÂë,ʶ±ðÂëÔÚLDChip.hÎļþÖУ¬×ÔÐж¨ÒåµÄÊý¾Ý PrintComBit(USART1,nAsrRes ); //´®¿ÚÊä³öʶ±ðÂë //Board_text(nAsrRes );//¿ª·¢°å²âÊÔÑÝʾ²¿·Ö---¶Ôʶ±ðÂëµÄ½øÐÐÅжÏ×ö³ö¶¯×÷ (Óû§Òà¿ÉÒÔÌí¼Ó×Ô¼ºµÄ¹¦ÄÜ£¬ÀýÈç¿ØÖÆIO¿ÚÊä³ö£¬´®¿ÚÊý¾ÝÊä³öµÈ) nAsrStatus = LD_ASR_NONE;break;case LD_ASR_FOUNDZERO:default: nAsrStatus = LD_ASR_NONE;break;}//switch //¿ª·¢°å²âÊÔBoard_text(nAsrRes );}// while
}static void Board_text(uint8 Code_Val)
{ switch(Code_Val) //¶Ô½á¹ûÖ´ÐÐÏà¹Ø²Ù×÷{case CODE_DD: //ÃüÁî¡°´ò¿ª¿ÍÌüµÆ¡±LED_KT=1;printf("´ò¿ª¿ÍÌüµÆ\r\n");break;case CODE_GD: //ÃüÁî¡°¹Ø±Õ¿ÍÌüµÆ¡±LED_KT=0;printf("¹Ø±Õ¿ÍÌüµÆ\r\n");break;case CODE_QDD: //ÃüÁî¡°´ò¿ªÎÔÊҵơ±//´ò¿ªÎÔÊÒµÆLED_WS = 1;printf("´ò¿ªÎÔÊÒµÆ\r\n");break;case CODE_DG: //ÃüÁî¡°¹Ø±ÕÎÔÊҵơ±//¹Ø±ÕÎÔÊÒµÆLED_WS = 0;printf("¹Ø±ÕÎÔÊÒµÆ\r\n");break;case CODE_LSD: //ÃüÁî¡°È«²¿´ò¿ª¡±//È«²¿´ò¿ªLED_KT=1;LED_WS = 1;printf("È«²¿´ò¿ª\r\n");break;case CODE_SSD: //ÃüÁî¡°È«²¿¹Ø±Õ¡±//È«²¿¹Ø±ÕLED_KT=0; LED_WS = 0;printf("È«²¿¹Ø±Õ\r\n");break;case CODE_DDR: //ÃüÁî¡°´ò¿ª·çÉÈ¡±//´ò¿ª·çÉÈprintf("´ò¿ª·çÉÈ\r\n");JDY_FS = 0;break;case CODE_RDD: //ÃüÁî¡°¹Ø±Õ·çÉÈ¡±//¹Ø±Õ·çÉÈJDY_FS = 1;printf("¹Ø±Õ·çÉÈ\r\n");break;default:break;}
}
/***********************************************************
* Ãû ³Æ£ºLD3320_Init(void)
* ¹¦ ÄÜ£ºÄ£¿éÇý¶¯¶Ë¿Ú³õʼÅäÖÃ
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void LD3320_Init(void)
{LD3320_GPIO_Cfg(); LD3320_EXTI_Cfg();LD3320_Spi_cfg(); LD_reset();}
/***********************************************************
* Ãû ³Æ£º RunASR(void)
* ¹¦ ÄÜ£º ÔËÐÐASR
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
uint8 RunASR(void)
{uint8 i=0;uint8 asrflag=0;for (i=0; i<5; i++) // ·ÀÖ¹ÓÉÓÚÓ²¼þÔÒòµ¼ÖÂLD3320оƬ¹¤×÷²»Õý³££¬ËùÒÔÒ»¹²³¢ÊÔ5´ÎÆô¶¯ASRʶ±ðÁ÷³Ì{LD_AsrStart(); //³õʼ»¯ASRLD3320_delay(100);if (LD_AsrAddFixed()==0) //Ìí¼Ó¹Ø¼ü´ÊÓïµ½LD3320оƬÖÐ{LD_reset(); // LD3320оƬÄÚ²¿³öÏÖ²»Õý³££¬Á¢¼´ÖØÆôLD3320оƬLD3320_delay(50); // ²¢´Ó³õʼ»¯¿ªÊ¼ÖØÐÂASRʶ±ðÁ÷³Ìcontinue;}LD3320_delay(10);if (LD_AsrRun() == 0){LD_reset(); // LD3320оƬÄÚ²¿³öÏÖ²»Õý³££¬Á¢¼´ÖØÆôLD3320оƬLD3320_delay(50); // ²¢´Ó³õʼ»¯¿ªÊ¼ÖØÐÂASRʶ±ðÁ÷³Ìcontinue;}asrflag=1;break; // ASRÁ÷³ÌÆô¶¯³É¹¦£¬Í˳öµ±Ç°forÑ»·¡£¿ªÊ¼µÈ´ýLD3320ËͳöµÄÖжÏÐźÅ}return asrflag;
}/***********************************************************
* Ãû ³Æ£º void Delay_( int i)
* ¹¦ ÄÜ£º ¶ÌÑÓʱ
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void Delay_( int i){ while( i--){ }}
/***********************************************************
* Ãû ³Æ£º LD3320_delay(unsigned long uldata)
* ¹¦ ÄÜ£º ³¤ÑÓʱº¯Êý
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/ void LD3320_delay(unsigned long uldata)
{unsigned int j = 0;unsigned int g = 0;for (j=0;j<5;j++){for (g=0;g<uldata;g++){Delay_(120);}}
}/***********************************************************
* Ãû ³Æ£ºLD3320_GPIO_Cfg(void)
* ¹¦ ÄÜ£º³õʼ»¯ÐèÒªÓõ½µÄIO¿Ú
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void LD3320_GPIO_Cfg(void)
{ GPIO_InitTypeDef GPIO_InitStructure;// ÅäÖÃPA8 Êä³ö 8M ²¨ÐÎ //¶¨ÒåRST/A0/CS/WR¶Ë¿Ú{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB ,ENABLE);//LD_CS /RSETGPIO_InitStructure.GPIO_Pin =GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_SetBits(GPIOB,GPIO_Pin_7); /*A0ĬÈÏÀ¸ß*/}
}
/***********************************************************
* Ãû ³Æ£ºLD3320_Spi_cfg(void)
* ¹¦ ÄÜ£ºÅäÖÃSPI¹¦ÄܺͶ˿ڳõʼ»¯
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void LD3320_Spi_cfg(void)
{GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTBʱÖÓʹÄÜ RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2ʱÖÓʹÄÜ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15¸´ÓÃÍÆÍìÊä³ö GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);LD_CS_H();GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //PB13/14/15ÉÏÀSPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //ÉèÖÃSPIµ¥Ïò»òÕßË«ÏòµÄÊý¾Ýģʽ:SPIÉèÖÃΪ˫ÏßË«Ïòȫ˫¹¤SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //ÉèÖÃSPI¹¤×÷ģʽ:ÉèÖÃΪÖ÷SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //ÉèÖÃSPIµÄÊý¾Ý´óС:SPI·¢ËͽÓÊÕ8λ֡½á¹¹SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //Ñ¡ÔñÁË´®ÐÐʱÖÓµÄÎÈ̬:ʱÖÓÐü¿Õ¸ßSPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //Êý¾Ý²¶»ñÓÚµÚ¶þ¸öʱÖÓÑØSPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSSÐźÅÓÉÓ²¼þ£¨NSS¹Ü½Å£©»¹ÊÇÈí¼þ£¨Ê¹ÓÃSSI룩¹ÜÀí:ÄÚ²¿NSSÐźÅÓÐSSIλ¿ØÖÆSPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //¶¨Òå²¨ÌØÂÊÔ¤·ÖƵµÄÖµ:²¨ÌØÂÊÔ¤·ÖƵֵΪ16SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //Ö¸¶¨Êý¾Ý´«Êä´ÓMSBλ»¹ÊÇLSBλ¿ªÊ¼:Êý¾Ý´«Êä´ÓMSBλ¿ªÊ¼SPI_InitStructure.SPI_CRCPolynomial = 7; //CRCÖµ¼ÆËãµÄ¶àÏîʽSPI_Init(SPI2, &SPI_InitStructure); //¸ù¾ÝSPI_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèSPIx¼Ä´æÆ÷SPI_Cmd(SPI2, ENABLE); //ʹÄÜSPIÍâÉè
}
/***********************************************************
* Ãû ³Æ£º LD3320_EXTI_Cfg(void)
* ¹¦ ÄÜ£º ÍⲿÖжϹ¦ÄÜÅäÖúÍÏà¹Ø¶Ë¿ÚÅäÖÃ
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void LD3320_EXTI_Cfg(void)
{EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;//¶¨ÒåIRQÖжÏÒý½ÅÅäÖÃRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//ÍⲿÖжÏÏßÅäÖÃGPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);EXTI_InitStructure.EXTI_Line = EXTI_Line3;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);EXTI_GenerateSWInterrupt(EXTI_Line3);GPIO_SetBits(GPIOA,GPIO_Pin_3); //ĬÈÏÀ¸ßÖжÏÒý½ÅEXTI_ClearFlag(EXTI_Line3);EXTI_ClearITPendingBit(EXTI_Line3);//ÖжÏǶÌ×ÅäÖÃNVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}/***********************************************************
* Ãû ³Æ£º EXTI1_IRQHandler(void)
* ¹¦ ÄÜ£º ÍⲿÖжϺ¯Êý
* Èë¿Ú²ÎÊý£º
* ³ö¿Ú²ÎÊý£º
* ˵ Ã÷£º
* µ÷Ó÷½·¨£º
**********************************************************/
void EXTI3_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line3)!= RESET ) {ProcessInt0();EXTI_ClearFlag(EXTI_Line3);EXTI_ClearITPendingBit(EXTI_Line3);}
}
相关文章:

stm32-c8t6实现语音识别(LD3320)
目录 LD3320介绍: 功能引脚 主要特色功能 通信协议 端口信息 开发流程 stm32c8t6代码 LD3320驱动代码: LD3320介绍: 内置单声道mono 16-bit A/D 模数转换内置双声道stereo 16-bit D/A 数模转换内置 20mW 双声道耳机放大器输出内置 5…...
Vue作用域插槽
下面,我们来系统的梳理关于 **Vue 作用域插槽 ** 的基本知识点: 一、作用域插槽核心概念 1.1 什么是作用域插槽? 作用域插槽是 Vue 中一种反向数据流机制,允许子组件将数据传递给父组件中的插槽内容。这种模式解决了传统插槽中父组件无法访问子组件内部状态的限制。 1.2…...
「数据分析 - NumPy 函数与方法全集」【数据分析全栈攻略:爬虫+处理+可视化+报告】
- 第 104 篇 - Date: 2025 - 06 - 05 Author: 郑龙浩/仟墨 NumPy 函数与方法全集 文章目录 NumPy 函数与方法全集1. 数组创建与初始化基础创建序列生成特殊数组 2. 数组操作形状操作合并与分割 3. 数学运算基础运算统计运算 4. 随机数生成基础随机分布函数 5. 文件IO文件读写 …...

爬虫学习记录day1
什么是逆向? 数据加密 参数加密 表单加密扣js改写Python举例子 4.1 元素:被渲染的数据资源 动态数据 静态数据 如果数据是加密的情况则无法直接得到数据 4.2 控制台:输出界面 4.3 源代码页面 4.4 网络:抓包功能,获取浏…...

agent基础概念
agent是什么 我个人认为agent并没有一个所谓完美的定义,它是一个比较活的概念,就像是你眼中的一个机器人你希望它做什么事,和我眼中的机器人它解决事情的流程,其实是可以完全不同的,没有必要非得搞一个统一的概念或流程来概况它。但我们依然可以概况几个通用的词来描述它…...
MS8312A 车规 精密、低噪、CMOS、轨到轨输入输出运算放大器,用于传感器、条形扫描器
MS8312A 车规 精密、低噪、CMOS、轨到轨输入输出运算放大器,用于传感器、条形扫描器 简述 MS8312A 是双通道的轨到轨输入输出单电源供电运放。它们具有低的失调电压、低的输入电压电流噪声和宽的信号带宽。 低失调、低噪、低输入偏置电流和宽带宽的特性结合使得 …...
计算机二级Python考试的核心知识点总结
以下是计算机二级Python考试的核心知识点总结,结合高频考点和易错点分类整理: 1. **数据类型与运算** ▷ 不可变类型:int, float, str, tuple(重点区分list与tuple) ▷ 运算符优先级:** > * /…...

让音乐“看得见”:使用 HTML + JavaScript 实现酷炫的音频可视化播放器
在这个数字时代,音乐不仅是听觉的享受,更可以成为视觉的盛宴!本文用 HTML + JavaScript 实现了一个音频可视化播放器,它不仅能播放本地音乐、控制进度和音量,还能通过 Canvas 绘制炫酷的音频频谱图,让你“听见色彩,看见旋律”。 效果演示 核心功能 本项目主要包含以下…...

CAD实体对象智能识别
CAD实体对象智能识别 概述 实体对象智能识别能够在CAD图纸中智能识别和匹配相似的实体对象。该系统采用模式匹配算法,支持几何变换(缩放、旋转),并提供了丰富的配置选项和可视化界面。 系统提供两种主要的识别方式:…...
MySQL中的部分问题(2)
索引失效 运算或函数影响列的使用 当查询条件中对索引列用了函数或运算,索引会失效。 例:假设有索引:index idx_name (name) select * from users where upper(name) ALICE; -- 索引失效因为upper(name)会对列内容进行函数处理…...
【从前端到后端导入excel文件实现批量导入-笔记模仿芋道源码的《系统管理-用户管理-导入-批量导入》】
批量导入预约数据-笔记 前端场馆列表后端 前端 场馆列表 该列表进入出现的是这样的,这儿是列表操作 <el-table-column label"操作" align"center" width"220px"><template #default"scope"><el-buttonlinktype"…...

LabVIEW音频测试分析
LabVIEW通过读取指定WAV 文件,实现对音频信号的播放、多维度测量分析功能,为音频设备研发、声学研究及质量检测提供专业工具支持。 主要功能 文件读取与播放:支持持续读取示例数据文件夹内的 WAV 文件,可实时播放音频以监听被测信…...
MySQL 8.0 绿色版安装和配置过程
MySQL作为云计算时代,被广泛使用的一款数据库,他的安装方式有很多种,有yum安装、rpm安装、二进制文件安装,当然也有本文提到的绿色版安装,因绿色版与系统无关,且可快速复制生成,具有较强的优势。…...

RoseMirrorHA 双机热备全解析
在数字化时代,企业核心业务系统一旦瘫痪,每分钟可能造成数万甚至数十万的损失。想象一下,如果银行的交易系统突然中断,或者医院的挂号系统无法访问,会引发怎样的连锁反应?为了守护这些关键业务,…...

day 18进行聚类,进而推断出每个簇的实际含义
浙大疏锦行 对聚类的结果根据具体的特征进行解释,进而推断出每个簇的实际含义 两种思路: 你最开始聚类的时候,就选择了你想最后用来确定簇含义的特征, 最开始用全部特征来聚类,把其余特征作为 x,聚类得到…...
pandas 字符串存储技术演进:从 object 到 PyArrow 的十年历程
文章目录 1. 引言2. 阶段1:原始时代(pandas 1.0前)3. 阶段2:Python-backed StringDtype(pandas 1.0 - 1.3)4. 阶段3:PyArrow初次尝试(pandas 1.3 - 2.1)5. 阶段4…...

LLMs 系列科普文(6)
截止到目前,我们从模型预训练阶段的数据准备讲起,谈到了 Tokenizer、模型的结构、模型的训练,基础模型、预训练阶段、后训练阶段等,这里存在大量的术语或名词,也有一些奇奇怪怪或者说是看起来乱七八糟的内容。这期间跳…...
exp1_code
#include <iostream> using namespace std; // 链栈节点结构 struct StackNode { int data; StackNode* next; StackNode(int val) : data(val), next(nullptr) {} }; // 顺序栈实现 class SeqStack { private: int* data; int top; int capac…...

serv00 ssh登录保活脚本-邮件通知版
适用于自己有服务器情况,ssh定时登录到serv00,并在登录成功后发送邮件通知 msmtp 和 mutt安装 需要安装msmtp 和 mutt这两个邮件客户端并配置,参考如下文章前几步是讲配置这俩客户端的,很简单,不再赘述 用Shell脚本实…...

意识上传伦理前夜:我们是否在创造数字奴隶?
当韩国财阀将“数字永生”标价1亿美元准入权时,联合国预警的“神经种姓制度”正从科幻步入现实。某脑机接口公司用户协议中“上传意识衍生算法归公司所有”的隐藏条款,恰似德里达预言的当代印证:“当意识沦为可交易数据流,主体性便…...

【AIGC】RAGAS评估原理及实践
【AIGC】RAGAS评估原理及实践 (1)准备评估数据集(2)开始评估2.1 加载数据集2.2 评估忠实性2.3 评估答案相关性2.4 上下文精度2.5 上下文召回率2.6 计算上下文实体召回率 RAGas(RAG Assessment)RAG 评估的缩写ÿ…...

ESP12E/F 参数对比
模式GPIO0GPIO2GPIO15描述正常启动高高低从闪存运行固件闪光模式低高低启用固件刷写 PinNameFunction1RSTReset (Active Low)2ADC (A0)Analog Input (0–1V)3EN (CH_PD)Chip Enable (Pull High for Normal Operation)4GPIO16Wake from Deep Sleep, General Purpose I/O5GPIO14S…...

第二十八章 字符串与数字
第二十八章 字符串与数字 计算机程序完全就是和数据打交道。很多编程问题需要使用字符串和数字这种更小的数据来解决。 参数扩展 第七章,已经接触过参数扩展,但未进行详细说明,大多数参数扩展并不用于命令行,而是出现在脚本文件中。 如果没有什么特殊原因,把参数扩展放…...

[RDK X5] MJPG编解码开发实战:从官方API到OpenWanderary库的C++/Python实现
业余时间一直在基于RDK X5搞一些小研究,需要基于高分辨率图像检测目标。实际落地时,在图像采集上遇到了个大坑。首先,考虑到可行性,我挑选了一个性价比最高的百元内摄像头,已确定可以在X5上使用,接下来就开…...
java复习 05
我的天啊一天又要过去了,没事的还有时间!!! 不要焦虑不要焦虑,事实证明只要我认真地投入进去一切都还是来得及的,代码多实操多复盘,别叽叽喳喳胡思乱想多多思考,有迷茫前害怕后的功…...

aardio 简单网页自动化
WebView自动化,以前每次重复做网页登录、搜索这些操作时都觉得好麻烦,现在终于能让程序替我干活了,赶紧记录下这个超实用的技能! 一、初次接触WebView WebView自动化就像给程序装了个"网页浏览器",第一步得…...

打卡第39天:Dataset 和 Dataloader类
知识点回顾: 1.Dataset类的__getitem__和__len__方法(本质是python的特殊方法) 2.Dataloader类 3.minist手写数据集的了解 作业:了解下cifar数据集,尝试获取其中一张图片 import torch import torch.nn as nn import…...
【评测】Qwen3-Embedding模型初体验
每一篇文章前后都增加返回目录 回到目录 【评测】Qwen3-Embedding模型初体验 模型的介绍页面 本机配置:八代i5-8265U,16G内存,无GPU核显运行,win10操作系统 ollama可以通过下面命令拉取模型: ollama pull modelscope…...
BeanFactory 和 FactoryBean 有何区别与联系?
导语: Spring 是后端面试中的“常青树”,而 BeanFactory 与 FactoryBean 的关系更是高频卡人点。很多候选人混淆两者概念,答非所问,轻则失分,重则直接被“pass”。本文将从面试官视角,深入剖析这一经典问题…...

如何做好一份优秀的技术文档:专业指南与最佳实践
如何做好一份优秀的技术文档:专业指南与最佳实践 技术文档是产品开发、用户支持和团队协作的核心工具。高质量的技术文档能够提升开发效率、降低维护成本并改善用户体验。本文将从实践出发,详细讲解如何编写专业、清晰且实用的技术文档。 🌟…...