📄 7738.c
字号:
//--------------------------------------------------------------------------------------------
//程序作用:用AD7738采集数据,由单片机将数据送往上位机
//2006.3 FDY 每个通道连续采样6次,求平均数
//作为本次采集的有效数据
//---------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//头文件以及全局变量定义
//---------------------------------------------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
#include <math.h>
sbit SCK=P1^1; // 将p1.1口模拟时钟输出
sbit MOSI=P1^2; // 将p1.2口模拟主机输出
sbit MISO=P1^3; // 将p1.3口模拟主机输入
sbit RDY=P3^2; // 数据准备好标志
unsigned long tdata,a,b,c;
float v,d;
float pdata kk;
float v0,v1,v2,v3,v4,v5,v6,v7;
float m1,m2,m3,m4,m5,m6;
float e[6],x;
#define delayNOP(); {_nop_();_nop_();_nop_();};
//---------------------------------------------------------------------------------------------
// 函数名称: delay
// 入口参数: N
// 函数功能: 延时16*N+24
//---------------------------------------------------------------------------------------------
void delay(int N)
{
int i;
for(i=0;i<N;i++);
}
//---------------------------------------------------------------------------------------------
// 函数名称: Write7738
// 入口参数: ch
// 函数功能: 向AD7738发送一个字节
//---------------------------------------------------------------------------------------------
void Write7738(unsigned char ch)
{
unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位
SCK = 1 ; //时钟置高
while(n--)
{
delayNOP();
//delay(3);
SCK = 0 ; //时钟置低
if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
{
MOSI = 1; // 传送位1
}
else
{
MOSI = 0; // 否则传送位0
}
delayNOP();
//delay(3);
ch = ch<<1; // 数据左移一位
SCK = 1 ; //时钟置高
}
}
//---------------------------------------------------------------------------------------------
// 函数名称: Reset7738
// 入口参数: 无
// 函数功能: 复位AD7738,使其恢复到向通信寄存器写状态
//---------------------------------------------------------------------------------------------
void Reset7738(void)
{
Write7738(0x00);
Write7738(0xFF);
Write7738(0xFF);
Write7738(0xFF);
Write7738(0xFF);
}
//---------------------------------------------------------------------------------------------
// 函数名称: Comp
// 入口参数:
// 函数功能: 按从小到大排列
//---------------------------------------------------------------------------------------------
void Comp(void)
{
int j,i;
e[0]=m1;e[1]=m2;e[2]=m3;e[3]=m4;e[4]=m5;e[5]=m6;
for(j=0;j<=4;j++)
{
for(i=0;i<=5-j;i++)
{
if(e[i]>e[i+1])
{x=e[i];e[i]=e[i+1];e[i+1]=x;}
}
}
}
//---------------------------------------------------------------------------------------------
// 函数名称: Init7738
// 入口参数: 通道数n
// 函数功能: 初始化AD7738各寄存器,设置AD转换相关参数
//---------------------------------------------------------------------------------------------
void Init7738(int n)
{
Reset7738( );
Write7738(0x30+n);
Write7738(0xFF); //设定通道n转换时间,实验中若将通转换时间设为零,则输出为满量程
Write7738(0x01);
Write7738(0x30); //设置RDY引脚在任何一个通道转换结束时变低
Write7738(0x28+n);
Write7738(0x05); //设置模拟输入基准为AINCOM,输入电压范围0--+2.5V,单转换模式
}
//---------------------------------------------------------------------------------------------
// 函数名称: Read7738
// 入口参数: 通道数z为整型,分别为0,1,2,3,4,5,6,7以表示读取相应通道的A/D转换结果
// 函数功能: 启动A/D转换,读取第z通道转换值并存入单片机
//---------------------------------------------------------------------------------------------
void Read7738(int z)
{
int i,j;
for(j=0;j<5;j++)
{
Write7738(0x38+z);
Write7738(0x43); //设置模式为单转换模式,数据为24位,启动第z通道A/D转换
while(RDY); //查询本通道转换是否结束,RDY=0时表明转换结束,数据可用
Write7738(0x48+z);
SCK=1;
MOSI=0;
for(i=0;i<8;i++)
{
delayNOP();
SCK=0;
delayNOP();
tdata=tdata<<1;
if(MISO==1)
tdata=tdata|0x01;
else
tdata=tdata&0xFE;
SCK=1;
}
a=tdata; //接受高8位数据并赋给a
for(i=0;i<8;i++)
{
delayNOP();
SCK=0;
delayNOP();
tdata=tdata<<1;
if(MISO==1)
tdata=tdata|0x01;
else
tdata=tdata&0xFE;
SCK=1;
}
b=tdata; //接受中8位数据并赋给b
for(i=0;i<8;i++)
{
delayNOP();
SCK=0;
delayNOP();
tdata=tdata<<1;
if(MISO==1)
tdata=tdata|0x01;
else
tdata=tdata&0xFE;
SCK=1;
}
c=tdata; //接受低8位数据并赋给c
d = ((a<<16)&0x00ff0000)+((b<<8)&0x0000ff00)+(c&0x000000FF);
v=d*2.50000000/0xFFFFFF; //注意此处0xFFFFFF若写成十进制数,则得到的最高电压值2.4999998不等于满量程2.5V
switch(j)
{
case 0:m1=v;break;
case 1:m2=v;break;
case 2:m3=v;break;
case 3:m4=v;break;
case 4:m5=v;break;
case 5:m6=v;break;
}
}
Comp();
v=(e[2]+e[3]+e[4])/3;
switch(z)
{
case 0:v0=v*409.6;break;
case 1:v1=v*409.6;break;
case 2:v2=v*409.6;break;
case 3:v3=v*409.6;break;
case 4:v4=v*409.6;break;
case 5:v5=v*409.6;break;
case 6:v6=v*409.6;break;
case 7:v7=v*409.6;break;
}
}
//---------------------------------------------------------------------------------------------
// 函数名称: SbufIN()
// 入口参数: 无
// 函数功能: 串口初始化子程序,假设单片机晶振为12M
//---------------------------------------------------------------------------------------------
void SbufIN(void)
{
TMOD=0x20; //设置波特率300,定时器1八位自动重装方式
TL1=0x98;
TH1=0x98; //装载TH1和TL1
SCON=0x50; //设置串行口工作方式1,10位异步通信方式
PCON=0x00; //波特率不加倍
TR1=1; //启动定时器1
}
//---------------------------------------------------------------------------------------------
// 函数名称: Send7738
// 入口参数: 通道数m
// 函数功能: 通过串行通信送通道m转换数据到上位机
//---------------------------------------------------------------------------------------------
void Send7738(int m)
{
switch(m)
{
case 0:SBUF='{';while(TI==0);TI=0;
SBUF='d';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v0/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v0-(int)(v0/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0; break;
case 1:SBUF='{';while(TI==0);TI=0;
SBUF='g';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v1/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v1-(int)(v1/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0;break;
case 2:SBUF='{';while(TI==0);TI=0;
SBUF='j';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v2/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v2-(int)(v2/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0; break;
case 3:SBUF='{';while(TI==0);TI=0;
SBUF='m';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v3/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v3-(int)(v3/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0;break;
case 4:SBUF='{';while(TI==0);TI=0;
SBUF='p';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v4/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v4-(int)(v4/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0; break;
case 5:SBUF='{';while(TI==0);TI=0;
SBUF='s';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v5/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v5-(int)(v5/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0;break;
case 6:SBUF='{';while(TI==0);TI=0;
SBUF='v';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v6/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v6-(int)(v6/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0; break;
case 7:SBUF='{';while(TI==0);TI=0;
SBUF='y';while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v7/100);while(TI==0);TI=0;
SBUF='|';while(TI==0);TI=0;
SBUF=(int)(v7-(int)(v7/100)*100);while(TI==0);TI=0;
SBUF='}';while(TI==0);TI=0;break;
}
}
//---------------------------------------------------------------------------------------------
// 主程序入口
//---------------------------------------------------------------------------------------------
void main(void)
{
int k;
SbufIN();
while(1)
{
for(k=0;k<8;k++)
{
Init7738(k); //初始化各通道
Read7738(k); //读取第k通道转换值
Send7738(k);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -