用标准库改写寄存器版本的LD3320库.c和.h文件

/*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已经被正确地初始化。在实际使用中,你可能需要根据你的硬件和软件环境进行适当的修改。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值