IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 音频数据的Flash读取与DAC播放 -> 正文阅读

[嵌入式]音频数据的Flash读取与DAC播放

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

Flash地址空间的数据读取

创建工程

打开STM32CubeMX,创建一个工程

配置定时器

?

?引脚配置

中断配置,将下面红线勾画的15改为0

?

?

  1. 调整堆栈大,将栈大小设为大于2k,因为本案例操作flash会用到:

?

?配置时钟

?之后点击创建工程即可。

修改工程

打开刚刚创建的工程文件

再此处添加一个flash.c文件。代码如下

/*
 * flash.c
 *
 * Created: 2018-01-29
 * Author: zhanglifu
 */
 
/*********************************************************************/
//                        í·???t
/*********************************************************************/
#include "flash.h"


// 2??ì2éμ?D′è?
// WriteAddr:?eê?μ??·
// pBuffer:  êy?Y????
// NumToWrite:×??úêyêy
void FlashWriteNoCheck( uint32_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite )
{
    uint16_t i;

    for( i=0; i<NumToWrite; i+=4 )
    {
        while( HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, WriteAddr+i,*(uint32_t *)(pBuffer+i) ) );
    }

}

extern void FLASH_PageErase(uint32_t PageAddress);
void FlashWriteBuff( const uint32_t destination_address, uint8_t *const buffer,uint32_t length )
{
    uint16_t i;
    uint8_t FlashBuff[FMC_SECTOR_SIZE];
    uint32_t StartAddress = destination_address - destination_address%FMC_SECTOR_SIZE;
    uint16_t Offset = destination_address - StartAddress;
    uint8_t *pBuf = buffer;
    uint32_t remaindNum = length;

    HAL_StatusTypeDef status = HAL_ERROR;

    // μ??·?ì2é
    if( (destination_address < FMC_FLASH_BASE) || ( destination_address + length >= FMC_FLASH_END) || (length <= 0) )
        return;

    HAL_FLASH_Unlock();	// ?a??
    do
    {
        // ?á3?ò?ò3êy?Y
        for(i=0; i < FMC_SECTOR_SIZE; i += 4 )
            *(uint32_t *)(FlashBuff+i) = *(uint32_t *)(StartAddress+i);

        // DT??òa??è?μ?êy?Y
        for ( i=0; (i+Offset)<FMC_SECTOR_SIZE && i< remaindNum; i++ )
            *(FlashBuff+Offset+i) = *(pBuf+i);


        // 2á3yò?ROWêy?Y
        FLASH_PageErase( StartAddress );

        // HAL?a FLASH_PageEraseóDBUFF,òa?óé?????èyDD′ú??
        while( status != HAL_OK )
            status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
        CLEAR_BIT(FLASH->CR, FLASH_CR_PER);

        // D′è?êy?Y
        FlashWriteNoCheck( StartAddress,FlashBuff,FMC_SECTOR_SIZE );

        // ?a??ò?ò3×?×?±?
        StartAddress +=  FMC_SECTOR_SIZE;
        remaindNum -= i;
        pBuf += i;
        Offset = 0;

    } while( remaindNum > 0 );

    HAL_FLASH_Lock();  // é???
		
}



// ′óFLASH?D?á???¨3¤?èêy?Y
void FlashReadBuff(const uint32_t source_address,uint8_t *const buffer,uint16_t length)
{
    uint16_t i;
    uint8_t Offset = 0;
    uint32_t StartAddress = source_address;
    uint16_t data;

    // μ??·?ì2a
    if( source_address + length > FMC_FLASH_END ) return;

    // è?1???óD??16??
    if( source_address & 1 )
    {
        Offset = 1;
        StartAddress = source_address-1;
    }

    // flashμ?2ù×÷òa?ó16???? ×?D??áD′2ù×÷16??±èì?
    if ( Offset )
    {
        data = *(uint16_t *)(StartAddress);
        buffer[0] = data >> 8;
        StartAddress += 2;
    }

    for ( i = 0; i < (length-Offset); i += 2)
    {
        data = *(uint16_t *)(StartAddress+i);
        buffer[i+Offset] = (data & 0xFF);
        if ( (i+Offset) < (length - 1) )
            buffer[i + Offset + 1] = (data >> 8);
    }

}



再在INC文件了添加一个flash.h文件,flash.h可在下面的链接中提取。

?链接:https://pan.baidu.com/s/1dn5vGVMufnqcsyRVrIvKsg?
提取码:jack

添加代码

在main.c添加如下代码

此处添加?#include "flash.h"

此处添加uint8_t FlashWBuff[255];
uint8_t FlashRBuff[255];

此处添加? ?uint8_t i;
?? ? uint8_t FlashTest[]="Hello This is 631907030411 lan Flash Test";

?

?此处添加?? ?FlashWriteBuff( DEVICE_INFO_ADDRESS, FlashTest,sizeof(FlashTest) ); ? ? ? ?// D′è?êy?Yμ?Flash
?? ?
?? ?for(i=0;i<255;i++)
?? ??? ?FlashWBuff[i] = i;
?? ?
? FlashWriteBuff( DEVICE_INFO_ADDRESS + sizeof(FlashTest), FlashWBuff,255 ); ?// D′è?êy?Yμ?Flash
?? ?FlashReadBuff( ?DEVICE_INFO_ADDRESS + sizeof(FlashTest),FlashRBuff,255 ?); ?// ′óFlash?D?áè?êy

编辑工程,没有错误即可开始调试程序。

程序调试

在这里需要用到ST-link,之前我们都是用FlyMCU直接进行烧录的,但是如果我们还是像之前一样的话我们就将无法进行测试,因为这次实验的现象是将数据写进内存,并没有配置串口输出。所以我们需要用ST-link直接在Keil中观察测试结果(数据是否存储进去)。
ST-link连线:

ST-link?? ?STM32
SWCLK?? ?SWCLK
SWDIO?? ?SWDIO
GND?? ?GND
VCC?? ?VCC
?

View->memory windows->memory 1打开内存观察窗口,并在地址栏中输入:0x800c000,观察将要修改的flash区间区容:?

?

View->Watch windows->Watch 1打开一个变量观察窗口,将变量FlashWBuff 和 FlashRBuff加入到 Watch 1 观察窗口:

?

View->Periodic Windows Update开启变量自动更新

F5,全速运行程序,可以看到数组FlashRBuff中内容与数组FlashWBuff中内容一样了:

?

?

基于片内Flash的提示音播放程序

使用Adobe Audition生成正弦波数据

创建文件

?参数设置,点击

点击效果-生成-音调

?修改完成点击确定

点击文件-点击导出,生成wav文件

生成wav文件之后,用UltraEdit将其打开,Ctrl+A选择全部然后右键点击选择选择范围,输入12-59列

?

Edit编辑->列块编辑->输入0x 一列一列加不要急。?

这里借用DAC生成正弦波的例程代码

链接:百度网盘 请输入提取码
提取码:706i

将内容复制到keil文件对应的位置,在下图红框中进行替换。

?使用DAC输出数字音频歌曲数据转换为模拟音频波形输出

打开我们的下好的mp3文件,先转化为wav。之后操作时一样的直接烧录就行,有条件可以听一下(我没盐)

?

?

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:06:15  更:2022-01-01 14:07:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:38:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码