122楼
ADC1采集引脚电压
晚上玩ADC。DMA方式读取引脚电压。
DMA配置如下:
//外设基地址
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
//数据存储地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;
//数据方向
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//缓存大小
DMA_InitStructure.DMA_BufferSize = 1;
//外设地址增量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//DMA_PeripheralInc_Disable;
//数据地址增量
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
//外设数据宽度
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//存储数据宽度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//循环采集模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//高优先级
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//内存到内存
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
ADC配置如下:
//独立模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
//连续扫描
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
//外部触发模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//数据对齐方式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//通道号
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel11 configuration */
//规则转换
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
由于没有0~3.3V之间的电压,只能用地线和3.3V电源替代了:
接地时候读出数据为0,接3.3电源时读出0X0FFF.不接基本都在乱跳。
图如下:
晚上玩ADC。DMA方式读取引脚电压。
DMA配置如下:
//外设基地址
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
//数据存储地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;
//数据方向
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//缓存大小
DMA_InitStructure.DMA_BufferSize = 1;
//外设地址增量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//DMA_PeripheralInc_Disable;
//数据地址增量
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
//外设数据宽度
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//存储数据宽度
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//循环采集模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//高优先级
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//内存到内存
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
ADC配置如下:
//独立模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
//连续扫描
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
//外部触发模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//数据对齐方式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//通道号
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel11 configuration */
//规则转换
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);
由于没有0~3.3V之间的电压,只能用地线和3.3V电源替代了:
接地时候读出数据为0,接3.3电源时读出0X0FFF.不接基本都在乱跳。
图如下:
123楼
这里用的fsmc操作,这个函数完全省略。直接lcd-reg=......就可以了。你先了解下fsmc操作。
125楼
软解MP3
1、Helix MP3解码器
Helix MP3是一个开源的MP3解码器。提供对MPEG-1、 MPEG-2和MPEG-2.5 的第3层(Layer 3)支持。它支持可变位速率、恒定位速率,以及立体声和单声道音频格式。有关实现和特性的详细信息,请访问 Helix MP3 解码器网站:https://datatype.helixcommunity.org/Mp3dec。
Helix MP3 解码器的源代码是开源代码,受制于源代码随附文件中描述的许可协议。
就是说咱们研究,就免费了。
可从Helix MP3 解码器网站下载代码:
https://datatype.helixcommunity.org/Mp3dec。
昨天研究一晚上没什么进展。有进展了再分享。
2、音频输出:
使用STM32自带的DAC输出。网上查了下,片子自带的DAC可以驱动耳机,没试过。两个DAC刚好驱动双声道。
3、录音功能实现:
如果板子上的ADC可以实现的话就试试,否则不做。
4、媒体文件读取:
使用SDIO驱动SD卡。板子上有SDIO驱动的SD卡插槽,可作为数据源。
使用FATFS解析文件系统。读取媒体文件。
最新动向:SDIO初始化完成。
SDIO初始化,使用3.5库:
都说3.5库的stm32f10x_sdio.c有问题,至少我今天没碰到:
我使用的几个函数:
SDIO_DeInit,SDIO_Init,SDIO_SetPowerState,SDIO_ClockCmd。。。。。
在初始化之前,发送命令什么的都可以的。
读取Block的时候就遇到了问题。读出的东西全是0,不知道为啥
调用代码:
if(SD_OK == SD_Init())
{
printf("SD卡初始化成功\r\n");
}
if(SD_OK == SD_GetCardInfo(&SDCardInfo1))
{
printf("成功读取SD卡信息 \n");
//cid的内容解析还不会,打印出来信息是错的。但这些信息读出来了
printf("ManufacturerID:%d\r\n",SDCardInfo1.SD_cid.ManufacturerID);
printf("OEM/Application ID:%d\r\n",SDCardInfo1.SD_cid.OEM_AppliID);
printf("Product Revision:%d\r\n",SDCardInfo1.SD_cid.ProdRev);
printf("Product Serial Number:%d\r\n",SDCardInfo1.SD_cid.ProdSN);
printf("Manufacturing Date:%d\r\n",SDCardInfo1.SD_cid.ManufactDate);
}
//这里读出全是0,有点小问题明天解决
SD_ReadBlock(0x00, (u32 *)(&buf[0]), 512);
最后,上图:
SDIO驱动代码
1、Helix MP3解码器
Helix MP3是一个开源的MP3解码器。提供对MPEG-1、 MPEG-2和MPEG-2.5 的第3层(Layer 3)支持。它支持可变位速率、恒定位速率,以及立体声和单声道音频格式。有关实现和特性的详细信息,请访问 Helix MP3 解码器网站:https://datatype.helixcommunity.org/Mp3dec。
Helix MP3 解码器的源代码是开源代码,受制于源代码随附文件中描述的许可协议。
就是说咱们研究,就免费了。
可从Helix MP3 解码器网站下载代码:
https://datatype.helixcommunity.org/Mp3dec。
昨天研究一晚上没什么进展。有进展了再分享。
2、音频输出:
使用STM32自带的DAC输出。网上查了下,片子自带的DAC可以驱动耳机,没试过。两个DAC刚好驱动双声道。
3、录音功能实现:
如果板子上的ADC可以实现的话就试试,否则不做。
4、媒体文件读取:
使用SDIO驱动SD卡。板子上有SDIO驱动的SD卡插槽,可作为数据源。
使用FATFS解析文件系统。读取媒体文件。
最新动向:SDIO初始化完成。
SDIO初始化,使用3.5库:
都说3.5库的stm32f10x_sdio.c有问题,至少我今天没碰到:
我使用的几个函数:
SDIO_DeInit,SDIO_Init,SDIO_SetPowerState,SDIO_ClockCmd。。。。。
在初始化之前,发送命令什么的都可以的。
读取Block的时候就遇到了问题。读出的东西全是0,不知道为啥
调用代码:
if(SD_OK == SD_Init())
{
printf("SD卡初始化成功\r\n");
}
if(SD_OK == SD_GetCardInfo(&SDCardInfo1))
{
printf("成功读取SD卡信息 \n");
//cid的内容解析还不会,打印出来信息是错的。但这些信息读出来了
printf("ManufacturerID:%d\r\n",SDCardInfo1.SD_cid.ManufacturerID);
printf("OEM/Application ID:%d\r\n",SDCardInfo1.SD_cid.OEM_AppliID);
printf("Product Revision:%d\r\n",SDCardInfo1.SD_cid.ProdRev);
printf("Product Serial Number:%d\r\n",SDCardInfo1.SD_cid.ProdSN);
printf("Manufacturing Date:%d\r\n",SDCardInfo1.SD_cid.ManufactDate);
}
//这里读出全是0,有点小问题明天解决
SD_ReadBlock(0x00, (u32 *)(&buf[0]), 512);
最后,上图:
SDIO驱动代码
127楼
只有3分?
SD卡读写数据成功。
配合上面给出的SD卡驱动函数。可以正常读出SD卡中数据。
我读出的是SD卡的00块数据,通过串口发送电脑显示。
然后将读出的数据全部改成0写入0x00块。再读出,发串口显示。
初始化代码:
void SDCard_Init(void)
{
SD_Error Status = SD_OK;
SD_CardInfo SDCardInfo;
/*-------------------------- SD Init ----------------------------- */
Status = SD_Init();
if (Status == SD_OK)
{
/*----------------- Read CSD/CID MSD registers ------------------*/
Status = SD_GetCardInfo(&SDCardInfo);
}
if (Status == SD_OK)
{
/*----------------- Select Card --------------------------------*/
Status = SD_SelectDeselect((u32) (SDCardInfo.RCA << 16));
}
if (Status == SD_OK)
{
//Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
}
/* Set Device Transfer Mode to DMA */
if (Status == SD_OK)
{
// Status = SD_SetDeviceMode(SD_DMA_MODE);//oet
Status = SD_SetDeviceMode(SD_POLLING_MODE);
//Status = SD_SetDeviceMode(SD_INTERRUPT_MODE);
}
}
使用库函数读写BLOCK代码:
//先读出来显示一下
SD_ReadBlock(0x00, (u32 *)(&buf[0]), 512);
for(i=0;i<512;i++)
{
printf("0X%X\t",buf[i]);
}
//修改block中数据,写入。0x01,0x02,0x..,0x..,0x03.后边数据不变.
printf("\r\n\r\n");
buf[0] = 1;
buf[1] = 2;
buf[4] = 3;
SD_WriteBlock(0x00, (u32 *)(&buf[0]), 512);
//SD_ReadBlock(0x00, (u32 *)(&buf[0]), 512);
for(i=0;i<512;i++)
{
printf("0X%X\t",buf[i]);
}
上图:
SDIO读取00块数据
SDIO读出数据与WinHex读出数据的对比,原图可放大查看详细信息:
SDIO 写入数据对比
SD卡读写数据成功。
配合上面给出的SD卡驱动函数。可以正常读出SD卡中数据。
我读出的是SD卡的00块数据,通过串口发送电脑显示。
然后将读出的数据全部改成0写入0x00块。再读出,发串口显示。
初始化代码:
void SDCard_Init(void)
{
SD_Error Status = SD_OK;
SD_CardInfo SDCardInfo;
/*-------------------------- SD Init ----------------------------- */
Status = SD_Init();
if (Status == SD_OK)
{
/*----------------- Read CSD/CID MSD registers ------------------*/
Status = SD_GetCardInfo(&SDCardInfo);
}
if (Status == SD_OK)
{
/*----------------- Select Card --------------------------------*/
Status = SD_SelectDeselect((u32) (SDCardInfo.RCA << 16));
}
if (Status == SD_OK)
{
//Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
}
/* Set Device Transfer Mode to DMA */
if (Status == SD_OK)
{
// Status = SD_SetDeviceMode(SD_DMA_MODE);//oet
Status = SD_SetDeviceMode(SD_POLLING_MODE);
//Status = SD_SetDeviceMode(SD_INTERRUPT_MODE);
}
}
使用库函数读写BLOCK代码:
//先读出来显示一下
SD_ReadBlock(0x00, (u32 *)(&buf[0]), 512);
for(i=0;i<512;i++)
{
printf("0X%X\t",buf[i]);
}
//修改block中数据,写入。0x01,0x02,0x..,0x..,0x03.后边数据不变.
printf("\r\n\r\n");
buf[0] = 1;
buf[1] = 2;
buf[4] = 3;
SD_WriteBlock(0x00, (u32 *)(&buf[0]), 512);
//SD_ReadBlock(0x00, (u32 *)(&buf[0]), 512);
for(i=0;i<512;i++)
{
printf("0X%X\t",buf[i]);
}
上图:
SDIO读取00块数据
SDIO读出数据与WinHex读出数据的对比,原图可放大查看详细信息:
SDIO 写入数据对比
129楼
你是说3.5库里边带的那个spi驱动sd卡吧?spi和sdio是不一样的。我已经给出了sdio驱动sd卡的程序了
130楼
FATFS移植以前琢磨过,那是用SPI读写SD卡。所以今天相对快点
FATFS是一个小日本写的文件系统程序。用的比较多。
移植需要提供哦你几个接口程序:SD卡初始化,SD卡读写Block
就这么多,其他fatFS自己搞定。
下载来代码后,需要新建一个文件:diskio.c。这是接口文件
需要写的函数原型已经在diskio.h里边定义了。你只需要根据需要改写就行了,并不一定要全部写出来。
下面是我的diskio.c里边写的几个函数:
/* 初始化驱动器 ,不需要 站自己写SDCard_Init()实现了这个功能*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
return 0;
}
/* 获取磁盘状态 不知道干啥的 没写*/
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{
return 0;
}
/* 读块,单块或多块 这个是核心 必须写完美*/
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
//memset(buff2, 0, sizeof(buff2));
if(count==1)
{
SD_ReadBlock(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE);
//memcpy(buff,buff2,SECTOR_SIZE);
}
else
{
SD_ReadMultiBlocks(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE,count);
//memcpy(buff,buff2,SECTOR_SIZE * count);
}
return RES_OK;
}
//往SD卡写数据 如果你对SD卡的操作是只读的,这个省略
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
//memset(buff2, 0, sizeof(buff2));
if(count==1)
{
//memcpy(buff2,buff,SECTOR_SIZE);
SD_WriteBlock(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE);
}
else
{
//memcpy(buff2,buff,SECTOR_SIZE * count);
SD_WriteMultiBlocks(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE,count);
}
return RES_OK;
}
//不知道干啥的函数
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
return RES_OK;
}
//没搞定RTC,凑合下弄0代替
DWORD get_fattime(void){
return 0;
}
在主函数中调用:
/*以上为读写SD卡测试程序*/
/*一下为fatFS测试程序*/
disk_initialize(0);
f_mount(0, &fs);
//列出根目录下文件
if (f_opendir(&dirs, "") == FR_OK)
{
printf("找到根目录\r\n");
while (f_readdir(&dirs, &finfo) == FR_OK) //目录下是否有文件
{
if(!finfo.fname[0]) break;
if (finfo.fattrib & AM_ARC) //文件属性为存档。
{
printf("找到文件:%s\r\n",finfo.fname);
printf("文件:[%s]的内容如下\r\n",finfo.fname);
//打开文件,发串口
//打开文件 只读方式
f_open(&fsrc, finfo.fname, FA_OPEN_EXISTING | FA_READ);
//读取文件内容
f_read(&fsrc,readBuf,READBUF_SIZE,&br);
//串口显示
printf("%s\r\n",readBuf);
//打印的东西太多了 只打印第一个吧
break;
}
}
}
最后上图:
FATFS是一个小日本写的文件系统程序。用的比较多。
移植需要提供哦你几个接口程序:SD卡初始化,SD卡读写Block
就这么多,其他fatFS自己搞定。
下载来代码后,需要新建一个文件:diskio.c。这是接口文件
需要写的函数原型已经在diskio.h里边定义了。你只需要根据需要改写就行了,并不一定要全部写出来。
下面是我的diskio.c里边写的几个函数:
/* 初始化驱动器 ,不需要 站自己写SDCard_Init()实现了这个功能*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
return 0;
}
/* 获取磁盘状态 不知道干啥的 没写*/
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{
return 0;
}
/* 读块,单块或多块 这个是核心 必须写完美*/
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
//memset(buff2, 0, sizeof(buff2));
if(count==1)
{
SD_ReadBlock(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE);
//memcpy(buff,buff2,SECTOR_SIZE);
}
else
{
SD_ReadMultiBlocks(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE,count);
//memcpy(buff,buff2,SECTOR_SIZE * count);
}
return RES_OK;
}
//往SD卡写数据 如果你对SD卡的操作是只读的,这个省略
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
//memset(buff2, 0, sizeof(buff2));
if(count==1)
{
//memcpy(buff2,buff,SECTOR_SIZE);
SD_WriteBlock(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE);
}
else
{
//memcpy(buff2,buff,SECTOR_SIZE * count);
SD_WriteMultiBlocks(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE,count);
}
return RES_OK;
}
//不知道干啥的函数
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
return RES_OK;
}
//没搞定RTC,凑合下弄0代替
DWORD get_fattime(void){
return 0;
}
在主函数中调用:
/*以上为读写SD卡测试程序*/
/*一下为fatFS测试程序*/
disk_initialize(0);
f_mount(0, &fs);
//列出根目录下文件
if (f_opendir(&dirs, "") == FR_OK)
{
printf("找到根目录\r\n");
while (f_readdir(&dirs, &finfo) == FR_OK) //目录下是否有文件
{
if(!finfo.fname[0]) break;
if (finfo.fattrib & AM_ARC) //文件属性为存档。
{
printf("找到文件:%s\r\n",finfo.fname);
printf("文件:[%s]的内容如下\r\n",finfo.fname);
//打开文件,发串口
//打开文件 只读方式
f_open(&fsrc, finfo.fname, FA_OPEN_EXISTING | FA_READ);
//读取文件内容
f_read(&fsrc,readBuf,READBUF_SIZE,&br);
//串口显示
printf("%s\r\n",readBuf);
//打印的东西太多了 只打印第一个吧
break;
}
}
}
最后上图:
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |