导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→[求教]一段中断程序[qingyu]

 *第42537篇: [求教]一段中断程序

  
楼 主:qingyu 2006年8月7日19:10
 [求教]一段中断程序
我要用单片机输出占空比可变的20k的pwm,pwm用两个定时器采用工作方式二产生,P2—7输出pwm,外部中断产生时,P1—0~P1—5,P2—6七个口并行送入pwm占空比的值,大约几百ms送一次,由另一个单片机与此单片机直接相连,产生中断并送数,现在问题是pwm能输出,外部中断0有下降沿跳变,但输出的pwm占空比始终不变为什么?
#include    <reg51.h>  

sbit  P1_0=P1^0;      //并行输入口
sbit  P1_1=P1^1;      //并行输入口
sbit  P1_2=P1^2;     //并行输入口
sbit  P1_3=P1^3;    //并行输入口
sbit  P1_4=P1^4;   //并行输入口
sbit  P1_5=P1^5;   //并行输入口
sbit  P2_6=P2^6;   //并行输入口
sbit  P2_7=P2^7;   //并行输入口

unsigned int   t=30;

void timer0(void) interrupt 1 using 1     //定时器0中断服务程序
{  
   TR0=0;  
   P2_7=1;
   TR1=1;   
}

void timer1(void) interrupt 3 using 2     //定时器1中断服务程序
{        
 TR1=0;
 P2_7=0;
 TR0=1; 
}

void service_int1(void) interrupt 0 using 3  //外部中断服务程序
{     
     EA=1;       //实现中断嵌套
     t=0;
     if(P2_6)  t=64;    //接收数据
     if(P1_5)  t=t+32;
     if(P1_4)  t=t+16;
     if(P1_3)  t=t+8;
     if(P1_2)  t=t+4;
     if(P1_1)  t=t+2;
     if(P1_0)  t=t+1;
     t=t/2;                   //送入t的范围是2=  <t  <=80
}     

void main(void)                            
{                      
        IP=0x0a;          //优先级设定,定时器高,外部中断低
        IT0=1;           //下降沿触发
        TMOD=0x22;         //工作方式二
        TH1=256-t;          //装载初值
        TL1=TH1;
        TH0=256-(41-t);
        TL0=TH0;
        IE=0x8b;    //开中断
        TR0=1;           //开定时器
        while(1);
}

  
2楼:wangxueyou 2006年8月7日19:49
 huifu
我看了看你的程序 我觉得你利用外部中断来进行时间的设置有点不妥 因为你的定时中断的优先级总是最高的  一但定时器的中断响应后就会无限的对定时器产生中断 你的外部中断跟本就不能响应  所以它总是输出一种定时波形. 你可以常试着用其他方式把你的控制时间输进去.
  
3楼:wangxueyou 2006年8月7日19:57
 回复
void main(void)                            
{                      
        IP=0x0a;          //优先级设定,定时器高,外部中断低
        IT0=1;           //下降沿触发
        TMOD=0x22;         //工作方式二
        TH1=256-t;          //装载初值
        TL1=TH1;
        TH0=256-(41-t);
        TL0=TH0;
        IE=0x8b;    //开中断
        TR0=1;           //开定时器
        while(1);
}
可以利用外部中断进行时间设置  但是你主程序中的while(1);
不能够是主程序不段的循环 而是对t采样一次后 就一直停留在while(1);
这句上了 根本就不能够在改变t的值了 你可以尝试着把程序变成这样
void main(void)                            
{                      
       while(1)
        {IP=0x0a;          //优先级设定,定时器高,外部中断低
        IT0=1;           //下降沿触发
        TMOD=0x22;         //工作方式二
        TH1=256-t;          //装载初值
        TL1=TH1;
        TH0=256-(41-t);
        TL0=TH0;
        IE=0x8b;    //开中断
        TR0=1;           //开定时器
        }
}
看看这样是不是可以实现.
  
4楼:qingyu 2006年8月7日21:05
 我试了,确实好使了,非常感谢!!!
我试了,确实好使了,非常感谢!!!
  
5楼:wangxueyou 2006年8月7日21:23
 huifu
不要那么客气  彼此学习 彼此提高
  
6楼:qingyu 2006年8月8日09:22
 回复
