打印

PIC16F886支持中断嵌套吗?

[复制链接]
6977|32
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
busdriver|  楼主 | 2010-11-8 14:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在想用中断嵌套,1ms定时中断和串口接收中断,请问PIC16F886支持中断嵌套吗?好用吗?谢谢!
沙发
busdriver|  楼主 | 2010-11-8 14:38 | 只看该作者
中档系列PIC 单片机的中断入口只有一个,因此整个程序中只能有一个中断服务函数。
惨了。。。

使用特权

评论回复
板凳
busdriver|  楼主 | 2010-11-8 14:38 | 只看该作者
该如何实现呢?

使用特权

评论回复
地板
Mary_luo| | 2010-11-8 18:05 | 只看该作者
帮楼主顶一下!:P

使用特权

评论回复
5
jianghehupo| | 2010-11-8 21:33 | 只看该作者
支持,不过在进入isr的时候终端自动被禁止,想要实现嵌套的话必须手动修改中断代码。
不过我觉得楼主没必要嵌套

使用特权

评论回复
6
yewuyi| | 2010-11-8 22:44 | 只看该作者
1、真正需要中断嵌套的应用是很少的,所以,LZ不妨把自己的应用讲讲,我们分析一下是否真的需要中断嵌套。
2、如果真的需要中断嵌套,那么需要在进入中断后自己应用代码打开GIE,否则是不行的,而且需要自己编写合适的代码防止中断嵌套造成的内存溢出。
3、如果希望实现类似51那样的独立中断向量方式的中断嵌套,那么,建议看看PIC18及以上的产品,那么有不少是可以实现硬件方式的中断嵌套。
4、祝你好远。

使用特权

评论回复
7
e掾木| | 2010-11-9 08:31 | 只看该作者
中断就是茅房,力争快进快出,1ms中断仅足够你在里面看短片,难道你就看着外面的人排队你在里面蹲着看好莱坞大片?——快进快出,使用状态机方式处理中断影响到的程序进程。

使用特权

评论回复
8
busdriver|  楼主 | 2010-11-9 12:43 | 只看该作者
楼上真是很幽默,说的很在理。
我的想法是使用2级中断:
(1)串口接收中断接收串口数据放入缓存区,优先级高;
(2)1ms定时中断访问按键,led数码管刷新等功能。
将串口优先级设置为高,是为了避免串口丢包问题。
诸位有什么好的建议?

使用特权

评论回复
9
busdriver|  楼主 | 2010-11-9 22:22 | 只看该作者
up

使用特权

评论回复
10
shizaigaole| | 2010-11-9 22:40 | 只看该作者
LS应该不需要中断嵌套。

PIC16F886 可以跑20M,即每条指令0.2us,
即5000条指令/MS,

如果没有什么其他非常大的运算量的话,

按键和数码管扫描放到主循环里面即可。
对按键消斗延时计时,在10ms定时器中断里面做,时间到设置延时完成标志位。

使用特权

评论回复
11
shizaigaole| | 2010-11-9 22:45 | 只看该作者
怎样设计关键是LZ有没有其他的大的运算量要求.

使用特权

评论回复
12
busdriver|  楼主 | 2010-11-10 13:30 | 只看该作者
听楼上君两席话,豁然开朗。
把按键和数码管扫描放在主循环,只用一个串口接收中断,是一个很好的建议。
还没考虑加按键消抖延时,到时根据需要加上吧。
运算量不大。
硬件还没做好,现在是闭门造车,具体怎么应用还得实际调试看效果。
采用的是内部8M晶振,0.5us,2000指令/ms

谢谢诸位的热心参与!!

使用特权

评论回复
13
shizaigaole| | 2010-11-10 16:06 | 只看该作者
本帖最后由 shizaigaole 于 2010-11-10 16:08 编辑

既然你的运算量不大,
按键消抖延时比较好办.

一般来说按键消除抖动,几十MS,不要时间过短,否则容易多次出发,
键消除抖动用计时器中断做。


伪代码:


void ScanKey()
{
   static unsigned char step = 0;

if(step == 0)//按键扫描
{
   扫描按键
   if(有键按下)
        step = 1;//进入消除抖动延时阶段
}
else if(step == 1)
{
       if( Delay() == 1 )//延时时间到,Delay()函数在Timer0 10ms 中断里面执行,
      {
                 GetKey();
                  step = 0;//重新开始扫描按键
      }
}
}

一个按键读取过程,几十ms时间可以跑几万条指令,
程序运算量不大,足够住循环跑很多个循环了,
应该不会发生按键丢失

使用特权

评论回复
14
busdriver|  楼主 | 2010-11-10 16:25 | 只看该作者
这样一来,加上timer定时中断和串口接收中断,还是有2个中断啊。
我的想法是不消抖,问题大吗?

使用特权

评论回复
15
busdriver|  楼主 | 2010-11-10 16:30 | 只看该作者
说明一下,我的按键不是键盘阵列,4个单独按键,两个(tact button)轻触按钮,两个push buttom.

使用特权

评论回复
16
busdriver|  楼主 | 2010-11-10 16:31 | 只看该作者
shizaigaole的程序好像是对阵列键盘。谢谢!

使用特权

评论回复
17
shizaigaole| | 2010-11-10 16:34 | 只看该作者
只要你的串口波特率不是很高,
2个中断也没有关系。

比如说9600波特率 = 1200字节/s,

即1/1200 = 0.83ms

这段时间可以跑1千多条指令(8M速度),

不要说只是一个10ms的Timer0中断,
即使再有几个其他中断,
也没有问题。

当然中断里面的代码要尽量精简

使用特权

评论回复
18
shizaigaole| | 2010-11-10 16:37 | 只看该作者
说明一下,我的按键不是键盘阵列,4个单独按键,两个(tact button)轻触按钮,两个push buttom.
busdriver 发表于 2010-11-10 16:30


我的代码主要是延时的方法,和什么方式链接的按键没有关系

使用特权

评论回复
19
busdriver|  楼主 | 2010-11-10 16:43 | 只看该作者
多谢!对多个中断源只有一个中断入口,只能在中断中根据中断标志位进行判断了。

/***********************************************************************
Name:void interrupt int_isr(void)
Function:interrupt service routine
Input:none
Output:none
************************************************************************/
void interrupt int_isr(void)
{
        //unsigned char i;
        /*
        if(TMR1IF)//if timer1 overflow interrupt
        {
               
                TMR1L = 0x18;
                TMR1H = 0xFC;//Reload timer1 initial value, TMR1H:TMR1L = 0xFC18 = 64536
                TMR1IF = 0;//Clear Timer1 interrupt flag bit               
               
                store_counter++;
                if(!key_active)
                        store_counter = 0;//clear counter
                if((store_counter == 10000) && (key_active == 1))//10s
                {
                        key_active = 0;
                        store_flag = 1;//write EEPROM per 10s
                        store_counter = 0;//clear counter
                }
               
                key_scan();       
                */
                /*
                if(on_off_flag)
                {
                        led_decode(led,*fout);
                        led_display(led);//display current and voltage on LEDs
                }
                else
                {
                        for(i=0;i<=4;i++)
                        {
                                led[i]=10;
                        }
                        led_display(led);//all off               
                }        */       
        //}

使用特权

评论回复
20
shizaigaole| | 2010-11-10 16:54 | 只看该作者
keysan()还是放到住循环里面吧,
消除抖动延时用timer0中断计数就行了,

中断尽量只干最需要的事情。
中断代码尽量精简比较好

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

416

帖子

0

粉丝