微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PIC18 全局中断启用位在按下键盘按钮时切换 目标到目前为止我做了什么我的问题更新 1

如何解决PIC18 全局中断启用位在按下键盘按钮时切换 目标到目前为止我做了什么我的问题更新 1

目标

我正在尝试将 4x3 矩阵键盘和 7 段 LED 显示器连接到 PIC18f4550 微控制器。当我按下键盘上的按钮时,我希望 7 段显示器相应地显示数字。


到目前为止我做了什么

根据我的研究,我可以使用扫描(连续轮询)或使用中断将键盘与 MCU 连接。我决定使用中断,这样微控制器就可以腾出时间用于其他操作。

以下是键盘与单片机的连接。

enter image description here

我使用 RB0-2 作为 MCU 的输入,RB4-7 被设置为 MCU 的输出。 RB4-7 永久设置为高电平,因此当用户按下键盘按钮时,将触发 RB0-2(INT0-INT2) 中断进行处理。

在这文章中,为了简单起见,我将只讨论键盘的第 1 列。

这就是我初始化和设置寄存器的方式。

void main(void)
{
OSCCON = 0x72;
TRISD = 0;
LATD = 0;
ADCON1 = 0x0F;
 
TRISB = 0x07;
LATB = 0xF0;// keep the RB4-7 high

INTCONbits.GIE = 1;
INTCONbits.INT0IF = 0;
INTCONbits.INT0IE = 1;
INTCON2bits.INTEDG0 = 1;

while (1);
}

我的中断处理如下:

if(INTCONbits.INT0IF == 1)
{
    for(char scan=0x10; scan>=0x80; scan <<= 1) // send 1 to each row starting from RB4 till RB7
    {
        LATB = scan;        
        if (PORTBbits.RB0 = 1) 
        {
            if(scan == 0x10)
            {
                display_number(1); 
            }
            if(scan == 0x20)
            {
                display_number(4);
            }
            if(scan == 0x40)
            {
                display_number(7);
            }
        }
        
    }
    LATB = 0xF0;
    INTCONbits.INT0IF == 0;

我的问题

当我运行模拟时,我注意到只要我按下第 1 列中的任何按钮,GIE 位就会在 0 和 1 之间快速切换,并且在 7segment 上也没有显示任何数字。我添加了监视窗口屏幕截图并突出显示了正在切换的 GIE 位。

enter image description here

我做错了什么?我处理中断的逻辑有问题吗?


更新 1

正如 DavidHoadley 所建议的,我已改为使用 unsigned char 而不是 char

我也更正了 for 循环条件。

我观察到的是,如果我将循环保留在中断例程中,循环会因某种原因卡住。

现在,我已经放弃尝试在中断函数中使用循环,而是在主 while 循环中使用一个函数来在每一行按顺序输出高电平,并且中断函数仅用于使用 { 检查输出{1}}。

解决方法

您的 for 循环结束条件看起来循环将立即退出。行:

for(char scan=0x10; scan>=0x80; scan <<= 1)

应该是:

for(char scan=0x10; scan<=0x80; scan <<= 1)

无法测试 - 希望它有效

,

这是 PIC 微控制器的正常行为。当 PIC 进入中断向量时,硬件复位 GIE 位,当它完成中断服务时,它通过设置 C 代码中不可见的 GIE 位返回 RETFIE 汇编指令。所以这件事你的代码没有错,这甚至不是问题。

我在您的代码中看到您仅使用 INT0 中断来检测按下,其余 INTx 引脚未激活。这就是为什么PIC micro 将能够检测到唯一第一列的变化。我建议您使用 RB 位上的更改中断 (IOC)。这样您就可以释放 INTx 引脚用于其他目的。您可以将 3 个引脚移动到 PORTB 以外的 PORT。如果您有兴趣,这里是程序或我的建议:

  • 将 RB 引脚配置为输入并启用其 IOC 功能。
  • 将任意 3 个引脚配置为任意端口的输出。
  • 如果您使用正逻辑,请将 3 个引脚设置为高电平,否则设置为低电平。
  • 在您的 ISR 中,轮询 RBIF 以了解 RB 引脚是否发生变化。
  • 如果是这样,请进行按钮扫描以检测按下的键。

很遗憾,由于您没有共享代码和显示配置,因此无法告诉您有关显示问题的任何信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。