今天又遇到问题了,就是按照while(1)改变位置后,由于在while(1)中有中断产生,使得有时定时器1的重新装载执行了,而定时器0的重新装载没执行,输出的波形总是在变化,我把程序改成定时器1定时总周期,但是输出总是高电平,不知为什么,有什么解决办法?
#include    <reg51.h>  

sbit  P1_0=P1^0;
sbit  P1_1=P1^1;
sbit  P1_2=P1^2;
sbit  P1_3=P1^3;
sbit  P1_4=P1^4;
sbit  P1_5=P1^5;
sbit  P2_6=P2^6;
sbit  P2_7=P2^7;

unsigned int   t=30;

void timer0(void) interrupt 1 using 1     //定时器0中断服务程序
{  
   TR0=0;  
   P2_7=0;  
}

void timer1(void) interrupt 3 using 2     //定时器1中断服务程序
{        
   P2_7=1;
   TR0=1; 
}

void service_int1(void) interrupt 0 using 3  //外部中断服务程序
{     
     EA=1;
     t=0;
     if(P2_6)  t=64;
     if(P1_5)  t=t+32;
     if(P1_4)  t=t+16;
     if(P1_3)  t=t+8;
     if(P1_2)  t=t+4;
     if(P1_1)  t=t+2;
     if(P1_0)  t=t+1;
     t=t/2;
}     

void main(void)                            
{       
      while(1)
     {          
          IP=0x0a;       
          IT0=1;
          TMOD=0x22;
          TH1=256-41;
          TL1=TH1;
          TH0=256-t;
          TL0=TH0;
          IE=0x8b;
          TR0=1;
          TR1=1;                        
   }
        
}

  
7楼:wangxueyou 2006年8月8日10:59
 huifu
你这个程序是越改越乱  在主程序中你写 TR0=1;
          TR1=1; 这样不是同时把两个记数器给开开了, 你说这样你产生的波形能不乱吗
  
8楼:wangxueyou 2006年8月8日11:20
 回复
下面是我改了的程序  不知道行不行 你自己试试    我只是凭感觉改的  不知道能不能达到你的目的 
#include      <reg51.h>    

sbit  P1_0=P1^0;      //并行输入口
sbit  P1_1=P1^1;      //并行输入口
sbit  P1_2=P1^2;     //并行输入口
sbit  P1_3=P1^3;    //并行输入口
sbit  P1_4=P1^4;   //并行输入口
sbit  P1_5=P1^5;   //并行输入口
sbit  P2_6=P2^6;   //并行输入口
sbit  P2_7=P2^7;   //并行输入口

unsigned int   t=30;

void timer0(void) interrupt 1 using 1     //定时器0中断服务程序
{  
   TR0=0;  
   P2_7=1;
   TR1=1;   
}

void timer1(void) interrupt 3 using 2     //定时器1中断服务程序
{        
 TR1=0;
 P2_7=0;
 TR0=1; 
}

void service_int1(void) interrupt 0 using 3  //外部中断服务程序
{     
     EA=1;       //实现中断嵌套
     t=0;
     if(P2_6)  t=64;    //接收数据
     if(P1_5)  t=t+32;
     if(P1_4)  t=t+16;
     if(P1_3)  t=t+8;
     if(P1_2)  t=t+4;
     if(P1_1)  t=t+2;
     if(P1_0)  t=t+1;
     t=t/2;                   //送入t的范围是2=    <t    <=80
     TMOD=0x22;         //工作方式二
     TH1=256-t;          //装载初值
     TL1=TH1;
     TH0=256-(41-t);
     TL0=TH0;
      TR0=1;

}     

void main(void)                            
{                      
        IP=0x01;          //优先级设定,定时器低,外部中断高, 只有通过外部设置好     
                                    了占空比后才可能产生定时中断
        IT0=1;           //下降沿触发
        IE=0x8b;    //开中断
       //TR0=1;           //开定时器
        while(1);
}


  
9楼:qingyu 2006年8月11日09:39
 谢谢大虾,改了n次终于完全好使了,谢谢!
谢谢大虾,改了n次终于完全好使了,谢谢!

>>>>>>对该主题发表你的看法

本主题贴数9,分页: [第1页]


[上一篇主题]:超简单的的跑马灯程序,烧录到AT89C51上好使,但是烧录到AT89S51上就不好使恳请大虾执教

[下一篇主题]:寻单片机程序开发(硬盘播放器方面)