首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

帮忙看一上单片机测量脉宽代码

2012-08-15 
帮忙看一下单片机测量脉宽代码[codeC/C++][/code]#include at89x52.h#include stdio.h#include absa

帮忙看一下单片机测量脉宽代码
[code=C/C++][/code]#include <at89x52.h>
#include <stdio.h>
#include <absacc.h>

#define fosc 11.0592 //晶振频率
#define time02500 //定时2500uS

//#define BIT_LED XBYTE[0xbfff] //位码寄存器地

sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5; 
sbit P16=P1^6;
sbit P17=P1^7;
sbit P33=P3^3;
sbit P31=P3^1;
sbit P32=P3^2;

unsigned char data ctl[4]={0x70,0xB0,0xD0,0xE0};//P2控制字组,选择4个数码管中的一个
unsigned char data display_bit,display_buffer[4];
unsigned char data time0_h,time0_l;
unsigned int idata time0_times;
unsigned char data time1_h,time1_l;
double idata k=0; //总的定时次数

int n=0; //定时次数
int a=0;  
int shuzi1,shuzi2,shuzi3,shuzi4; //7段数码管显示的4位数字
int daima1,daima2,daima3,daima4;
double maikuan=0; //555产生信号的周期

unsigned char get_code(unsigned char i);
void display(void);

void delay(void);
void m1(double number1);
void m2(double number2);

main()

P33=0;

P1=0xFF; //P1口置1  
TMOD=0x91; //定时器/计数器1工作于定时方式1,定时器/计数器0工作于方式1
TH1=0;
TL1=0;
EA=ET1=1; //定时器溢出中断允许
EX1=1; //外部中断下降沿触发
IT1=1;
TR1=1; //启动定时器/计数器1开始计数  
delay(); //由于定时器/计数器1的再次利用,需延时0.4秒

//由于GATE,等待int0信号进行启动T1;



display_bit=0x01;//选中数码管1


time0_times=65536-time0*fosc/12;//计数器0开始计数2500us
time0_h =(time0_times/256 );
time0_l =(time0_times%256);
TH0=time0_h;TL0=time0_l; //高8位和低8位时间常数
TR0=1; //启动定时器0
ET0=1;


 
 
while(1);//稳定显示
}

  //问题点:无法进入else的转支,即无法计算脉宽
void INT1_int(void) interrupt 2 //外部中断1服务子程序:计算脉宽,

if(a==0)
{a++;TH1=0;TL1=0;}//T1重新计数
 
else{
TR1=0; //关闭T1
EX1=0;
time1_h=TH1;time1_l=TL1;
k=time1_h*256+time1_l+n*65536; //计算脉宽:k个周期
maikuan=(double)k/(11.0592/12); //单位:微秒
//maikuan=99 ;

//按单位进行BCD转换
if(maikuan<1000)
{ //输出R的单位:微秒
m1(maikuan);

}
else//单位:毫秒
{
m2(maikuan); 
}
display_buffer[3]=shuzi1;//将转换后的BCD码放到数组中
display_buffer[2]=shuzi2;
display_buffer[1]=shuzi3;
display_buffer[0]=shuzi4;
}
}
void time1_int(void) interrupt 3 //定时器1溢出中断服务子程序
{
n=n+1;
TH1=0;//T1重新计数
TL1=0;
}
void time0_int(void) interrupt 1 //定时器0溢出中断服务子程序
{ display();//T0计数完成后显示
TH0=time0_h;TL0=time0_l;//T0重新计数

 
}

想法是从INT1端输入待测脉冲,利用GATE门对T1进行定时,INT1中断来到时停止T1计数并算脉宽
如果强制给变量maikuan赋值的话,显示在仿真上能正确实现,问题出在脉宽的测量上面,maikuan一直都是0,也就是一直都显示0。

请大家帮忙看一下,第一次弄单片机的程序,好多都不清楚啊,感谢啊




[解决办法]
你把a改成unsigned int
display()最好放在main中的while(1){}里面

你待测的脉冲宽度是多少?是不是太快了测不出来

你手动控制外部中断的那条线,看你第二次把它拉低时能不能进到else里面
[解决办法]
大哥,你的中断里做的事也太多了点吧

 中断里尽量少做计算
------解决方案--------------------


volatile int a=0;

热点排行