当前位置:首页 > 技术分享 > 正文

扩展32KRAM的STC8H8K信号采集版

简介RAM是计算机系统中保存临时结果的器件,它的大小也决定了计算机处理数据的规模。在嵌入式计算机(单片机中),由于受到价格、功耗等原因,内部的RAM的容量往往比较小,比如从几百字节到十几k字节不等。这能够满足大部分单片机应用的需求了。但是在一些特殊的应用情况下,有时需要大容量的RAM来存储采集到的数...

简介RAM是计算机系统中保存临时结果的器件,它的大小也决定了计算机处理数据的规模。在嵌入式计算机(单片机中),由于受到价格、功耗等原因,内部的RAM的容量往往比较小,比如从几百字节到十几k字节不等。这......

简介

RAM是计算机系统中保存临时结果的器件,它的大小也决定了计算机处理数据的规模。在嵌入式计算机(单片机中),由于受到价格、功耗等原因,内部的RAM的容量往往比较小,比如从几百字节到十几k字节不等。这能够满足大部分单片机应用的需求了。

但是在一些特殊的应用情况下,有时需要大容量的RAM来存储采集到的数据,或者缓存通信数据。此时则需要通过外扩内存来完成。比如最近实验声音信标信号[1]相关系统测试和算法优化,则需要采集到多路音频信号。此时需要通过外扩RAM来解决。

通常静态RAM芯片接口包括有数据、地址和控制总线,与单片机对应的端口相连便可以加成数据的写入和读出。

▲MCU外部RAM

有的单片机在扩展外部RAM的时候,为了节省有限的IO端口,通过使用外部锁存器来复用同一八位地址端口来扩展地址总线到16位的目的。比如8051单片机。这样设计的代价就是需要增加外部锁存器芯片74LS372。

▲8051外部数据总结接口

虽然数据总线和地址总线按照逻辑都标有数据位的顺序:比如16位地址总线按照A0~A15,8位数据总线表明D0-D7。但是在方位静态RAM的时候,数据总线,地址总线内部的这些位的顺序是可以任意调整的。比如在下面设计的单片机系统中,为了满足能够尽量减少PCB布线的交叉,就是通过调整数据线和地址总线内部的位的顺序来满足的。

扩展STC8H8K外部32k字节RAM1.设计说明

STC8H8K单片机具有16路12位的AD转换器,在本实验中用于采集信标发出的Chirp声音,并传送给计算机加以处理。

在博文“基于STC8G8K64U三通道高速ADC采集板[2]"给出了利用STC8H8K内部的8kRAM进行声音信号采集电路设计方案。但是受限于内有8KRAM的空间限制,所能够采集音频信号的路数和时间长度都无法满足研究的目的。所以此次通过外部扩一片32k字节的SRAM来扩展信号采集的容量。

同样通过WiFi-UART转换模块,实现采集数据与PC机之间的数据传送,这一点设计与前面博文中的设计方案是一致的。

2.原理图

所使用的STC8H8K芯片的封装为TSOP48。使用P2端口作为数据总结,使用P0,P4端口作为地址总线。不需要外部的锁存器。

使用UART3与WiFi-UART模块通信。将ADC中的AD0~AD2引到输入端口接收外部被采集的信号。

具体的电路图如下图所示:

▲实验板的原理图

外部接口设计:

(1)ISP端口:

序号符号功能1VCC+5V工作电源2GND工作电源地3TXDMCU串口输出4RXDMCU串口输入

(2)ADC端口:

序号符号功能1ADC0ADC通道02ADC1ADC通道13ADC2ADC通道2,可以作为普通IO

2.PCB板

这里需要需要说明的是,为了能够适应快速制版的实验需要。使用了单面PCB板工艺。为了消除在布线中的交叉部分(因为交叉部分则需要过孔和双面布线),对数据总线和地址总线的顺序进行了调整,由此可以仅仅使用一面PCB便将所有的数据和地址总线完成连接。

下面给出了具体的PCB连接方式。前面原理图中显示了调整后的地址线和数据线的逻辑设计。

▲使用单面覆铜板制作实验电路板

在实际电路设计工程中,有的时候为了方便布线,需要对引线的顺序进行调整。在复杂电路设计中,优势会通过FPGA、CPLD等大规模可编程逻辑器件来对芯片外部引线的顺序进行调整,方便进行布线。当然这也需要付出设计的复杂度和额外增加的芯片价格。

硬件调试

软件开发工程所在的目录:

通过设计,电路板腐蚀、焊接与安装,很快得到实验电路。下面对其进行测试。

▲通电之后的实验电路板

STC8H单片机硬件变成选项配置如下:

▲单片机编程硬件选项参数

单片机工作的主要指标:

内部工作主频:40MHz

ISPUART1波特率:500000bps;

WiFI-UART波特率:460800bps

1.扩展SRAM的实验

(1)访问外部SRAM的子程序:根据设计,对于外部RAM访问软件结构通过以EXTSRAM模块来完成:

程序头文件:

