STM32智能语音学习笔记:第二天

目录

1. 点亮LED

1.1 LED.c的代码:(使用了条件编译,方便做移植操作,万一需要修改引脚,通过条件编译和自定义的宏就可以很快的做修改)

1.2 LED.h的代码:

1.3 my_config.h内的代码:(这个文件用来配置端口相关的时钟的引脚,后续添加的硬件也会在这里配置,有利于移植)

2. 编写延时函数

2.1 使用CPU来实现延时

2.2 使用滴答定时器来实现延时(简单略过)

3. 认识语音播报芯片


1. 点亮LED

        点亮LED,GPIO口使用通用、推挽输出。编写代码时,推荐先将整体思路用注释的方式写下。

1.1 LED.c的代码:(使用了条件编译,方便做移植操作,万一需要修改引脚,通过条件编译和自定义的宏就可以很快的做修改)

#include "led.h"
#include "my_config.h"

#ifndef LED2_GPIO_CLOCK
#define LED2_GPIO_CLOCK RCC_APB2Periph_GPIOC // LED灯(绿灯)对应的GPIO组的时钟

#endif

#ifndef LED2_GPIO_PORT
#define LED2_GPIO_PORT GPIOC // LED所在的GPIO组

#endif

#ifndef LED2_PIN
#define LED2_PIN GPIO_Pin_13 // LED所在的GPIO组上的具体引脚

#endif

#ifndef LED2_ON
#define LED2_ON() GPIO_ResetBits(LED2_GPIO_PORT, LED2_PIN)
#endif

#ifndef LED2_OFF
#define LED2_OFF() GPIO_SetBits(LED2_GPIO_PORT, LED2_PIN)
#endif

/**
 * @brief LED初始化函数
 */
void LED2_Init(void)

{
	GPIO_InitTypeDef GPIO_InitTypeStructure; // GPIO初始化要用到的结构体

	RCC_APB2PeriphClockCmd(LED2_GPIO_CLOCK, ENABLE); // 使能GPIOC 的时钟

	GPIO_InitTypeStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitTypeStructure.GPIO_Pin = LED2_PIN;
	GPIO_InitTypeStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LED2_GPIO_PORT, &GPIO_InitTypeStructure); // 初始化GPIO

	// 先熄灭LED灯
	LED2_OFF();
}



1.2 LED.h的代码:

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"

void LED2_Init(void); // LED初始化

#endif

1.3 my_config.h内的代码:(这个文件用来配置端口相关的时钟的引脚,后续添加的硬件也会在这里配置,有利于移植)

#ifndef __MY_CONFIG_H
#define __MY_CONFIG_H

// ==========================================================================
// LED端口相关配置
#define LED2_GPIO_CLOCK         RCC_APB2Periph_GPIOC                      // LED灯(绿灯)对应的GPIO组的时钟
#define LED2_GPIO_PORT          GPIOC                                     // LED所在的GPIO组
#define LED2_PIN                GPIO_Pin_13                               // LED所在的GPIO组上的具体引脚
#define LED2_ON()               GPIO_ResetBits(LED2_GPIO_PORT, LED2_PIN)  // 点亮LED2
#define LED2_OFF()              GPIO_SetBits(LED2_GPIO_PORT, LED2_PIN)    // 熄灭LED2
// ==========================================================================

#endif

        以上代码,使用了大量的宏,需要一定的C语言基础来阅读。

2. 编写延时函数

        可以使用两种方式实现延时:消耗CPU 和 使用定时器(滴答定时器)。

2.1 使用CPU来实现延时

        CPU是根据节拍来执行代码的,而 __nop()函数 刚好占用一次节拍,经过实验/实践测得,(在STM32F103中)for循环占用5个节拍。只要知道了时钟频率,就可以使用循环和__nop()函数来实现延时。

        通过查阅相关资料,STM32F103C8T6的时钟最大为72MHz,1s有72 * 10的六次方次节拍。

        也就是 1000ms 有 72 * 10 00 0000次节拍;

        1000 000 us 有 72 * 10 00 0000次节拍;

        化简之后,1us刚好对应72次节拍。

        那么可以在代码中使用for循环+(72-5)个__nop()函数来实现微妙级的延时。

        相关代码:

/**
 * @brief 使用消耗CPU节拍的方式实现微秒级延时
 * 
 * @param nTimes 延时时间,单位:微秒
 */
void simple_delay_us(uint32_t nTimes)
{
    for (int i = 0; i < nTimes; i++)
    {
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
        __nop();__nop();__nop();__nop();__nop();__nop();__nop();
    }
}

/**
 * @brief 使用消耗CPU节拍的方式实现毫秒级延时
 * 
 * @param nTimes 延时时间,单位:毫秒
 */
void simple_delay_ms(uint32_t nTimes)
{
    while(nTimes--)
    {
        simple_delay_us(1000);
    }
}

/**
 * @brief 使用消耗CPU节拍的方式实现秒级延时
 * 
 * @param nTimes 延时时间,单位:秒
 */
void simple_delay_s(uint32_t nTimes)
{
    while(nTimes--)
    {
        simple_delay_ms(1000);
    }
}

        可以通过MDK内的仿真来观察延时是否准确:

        先设置STM32使用的外部晶振:8MHz。(不然后续的软件仿真结果会不同)

        点击魔术棒,在Debug栏下,选择"Use Simulator",使用软件仿真。接着在"Dialog DLL"填入"DARMSTM DLL","Parameter"填入"-pSTM32F103C8"a。

        在MDK菜单栏点击开始调试按钮(start debug)->添加逻辑分析仪(Logic Analyzer)->在新的窗口中点击setup->新建->填入"PORTC.13"。

        接着,在"Display Type"中选择"Bit":

        设置完成后,点击运行(RUN)按钮:

        当它出现了数个波形后,便可以点击停止按钮,观察相邻的两个边沿的时间间隔是否在0.5s范围内:

        对比后发现,相邻的两个边沿在0.5s左右,有微小的误差,可以忽略不计。

2.2 使用滴答定时器来实现延时(简单略过)

        可以直接使用正点原子的延时代码,也可以看着CM3/CM4权威指南来一步步配置滴答定时器的相关寄存器来实现延时。

        这里我是直接使用正点原子的代码,省略详细的操作。

        通过软件仿真发现,使用滴答定时器的延时比使用CPU延时的精度会高一些(0.0001us左右)。

3. 认识语音播报芯片

        本项目使用SYN6288芯片作为语音播报的主控芯片,以下是它对应的语音播报模块图片:

        SYN6288,也有的型号是SYN6288E,这两种型号的芯片使用方式一致,不影响代码的编写。

        在本次项目中,我们使用3.3V电压给它供电。

        该芯片使用串口来(异步)通信。在硬件连接上,它与STM32C8T6的串口3(USART3)相连。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32智能语音学习笔记:第二天

发表评论