电赛初探(二)——语音采集回放系统
一、系统结构
1.基本要求
(1)话音/功率放大器增益均可调;
(2)带通滤波器:通带为300Hz~3.4kHz ;
(3)ADC:采样频率f s=8kHz,字长不小于8位;
(4)语音存储时间≥10秒;
(5)DAC:变换频率f c=8kHz,字长不小于8位;
(6)回放语音质量良好。
2.发挥部分
在保证语音质量的前提下:
(1)减少系统噪声电平,增加自动音量控制功能;
(2)语音存储时间增加至20秒以上;
(3)提高存储器的利用率(在原有存储容量不变的前提下,提高语音存储时间);
(4)把采集的语音信号在显示屏上显示。
二、咪头放大电路设计
1、电路仿真
2、要点:
(1) 系统的增益主要通过R5这个滑动变阻器来控制,咪头采集的信号的幅值,必须控制好,否则在进入AD转换后会导致失真。
(2) 必要时可不需要第二级运放电路,第二级电路只是起一个转接下一级的作用。
(3) 由于咪头采集的信号不仅仅是音频信号,所以之后必须加入一个带通滤波过滤掉无用信号。
三、带通滤波器的设计
1、设计软件
2、电路仿真
3、设计要点
(1)选取高Q值,且斜率比较陡的电路较好。
(2)一般需要强制阶数,要不电路太庞大
(3)明白调节增益的关键电阻。
四、AD0809设计
1、程序如下:
#ifndef _ADC0809_H
#define _ADC0809_H #include "stm32f10x.h"
#include "init.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h" //ADC0809µÄ¿ØÖƶË-GPIOA
#define CLK GPIO_Pin_0
//µØÖ·ÊÖ¶¯ÉèÖÃ
//#define A GPIO_Pin_1
//#define B GPIO_Pin_11
//#define C GPIO_Pin_3
#define ALE GPIO_Pin_4 //µØÖ·Ëø´æÔÊÐíÐźÅÊäÈë¶Ë£¬ALE=1£¬µØÖ·Ëø´æ
#define ST GPIO_Pin_5 //ת»»Æô¶¯ÐźÅ
#define OE GPIO_Pin_6 //Êä³öÔÊÐí¿ØÖÆ¶Ë£¬OE=1,Êä³öת»»Êý¾Ý //ADC0809µÄÊý×ÖÊä³ö-GPIOB
#define D0 GPIO_Pin_0
#define D1 GPIO_Pin_1
#define D2 GPIO_Pin_2
#define D3 GPIO_Pin_3
#define D4 GPIO_Pin_4
#define D5 GPIO_Pin_5
#define D6 GPIO_Pin_6
#define D7 GPIO_Pin_7
#define EOC GPIO_Pin_8 //ת»»½áÊøÐźţ¬EOC=1ʱ£¬×ª»»½áÊø void adc0809_init(void); u8 adc0809_input(void); //AD²ÉÑù void ADC0809_Clock(void); //ADC0809Clock²¨ #endif
#include "adc0809.h"
#include "gpio.h"
#include "timer.h"
#include "pbdata.h" void adc0809_init(void)
{
//Êä³ö¹Ü½Å
set_out(GPIOA, CLK|ALE|ST|OE); //ÊäÈë¹Ü½Å
set_FIN(GPIOB, D0|D1|D2|D3|D4|D5|D6|D7|EOC);
timer2_pwm(600*1000, 0.5); //A0¹Ü½Å set_outL(GPIOA, ALE);
//µØÖ·ÊÖ¶¯ÉèÖÃ
// set_outL(GPIOA, A);
// set_outL(GPIOA, B);
// set_outL(GPIOA, C);
delay_us(5);
set_outH(GPIOA, ALE); //µØÖ·Ëø´æ
} u8 adc0809_input() //AD²ÉÑù
{
u8 val;
//ST²úÉúÉÏÉýÑØºÍϽµÑØ£ºÉÏÉýÑØ£¬¼Ä´æÆ÷ÇåÁ㣻ϽµÑØ£º¿ªÊ¼ADת»»
set_outH(GPIOA,ST);
delay_us(5);
set_outL(GPIOA, ST);
delay_us(5);
while(read_in(GPIOB, EOC) == 0); //ת»»¹ý³Ì // EXTI_GenerateSWInterrupt(EXTI_Line14); set_outH(GPIOA,OE); //Êä³öÔÊÐí¿ØÖÆ¶Ë£¬OE=1,Êä³öת»»Êý¾Ý
val = read_in(GPIOB, D0)*0x0001 + read_in(GPIOB, D1)*0x0002 +
read_in(GPIOB, D2)*0x0004 + read_in(GPIOB, D3)*0x0008 +
read_in(GPIOB, D4)*0x0010 + read_in(GPIOB, D5)*0x0020 +
read_in(GPIOB, D6)*0x0040 + read_in(GPIOB, D7)*0x0080; set_outL(GPIOA,OE); return val;
}
华丽的分割!!!!!!!!!!!!!!!
这里是程序中的调用:
adc0809_init();
val = adc0809_input();
DtoB(valB,val);
set_outL(GPIOC,ILE);
delay_us(5);
2、要点
(1) AD需要单片机提供500KHz的方波作为时钟信号,当你提供500KHz的时钟信号时,AD0809便会以8KHz的频率进行采样。
(2) 程序中需要巧妙使用EOC提供的转换停止信号,进行采集,以及接下来的储存和DA转化所应该采取的频率基础来源。
(3) AD0809的参考电压只能是正,且不能大于10V。
五、DA0832使用
1、程序如下
#include "stm32f10x.h" //DAC0832µÄÊý×ÖÊäÈë-GPIOC
#define DI0 GPIO_Pin_0
#define DI1 GPIO_Pin_1
#define DI2 GPIO_Pin_2
#define DI3 GPIO_Pin_3
#define DI4 GPIO_Pin_4
#define DI5 GPIO_Pin_5
#define DI6 GPIO_Pin_6
#define DI7 GPIO_Pin_7
#define ILE GPIO_Pin_8 void da0832_init(void); void DtoB(int valB[],int val);
#include "adc0809.h"
#include "gpio.h"
#include "timer.h"
#include "pbdata.h" void adc0809_init(void)
{
//Êä³ö¹Ü½Å
set_out(GPIOA, CLK|ALE|ST|OE); //ÊäÈë¹Ü½Å
set_FIN(GPIOB, D0|D1|D2|D3|D4|D5|D6|D7|EOC);
timer2_pwm(600*1000, 0.5); //A0¹Ü½Å set_outL(GPIOA, ALE);
//µØÖ·ÊÖ¶¯ÉèÖÃ
// set_outL(GPIOA, A);
// set_outL(GPIOA, B);
// set_outL(GPIOA, C);
delay_us(5);
set_outH(GPIOA, ALE); //µØÖ·Ëø´æ
} u8 adc0809_input() //AD²ÉÑù
{
u8 val;
//ST²úÉúÉÏÉýÑØºÍϽµÑØ£ºÉÏÉýÑØ£¬¼Ä´æÆ÷ÇåÁ㣻ϽµÑØ£º¿ªÊ¼ADת»»
set_outH(GPIOA,ST);
delay_us(5);
set_outL(GPIOA, ST);
delay_us(5);
while(read_in(GPIOB, EOC) == 0); //ת»»¹ý³Ì // EXTI_GenerateSWInterrupt(EXTI_Line14); set_outH(GPIOA,OE); //Êä³öÔÊÐí¿ØÖÆ¶Ë£¬OE=1,Êä³öת»»Êý¾Ý
val = read_in(GPIOB, D0)*0x0001 + read_in(GPIOB, D1)*0x0002 +
read_in(GPIOB, D2)*0x0004 + read_in(GPIOB, D3)*0x0008 +
read_in(GPIOB, D4)*0x0010 + read_in(GPIOB, D5)*0x0020 +
read_in(GPIOB, D6)*0x0040 + read_in(GPIOB, D7)*0x0080; set_outL(GPIOA,OE); return val;
}
2、要点
(1) DA0832芯片输出的是电流信号,也就是说DA出来的是电流量,我们需要外接一个运放来转换成电压信号。
(2) DA0832芯片输出时候的频率应该由EOC来控制。
(3) DA0832芯片输出会产生反相的作用
(4) DA0832与AD0809在直通时,会产生低频干扰,但由于是采集回放系统,所以很好的避免这个问题。否则需要采取软件去抖动的方法。
六、SD储存
1、程序如下
#ifndef _SD_H
#define _SD_H #include "stm32f10x.h"
#include "pbdata.h"
#include "stm32f10x.h"
#include "usart1.h"
#include "stm32f10x_gpio.h"
#include "SD_driver.h" #define LED_D1_ON() (GPIOA->ODR &= ~GPIO_Pin_8)
#define LED_D1_OFF() (GPIOA->ODR |= GPIO_Pin_8) void ConfigurationLED(void);
void InitSys(void);
void InitBSP(void); #endif
#include "SD.h" void ConfigurationLED(void)
{
GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE);
/**
* LED -> PB1
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
} void InitSys(void)
{
SystemInit();
}
/***************************************************************************************/
void InitBSP(void)
{
ConfigurationUsart1();
ConfigurationLED();
printf("\r\n this is a SD Test demo \r\n");
USART1_printf(USART1, "\r\n this is a SD Test demo \r\n");
USART1_printf(USART1, "\r\n ("__DATE__ " - " __TIME__ ") \r\n"); ConfigurationSDCard();
while(1)
{
if(TestSD_ReadWriteFunction())
{
printf ( "SD ReadWriteFunction success !\n");
break;
}
LED_D1_ON(); //D1
printf ( "SD ReadWriteFunction error !\n");
} }
华丽的分割!!!!!!!!!!!!!!!!!!!!!!!!!!!
完整版的AD DA SD程序(仅仅main函数)
u16 sound_p = 0;
InitSys();
InitBSP();
set_out(GPIOA,Pin8);
extern_interrupt_init();
adc0809_init();
da0832_init();
set_outL(GPIOA, ST);
set_out(GPIOA,Pin11); //timer3_init(10000); //¶¨Ê±Æ÷ÖжÏÅäÖÃ
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, DISABLE);
while(1)
{
if(function == Function_In)
{
val = adc0809_input();
music[i++]=val;
// printf("\r %d \n",val);
if(i>=512)
{
i=0;
if(SD_WriteSingleBlock(++Sector_pointer_In, music))
{
// printf("Write Error!");
}
}
} if(function==Function_Out)
{ set_outL(GPIOA, ST);
delay_us(5);
set_outH(GPIOA,ST);
delay_us(5);
set_outL(GPIOA, ST);
delay_us(5);
while(read_in(GPIOB, EOC) == 0); //ת»»¹ý³Ì
if((Sector_pointer_Out<=Sector_pointer_In)&&(Sector_pointer_In!=0))
{
if(i==0)
{
if(SD_ReadSingleBlock(++Sector_pointer_Out, music))
{
// printf("Read Error!");
}
}
DtoB(valB,music[i++]);
// printf("\r %d \n",music[i-1]); GPIO_SetBits(GPIOC, DI0*valB[0] + DI1*valB[1] + DI2*valB[2] + DI3*valB[3] +
DI4*valB[4] + DI5*valB[5] + DI6*valB[6] + DI7*valB[7]);
GPIO_ResetBits(GPIOC, DI0*(1-valB[0]) + DI1*(1-valB[1]) + DI2*(1-valB[2]) + DI3*(1-valB[3]) +
DI4*(1-valB[4]) + DI5*(1-valB[5]) + DI6*(1-valB[6]) + DI7*(1-valB[7]));
if(i>=512)
{
i=0;
}
}
else
{
function=Function_Stop;
}
}
七、功率放大电路
1、采用TDA2030A作为功放芯片,电路如下:
2、要点:
(1)需要调节C7的电容,去掉直流分量。。。虽然不知道为什么会有,在测试的时候220nF会产生10V的直流分量。
(2)需要改变R1来控制增益。
八、总PCB设计
要点:
(1)各级电路之间要用短接帽的方式隔开
(2)电源排针需要多接几个,弄成一排。
(3)电源要用大电容小电容进行滤波
(4)半手工PCB版由于工艺。。最好是把铜线布宽点。
九、成品图
电赛初探(二)——语音采集回放系统的更多相关文章
- 电赛初探(一)——正弦波、方波、锯齿波转换
一.题目要求: 1.使用555做出脉冲方波 2.使用TL084运放做出方波和锯齿波 3.使用TLM314稳压做直流偏置 4.方波要求峰峰值为1V,正弦波要求峰值为0~2V,锯齿波要求峰峰值为1V. 二 ...
- 从电商秒杀与抢购谈Web系统大规模并发
从电商秒杀与抢购谈Web系统大规模并发 http://www.iamlintao.com/4242.html 一.大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程 ...
- Java生鲜电商平台-高可用微服务系统如何设计?
Java生鲜电商平台-高可用微服务系统如何设计? 说明:Java生鲜电商平台高可用架构往往有以下的要求: 高可用.这类的系统往往需要保持一定的 SLA,7*24 时不间断运行不代表完全不挂,而是有一定 ...
- 【系列】关于NJUPT电赛自控方向第一次积分赛的总结
本人是NJUPT电子科学与技术专业大一摸鱼狗一枚.本博客旨在总结与分享个人准备电赛所学知识,同时也是为了防止遗忘,锻炼写文章的能力.目前电赛方向为自控方向.主要研究方向为单片机.图像处理.自动控制相关 ...
- 基于JESD204B和PCIe DMA的多通道数据采集和回放系统
基于JESD204B和PCIe DMA的多通道数据采集和回放系统 在主机端PCIe驱动的控制和调度下,数据采集与回放系统可以同时完成对多个JESD204B接口AD数据的采集以及JESD204B接口DA ...
- B2C 电商网站需要怎样的 ERP 系统
B2C 电商网站需要怎样的 ERP 系统 主要由如下一些系统组成:1.进销存系统,你的产品的采供销当然最好是由系统来实现:2.BI系统,BI包括所有的流量.订单.商品.库存.发货等所有数据节点,亦包含 ...
- 在VirtualBox虚拟机上采集Fedora15系统
在VirtualBox虚拟机上采集Fedora15系统 第一部分:创建系统并磁盘分区 1.点击VirtualBox上的新建 2.添加名称,选择类型和版本,点下一步 3.写入内存(不要超过物理内存),点 ...
- [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania
[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见&quo ...
- TI MSP430工程配置及2019年电赛A题编程示例(使用430 F5529)
配置 第一步:右击工程,选择Options 第二步:在General Options的Target选项卡里选择对应的器件Device,这里是MSP430G2231 第三步:在Debugger里选择FE ...
随机推荐
- 部署在IIS上的网站如何调试
引言 今天突然有个朋友问我,总听同事说在IIS中如何如何调试,到底如何调试呢?没办法,人家刚入门,还是亲手给他操作了一遍.也记录一下,希望能帮到那些不知道的孩纸. IIS中的网站调试 调试最常见的一般 ...
- 【转】 浅谈Radius协议
浅谈Radius协议 2013-12-03 16:06 5791人阅读 评论(0) 收藏 举报 分类: Radius协议分析(6) 从事Radius协议开发有段时间了,小弟不怕才疏学浅,卖弄一下, ...
- 你真的会用AsyncTask吗?(一)
一个典型AsyncTask的. view source print? 01 public class DialogTestActivity extends Activity { 02 priv ...
- 作为一名职高生学习Linux的心酸经历
当你点进这篇文章的时候,一定会好奇我为什么要用“心酸”这个词,这个词已经太久没被人提起,也许心酸这种感情只能存在于一个人在追中梦想过程中内心角落吧.从小我们总是会被问这样一个问题“你的梦想是什么?”每 ...
- Unity游戏开发之“屏幕截图”
原地址:http://sygame.lofter.com/post/117105_791680 在unity游戏开发中,可能会遇到在游戏中截屏的效果.这儿提供两种截屏方法.(方法二提供显示截图缩略图代 ...
- 《linux备份与恢复之一》.tar.bz2与.tar.gz格式的文本压缩率比较
对于文本压缩,据说bzip的算法要优于gzip,从而拥有更好的压缩比.特地找了两个文件来做一下测试,以下为测试结果: (1)源文件为591MB, .tar.bz2文件为61MB(10.32%), ...
- PHP 逻辑思维题
约瑟夫环 一群猴子排成一圈,按1,2,...,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去...,如此不停的进行下去,直到最后只剩下一只猴子为止 ...
- Calico在Kubernetes中的搭建
一,需求 Kubernetes官方推荐的是Flannel,但是Flannel是一个overlay的网络,对性能会有一定的影响.Calico恰好能解决一下overlay网络的不足. Calico在Kub ...
- 90天打造日均在线网站1W+的友情链接平台
导读:三个月过去了,好友张森终于把一款默默无名的软件打造出了日均1W+在线的平台,我认为成功的因素很简单,1,找准了用户群体的痛点;2,肯花精力做运营;3,合理的推广.本文是他的自述,打造一款产品,说 ...
- MyBatis3: There is no getter for property named 'code' in 'class java.lang.String'
mybatis3 : mysql文如下,传入参数为string类型时‘preCode’,运行报错为:There is no getter for property named 'preCode' i ...