转自:http://ren-hw.blog.163.com/blog/static/3123414420104233734884/
为了将模拟信号采集到,并对其经AD变换后的数字信号进行保存并处理,包括一些简单的如数字滤波和傅里叶变换等,或者之后可能用到现代的信号处理方法,于是考虑使用stm32负责信号的采集,将数据经232串口送入PC进行处理。在PC端进行数据接收的方法也很多,典型的应该是用VC++吧?但考虑到MATLAB在信号处理方面比较适合,于是用了MATLAB的串口通信。
单片机方面,stm32f103rb的工作包括时钟、中断、IO口、串口及AD的初始化,然后启动转换,便可以向串口发数据。需要注意的是,当向串口发送连续两个数据时(比如16位的高低8位),在等待第一个数据发送完成的方式选择上,不能查询发送完成标志位(TC)。若采用了查询发送完成标志位,第二个数据将覆盖第一个数据。解决办法是采用查询发送数据寄存器空标志位(TXE)。这次的主要工作放在了MATLAB上,因为之前对MATLAB的串口通信不熟,所以是边学边做的,然后顺便又利用GUIDE做了个简单的界面,基本达到要求,等具体用到的时候再去完善吧。
要使用MATLAB接收串口数据,首先需要新建一个串口对象,并初始化,包括波特率,停止位,有无校验,输入输出缓冲区大小等。
scom=serial('COM1');
%串口com1
scom.BaudRate =
9600;
%波特率
scom.InputBufferSize =
1024;
%输入缓冲区
scom.OutputBufferSize =
1024;
%输出缓冲区
scom.ReadAsyncMode =
'continuous';
%异步通信时,连续读串口数据
scom.BytesAvailableFcnMode =
'byte'; %中断触发事件
scom.BytesAvailableFcnCount =
100; %当缓冲区数据
scom.BytesAvailableFcn =
@instrcallback;
%调用回调函数
以上是串口的部分属性及相应的修改,若要查看全部属性,可使用语句get(scom),并根据需要自己的修改相关属性。特别要注意的是上面最后一句(scom.BytesAvailableFcn
= @instrcallback;),这个烦了我很久。意思是当缓冲区中的数据达到100
bytes时调用instrcallback回调函数。MATLAB接收串口数据有两种方式,包括查询和调用回调函数。查询就比较简单,但是会很忙。调用回调函数就类似中断,当用户具体的串口通信事件发生时,执行中断处理。instrcallback.m在MATLAB7\toolbox\matlab\iofun\@instrument目录下面,尽量不要改动原来的内容,在末尾添加当缓冲区有指定量的数据时需要MATLAB做的工作,比如绘图,数据保存之类的。我在回调函数中做的工作暂时比较简单一点,包括将连续两个8位数据拼成16位,并存入一个二进制文件中。部分代码如下:
data=zeros(100,1);
data=fread(obj,100,'uint8');
dataout=zeros(50,1);
for i=1:50
dataout(i)=256*data(2*i)+data(2*i-1);
end
str='D:\MATLABwork\test.dat'
fid = fopen(str,'a+');
fwrite(fid,dataout,'int16');
fclose(fid);
当然,串口对象初始化之后,记得使用fopen(scom)打开串口,当工作完成时,使用fclose(scom)和delete(scom)关闭与清除串口设备。于是整个流程大致就是:创建串口的对象,初始化,打开串口,等待时间发生时调用回调函数,在主程序或者回调函数中根据自己需要关闭并清除串口对象。
经测试,能完成PC端与stm32基本的串口通信问题,包括控制信号的发送接收,数据的接收保存等,当然下位机如果使用其他单片机,只要根据协议修改相关的串口代码,同样能完成通信。
加载中,请稍候......