找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1890|回复: 12
打印 上一主题 下一主题
收起左侧

单片机外部中断0中启动定时器2,无法再触发外部中断0

[复制链接]
跳转到指定楼层
楼主
ID:961122 发表于 2021-10-5 17:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机程序如下,想实现的功能中两个按钮分别是启动和停止。按下启动灯亮 开启INT0,按下停止灯灭 关闭INT0。启动后按INT0切换指示灯的状态,并启动定时器T2(定时器2的中断程序未写)。
但在中断中加入定时器T2的设置命令就无法通过 再按停止——启动——INT0来实现切换了,此时再按INT0进不了中断。
还请高手指点一下。
void pressBtn(void)
{
if (I_start == 0 && BtnState == 0)                                
        {        
        Delay(1);
        if (I_start==1)                                                               
                return;                                                                        
        BtnState        =         1;                                                                                 
        Q_motor                =         1;                                                                           
        Q_light                =         1;                                                                                                                                
        EA                        =        1;                                                                                
        EX0                        =        1;                                                                                
        EX1                        =        1;                                                                                

        Objshot                =        0;                                                                                
        
        }                                                                                         
if (I_stop == 0 && BtnState == 1)                                       
        {        
        Delay(1);
        if (I_stop==1)                                                               
                return;
        while (TR0);                                                               
        BtnState=        0;                                                                 
        Q_motor        =        0;                                                         
        Q_light        =        0;                                                               
        EA                =        0;
        EX0                =        0;
        EX1                =        0;               
        }
}

void Initobj(void) interrupt 0
{
if((Objshot==0 && C_obj==0) ||(Objshot==1 && C_obj==1))                  
{
        Q_light                =        ~Q_light;                                                                        
        ACC_delay        =        0;                                                                                       
        AUXR                 |=         0x10;                    //屏蔽此语句可实现中断切换   Q_light                                 
        IE2                  |=         0x04;                            //屏蔽此语句可实现中断切换   Q_light                  
        EX0                 =         0;                                                                                                                                                                                                         
}
Objshot=~Objshot;                                                           

}

