/*LD3320 CS Control*/
#define LD_CS_H() GPIOB->ODR |= (1 << 12)
#define LD_CS_L() GPIOB->ODR &= ~(1 << 12)
/*LD3320 RST Control*/
#define LD_RST_H() GPIOB->ODR |= (1 << 9)
#define LD_RST_L() GPIOB->ODR &= ~(1 << 9)
这个就是写H和L高低电平:
/*LD3320 CS Control MCU: SPI2_CS PB12*/
#define LD_CS_H() GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define LD_CS_L() GPIO_ResetBits(GPIOB, GPIO_Pin_12)
/*LD3320 RST Control MCU: LD_RST PB9*/
#define LD_RST_H() GPIO_SetBits(GPIOB, GPIO_Pin_9)
#define LD_RST_L() GPIO_ResetBits(GPIOB, GPIO_Pin_9)
/*用于记录是否有识别结果产生*/
uint8_t ucRegVal;
/*用于记录是否有识别结果产生*/
uint8_t nAsrStatus=0;
这两个变量是在C语言中定义的全局变量,用于在程序的不同部分之间共享数据。
- uint8_t ucRegVal;:这是一个无符号8位整数(可以存储0到255的值),用于记录某种识别结果。具体的识别结果取决于程序的其他部分如何使用这个变量。
- uint8_t nAsrStatus=0;:这也是一个无符号8位整数,初始值被设置为0。这个变量可能被用来记录语音识别(ASR,Automatic Speech Recognition)的状态。例如,不同的值可能代表ASR系统的不同状态(如空闲、运行中、错误等)。具体的含义取决于程序的其他部分如何使用和修改这个变量。
/*用来记录当前是在进行ASR识别还是在播放MP3*/
uint8_t nLD_Mode = LD_MODE_IDLE;
nLD_Mode 是一个全局变量,用于记录当前的工作模式。它是一个 uint8_t 类型的变量,可以有两个值:
- LD_MODE_IDLE:这是默认值,表示当前没有进行任何操作。
- 0x08:表示当前正在进行ASR(Automatic Speech Recognition,自动语音识别)识别。
- 0x40:表示当前正在播放MP3。
这个变量的值会根据程序的运行情况进行改变,用于控制和跟踪LD3320芯片的工作状态。
/* Handle / Register **********************************************************/
/*Handle*/
const static ld3320_cfg_t *__p_ld3320_cfg = NULL; //一个静态只读的结构体指针,初始化为NULL
/*Register Function*/
uint8_t ld3320_cfg_register (const ld3320_cfg_t *p_cfg)
{
__p_ld3320_cfg = p_cfg;
return LD_OK;
}
__p_ld3320_cfg 是一个静态的只读指针,它指向一个 ld3320_cfg_t 类型的结构体。这个结构体通常包含了LD3320芯片的配置信息。
这个指针被初始化为 NULL,表示它一开始并没有指向任何有效的内存地址。在程序运行过程中,通过调用 ld3320_cfg_register 函数,可以将它指向一个有效的 ld3320_cfg_t 结构体,从而保存LD3320芯片的配置信息。
由于这个指针被声明为 static,所以它的生命周期是整个程序运行期间,而不仅仅是包含它的代码块。这意味着一旦这个指针被赋予了一个有效的地址,那么这个地址就会被保留,直到程序结束。同时,由于它是 const,所以一旦被赋值,就不能再改变它的值(即不能再让它指向另一个地址)。
/*长延时函数*/
void __delay_long(unsigned long uldata)
{
for (unsigned int j=0 ; j<5 ; j++)
for (unsigned int g = 0; g < uldata ; g++)
for(unsigned int i = 120 ; i > 0 ; i--);
}
这是一个用于产生长时间延迟的函数,名为 __delay_long。它接收一个 unsigned long 类型的参数 uldata,该参数决定了延迟的时长。
函数的实现基于三层嵌套的 for 循环。每一层循环都会消耗一定的处理器时间,从而产生延迟。最内层的循环固定执行120次,中间的循环执行 uldata 次,最外层的循环固定执行5次。因此,总的延迟时长与 uldata 的值成正比。
需要注意的是,这种基于循环的延迟方法并不精确,实际的延迟时长还会受到处理器速度、编译器优化等因素的影响。在需要精确控制延迟时长的场合,通常会使用硬件定时器或者专门的延迟函数,如 usleep、nanosleep 等。
/*SPI传输函数*/
uint8_t ld_spi_tran(uint8_t data)//0:接收缓冲为空;1:接收缓冲非空。
{
/* 1. 等待发送缓冲区为空 */
while ((SPI2->SR & 0x2) == 0);//while ((SPI2_SR & (1<<1)) == 0)
/* 2. 发送数据 */
SPI2->DR = data;
/* 3. 等待接收非空 */
while ((SPI2->SR & 0x1) == 0);//while ((SPI2_SR & (1<<0)) == 0)
/* 4. 返回接收的数据 */
return (uint8_t)SPI2->DR;
}
这是一个用于SPI(Serial Peripheral Interface)传输的函数,名为 ld_spi_tran。它接收一个 uint8_t 类型的参数 data,这是要发送的数据。
函数的工作流程如下:
1. 等待发送缓冲区为空:通过检查 SPI2 的状态寄存器(SR)的第二位(对应于 0x2),如果该位为0,表示发送缓冲区为空,可以发送数据。如果不为空,则持续等待。
2. 发送数据:将要发送的数据 data 写入到 SPI2 的数据寄存器(DR)中,开始发送。
3. 等待接收非空:通过检查 SPI2 的状态寄存器(SR)的第一位(对应于 0x1),如果该位为1,表示接收缓冲区非空,有数据可以读取。如果为空,则持续等待。
4. 返回接收的数据:从 SPI2 的数据寄存器(DR)中读取接收到的数据,并返回。
这个函数实现了SPI的全双工通信,即同时进行发送和接收。在发送数据的同时,也会接收数据。
用库函数改写之后就变成这样的:
如果你想将这个函数改写为一个库函数,你可能需要将它放在一个头文件中,并在一个对应的源文件中实现它。这样,其他的源文件就可以通过包含这个头文件来使用这个函数。以下是一个可能的实现:
首先,创建一个头文件,例如 ld3320_spi.h:
#ifndef LD3320_SPI_H
#define LD3320_SPI_H
#include <stdint.h>
uint8_t ld_spi_tran(uint8_t data);
#endif // LD3320_SPI_H
然后,在一个对应的源文件 ld3320_spi.c 中实现这个函数:
#include "ld3320_spi.h"
#include "stm32f10x.h"
uint8_t ld_spi_tran(uint8_t data)
{
/* 1. 等待发送缓冲区为空 */
while ((SPI2->SR & 0x2) == 0);
/* 2. 发送数据 */
SPI2->DR = data;
/* 3. 等待接收非空 */
while ((SPI2->SR & 0x1) == 0);
/* 4. 返回接收的数据 */
return (uint8_t)SPI2->DR;
}
现在,其他的源文件可以通过包含 ld3320_spi.h 来使用 ld_spi_tran 函数。例如:
#include "ld3320_spi.h"
void some_function(void)
{
uint8_t data_to_send = 0x55;
uint8_t received_data = ld_spi_tran(data_to_send);
// Do something with received_data...
}
注意,这个例子假设你正在使用STM32F10x系列的微控制器,并且SPI2已经被正确地初始化。在实际使用中,你可能需要根据你的硬件和软件环境进行适当的修改。