基于stm32f4的数字化语音存储及回放(软件部分)
1.程序部分整体思路
-
在主函数中放置模式选择,通过按键来实现 -
主函数定期会跳出去执行中断 -
在定时器中断中放置不同模式下的执行函数,通过调整定时器的频率来改变adc采样的频率 -
中断里read模式下adc获得值存放在flash -
Play模式下flash指定区域获得数值,通过dac放出 -
Stop模式下获得现在的adc值,并通过dac放出,未有保存操作 -
可使用自制串口上位机通过蓝牙模块或无线模块控制(可以用)
2.以下为主要程序部分,分别为main.c | led.c| adc.c | timer.c |dac.c| flash.c部分
本次主要是对adc采样进行调参
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "adc.h"
#include "timer.h"
#include "dac.h"
u8 mode;
extern __IO uint16_t ADC_ConvertedValue;
int main(void){
LED_Init();
KEY_Init();
ADC_1_Init();
Dac1_Init();
delay_init(168);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM3_Int_Init(4200,1);
mode = wait;
while(1){
if(KEY0 == 0){
delay_ms(10);
if(KEY0 == 0)
mode = re;
}
if(KEY1 == 0){
delay_ms(10);
if(KEY1 == 0)
mode = play;
}
if(KEY2==0){
delay_ms(10);
if(KEY2==0)
mode=clear;
}
if(WK_UP==1)
{
TIM3_Int_Init(6300,1);
}
}
}
led.c
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10| GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_SetBits(GPIOF,GPIO_Pin_10| GPIO_Pin_9);
}
adc.c
#include "ADC.h"
__IO uint16_t ADC_ConvertedValue;
void ADC_1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2|RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA,&GPIO_InitStructure);
DMA_DeInit(DMA2_Stream0);
DMA_InitStructure.DMA_Channel=DMA_Channel_0;
DMA_InitStructure.DMA_BufferSize=1;
DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&ADC_ConvertedValue;
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_PeripheralInc = 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_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0,&DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConv(ADC1);
}
timer.c
#include "timer.h"
#include "led.h"
#include "dac.h"
#include "adc.h"
#include "key.h"
#include "flash.h"
#include "delay.h"
#define TEXT_LENTH sizeof(adc)
#define size TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)
extern u8 mode;
extern __IO uint16_t ADC_ConvertedValue;
int x=0,y=0;
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSture;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseInitSture.TIM_Period=arr;
TIM_TimeBaseInitSture.TIM_Prescaler=psc;
TIM_TimeBaseInitSture.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitSture.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitSture);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x03;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3,ENABLE);
}
void TIM3_IRQHandler(void){
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET){
switch (mode){
case re:
LED0 = 0;
LED1 = 1;
STMFLASH_Write(ADDR_FLASH_SECTOR_4+x,(u32*)&ADC_ConvertedValue,1);
x+=4;
break;
case play:
LED0 = 1;
LED1 = 0;
if((ADDR_FLASH_SECTOR_4+y)>=0x080FFFFF){
LED1=1;
break;
}
DAC_SetChannel1Data(DAC_Align_12b_R,(u16)STMFLASH_ReadWord(ADDR_FLASH_SECTOR_4+y));
y+=4;
break;
case clear:
mode=wait;
LED0 = 0;
LED1 = 0;
flash_clear();
delay_ms(500);
LED0 = 1;
LED1 = 1;
break;
default :
LED1 = 1;
LED0 = 1;
x=y=0;
break;
}
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
dac.c
#include "dac.h"
void Dac1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitType;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
DAC_InitType.DAC_Trigger=DAC_Trigger_None;
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;
DAC_Init(DAC_Channel_1,&DAC_InitType);
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_SetChannel1Data(DAC_Align_8b_R,0);
}
void Dac1_Set_Vol(u16 vol)
{
double temp=vol;
temp/=1000;
temp=temp*4096/3.3;
DAC_SetChannel1Data(DAC_Align_12b_R,temp);
}
falsh.c
#include "flash.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
u32 STMFLASH_ReadWord(u32 faddr)
{
return *(vu32*)faddr;
}
uint16_t STMFLASH_GetFlashSector(u32 addr)
{
if(addr<ADDR_FLASH_SECTOR_1)return FLASH_Sector_0;
else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_Sector_1;
else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_Sector_2;
else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_Sector_3;
else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_Sector_4;
else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_Sector_5;
else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_Sector_6;
else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_Sector_7;
else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_Sector_8;
else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_Sector_9;
else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_Sector_10;
return FLASH_Sector_11;
}
void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
{
FLASH_Status status = FLASH_COMPLETE;
u32 endaddr=0;
if(WriteAddr>=0x080FFFFF){
LED0 = 1;
return;
}
if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return;
FLASH_Unlock();
FLASH_DataCacheCmd(DISABLE);
endaddr=WriteAddr+NumToWrite*4;
if(status==FLASH_COMPLETE)
{
while(WriteAddr<endaddr)
{
if(FLASH_ProgramWord(WriteAddr,*pBuffer)!=FLASH_COMPLETE)
{
break;
}
WriteAddr+=4;
}
}
FLASH_DataCacheCmd(ENABLE);
FLASH_Lock();
}
void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)
{
if(ReadAddr>=ADDR_FLASH_SECTOR_5){
LED1 = 1;
return;
}
u32 i;
for(i=0;i<NumToRead;i++)
{
pBuffer[i]=STMFLASH_ReadWord(ReadAddr);
ReadAddr+=4;
}
}
void flash_clear(){
u32 addrx=0;
FLASH_Status status = FLASH_COMPLETE;
addrx=ADDR_FLASH_SECTOR_4;
FLASH_Unlock();
FLASH_DataCacheCmd(DISABLE);
if(ADDR_FLASH_SECTOR_4<0x080FFFFF)
{
while(addrx<=0x080FFFFF)
{
if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)
{
status=FLASH_EraseSector(STMFLASH_GetFlashSector(addrx),VoltageRange_3);
if(status!=FLASH_COMPLETE)break;
}else addrx+=4;
}
}
FLASH_DataCacheCmd(ENABLE);
FLASH_Lock();
}
|