RB口电平中断,程序一运行就会进一次中断

2020-02-09 09:36发布

用PICC编译,访真运行,开始会进一次中断,请帮着看看
//按键中断处理程序
//对应端口
//RB4=K1
//RB5=K2
//RB6=K3
//RB7=K4
//使用电平中断,打开内部弱上拉。
#include                <pic.h>
#include                 <math.h>
#include                 <stdio.h>
__CONFIG(0x1832);        
//芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡
//*该程序用于通过PORTB的"电平变化中断"进行键盘的识别。*/
//*程序设置一个键值寄存器j,当按下S9键时j=1,按下S11键时 */
//*j=2,按下S10键时,j=3,按下S12键时j=4*/
unsigned         char                data;
unsigned         int                i;
unsigned         char                j;
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
//*B口“电平变化中断”初始化子程序*/
void                 PORTBINT()
{
       TRISB=0XF1;         //B口RB0输入7705数据准备好信号,RB4,RB5,RB6,RB7按键输入,
                        //RB1输出EPROM片选,RB2输出7705片选,RB3输出1269片选
        INTCON=0x00;            //*关闭所有中断*/
    RBPU=0;             //开启按键开弱上拉
        RBIE=1;                                //*B口变位中断允许 */
        //PORTB=PORTB;                        //*读B口的值,为变位中断创造条件*/
}
//*spi初始化子程序*/
void                 SPIINIT()
{
        PIR1=0;
        SSPCON=0x20;       
        SSPSTAT=0xC0;
        TRISC=0xD7;                        //*SDO引脚为输出,SCK引脚为输出*/
}
//*系统各输入输出口初始化子程序*/
void                initial()
{
        TRISA=0xDF;
        INTCON=0x00;                        //*关闭所有中断*/
        data=0X00;                                //*待显示的寄存器赋初值*/
}
//*键服务子程序*/       
void                KEYSERVE()
{
        if(RB4==0)        j=0X01;
        if(RB5==0)        j=0X02;
        if(RB6==0)        j=0X03;
        if(RB7==0)        j=0X04;                //*以上通过逐行逐列扫描,以确定是何键按下*/       
        PORTB=0XFF;                        //*恢复PORTB的值*/
}
//*软件延时子程序*/
void                 DELAY()
{
        for(i = 6553; --i ;)
        continue;
}
//*SPI发送子程序*/
void          SPILED(int data)
{
        SSPBUF=data;                        //*启动发送*/
        do
        {
           ;
        }while(SSPIF==0);
        SSPIF=0;
}
void                IDEDIS()
{
        KEYSERVE();                        //*进行键盘的识别*/
        data=table[j];                                //*获得需要送出显示的段码*/
        RA5=0;                                        //*LACK信号清0,为锁存做准备*/
        SPILED(data);
        RA5=1;                                        //*最后给一个锁存信号,代表显示任务完成*/
}
//*中断服务程序*/
void        interrupt        keyint(void)
{
        DELAY();                                //*软件延时*/
        if ((RB7==0)||(RB6==0)||(RB5==0)||(RB4==0))                //*该语句除了能够确认按键是否为干扰外,*/
                                                        //*还可以屏蔽一次键松开时引起的中断*/
        IDEDIS();                                //*键识别和显示模块*/
        //PORTB=PORTB;                        //*读B口的值,改变中断发生的条件,避免键*/
                                                        //*一直按下时,连续进行键识别*/       
        RBIF=0;                                    //*键扫描时可能会产生"电平变化"而使RBIF*/
        //INTF=0;                                //*置1,再清除一次RBIF以避免额外中断*/
}
main()
{
        initial();                                //*系统初始化*/
        PORTBINT();                            //*B口变位中断初始化*/
        SPIINIT()        ;                    //*利用SPI显示初始化*/
    //INTE=1;
        ei();                                        //*总中断允许*/
while(1)
        {
                ;
        }                                                //*等待中断*/
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
Yaksa
1楼-- · 2020-02-09 10:52
不知道你用的是哪款芯片,也不知道ei()是什么,你的程序我这里仿真没任何效果.说说我的看法

1.PORTBINIT()函数中:
    //PORTB=PORTB; //*读B口的值,为变位中断创造条件*/
    的确应该读一下B口的值,可这么写会被优化掉吧,我猜.我是用的PORTB=0xf0
2.你都没设置IOCB,怎么可能进入电平变化中断呢?
3.不知道ei()是什么,GIE和PEIE都打开了吗?
下面是我的测试程序和仿真.

//PORTB电平变化中断
//按下button1~4时,对应的LED1~4分别点亮

#include  "pic.h"

void interrupt key(void)
{
    if(RBIF)
    {
        RC4=!RB4;
        RC5=!RB5;
        RC6=!RB6;
        RC7=!RB7;
        RBIF=0;
    }
}

void main(void)
{
    TRISB=0XF0;
    PORTB=0xf0;
    TRISC=0;
    ANSEL=0;
    ANSELH=0;

    RBIE=1;
    PEIE=1;
    GIE=1;
    IOCB=0xff;  //PORTB电平变化中断寄存器

    while(1)
    {
    }
}


(原文件名:sim.PNG)
st1235
2楼-- · 2020-02-09 16:46
回复【1楼】Yaksa 解烟客
-----------------------------------------------------------------------

谢谢回复,用的是PIC16F876,ei();是打开总中断,程序在运行时会进入一次中断,然后正常。
my2009
3楼-- · 2020-02-09 21:16
 精彩回答 2  元偷偷看……
lixue51
4楼-- · 2020-02-09 21:42
先清一下中断标志位 再开总的中断

一周热门 更多>