/********************************************:--,2020-04-28****Description:********************************************/define__EXTSRAM__//------------------------------------------------------------------------------defineEXTSRAM_EXTdefineEXTSRAM_EXTexterndefineEXTSRAM_EN1//------------------------------------------------------------------------------voidExtSramInit(void);//------------------------------------------------------------------------------defineEXTSRAM_WR3,7voidExtSramPortInit(void);voidExtSramDataInput(void);voidExtSramDataOutput(void);//------------------------------------------------------------------------------defineEXTSRAM_WR_CLOCKOFF(EXTSRAM_WR),ON(EXTSRAM_WR)voidExtSramAddress(unsignedintnAddress);voidExtSramWrite(unsignedintnAddress,unsignedcharucChar);unsignedcharExtSramRead(unsignedintnAddress);//------------------------------------------------------------------------------unsignedintExtSramCheck(unsignednLength);//***************************************//ENDOFTHEFILE://------------------------------------------------------------------------------defineEXTSRAM_GLOBALS1//Definetheglobalvariablesinclude""include""!/usr/local/bin/python************************************************************fromheadmimport***------------------------------------------------------------------------------------------------------------------------sampledata=[]ch1,ch2=()ch1,ch2=(0x4000)()(ch1,linewidth=1,label='CH1')(ch2,linewidth=1,label='CH2')('Sample')('Amplitude')(True)(loc='upperright')([0,len(ch1),0,0xfff])()(.5)(plt)(1)printf("i=%d"%i)((ch1,ch2))tspsave('sampledata',data=sampledata)(r'd:\temp\')printf('\a')()ENDOFFILE:!/usr/local/bin/python************************************************************fromheadmimport**------------------------------------------------------------defADCCmd(str):data=bytes(str+'\r','gbk')ADDR=(ADC_IP,ADC_PORT)(data,ADDR)defADCCmdData(str,length=8192):data=bytes(str+'\r','gbk')ADDR=(ADC_IP,ADC_PORT)(data,ADDR)(.2)try:rdata,ADDR=(length):print('UDPtimeout.')rdata=b''(.5)recedata=ADCCmdData('buf%d%d'%(startn,recelen))iflen(recedata)*recelen*2:breakdata=data+recedataprintff(startn,n,len(recedata))------------------------------------------------------------ADC_DATA_STEP=500defADCExtBufferData(length):rece_step=int((length+ADC_DATA_STEP-1)/ADC_DATA_STEP)data=b''foriinrange(rece_step):startn=i*ADC_DATA_STEPn=startn+ADC_DATA_STEPifnlength:n=lengthrecelen=n-startnforjinrange(20):recedata=ADCCmdData('sbuf%d%d'%(startn,recelen))iflen(recedata)*recelen*2:breakdata=data+recedataprintff(startn,n,len(recedata))dataarray=[x*256+yforx,yinzip(data[0::2],data[1::2])]ADCCmd('adc')returndataarray[0::2],dataarray[1::2]------------------------------------------------------------defExtBufferCH12():length=0x8000read_step=(length+EXT_BUFFER_STEP-1)//EXT_BUFFER_STEPdata=b''foriinrange(read_step):startn=i*EXT_BUFFER_STEPrecelen=EXT_BUFFER_STEPifstartn+recelenlength:recelen=length-startnforjinrange(20):recedata=ADCCmdData('sbyte%d%d'%(startn,recelen),recelen)iflen(recedata)*recelen:breakdata=data+recedataprintff(startn,startn+recelen,len(recedata))dataarray=[x*256+yforx,yinzip(data[0::2],data[1::2])]ADCCmd('adc')returndataarray[0::2],dataarray[1::2]------------------------------------------------------------******************************

▲采集两路测试信号:正弦波以及三角波信号

2.采集Chirp音频信号

▲采集的Chirp声音信号

▲两个信号的相关信号

▲两个信号的相关信号中心位置波形

公众号留言

打扰了卓老师,先休息了

卓大大,实话实说,这次比赛实在是太太太太太赶了,学校大概六月初左右返校,然后还要准备期末考试。我们队伍参加的是直立节能组。别的组别或许还可以在没有仪器的情况下就把车做出来,但是我们是万万不可能的。充电板和车模一旦有一点问题更正周期是以周计算的,按照以往学长的进度,正常比赛留给软件调试的时间也不过就是半个月左右,现在准备时间压缩到两个月,这次规则的软件又比以往都要难一些,感觉除非开学之后每天通宵,不然实在是不能确保小车的稳定性。求大大考虑考虑节能的兄弟们。

卓老师好,深夜打扰。请问这款芯片可以在信标组中使用,还是说只要涉及到控制的微处理器都要用infineon的呢?

▲电机控制单片机

另外,我听说了一种想法,有些同学在群里讨论用1064自制openmv,事实上偷偷用1064跑信标,我虽然没有验证过可行性,但是不希望有这种想法伤害到比赛的公平性,也不愿意看到openmv因此而被禁止,所以也很卓大提及一下这种想法。

▲自制的OpenMVP模块

再提出一个建议:音标比赛只允许使用成品openmv

参考资料

[1]

声音信标信号:

[2]

基于STC8G8K64U三通道高速ADC采集板:

最新文章