设计采集板的目标
设计基于STC8G8K64U单片机的高速ADC采样板,可以为普通的电路实验提供快速波形采样的模块。
该模块也可以应用于全国大学生智能车竞赛声音信标组数据采集实验中。
设计采样板的技术指标:
- 采样频率:10kHz;
- 采样通道:2通道
- 采样信号:0~5V,数据位12bit。
- 外部数据接口:(1)UART2通过USR-WiFi接口发送到局部无线网; (2)通过串口UART1通过调试器将数据发送到调试界面;
电路板设计
电路设计工程文件:
D:\zhuoqing\AltiumDesigner\SmartCar\2020\ADC2C8G8K.PcbDoc *
1. 原理图设计
▲ 原理图设计
对外接口定义:
(1)ISP端口:
序号 | 管脚名称 | 功能 |
---|---|---|
1 | VCC | +5V电源 |
2 | GND | 电源地线 |
3 | TXD | 连接UART1-TXD |
4 | RXD | 连接UART1-RXD |
(2)ADC端口:
序号 | 管脚名称 | 功能 |
---|---|---|
1 | ADC0 | 模拟输入端口0 |
2 | ADC1 | 模拟输入端口1 |
3 | ADC2 | 模拟输入端口2 |
4 | GND | 信号底线 |
(3)WiFI UART接口:
详见电路原理图的PCB的管脚定义。
2. PCB版图设计
▲ PCB板图设计
▲ 焊接之后的电路板
▲ 安装有WiFi-UART模块后的电路板
3. 电路软件调试
软件工程文件:
D:\zhuoqing\window\C51\STC\Tools\ADC2C8H8K\ADC2C8H8K.uvproj
(1)单片机的硬件配置:
由于配置STC8H8K工作在48MHz,提高单片机运行速度。
▲ 单片机硬件配置
(2)串口波特率配置:
- UART1:配置波特率115200 ,这与下载器上的PL2303可以使用的波特率相匹配;
- UART2::配置的波特率为460800,这与WiFi-UART
▲ 硬件连接调试
(3)配置WiFI-UART:
STEP1:使用手机,或者平板电脑,选择USR-WIFI232-T-191无线网关,登录 10.10.100.254地址。在登录界面输入用户名和密码都是admin。
▲ 无线登录界面
STEP2:按照下面的设置,设置WIFI-UART模块的工作参数。
STA设置:
▲ STA设置
AP设置:
▲ AP设置
网络设置:
▲ 网络设置
串口设置:
▲ 串口设置
设置后的系统信息:
▲ 设置后的系统信息
4. 软件命令
模块通过UART1(115200),UART2(460800)接收字符命令,分别输出采集的结果以及重新开始新的采集过程。具体的功能可以参见下面一段程序:
void SerialDebugProcessBuffer(void) {
unsigned int i;
unsigned int nNumber;
unsigned int nStart, nLength, nCheck;
SerialDebugBuffer2Argument();
if(g_ucSDANumber == 0) return;
if(strcmp("hello", (char *)STD_ARG[0]) == 0)
printf("%s is ready !\r\n", VERSION_STRING);
else IFARG0("adc") {
g_nADBufferPoint = 0;
TIME3_INT_ENABLE;
}
else IFARG0("buf") {
sscanf(SDA(1), "%d", &nStart);
sscanf(SDA(2), "%d", &nLength);
nCheck = 0;
for(i = 0; i < nLength; i ++) {
nNumber = g_nADBuffer[i + nStart];
UART2SendChar((unsigned char)(nNumber >> 8));
UART2SendChar((unsigned char)(nNumber & 0xff));
nCheck += nNumber;
}
} else IFARG0("sf") {
SendChar(0x0);
for(i = 0; i < AD_BUFFER; i ++) {
printf("%d ", g_nADBuffer[i]);
}
printf("\r\n");
g_nADBufferPoint = 0;
TIME3_INT_ENABLE;
}
else printf("Error command : %s !\r\n", STD_ARG[0]);
}
5. PYTHON获取数据程序
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2020-04-24
#
# Note:
#============================================================
from headm import *
from tsmodule.tsstm32 import *
import adcsub
from tsmodule.tsdraw import *
#------------------------------------------------------------
#adcsub.ADCCmd('sf')
#------------------------------------------------------------
pltgif = PlotGIF()
for i in range(20):
ch1,ch2 = adcsub.ADCBufferData(4096)
plt.clf()
plt.plot(ch1, label='CH1')
plt.plot(ch2, label='CH2')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend(loc='upper right')
plt.axis([0, len(ch1), 0, 3000])
plt.draw()
plt.pause(.5)
pltgif.append(plt)
pltgif.save(r'd:\temp\SampleGIF.gif')
printf('\a')
#------------------------------------------------------------
# END OF FILE : TEST1.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# ADCSUB.PY -- by Dr. ZhuoQing 2020-04-25
#
# Note:
#============================================================
from headm import *
import socket
from tsmodule.tsstm32 import *
#------------------------------------------------------------
ADC_PORT = 8899
ADC_IP = '192.168.0.191'
ADCSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ADCSocket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 8192)
#------------------------------------------------------------
def ADCCmd(str):
data = bytes(str+'\r', 'gbk')
ADDR = (ADC_IP, ADC_PORT)
ADCSocket.sendto(data, ADDR)
def ADCCmdData(str):
data = bytes(str+'\r', 'gbk')
ADDR = (ADC_IP, ADC_PORT)
ADCSocket.sendto(data, ADDR)
ADCSocket.settimeout(.2)
try:
rdata, ADDR = ADCSocket.recvfrom(8192)
except socket.timeout:
print('UDP time out.')
rdata = b''
return rdata
#------------------------------------------------------------
ADC_DATA_STEP = 500
def ADCBufferData(length):
rece_step = int((length + ADC_DATA_STEP - 1) / ADC_DATA_STEP)
data = b''
for i in range(rece_step):
startn = i * ADC_DATA_STEP
endn = startn + ADC_DATA_STEP
if endn > length: endn = length
recelen = endn - startn
for j in range(5):
# time.sleep(.5)
recedata = ADCCmdData('buf %d %d'%(startn, recelen))
if len(recedata) == recelen * 2:
break
data = data + recedata
printff(startn, endn, len(recedata))
# dataarray = frombuffer(data, uint16)
dataarray = [x*256+y for x,y in zip(data[0::2],data[1::2])]
ADCCmd('adc')
return dataarray[0::2], dataarray[1::2]
#------------------------------------------------------------
def ADCMemoData():
ADCCmd('sf')
time.sleep(2)
stm32cmd('COPY')
data = [int(s) for s in clipboard.paste().strip('\r\n').split(' ') if len(s) > 0]
return data[0::2], data[1::2]
#------------------------------------------------------------
# END OF FILE : adcsub.PY
#============================================================
模块测试性能
1. 数据传送时间
通过WiFi-UAR收到4096(8192 bytes)数据为0.489s左右。
下图是对两路正弦波采集到的数据波形:
▲ 两个通道采集的波形