//////////T法测频调试程序改进版2/////////////
/////////t3 频率方波输出//////////////
/////////t4 脉冲计数/////////////////////
/////////t2 计时////////////////////////////
/////////t2t3t4_pro2.c//////////////////////////
#include <C8051F040.h>
#define T3RUN temppage=SFRPAGE;SFRPAGE=0x01;TR3=1;SFRPAGE=temppage
#define T4RUN temppage=SFRPAGE;SFRPAGE=0x02;TR4=1;SFRPAGE=temppage
#define T4STOP temppage=SFRPAGE;SFRPAGE=0x02;TR4=0;SFRPAGE=temppage
#define T3STOP temppage=SFRPAGE;SFRPAGE=0x01;TR3=0;SFRPAGE=temppage
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long ulong;
sfr16 RCAP2=0xca;
sfr16 RCAP3=0xca;
sfr16 RCAP4=0xca;
sfr16 TMR4=0xcc;
sfr16 TMR3=0xcc;
sfr16 TMR2=0xcc;
uchar temppage;
uchar tf2num;
bit isnewdata;
ulong freTime;
bit isfilter;
void t4ISR();
void t2ISR();
void delay1ms(uint time){//延迟1ms
uint i;
uint j;
for (i=0;i<time;i++){
for(j=0;j<300;j++);
}
}
void t3_fre_set(uint val){//T3频率设置,计算公式为:(T3时钟频率/(2*val))
temppage=SFRPAGE;
SFRPAGE=0x01;
RCAP3=~val+1;
TMR3=RCAP3;
SFRPAGE=temppage;
}
void t3_ini(){//t3为频率输出模式
temppage=SFRPAGE;
SFRPAGE=0x01;
TMR3CN=0x00;//TR3=0,T3尚未启动
TMR3CF=0x0e;//T3采用系统时钟,TOG3=1,T3不计数时输出为1,DCEN=0
SFRPAGE=temppage;
}
void t4_ini(){//T4为计数模式
temppage=SFRPAGE;
SFRPAGE=0x02;
TMR4CF=0X08;//计数模式下,对T4M1-T4M0设置无效,DCEN=0,向下计数禁止
TMR4CN=0X02;//CT4=1,T4为计数器模式
SFRPAGE=0X00;
EIE2|=0X04;//T4中断使能
EIP2|=0x04;//T4中断优贤级置高
SFRPAGE=temppage;
}
void t2_ini(){//t2为定时器模式
temppage=SFRPAGE;
SFRPAGE=0x00;
TMR2CN=0X00;//定时器模式,自动重载
TMR2CF=0x08;//DCEN=0,向下计数禁止,采用系统时钟
RCAP2=0x0000;
TMR2=0x0000;
SFRPAGE=0X00;
IE|=0X20;//T2中断使能
SFRPAGE=temppage;
}
void t2_start(){
temppage=SFRPAGE;
SFRPAGE=0x00;
TMR2=0x0000;
TF2=0;
TR2=1;
SFRPAGE=temppage;
}
void t4_set(uint val){//val为计数脉冲数
temppage=SFRPAGE;
SFRPAGE=0x02;
RCAP4=~val+1;
TMR4=RCAP4;
SFRPAGE=temppage;
}
void startCount(uint val){//开始计时
t4_set(1);
SFRPAGE=0x00;
TMR2=0;//原本要加处理延迟补偿,但由于中断延迟还需要补偿,故此不作补偿
TF2=0;
SFRPAGE=0x02;
EA=0;//关闭中断
TR4=1;
while(!TF4);//约为3-4个指令周期
TF4=0;//2个指令周期
SFRPAGE=0x00;//2个指令周期
TR2=1;//2个指令周期
t4_set(val);
T4RUN;
EA=1;
tf2num=0;
isnewdata=0;
}
void config(){
//看门狗禁止
WDTCN = 0x07;
WDTCN = 0xDE;
WDTCN = 0xAD;
SFRPAGE = 0x0F;
//交叉开关配置,T3=P0.0,T4=P0.1,测试时将T3与T4相连
XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x48;
XBR3 = 0x01;
//管脚输出配置,P0口为开漏输出,其中P0.0接上拉电阻,P0为数字输入口
SFRPAGE = 0x0F;
P0MDOUT = 0x00;
P1MDIN = 0xFF;
//晶振配置,采用内部晶振8分频
SFRPAGE = 0x0F;
CLKSEL = 0x00;
OSCXCN = 0x00;
OSCICN = 0x84;
}
void main(void){
xdata float t3frequency[10];
uint frenum=10;
ulong fre_factor;
uchar k=0;
config();
t2_ini();
t3_ini();
t4_ini();
EA=1;
fre_factor=255208L*12*(ulong)frenum;
t3_fre_set(10000);
T3RUN;
startCount(frenum);
isnewdata=0;
while(1){
if(isnewdata){
if(k>=10)
k=0;//在此设断点观察数据
t3frequency[k++]=(float)fre_factor/freTime;
delay1ms(100);
startCount(frenum);
}
}
}
void t4ISR() interrupt 16 {//frenum个频率计满,产生T4中断
SFRPAGE=0X00;
TR2=0;//将T2停止,并计算frenum个脉冲所需要的时间,从而可以计算频率
freTime=TMR2;
SFRPAGE=0X02;
TR4=0;
TF4=0;
isnewdata=1;
freTime+=65536L*tf2num-34;//需要加上T2的溢出时间,并减去中断延迟的补偿时间
//注意若频率不是很高,frenum不宜过大,否则会使freTime计算溢出
}
void t2ISR() interrupt 5{//T2定时溢出处理
temppage=SFRPAGE;
SFRPAGE=0X00;
TF2=0;
tf2num++;
SFRPAGE=temppage;
}