#i nclude <stdioh>
#i nclude <REGX51H>
#i nclude "iich"
#define uchar unsigned char
#define uint unsigned int
uint Timer_Pro_Flag=0;//0为显示处理,1为时序采集处理
sbit TEST_CAP_VOL_CRLT=P1^0;//用于控制外部继电器
sbit PWM_Pin=P3^7;//PWM输出
sbit IrDA_in_Pin=P1^0;//红外脉冲输入检测脚
bit PWMFlag=0;
uchar OLD_TH0,OLD_TL0;
#define MAXCMD_LENGTH 7
#define AD_VOL_PER 104058 //正常采集时的电压校准值
#define AD_Loop_PickVol_PER 104058 //CD4051循环采集时的电压校准值
sbit WDTRST=0xA6;//At89S5x看门狗寄存器
sbit ADCLK=P2^0;
sbit ADOUT=P2^1;
sbit ADCS=P2^2;
//--------------------------
/CD4051---8选1模拟开关芯片/
/
|------------------------------------------------------|
| 4 2 1 |
|-----------------------------------------------|------|
|端口 | INH C B A | | |
|------ 7 6 5 4 3 2 1 0 | 正值 | 取反 |
| 通道 |--------------------------------|-------|------|
|------||8 4 2 1 | | |
|------|---------------|----------------|-------|------|
| 0 |0 0 0 0 0 0 0 0 | 0x00 | 0xff |
| 1 |0 0 0 0 0 0 1 0 | 0x02 | 0xf7 |
| 2 |0 0 0 0 0 1 0 0 | 0x04 | 0xfb |
| 3 |0 0 0 0 0 1 1 0 | 0x06 | 0xf3 |
| 4 |0 0 0 0 1 0 0 0 | 0x08 | 0xfd |
| 5 |0 0 0 0 1 0 1 0 | 0x0A | 0xf8 |
| 6 |0 0 0 0 1 1 0 0 | 0x0C | 0xf9 |
| 7 |0 0 0 0 1 1 1 0 | 0x0e | 0xf1 |
|---------------------------------------|-------|------|
/
uchar CD4051_NUM[]={0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0e}; //0~7编码
sbit CD4051_A=P1^1;
sbit CD4051_B=P1^2;
sbit CD4051_C=P1^3;
sbit CD4051_INH=P1^4; //CD4051_INH为1时,,所有通导都不导通
bit CD4051_Vol_Conver_Flag=0; //0时为正常采集,1为CD4051循环采集
//--------------------------
//LED显示
//--------------------------
uchar LedCount=0;
uchar LED_BIT[5]; //用于显示的每一位数据码的内容
uchar LED_NUM[]={0x00,0x10,0x20,0x40,0x80};//选择显示位
//--------------------------------------------------------
void SendByte(unsigned char word)
{
TI=0;
SBUF=word;
while(TI==0);
TI=0;
}
uchar ComBuf[MAXCMD_LENGTH];//用于保存串口的数据
/---少量延时---/
void delay(uint t)
{
uint i=0;
for(;i<=t;i++);
}
void Pluckdelay(uint t)
{
uint i=0,j;
for(;i<=t;i++)
for(j=1;j<=1000;j++);
}
/=================================
ComBuf[5]加入CheckSUM校验码
算法:0x01+not(字节1+字节2++字节N)
=================================/
void SetCheckSUM()
{
ComBuf[5]=0x01+~(ComBuf[0]+ComBuf[1]+ComBuf[2]+ComBuf[3]+ComBuf[4]);
}
/=============================================================
检测上位机发送来的ComBuf[5]checksum校验码和计算后的是否相等
正确则返回:1
错误则返回:0
==============================================================/
bit ISCheckSUM()
{
uchar crc;
crc=0x01+~(ComBuf[0]+ComBuf[1]+ComBuf[2]+ComBuf[3]+ComBuf[4]);
if(ComBuf[5]==crc)
return 1;
else
{
ComBuf[1]=crc;//如果错误,则返回计算后得到的CHECKSUM校验码
ComBuf[2]=ComBuf[5];//返回原来上位机发送来的CHECKSUM校验码
return 0;
}
}
/-----------------------------------
等待接收上位机发来的指令
-------------------------------------/
void WaitComm()
{
uchar n=0;
RI=0;
while (1)
{
while(!RI);//等接收数据
//-----------------
ComBuf[n]=SBUF;
RI=0;
// SBUF=ComBuf[n];
if (ComBuf[n]==0x7e) break;//接收到结束符则退出
if (n>=MAXCMD_LENGTH)
n=0;//接收10个字节,如果还没有接收到0x7e结束符,就重新记录
else
n++;
}
}
/-------------------------------
发送combuf数据至上位机
--------------------------------/
void SendByteArray()
{
unsigned i;
SetCheckSUM();//加入ComBuf[5]的checkSUM校验码
ComBuf[4]=P0;//取读本模块地址
ComBuf[6]=0x7e;//结束符
for(i=0;i<=MAXCMD_LENGTH-1;i++)
{
SendByte(ComBuf[i]);
}
}
/-------------------------------
送端口状态至上位机
--------------------------------/
void GetP0()
{
switch(ComBuf[2])
{
case 0x00: ComBuf[3]=P0_0; break;
case 0x01: ComBuf[3]=P0_1; break;
case 0x02: ComBuf[3]=P0_2; break;
case 0x03: ComBuf[3]=P0_3; break;
case 0x04: ComBuf[3]=P0_4; break;
case 0x05: ComBuf[3]=P0_5; break;
case 0x06: ComBuf[3]=P0_6; break;
case 0x07: ComBuf[3]=P0_7; break;
default:
ComBuf[3]=P0;//为8时则以上传整个port状态
}
}
//--------------------
void GetP1()
{
switch(ComBuf[2])
{
case 0x00: ComBuf[3]=P1_0; break;
case 0x01: ComBuf[3]=P1_1; break;
case 0x02: ComBuf[3]=P1_2; break;
case 0x03: ComBuf[3]=P1_3; break;
case 0x04: ComBuf[3]=P1_4; break;
case 0x05: ComBuf[3]=P1_5; break;
case 0x06: ComBuf[3]=P1_6; break;
case 0x07: ComBuf[3]=P1_7; break;
default:
ComBuf[3]=P1;//为8时则以上传整个port状态
}
}
//---------------
void GetP2()
{
switch(ComBuf[2])
{
case 0x00: ComBuf[3]=P2_0; break;
case 0x01: ComBuf[3]=P2_1; break;
case 0x02: ComBuf[3]=P2_2; break;
case 0x03: ComBuf[3]=P2_3; break;
case 0x04: ComBuf[3]=P2_4; break;
case 0x05: ComBuf[3]=P2_5; break;
case 0x06: ComBuf[3]=P2_6; break;
case 0x07: ComBuf[3]=P2_7; break;
default:
ComBuf[3]=P2;//为8时则以上传整个port状态
}
}
//--------------
void GetP3()
{
switch(ComBuf[2])
{
case 0x00: ComBuf[3]=P3_0; break;
case 0x01: ComBuf[3]=P3_1; break;
case 0x02: ComBuf[3]=P3_2; break;
case 0x03: ComBuf[3]=P3_3; break;
case 0x04: ComBuf[3]=P3_4; break;
case 0x05: ComBuf[3]=P3_5; break;
case 0x06: ComBuf[3]=P3_6; break;
case 0x07: ComBuf[3]=P3_7; break;
default:
ComBuf[3]=P3;//为8时则以上传整个port状态
}
}
//-------发送AT89S5x的指定端口状态到上位机-----
void SendPortData()
{
switch (ComBuf[1])/Port号/
{
case 0x00: GetP0(); break;
case 0x01: GetP1(); break;
case 0x02: GetP2(); break;
case 0x03: GetP3(); break;
}
/--------------------/
SendByteArray();//发送数据
}
/-------------------------------
各个端口的状态设定
--------------------------------/
void SetP0()
{
switch(ComBuf[2])
{
case 0x00: P0_0=ComBuf[3]; break;
case 0x01: P0_1=ComBuf[3]; break;
case 0x02: P0_2=ComBuf[3]; break;
case 0x03: P0_3=ComBuf[3]; break;
case 0x04: P0_4=ComBuf[3]; break;
case 0x05: P0_5=ComBuf[3]; break;
case 0x06: P0_6=ComBuf[3]; break;
case 0x07: P0_7=ComBuf[3]; break;
default:
P0=ComBuf[3];//为8时则设置整个port状态
}
}
//=================================
void SetP1()
{
switch(ComBuf[2])
{
case 0x00: P1_0=ComBuf[3]; break;
case 0x01: P1_1=ComBuf[3]; break;
case 0x02: P1_2=ComBuf[3]; break;
case 0x03: P1_3=ComBuf[3]; break;
case 0x04: P1_4=ComBuf[3]; break;
case 0x05: P1_5=ComBuf[3]; break;
case 0x06: P1_6=ComBuf[3]; break;
case 0x07: P1_7=ComBuf[3]; break;
default:
P1=ComBuf[3];//为8时则设置整个port状态
}
}
//=================================
void SetP2()
{
switch(ComBuf[2])
{
case 0x00: P2_0=ComBuf[3]; break;
case 0x01: P2_1=ComBuf[3]; break;
case 0x02: P2_2=ComBuf[3]; break;
case 0x03: P2_3=ComBuf[3]; break;
case 0x04: P2_4=ComBuf[3]; break;
case 0x05: P2_5=ComBuf[3]; break;
case 0x06: P2_6=ComBuf[3]; break;
case 0x07: P2_7=ComBuf[3]; break;
default:
P2=ComBuf[3];//为8时则设置整个port状态
}
}
//=================================
void SetP3()
{
switch(ComBuf[2])
{
case 0x00: P3_0=ComBuf[3]; break;
case 0x01: P3_1=ComBuf[3]; break;
case 0x02: P3_2=ComBuf[3]; break;
case 0x03: P3_3=ComBuf[3]; break;
case 0x04: P3_4=ComBuf[3]; break;
case 0x05: P3_5=ComBuf[3]; break;
case 0x06: P3_6=ComBuf[3]; break;
case 0x07: P3_7=ComBuf[3]; break;
default:
P3=ComBuf[3];//为8时则设置整个port状态
}
}
/=================================
WritePortData()
按上位机传来的格式进行端口的设置
=================================/
void WritePortData()
{
switch (ComBuf[1])/Port号/
{
case 0x00: SetP0(); break;
case 0x01: SetP1(); break;
case 0x02: SetP2(); break;
case 0x03: SetP3(); break;
}
}
/----------------------------------
SetEA()
中断允许设定,(EA寄存器)
ComBuf[1]==>0x00为EA设定
0x01为读取EA值
------------------------------------/
void SetEA()
{
if (ComBuf[1]==0x00)
EA=ComBuf[3];
else
{
ComBuf[3]=EA;
SendByteArray();//发送数据
}
}
/--------------------------------------------------------------- float型转为2位char型,并发送至串行 void Convert_AD_VOL_ValueToChar() ---------------------------------------------------------------/ void Convert_AD_VOL_ValueToChar(uint vol) { float temp_float_vol; unsigned int temp; uchar AD_Hight,AD_Low; temp_float_vol=vol00048AD_VOL_PER; temp=temp_float_vol100; AD_Hight=temp /100;//取个位数 AD_Low=temp-AD_Hight100;//取2位小数 ComBuf[2]=AD_Hight; ComBuf[3]=AD_Low; SendByteArray();//发送数据 } /-------------------------------- 预先采集一次AD数据 --------------------------------/ void Befor_Once_AD() { uchar i; ADCLK=ADOUT=0; //---------- ADCS=0; //开启控制电路,使能DATA OUT和I/O CLOCK for(i=1;i<=10;i++) { ADCLK=1; ADCLK=0; } ADCS=1; delay(25);//两次转换间隔大于21us } /--------------------------------------------------------------- GetAD() TLC1549数据采集 sbit ADCLK=P2^0; sbit ADOUT=P2^1; sbit ADCS=P2^2; -----------------------------------------------------------------/ void GetAD() { uchar i=1,w,PickCount; uint vol; Befor_Once_AD();//预先采集一次AD数据 //--------------- if (ComBuf[1]==0)ComBuf[1]=0x01; PickCount=ComBuf[1]; for(w=1;w<=PickCount;w++) { ADCLK=ADOUT=0; vol=0; ADCS=0; //开启控制电路,使能DATA OUT和I/O CLOCK for(i=1;i<=10;i++) { //给一个脉冲 ADCLK=1; vol<<=1; if(ADOUT)vol|=0x01; ADCLK=0; } ADCS=1; delay(21);//两次转换间隔大于21us //--------------- ComBuf[1]=w;//发送第几次采集的序号 Convert_AD_VOL_ValueToChar(vol);//对float转为2位char型,并发送至串行口 P2=0xff;//p2口置初始状态 } } /--------------------------------------------------------------- TLC1549数据软件滤波采集 -----------------------------------------------------------------/ void GetAD_With_VOL_Filter() { uchar i,w,j,k,PickCount,AD_Hight=0,AD_Low=0; uint Vol=0,VolArray[10],temp; float SumVol=0; Befor_Once_AD();//预先采集一次AD数据 //--------------- //--------------- PickCount=11; for(w=0;w<=PickCount;w++) { ADCLK=ADOUT=0; Vol=0; ADCS=0; //开启控制电路,使能DATA OUT和I/O CLOCK for(i=1;i<=10;i++) { //给一个脉冲 ADCLK=1; Vol<<=1; if(ADOUT)Vol|=0x01; ADCLK=0; } ADCS=1; delay(21);//两次转换间隔大于21us VolArray[w]=Vol;//保存采集来的数据 //--------------- P2=0xff;//p2口置初始状态 } //-------按从小到大排序-------- //选择排序法 for(i=0;i<=PickCount-1;i++) { k=i; for(j=PickCount+1;j<i;j++) { if(VolArray[j]>VolArray[k])k=j; if(k!=i) { temp=VolArray[k]; VolArray[k]=VolArray[i]; VolArray[i]=temp; } } } //----------累加计算平静均值------------ //乎略最小和最大值 for(i=1;i<=PickCount-1;i++) { SumVol=SumVol+VolArray[i];//累加结果 } SumVol=SumVol/(PickCount-1)00048;//电压值=平均值介数 /------------------------------ 0时为正常采集,1为CD4051循环采集 因为CD4051通道存在电压消耗, 所以和正常的直接采集的校准值不一样 -------------------------------/ /电压校准比/ if(CD4051_Vol_Conver_Flag) SumVol=AD_Loop_PickVol_PER;//采用CD4051时的电压校准值 else SumVol=AD_VOL_PER;//直接输入时的电压校准值 //---------------- temp=SumVol100;//保留2位小位 AD_Hight=temp /100;//取个位数 AD_Low=temp-AD_Hight100;//取2位小数 //ComBuf[1]=w;//发送第几次采集的序号 ComBuf[2]=AD_Hight; ComBuf[3]=AD_Low; SendByteArray();//发送数据 } /------------------------------------------------------------------------- CD4051_PickVol8路选通TLC1549采集 -------------------------------------------------------------------------/ void CD4051_PickVol() { CD4051_Vol_Conver_Flag=1; P1=CD4051_NUM[ComBuf[1]];//CD4051通道选通 // delay(2300);//通道切换时间间隔,避免电路的残余电 GetAD_With_VOL_Filter(); CD4051_Vol_Conver_Flag=0; } /------------------------------------------------------------------------- CD4051_LoopPickVol()8路巡检TLC1549采集 -------------------------------------------------------------------------/ void CD4051_LoopPickVol() { uchar i=0,w; w=ComBuf[1]-1;//通导号等于。。。通道数-1 for(;i<=w;i++) { ComBuf[1]=i;//通道号 CD4051_PickVol(); } P1=0xff;//关闭通道 } /------------------------------------------------------------------------- 电容放电计数测试 TestCapCount() -------------------------------------------------------------------------/ void TestCapCount() { uint Vol,TempVol=0xff,Count=0,temp1,temp2; uchar i,CAPDELAYTIME; float TEST_CAP_OUT_value="/005;" P1=CD4051_NUM[1];//CD4051通道选通,1号通道 TEST_CAP_VOL_CRLT=0;//打开电源 if (ComBuf[1]==0x00)//为0x00时为电容测量方式,0x01为电压测量方式 { for(i=0;i<=ComBuf[2];i++)delay(60000);//等待电容充电 TEST_CAP_VOL_CRLT=1;//断开电源 TEST_CAP_OUT_value="/001;//当为电容测量时。。下限电压" } CAPDELAYTIME=ComBuf[3];//延时常量 //-------------- P1_1=0;//打开LED状态指示 while(TempVol00048AD_VOL_PER>=TEST_CAP_OUT_VALUE)//当放电到0V时退出 { ADCLK=ADOUT=0; Vol=0; ADCS=0; //开启控制电路,使能DATA OUT和I/O CLOCK for(i=1;i<=10;i++) { //给一个脉冲 ADCLK=1; Vol<<=1; if(ADOUT)Vol|=0x01; ADCLK=0; } ADCS=1; delay(21);//两次转换间隔大于21us //--------------- P2=0xff;//p2口置初始状态 Count++;//计数 ComBuf[0]=0x05;//利用软件滤波的处理过程显示 if(Count>2)TempVol=Vol;//第一次的取值有可能是1,,去掉不要 Convert_AD_VOL_ValueToChar(Vol);//转换并发送本次数据 Pluckdelay(CAPDELAYTIME);//采集间隔时间,为ComBuf[4]1000的时间常数 } //从高到低取 P1=0xff;//初始P1口 ComBuf[0]=0x0b; temp1=Count/1000;//取前1-2位 ComBuf[1]=temp1; temp2=Count/10-temp1100;//得到3-4位 ComBuf[2]=temp2; ComBuf[3]=Count-(temp11000+temp210); SendByteArray();//发送数据 } //--------------------------------------------------------------------------// //写一个字节到AT24C04EEPROM void WriteAT24C04() { uchar address,RomData; address=ComBuf[1]; RomData=ComBuf[2]; WriteByte_24c04(RomData,address); } //读取AT24C04EEPROM一个字节 void ReadAT24C04() { ComBuf[2]=ReadByte_24c04(ComBuf[1]); SendByteArray();//发送数据 } //================================= // 看门狗设置 //================================= //void watchdog() //{ //WDTRST=0x1E; //WDTRST=0xE1;//喂狗指令 //} void SetLedData() { uchar ShowData,ShowBit; Timer_Pro_Flag=0;//0为显示处理,1为时序采集处理 ShowBit=ComBuf[1]; ShowData=LED_NUM[ShowBit];//选择位 ShowData|=ComBuf[2];//显示内容 LED_BIT[ShowBit]=0x00; LED_BIT[ShowBit]=ShowData; TH0=(65536-4000)>>8; TL0=(65536-4000)&0xff; TR0=ComBuf[3]; if(ComBuf[3]) P0=0x00;//关闭显示 } /========================================= PluckPulse----时序采集 ===========================================/ void PluckPulse() { Timer_Pro_Flag=1;//0为显示处理,1为时序采集处理 OLD_TH0=ComBuf[2]; OLD_TL0=ComBuf[3]; TH0=OLD_TH0; TL0=OLD_TL0; TR0=ComBuf[1];//关闭或启动计时器 } //------------ /========================================= PWM----时序采集 ===========================================/ void PWM() { Timer_Pro_Flag=2;//0为显示处理,1为时序采集处理 OLD_TH0=ComBuf[2]; OLD_TL0=ComBuf[3]; TH0=OLD_TH0; TL0=OLD_TL0; TR0=ComBuf[1];//关闭或启动计时器 } //------------ void timer0(void) interrupt 1 using 1 { //------------------- switch(Timer_Pro_Flag) { case 0: //LED显示处理 TH0=(0xffff-4000)>>8; TL0=(0xffff-4000)&0xff; if (LedCount>4) LedCount=0; P0=0x00; P0=LED_BIT[LedCount++]; break; case 1: // 时序采集 TH0=OLD_TH0; TL0=OLD_TL0; SendByte(IrDA_in_Pin);//发送P1^0引脚状态 break; case 2://模拟PWM输出 if(!PWMFlag) { TH0=OLD_TH0; TL0=OLD_TL0; TR0=1; PWMFlag=1; PWM_Pin=0; } else { PWM_Pin=1; TR0=0; TH0=OLD_TH0; TL0=OLD_TL0; TR0=1; PWMFlag=0; } break; } } /=================================================================== 主程序开始处 ===================================================================/ void main() { //晶振:110592,波特率:19200 TMOD=0x21; TL1=0xfd; TH1=0xfd; SCON=0xd8; PCON=0x80;//高位为0时不倍频:9600pbf,1时倍频:19200bpf TR1=1; //------------------ // TMOD=0x01;//工作在定时器方式1,16位计数器 TH0=(65536-4000)/256; TL0=(65536-4000)%256; ET0=1; EA=1;//中断允许 //------------- while(1) { WaitComm();//等待接收数据 //校对checksum校验码是否正确,如正确则进行相关的 *** 作 if(ISCheckSUM()) { switch (ComBuf[0]) { case 0x01:WritePortData(); break; //响应上位机发送的写 *** 作 case 0x02:SendPortData(); break; //响应上位机发送的读 *** 作 case 0x03:SetEA();break; //中断允许设定 case 0x04:GetAD();break; //TLC1549数据采集 case 0x05:GetAD_With_VOL_Filter();break;//采软件滤软件的TLC1549数据采集 case 0x06:CD4051_PickVol();break; //CD4051--8选1TLC1549采集 case 0x07:CD4051_LoopPickVol();break; //8路巡检TLC1549采集 case 0x08:ReadAT24C04();break; //读取AT24C04EEPROM一个字节 case 0x09:WriteAT24C04();break; //写一个字节到AT24C04EEPROM case 0:SetLedData();break; //设定显示的数据 case 0x0b:TestCapCount();break; //电容放电时间计数测试 case 0x0c:PluckPulse();break; //时序采集 case 0x0d:PWM();break; //控制P2_7模拟输出PWM } } else//如检验错误则返回上位机错误信息 { ComBuf[0]=0xFF; SendByteArray();//返回错误信息 } } }
二、工作原理
实现11位A/D转换由PIC16C711做2次8位A/D转换完成。PIC16C711有4个模拟量输入通道RA0~RA3,这些模拟量输入通道复用1个采样保持器进入到A/D转换器。参考电压Vref可以来自外部也可以来自内部VDD,A/D转换器属于逐次逼近式,转换结果(8位)存入ADRES寄存器。在A/D转换前必然选择适当的通道,设置足够的采样时间。用户可以通过设置A/D控制寄存器ADCON0和ADCON1来控制其转换过程,同时A/D转换的状态也会在ADCON0中体现出来。
先将待转换的电压Vi送到PIC16C711的RA0通道做一次A/D转换。根据转换所得的数字量由软件算出Vi在8档中位置,用Vi减去Vi所在档的起始电压。将所得差值放大8位,使之变为0~5V电压信号,再送给PIC16C711的RA1通道做1次A/D转换,所得数字量是11位AD转换的低8位,而档位CBA就是高3位,从而实现11位A/D转换。
举例说明如下:假设输入电压Vi为3V,程序控制PIC16C711的RA0通道先进行第1次A/D转换,所得结果是153,即3/5×255=153,对应8位数字量为10011001。将低5位屏蔽,得10000000,循环右移5次,得00000100,此时低3位对应的就是Vi=3V电压时的档位,即第4档,CBA=100,程序将该档位由RB2,RB1,RB0输出,作为8选一模拟开关的通道选择,使CD4051输出25V,即5/8×4=25V。该电压经IC2运放跟随,再经IC3进行差分放大。设计时调整R11,R12,R13和R14的阻值,使放大倍数为8位,则得放大器IC3输出Vo=8(Vi-25)=8(3-25)=40V。选择RA1通道进行第2次A/D转换,结果为11001100,这就是11位A/D转换结果的低8位。档位100为11位A/D转换的高3位,合起来就是11位A/D转换的结果10011001100。
三、程序
以下是使用PIC16C711指令系统完成11位A/D转换的程序段。
BSF STATUS,RP0;选页面1
MOVLW 00000010B ;RA0、RA1为模拟通道
MOVWF ADCON1 ;内部参考电压
BCF STATUS,RP0 ;选页面0
MOVLW 11000001B ;选RA0通道和内部时钟
MOVWF ADCON0
MOVLW 125 ;延时125μs,等待输入
CALL WAIT ;稳定
BSF ADCON0,GO ;启动A/D
LOOP BTFSC ADCON0,GO ;判断A/D完成否
GOTO LOOP
MOVF ADRES,W ;取转换结果
ANDLW 0E0 ;屏蔽低5位
MOVWF D1 ;存入D1
BCF STATUS,C
RRF D1,1 ;右移5次
RRF D1,1
RRF D1,1
RRF D1,1
RRF D1,1
MOVF D1,W
MOVWF PORTB ;档位输出
MOVLW 11001001B ;选RA1通道
MOVWF ADCON0
MOVLW 60 ;延时60μs
CALL WAIT
BSF ADCON0,GO ;启动A/D
LOOP1 BTFSC ADCON0,GO ;判断A/D完成否
GOTO LOOP1
MOVF ADRES,W ;A/D转换结果存D0
MOVWF D0
WAIT MOVWF TEMP ;延时子程序
NEXT DECFSZ TEMP,1
GOTO NEXT
RETURN
用这种方法实现的11位A/D转换速度快PIC16C711基本上都是单周期指令,在4MHz振荡频率下指令周期1μs,进行1次A/D转换最短时间20μs;2次A/D转换40μs;2个运放变换时间20μs×2=40μs。总的转换时间为百μs级。
光电检测系统的基本组成,和各部分的主要作用
其基本组成部分可分为:光源、被检测对象及光信号的形成、光信号的匹配处理、光电转换、电信号的放大与处理、微机、控制系统和显示等部分。
光源 光源发出的光束作为携带待测信息的物质 被检测对象及光信号的形成 利用各种光学效应,如反射,吸收,干涉,衍射,偏振等,使光束携带上被测对象的特征信息,形成待检测的光信号 光信号的匹配处理 更好的获得待测量的信息。以满足光电转换的需要 光电转换 将光信号转化成电信号 电信号的放大与处理 采用不同功能的电路,来实现各种检测目的 微机、控制系统和显示 将处理好的待测量电信号直接经显示系统显示
2 直接测量,间接测量,真值,指定值,实用值
直接测量 用待测量直接与另一个同类已知量相比较 间接测量 用待测量间接与另一个同类已知量相比较 真值 某物理量的理论值或定义值 指定值 由国家设立的各种尽可能维持不变的实物基准或标准原器所规定的值。 实用值 采用计量标准传递的方法将指定值、基准量逐级传递到各级计量站,以及具体的检测仪器中。各级计量站或检测仪器在进行比较测量时,把上一级标准器的量值当作近似的真值,把它们都叫做实用值、参考值或传递值。 3 用标准重物检验磅称,用磅称称出物体的重量,用照度计测量夜天光的强度,用卡尺测定工件的尺寸,以上检测哪些是实用值
标准重物检验磅称 非 用磅称称出物体的重量 非 用照度计测量夜天光的强度 是 用卡尺测定工件的尺寸 非
4 什么是系统误差,随机误差,它们产生的原因是什么
系统误差 在检测过程中产生恒定不变的误差叫恒差或按一定规律变化的误差叫变差 系统误差产生的原因有工具误差、装置误差、方法误差、外界误差和人身误差等。
如果阻值很大,可以用电子开关CD4051来切换电阻。
如果要阻值很小,那可以用MOS场效应管。单片机输出PWM信号经滤波后转换成变化的直流电压加在MOS栅极上,DS之间的电阻就会随着变化,不过可能会不太稳定。
以上就是关于急急急啊啊啊啊全部的内容,包括:急急急啊啊啊啊、PIC16C711单片机的程序存储器为什么是14位的、光电检测系统的组成及其作用等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)