void main(void)
{
Q_light                =        0 ;                                                        
BtnState        =        0 ;                                                        
                                                         

/*
Timer2初始化  设T2 为2ms
*/
AUXR         |=         0x04;                                                
T2L         =         0x9A;                                                        
T2H         =         0xA9;                                                        

InitAD(1);
InitAD(0);                                                        

Labelshot        =        0;                                                

while(1)
        {                                                  
        pressBtn();                                                                                       
        do                                                                                                        
        {
                ADC_obj=Get_ADC10bitResult(1);                                         
        }
        while(ADC_obj!=Get_ADC10bitResult(1));
        do
        {
                ADC_label=Get_ADC10bitResult(0);                                 
        }
        while(ADC_label != Get_ADC10bitResult(0));
        }  
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2021-10-5 17:52 | 只看该作者
如果你开了 T2 中断,而没有写T2 中断程序, 程序就会死。

所以,你开了T2 中断,至少要写一个空的T2 中断程序,
回复

使用道具 举报

板凳
ID:961122 发表于 2021-10-5 17:56 | 只看该作者
好的,明白,谢谢
回复

使用道具 举报

地板
ID:57657 发表于 2021-10-5 18:45 | 只看该作者
你开了两个中断,为何只有1个带 interrupt 的函数?
回复

使用道具 举报

5#
ID:624769 发表于 2021-10-5 18:55 | 只看该作者
npn 发表于 2021-10-5 18:45
你开了两个中断,为何只有1个带 interrupt 的函数?

你可以参见楼主正文第二行的括号里的内容。

我是看见这句话,就直接就跳过他的程序了。


回复

使用道具 举报

6#
ID:961122 发表于 2021-10-6 08:20 | 只看该作者
加进定时中断程序还是一样,只要 AUXR  和 IE2指令在 void Initobj(void) interrupt 0里面结果一样。外部中断只能执行一次。我将开启定时中断的AUXR和IE2语句移到main()里面,通过Int0中断更改变变量运行就可以,但出现按启动按钮后,还没触发外部中断,定时中断自动被执行。
回复

使用道具 举报

7#
ID:161164 发表于 2021-10-6 11:41 | 只看该作者
说了那么多,还是没有说用什么型号的单片机
根据AUXR的设置和有ADC
是STC15W4XXAS吗?

还有。。。把程序贴全一点
去头去尾的,想帮你检查都要推理一下代码的运作
C_obj是什么鬼?
回复

使用道具 举报

8#
ID:624769 发表于 2021-10-6 19:47 | 只看该作者
litingkun 发表于 2021-10-6 08:20
加进定时中断程序还是一样,只要 AUXR  和 IE2指令在 void Initobj(void) interrupt 0里面结果一样。外部中 ...

由于代码不全,只能靠猜, 就你目前的代码,有如下两个疑惑, 都是有可能会卡死程序的,你看一下。  


while (TR0);                <== 这个 TR0 通过什么控制? 你能保证 如果卡在这里,有地方 让TR0 = 0么?                                      
        BtnState=        0;                                                                 
        Q_motor        =        0;                                                         
        Q_light        =        0;                                                               
        EA                =        0;       <===  你这里关闭了所有的中断, 你什么地方会再把中断打开?
        EX0                =        0;
        EX1                =        0;               
回复

使用道具 举报

9#
ID:961122 发表于 2021-10-6 22:02 | 只看该作者
TR0可以去掉的,T0定时器还没用,所以TR0会一直都是零。
回复

使用道具 举报

10#
ID:961122 发表于 2021-10-6 22:22 | 只看该作者
不好意,没把程充贴全,这是加了定时的程序main.c,程序想通过按 I_start启动, Q_light亮起,后通过按中断0启动定时中断,在定时到一定时间后,定时中断将 Q_light关掉。之后按下I_stop按钮,再按一下I_start灯亮,再按中断0应该是又重复上面动作,但实际上亮没有变化。
请高手有时间帮忙看一下。C_Obj用于控制上升沿触发还是下降沿触发的一个开关。
#include <reg51.h>
#include <intrins.h>
#include <ad.h>




sbit I_start         =         P2^4;                                                //启动按钮
sbit I_stop         =         P2^3;                                                //停止按钮
sbit I_obje         =        P3^2;                                            //测物触发
sbit I_label        =         P3^3;                                               
sbit C_obj                 =        P5^5;                                                  //测物沿转换
sbit C_label         =         P5^4;                                               
sbit Q_pulse         =         P1^4;                                                //脉冲输出
sbit Q_motor        =         P1^3;                                                //电机输出
sbit Q_light        =         P1^2;                                                //指示灯输出
                                    


b1 BtnState;                                                           //启动/停止按钮状态 0停止 1启动
u8 ADC_obj;                                                                //测物延时模拟量
u8 ADC_label;                                                          //测物延时模拟量

b1 Labelshot;
u8 ACC_delay;
b1 Objshot;       

u8 x;

/*****************************************************************************

** 函数名称: pressBtn()

** 功能描述: 按钮启动/停止

** 全局变量: BtnState

** 调用模块: main()

** 输入: 无

** 输出: 无

******************************************************************************/
void pressBtn(void)
{
if (I_start == 0 && BtnState == 0)                                //启动按钮按下 停止状态 -启动
        {       
        Delay(1);
        if (I_start==1)                                                                //误触发判断
                return;                                                                        
        BtnState        =         1;                                                                                 //运行状态置1
        Q_motor                =         1;                                                                            //启动电机
        Q_light                =         1;                                                                                //绿灯亮                                                               
        EA                        =        1;                                                                                //中断使能
        EX0                        =        1;                                                                                //外部中断0中断允许位
        EX1                        =        1;                                                                                //外部中断1中断允许位

        Objshot                =        0;                                                                                //测物触发状态
       
        }                                                                                         
if (I_stop == 0 && BtnState == 1)                                //停止按钮按下 动行状态 -停止       
        {       
        Delay(1);
        if (I_stop==1)                                                                //误触发判断
                return;
        //while (TR0);                                                               
        BtnState=        0;                                                                 //运行状态置1
        Q_motor        =        0;                                                            //启动电机
        Q_light        =        0;                                                                //绿灯亮
        EA                =        0;
        EX0                =        0;
        EX1                =        0;               
        }
}
/*****************************************************************************

** 函数名称: Obj_Time()

** 功能描述: 中断3 测物触发延时中断

** 全局变量:

** 调用模块: -

** 输入: 无

** 输出: 无

******************************************************************************/
void Obj_time(void) interrupt 12
{

if (ADC_obj == ACC_delay)                                                       //定时计数,最小定时量2ms  最大量254ms ACC_delay定时器计数值 每次INT0触发时清零
{
Q_light        =~Q_light;
AUXR        |=        ~0x10;                                             //加速定时器,关闭定时中断
IE2          |=         ~0x04;
ACC_delay        =        0;
EX0                 =         1;                                                                                               
}
else
ACC_delay++;                                                                                               
}
/*****************************************************************************

** 函数名称: Initobj()

** 功能描述: 中断0 测物触发

** 全局变量: bit Objshot ,bit TACP0(TR0)

** 调用模块: -

** 输入: 无

** 输出: 无

******************************************************************************/
void Initobj(void) interrupt 0
{

if((Objshot==0 && C_obj==0) ||(Objshot==1 && C_obj==1))                   //沿判断设置,C_obj=0上升沿
{       
        ACC_delay        =        0;                                                                                        //初始化定时时长
        EX0                 =         0;                                                                                        //关闭外部中断0
        IE2                  |=         0x04;                                           //使能定时器中断
        AUXR                 |=         0x10;                                           //启动定时器                                                                                                        
}
Objshot=~Objshot;                                                                   //取反

}
/*****************************************************************************

** 函数名称: mina()

** 功能描述: 主程序

** 全局变量:BtnState 启动状态

** 调用模块:

** 输入: 无

** 输出: 无

******************************************************************************/
void main(void)
{
Q_light                =        0 ;                                                        //初始化 启动灯
BtnState        =        0 ;                                                        //设备初始设备置 停止
                                                         

/*
Timer2初始化  设T2 为2ms
*/
AUXR         |=         0x04;                                                //定时器时钟1T模式
T2L         =         0x9A;                                                        //设置定时初始值
T2H         =         0xA9;                                                        //设置定时初始值

InitAD(1);
InitAD(0);                                                        //初始化ADC 只启动 设置speed

Labelshot        =        0;                                                //标签触发状态           ?
while(1)
        {                                                 
        pressBtn();                                                                                        //开关按钮扫描  按钮启动/停止
        do                                                                                                        //采集2次如果相同就停止,如果不同继续采集
        {
                ADC_obj=Get_ADC10bitResult(1);                                         //读取ADC1数据 测物延时
        }
        while(ADC_obj!=Get_ADC10bitResult(1));
        do
        {
                ADC_label=Get_ADC10bitResult(0);                                 //读取ADC0数据 标签触发延时
        }
        while(ADC_label != Get_ADC10bitResult(0));
        }        
}
回复

使用道具 举报

11#
ID:624769 发表于 2021-10-6 23:48 | 只看该作者
AUXR        |=        ~0x10;                                             //加速定时器,关闭定时中断
IE2          |=         ~0x04;
上述写法,你所有定时器的时间都不对了……
关闭T2定时中断的话……
AUXR        &=        ~0x10;        
IE2          &=         ~0x04;
而实际上,一般只要关了定时器,中断不用管……

最后,ad.h 呢?
             ADC_obj=Get_ADC10bitResult(1);                                         //读取ADC1数据 测物延时
这里面写的啥,不知道啊……
回复

使用道具 举报

12#
ID:961122 发表于 2021-10-7 00:43 | 只看该作者
感谢!
这是AD.c 和AD.h 的文件,就是筒单读取指定端口AD的函数,AD测试过了没什么问题。
#ifndef          __AC_H_
#define   __AC_H_


#include <reg51.h>
#include <intrins.h>

sfr P1ASF = 0x9D;



//sfr ADC_CONTR   =   0xBC;           //ADC控制寄存器
//sfr ADC_RES     =   0xBD;           //ADC高8位结果
//sfr ADC_LOW2    =   0xBE;           //ADC低2位结果
//sfr P1ASF       =   0x9D;           //P1口第2功能控制寄存器

extern void Delay(u16 n);
extern void InitAD(u8 channel);
extern u8        Get_ADC10bitResult(u8 channel);
#endif


#include "AD.H"



/*****************************************************************************

** 函数名称: Delay

** 功能描述: 延时程序

** 全局变量:

** 调用模块: -

** 输入: 无

** 输出: 无

******************************************************************************/
void Delay(u16 n)
{
        unsigned int x;
        while(n--)
        {
                x=5000;
                while(x--);
        }

}
/*****************************************************************************

** 函数名称: InitAD()  

** 功能描述: AD初始化

** 全局变量:

** 调用模块: -

** 输入: 无

** 输出: 无

******************************************************************************/

void InitAD(u8 channel)
{
  P1ASF |= (1 << channel);                                       //设置P1口为AD口
  ADC_RES = 0;
  ADC_RESL = 0;                                                           //清除结果寄存器
  ADC_CONTR |= 0x80;                                                          //540脉冲采集1次 0x80:POWER
  Delay(2);                                                               //ADC上电并延时


}
/*****************************************************************************

** 函数名称: Get_ADC10bitResult

** 功能描述: 读取AD数据

** 全局变量:

** 调用模块: -

** 输入: 无

** 输出: 无

******************************************************************************/
u8 Get_ADC10bitResult(u8 channel)  //channel = 0~7
{       

ADC_CONTR |= 0x08 | channel;                                                   //start the ADC         0x08:ADC_START
_nop_();
_nop_();
_nop_();                                                                                               
while((ADC_CONTR & 0x10) == 0);                                   //wait for ADC finish
ADC_CONTR &= ~0x10;                                                     //清除ADC结束标志
return ADC_RES;
}
回复

使用道具 举报

13#
ID:961122 发表于 2021-10-7 00:48 | 只看该作者
188610329 发表于 2021-10-6 23:48
AUXR        |=        ~0x10;                                             //加速定时器,关闭定时中断
...

感谢大神指点,应该是这样。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表