找回密码
 立即注册

QQ登录

只需一步,快速开始

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

这是单片机中断优先级造成的吗?

[复制链接]
跳转到指定楼层
楼主
本帖最后由 wtm_lxy 于 2019-3-19 08:35 编辑

我做采集模拟电压控制指示灯的效果:
temp是采集到的模拟电压值,tv是保存的临时值。
我想实现的效果是:
当temp<=800时打开计数器1,同时保留当前的temp值;当计时3秒后,比较当前temp值与前面保存值的差值。

从反应效果看,count一直没有值,好像是终端1没有执行
是不是优先级导致它没有执行?
这个该怎么办?

下面是完整的单片机程序代码:

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int

uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};   //段选
sbit CLK=P1^3;   //ADC0808的控制端口
sbit ST=P1^2;
sbit EOC=P1^1;
sbit OE=P1^0;   

sbit LED=P1^7;    //指示灯,电机转动指示灯亮,不转时熄灭

sbit L0=P2^0;   //数码管位选,4个数码管
sbit L1=P2^1;
sbit L2=P2^2;
sbit L3=P2^3;

sbit LED2=P2^7;     //报警指示灯

uint count;   //定时计数

void DelayMS(uint ms)
{
        uchar i;
        while(ms--)
                for(i=0;i<120;i++);
}
/******************显示采集的电压**********************************/
void Display_Result(uint d)
{
        P0=0x00;//消隐    加了这句后第一位不闪烁了!!!
        
        L3=0;L2=1;L1=1;L0=1;   //P2=0xf7;     //1111 0111最右边的数码管显示
        P0=DSY_CODE[d%10];           
        DelayMS(5);
        
        L3=1;L2=0;L1=1;L0=1;    //P2=0xfb;     //左边第三个数码管  1111 1011
        P0=DSY_CODE[d%100/10];           
        DelayMS(5);
               
        L3=1;L2=1;L1=0;L0=1;     //P2=0xfd;     //左边第二个数码管  1111 1101
        P0=DSY_CODE[d%1000/100]|0x80;   //加小数点显示
        DelayMS(5);
        
        L3=1;L2=1;L1=1;L0=0;    //P2=0xfe;     //左边第一个数码管  1111 1110
        P0=DSY_CODE[d/1000];   
        DelayMS(5);

}

void main()
{
       uint temp;
       uint tv;

        EA=1;                  //开总中断
        
        TMOD=0x10;             //使用定时器T1的模式1
        ET1=1;                 //定时器T1中断允许         
        TH1=(65536-1000)/256; //定时器T1的高8位赋初值
        TL1=(65536-1000)%256; //定时器T1的高8位赋初值
        TR1=0;
        
        TMOD=0x02;
        TH0=(65536-3500)/256;    //0x14;   
        TL0=(65536-3500)%256;    //0x00;
        IE=0x82;
        TR0=1;
        
        while(1)
        {
                ST=0;ST=1;ST=0; //ADC启动
                while(EOC==0); //空循环;转换结束信号,没结束时EOC一直为0,转换结束为高电平
               
                OE=1;                //输出使能
                temp=P3*1.0/255*500;   //ADC0808输出和输入之间的关系,P3是输出值,temp是输入值
                temp=3.4*temp;  //转换为压力显示,有可能是4位数
                Display_Result(temp);
               
                if(temp<=800)
                {       LED=0;        //电机启动指示灯
                        TR1=1;         //打开计时器2
                        tv=temp;     //保存启动时的压力值
                }
               
                if(count==3000)
                {
                        count=0;
                        TR1=0;
                  if(temp-tv<=30 && LED==0)      //必须加上一个判断,电机已经转动并且增量小于30
                   {   
                          LED2=0;  //启动后3秒,如果压力没有上升,就报警
                    }
                 }
               
                if(temp>=1200)
                {LED=1;  LED2=1;}
               
                OE=0;   //IF判断必须加在“使能”的中间,否则P3没有值了
               
        }
}

void Timer0() interrupt 1
{
        CLK=~CLK;
}

void Time1() interrupt 3 using 0 //“interrupt”声明函数为中断服务函数
                 //其后的3为定时器T1的中断编号;0表示使用第0组工作寄存器
{
        count++;   //自加1  每次1ms
          TH1=(65536-1000)/256;        //定时器T1的高8位重新赋初值
        TL1=(65536-1000)%256;      //定时器T1的高8位重新赋初值
}

ADC0808采集电压并显示02.png (30.57 KB, 下载次数: 66)

ADC0808采集电压并显示02.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2019-3-18 20:53 | 只看该作者
T0设置错误:定时器模式2是8位自动重载,最大定时时间256us,超过255部分溢出无效,你这样设置的结果是定时14us。
回复

使用道具 举报

板凳
ID:466164 发表于 2019-3-18 22:14 | 只看该作者
不是优先级导致
TMOD=0x02; 模式0000  0010 你选模式2  八位自动装载你看你赋值还不一样
        TH0=(65536-3500)/256;    //0x14;   
        TL0=(65536-3500)%256;    //0x00;
再看你中断,又给赋值
void Time1() interrupt 3 using 0 //“interrupt”声明函数为中断服务函数
                 //其后的3为定时器T1的中断编号;0表示使用第0组工作寄存器
{
        count++;   //自加1  每次1ms
          TH1=(65536-1000)/256;        //定时器T1的高8位重新赋初值
        TL1=(65536-1000)%256;      //定时器T1的高8位重新赋初值
}
估计问题出在此处
回复

使用道具 举报

地板
ID:487930 发表于 2019-3-19 08:31 | 只看该作者
wulin 发表于 2019-3-18 20:53
T0设置错误:定时器模式2是8位自动重载,最大定时时间256us,超过255部分溢出无效,你这样设置的结果是定时 ...

我不是很明白,这里T0是给ADC0808做时钟脉冲输入端的,从检测结果来看,是可以检测到模拟值的。

问题是T1好像没有生效。
我用T1来控制报警指示和保存临时电压值。这个if(count==3000)总是不能成立。
回复

使用道具 举报

5#
ID:487930 发表于 2019-3-19 08:33 | 只看该作者
7358655 发表于 2019-3-18 22:14
不是优先级导致
TMOD=0x02; 模式0000  0010 你选模式2  八位自动装载你看你赋值还不一样
        TH0=(65 ...

        TMOD=0x02;
        TH0=0x14;   
        TL0=0x00;   
        IE=0x82;
        TR0=1;
应该不是T0的问题吧?我改成这样了。
我的问题是T1没有生效?T0是正常的。
回复

使用道具 举报

6#
ID:495226 发表于 2019-3-21 10:58 | 只看该作者
把 if(count==3000)改成  if(count>=3000)试试,主循环怎么能那么巧判断到3000,如果你正在送显示时中断计数可能超过3000了
回复

使用道具 举报

7#
ID:69072 发表于 2019-3-21 20:49 | 只看该作者
不一定 protues仿真软件 本身也存在一些问题
建议用最新版本
回复

使用道具 举报

8#
ID:427430 发表于 2019-3-21 21:35 | 只看该作者
.不会2.因为在默认情况下(即每次单片机复位时),中断优先级寄存器ip为xxx0 0000b,未设置ip时,所有中断都是同等级的!
回复

使用道具 举报

9#
ID:495752 发表于 2019-3-21 21:46 | 只看该作者

T0设置错误:定时器模式2是8位自动重载,最大定时时间256us,超过255部分溢出无效。也有可能是软件模拟的问题。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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