音频数据的Flash读取与DAC播放

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

Flash地址空间的数据读取

创建工程

打开STM32CubeMX,创建一个工程

配置定时器

 

 引脚配置

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

 

 

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

 

 配置时钟

 之后点击创建工程即可。

修改工程

打开刚刚创建的工程文件

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

/*
 * flash.c
 *
 * Created: 2018-01-29
 * Author: zhanglifu
 */
 
/*********************************************************************/
//                        Í·Îļþ
/*********************************************************************/
#include "flash.h"


// ²»¼ì²éµÄдÈë
// WriteAddr:ÆðʼµØÖ·
// pBuffer:  Êý¾ÝÖ¸Õë
// NumToWrite:×Ö½ÚÊýÊý
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;

    // µØÖ·¼ì²é
    if( (destination_address < FMC_FLASH_BASE) || ( destination_address + length >= FMC_FLASH_END) || (length <= 0) )
        return;

    HAL_FLASH_Unlock();	// ½âËø
    do
    {
        // ¶Á³öÒ»Ò³Êý¾Ý
        for(i=0; i < FMC_SECTOR_SIZE; i += 4 )
            *(uint32_t *)(FlashBuff+i) = *(uint32_t *)(StartAddress+i);

        // ÐÞ¸ÄÒª¸ÄÈëµÄÊý¾Ý
        for ( i=0; (i+Offset)<FMC_SECTOR_SIZE && i< remaindNum; i++ )
            *(FlashBuff+Offset+i) = *(pBuf+i);


        // ²Á³ýÒ»ROWÊý¾Ý
        FLASH_PageErase( StartAddress );

        // HAL¿â FLASH_PageEraseÓÐBUFF,Òª¼ÓÉÏÏÂÃæÈýÐдúÂë
        while( status != HAL_OK )
            status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
        CLEAR_BIT(FLASH->CR, FLASH_CR_PER);

        // дÈëÊý¾Ý
        FlashWriteNoCheck( StartAddress,FlashBuff,FMC_SECTOR_SIZE );

        // ΪÏÂÒ»Ò³×ö×¼±¸
        StartAddress +=  FMC_SECTOR_SIZE;
        remaindNum -= i;
        pBuf += i;
        Offset = 0;

    } while( remaindNum > 0 );

    HAL_FLASH_Lock();  // ÉÏËø
		
}



// ´ÓFLASHÖжÁÖ¸¶¨³¤¶ÈÊý¾Ý
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;

    // µØÖ·¼ì²â
    if( source_address + length > FMC_FLASH_END ) return;

    // Èç¹ûûÓжÔ16Æë
    if( source_address & 1 )
    {
        Offset = 1;
        StartAddress = source_address-1;
    }

    // flashµÄ²Ù×÷ÒªÇó16¶ÔÆë ×îС¶Áд²Ù×÷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) );        // дÈëÊý¾Ýµ½Flash
    
    for(i=0;i<255;i++)
        FlashWBuff[i] = i;
    
  FlashWriteBuff( DEVICE_INFO_ADDRESS + sizeof(FlashTest), FlashWBuff,255 );  // дÈëÊý¾Ýµ½Flash
    FlashReadBuff(  DEVICE_INFO_ADDRESS + sizeof(FlashTest),FlashRBuff,255  );  // ´ÓFlashÖжÁÈ¡Êý

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

程序调试

在这里需要用到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。之后操作时一样的直接烧录就行,有条件可以听一下(我没盐)

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值