📄 single.#2
字号:
//////////单端输入,定时启动,由T2定时,选择AIN0.3为ADC0转化通道////////////////
//////single.c///////////////////////////////////
#include "lcd.h"//笔者所写的LCD显示头文件,具体见LCD章节
/*
若读者没有条件使用"lcd.h"的各显示和键盘函数,则可在lcd.h文件中如下定义:
#include "c8051f040.h"
void dispini();
void showf();
//则该调试文件能编译通过,用户也可调试,只是要通过设断点来观察数据
*/
#define ADC0START temppage=SFRPAGE;SFRPAGE=0x00;AD0BUSY=1;SFRPAGE=temppage
#define REAL_RATE 488L
#define ADJRATEDIF 237L
#define ADJRATESE 118L
/*
REAL_RATE为物理量转化系数,由具体对象而定
ADJRATEDIF为差动模式下,增益为0.5时ADC0转化值与真实电压的转换系数
ADJRATESE为单端输入模式下,增益为0.5时ADC0转化值与真实电压的转换系数
*/
sfr16 RCAP2=0xca;
sfr16 RCAP3=0xca;
sfr16 RCAP4=0xca;
sfr16 TMR4=0xcc;
sfr16 TMR3=0xcc;
sfr16 TMR2=0xcc;
sfr16 PCA0CP0=0xfb;
sfr16 PCA0CP1=0xfd;
sfr16 PCA0CP2=0xe9;
sfr16 PCA0CP3=0xeb;
sfr16 PCA0CP4=0xed;
sfr16 PCA0CP5=0xe1;
sfr16 ADC0VAL=0xbe;//将ADC0H-ADC0L通过sfr16实现
sfr16 ADC0GT=0xc4;
sfr16 ADC0LT=0xc6;
sfr16 DPTR=0x82;
uchar temppage;
bit isnewdata;
int kk;
long target_val;//工程量转化值
long realvol;//真实测量电压值
float temp;
void adc0_mux(uchar type,uchar source);
void adc0_source(uchar source);
void p3anolog_ini(uchar port);
void HVDA_ini(uchar gaind);
void adc0_ini();
void config();
void t2_ini();
void t2_baud(uint t2reload);
void t2_ini(){
SFRPAGE = 0x00;
TMR2CF = 0x08; // T2时钟为系统时钟,计数方向为增值计数
TMR2CN = 0x04; // T2为16bit定时器模式,并启动定时器运行
}
void t2_baud(uint t2reload){//每隔t2reload个T2时钟,产生一次定时溢出
SFRPAGE = 0x00;
RCAP2=~t2reload+1;//相当于65536-t2reload
TMR2=RCAP2;
}
void adc0_mux(uchar type,uchar source){//type 配置测量方式为差动还是单端输入
//source 为ADC0通道选择(共有9个通道)
SFRPAGE=0x00;
AMX0CF=type;
AMX0SL=source;
}
void adc0_source(uchar source){//ADC0通道选择,为adc0_mux()的简化函数
SFRPAGE=0x00;
AMX0SL=source;
}
void p3anolog_ini(uchar port){//配置p3口模拟输入管脚
SFRPAGE=0x00;
AMX0PRT=port;
SFRPAGE=0x0f;
P3MDIN&=~port;//将相应管脚配置成模拟输入口
}
void HVDA_ini(uchar gaind){
/*高压差动放大器配置,调的只是第二级的增益,整体增益还需再乘以0.05;*/
//HVDA禁止时,HCAP+上检测到的是HVAIN+的电压
SFRPAGE=0x00;
HVA0CN=gaind;
}
void adc0_ini(){
SFRPAGE=0x00;
ADC0CF=0x0f;//ADC0时钟为系统时钟2分频,PGA增益为0.5
ADC0CN=0x8c;//AD0TM=0,ADC0为连续跟踪模式,由T2溢出率启动ADC0
//AD0LJST=0,数据存储格式右对齐,即ADC0H存放12bit高四位
REF0CN&=0x0f;//AD0VRS=0,ADC0参考电压为VREFA
REF0CN|=0x07;//TEMPE=1,内部温度传感器工作
//BIASE=1,偏移产生器工作
/*REFBE=1,内部参考电平工作,电路部分须将VREF参考输出(C8051F40的第12管脚)与 VREF0(C8051F040的16管脚相连,并最好并联一个4.7uF和0.1uF的旁路电容以电平滤波*/
adc0_mux(0x08,3);//PORT3IC=1,ADC0 6、7通道为差动模式
//HVDA2C=0,4、5通道为单端模式
//AIN0.0-AIN0.3均为单端模式
//选择AIN0.3为ADC0转化通道
EIE2 |= 0x02; //开ADC0中断
t2_ini();
t2_baud(2000);//每隔2000个T2时钟产生一次ADC0采样
SFRPAGE=0x00;
TR2=1;
}
void config (void) {
//看门狗禁止
WDTCN = 0x07;
WDTCN = 0xDE;
WDTCN = 0xAD;
SFRPAGE = 0x0F;
XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x40; //交叉开关使能,使得P0-P3口能输出
XBR3 = 0x00;
SFRPAGE = 0x0F;
P0MDOUT = 0x00; //端口配置,P0-P3,P6-P7口为开漏输出
P1MDOUT = 0x00;
P2MDOUT = 0x00;
P3MDOUT = 0x00;
P4MDOUT = 0x00; //P4口为开漏,也可推挽
P5MDOUT = 0x07;
P6MDOUT = 0x00;
P7MDOUT = 0x00;
P1MDIN = 0xFF; //所有端口为数字输入,没有模拟输入端口
P2MDIN = 0xFF;
P3MDIN = 0xFF;
SFRPAGE = 0x0F;
CLKSEL = 0x00;
OSCXCN = 0x00;
OSCICN = 0x84;
//采用内部晶振,为24.5MHZ8分频
}
void main()
{
uint current;
uint voltage;
uint force; //寻址变量
uint cooldata;
uint highdata;
uint lowdata;
uchar i;
uchar j;
uchar n;//设置焊接段数
uint PerCur;
uint PerVol;
uint PerFor;
xdata uint PerCur[192];
xdata uint PerVol[192];
xdata uint PerFor[192];
void shujucaiji()
{
bit T2END;
bit CUREND;
bit VOLEND;
bit WELDSTART;
bit NOWELDSTART;
uint CurJudge;
WELDSTART=0;
NOWELDSTART=1;
while(1)
{
if(NOWELDSTART)
{
T2END=1;
if(AD0INT&&T2END)
{
AD0INT=0;
T2END=0;
T2START;
PerCur[i]=ADC0VAL;
adc0_source(1);//输入通道选择
ADC0START;
CurJudge+=PerCur[i];
CUREND=1;
for(j=0;j++;j<=16);//延时
}
if(AD0INT&&CUREND)
{
AD0INT=0;
CUREND=0;
PerVol[i]=ADC0VAL;
adc0_source(2);//输入通道选择
ADC0START;
VOLEND=1;
for(j=0;j++;j<=16);//延时等待
}
if(AD0INT&&VOLEND)
{
AD0INT=0;
VOLEND=0;
PreFor[i]=ADC0VAL;
i++;
}
if(i%16==0)
{
if(CurJudge<= 30000 ||CurJudge>=35000 )
{WELDSTART=1;
}
if(i%192==0)
{i=0;}
}
}
if(WELDSTART)
{
current=0;voltage=0;force=8000;
if(AD0INT&&T2END)
{
AD0INT=0;
T2END=0;
T2START;
XWORD[current]=ADC0VAL;
adc0_source(1);//输入通道选择
ADC0START;
current+=2;
CurJudge+=XWORD[current];
CUREND=1;
}
if(AD0INT&&CUREND)
{
AD0INT=0;
CUREND=0;
//片选
XWORD[voltage]=ADC0VAL;
adc0_source(2);//输入通道选择
ADC0START;
voltage+=2;
VOLEND==1;
for()
}
if(AD0INT&&VOLEND)
{
AD0INT=0;
VOLEND=0;
//片选
XWORD[force]=ADC0VAL;
force+=2;
}
if(voltage%16==0)
{
if(CurJudge>=60000 )
{highdata++;
cooldata=0;
}
else if(CurJudge<=10000 )
{lowdata++;
cooldata=0;
}
else cooldata++;
}
if(cooldata>=12)
goto shujuchuli();
}
}
void ADC0_ISR() interrupt 15{
SFRPAGE=0x00;
AD0INT=0;
kk=ADC0VAL;
realvol=(long)kk*ADJRATESE;
/*
ADC0转化值乘以单端电平系数,其结果为电平真实值乘以100000
例如ADC0VAL=1024时,realvol=1024*118=120832,即表示真实电压为1.20832v
*/
target_val=(long)kk*REAL_RATE;
/*
ADC0转化值乘以物理量转化系数,来表示物理量值
例如某速度传感器输出为0-2.43V,其量程为0-1m/s,
则target_val为物理量值乘以1000000
例如ADC0VAL=1024时,target_val=1024*488=499712,即表示真实物理量为0.499712m/s
这里存在计算误差是因为没有采用浮点运算,对于精度要求低于0.2%,则采用上述长整型计算即可满足要求
若系统要求更高精度,则可考虑浮点运算。
*/
isnewdata=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -