发表于:2010/4/18 21:48:41
#0楼
想做一个简易数据采集卡。包含一个TLC1543(10位串行AD转换),一个51单片机以及其他一些小零件。关键是使用串行通信发送给计算机。由于我没有基础,是通过做这个设计来学习单片机的,所以对结果的预料不足。在我花费了很长时间做,到现在接近尾声时发现,要走自定协议的话51串行通信的速度跟不上!!
以下是我做过的两个通信测试实验:
(1)不使用协议
我正确地把AD转换器与单片机相连,采集一个电压(例如3.2V)。我的程序大概如下:
while(1)
{
TLC1543(); //进行AD转换
sent(); //把转换结果发送给计算机
}
TLC1543是10位转换器,所以要用2个字节来保存。但我只发送高8位给计算机。
通过LabVIEW做的小程序把转换的十六进制经过一定算法转化为相应电压值后发现基本保持一条直线(如采集3.2V时,在3.0~3.4间波动)。
这个结果让我相当满意,心想只要把协议加上就大功告成。
(2)使用协议。
我自己定义了一些握手信号,设计了一个不太严谨的协议。
假设:
发A,返回数据a
发B,返回数据b
发C,返回数据c
这次实验就连AD转换也没用,直接定义单片机接收一个值(A),返回对应值(a)。
可是我在使用串口助手调试时却发现这样一个问题:我使用“自动发送”给单片机发A,单片机根本无法及时返回(没有AD转换,我的程序已足够精简)。举个例子,串口助手提示发送500个数据时,可能只收到300个数据。我尝试把发送周期改大,丢失的数据少了,但依然无法做到一发一收!况且,在50ms的发送周期依然有数据丢失的情况下,即使能正确收发,如此低的采样频率实用价值也不大。
这样的结果导致我无法添加通信协议,只能用while循环不断给计算机发送数据。虽然一定情况下也能够显示出大概的波形,但这样一来,根本无从得知,也无从设置采样频率。而过低的采样频率就只能测一些与时间关系不大的对象。
因为基础差,我不很自信,我怀疑是不是有哪一个步骤出错了,所以上来发帖请教各位老师,望指点。以下贴出我第2个实验的代码:
#include<reg51.h>
unsigned char flag;
unsigned char RX;
uint i,j;
void preset();
void sent(uint TX);
void main()
{
preset(); //预设
flag=0;
while(1)
{
switch(RX)
{
case 0x24: sent(0x00);
break;
case 0x3C: sent(0x30);
break;
case 0xC3: sent(0x2C);
break;
}
}
}
//串口通信预设
void preset()
{
//设置计时器
TMOD=0x20; //设置Timer 1在方式2的计时模式
TR1=1; //启动Timer 1
TH1=0xfd;
TL1=0xfd; //根据波特率9600计算得出TH1和TL1值
EA=1; //开总中断
//设置通信模式
SM0=0;
SM1=1; //模式1
REN=1; //允许接收
ES=1; //开串行口中断
}
//发送串口值
void sent(uint TX)
{
if(flag==1)
{
ES=0; //关串行中断
flag=0;
SBUF=TX;
while(!TI); //确保TI置位
TI=0;
ES=1; //开串行中断
}
}
//串口接收
void receive() interrupt 4
{
flag=1;
RX=SBUF;
RI=0; //RI由硬件置位,软件复位
}
以下是我做过的两个通信测试实验:
(1)不使用协议
我正确地把AD转换器与单片机相连,采集一个电压(例如3.2V)。我的程序大概如下:
while(1)
{
TLC1543(); //进行AD转换
sent(); //把转换结果发送给计算机
}
TLC1543是10位转换器,所以要用2个字节来保存。但我只发送高8位给计算机。
通过LabVIEW做的小程序把转换的十六进制经过一定算法转化为相应电压值后发现基本保持一条直线(如采集3.2V时,在3.0~3.4间波动)。
这个结果让我相当满意,心想只要把协议加上就大功告成。
(2)使用协议。
我自己定义了一些握手信号,设计了一个不太严谨的协议。
假设:
发A,返回数据a
发B,返回数据b
发C,返回数据c
这次实验就连AD转换也没用,直接定义单片机接收一个值(A),返回对应值(a)。
可是我在使用串口助手调试时却发现这样一个问题:我使用“自动发送”给单片机发A,单片机根本无法及时返回(没有AD转换,我的程序已足够精简)。举个例子,串口助手提示发送500个数据时,可能只收到300个数据。我尝试把发送周期改大,丢失的数据少了,但依然无法做到一发一收!况且,在50ms的发送周期依然有数据丢失的情况下,即使能正确收发,如此低的采样频率实用价值也不大。
这样的结果导致我无法添加通信协议,只能用while循环不断给计算机发送数据。虽然一定情况下也能够显示出大概的波形,但这样一来,根本无从得知,也无从设置采样频率。而过低的采样频率就只能测一些与时间关系不大的对象。
因为基础差,我不很自信,我怀疑是不是有哪一个步骤出错了,所以上来发帖请教各位老师,望指点。以下贴出我第2个实验的代码:
#include<reg51.h>
unsigned char flag;
unsigned char RX;
uint i,j;
void preset();
void sent(uint TX);
void main()
{
preset(); //预设
flag=0;
while(1)
{
switch(RX)
{
case 0x24: sent(0x00);
break;
case 0x3C: sent(0x30);
break;
case 0xC3: sent(0x2C);
break;
}
}
}
//串口通信预设
void preset()
{
//设置计时器
TMOD=0x20; //设置Timer 1在方式2的计时模式
TR1=1; //启动Timer 1
TH1=0xfd;
TL1=0xfd; //根据波特率9600计算得出TH1和TL1值
EA=1; //开总中断
//设置通信模式
SM0=0;
SM1=1; //模式1
REN=1; //允许接收
ES=1; //开串行口中断
}
//发送串口值
void sent(uint TX)
{
if(flag==1)
{
ES=0; //关串行中断
flag=0;
SBUF=TX;
while(!TI); //确保TI置位
TI=0;
ES=1; //开串行中断
}
}
//串口接收
void receive() interrupt 4
{
flag=1;
RX=SBUF;
RI=0; //RI由硬件置位,软件复位
}
[此贴子已经被作者于2010-4-18 22:14:44编辑过]