打印

16F877A中断计数器响应问题,在此恳请高人指点

[复制链接]
2403|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
songzhijing|  楼主 | 2012-8-16 10:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*暂时使用1位数码管程序顺利后使用4位的数码管,程序目的INT(RB0口)中断作为计数器使用,每中断一次数码管计数加一,当没有中断后开始延时或启动定时器10S自动睡眠,只要有中断产生立刻唤醒,数码管加一,无中断10S后睡眠如此循环工作。因为需要低功耗所以使用32.768K的晶体*/
#include<16F877A.h>           //使用877A的芯片
#include <pic.h>                    // 包含系统寄存器定义
__CONFIG (WDTDIS);            // 开启看门狗
unsigned char g_Counter=0;
void interrupt ISR(void)      //中断服务函数,
{
  if(INTE&INTF)               // 判断INT中断标志是否置位(为一)
  {
    INTF=0;                   // INTF置位,说明有中断产生,需要清除中断标志
    g_Counter++;              //中断次数计数器加一
    if(g_Counter==10)         //若等于10说明超过9了
    {
      g_Counter=0;            // 计数器清零,因为一位数码管只能记录0到9
      }
    }
}         
main()                       // 主函数入口
{
  int p=0;                   //暂时不会使用定时器,定义用延时变量
  const char SMG_Font[]={0b00111111,0b00000110,0b01011011,
           0b01001111,0b01100110,0b01101101,0b01111101,
           0b00000111,0b01111111,0b01101111};
  TRISB=0X01;                //RB0口做输入口
  INTE=1;                    // 打开INT中断
  INTEDG=1;                  // 设置触发中断的条件为电平从高到低触发
  TRISC=0;                   // C口方向设置为输出
  GIE=1;                     // 打开总中断
while(1)                    // 主循环必须是死循环
{
    CLRWDT();                //喂狗指令,
    PORTC=SMG_Font[g_Counter];    //数码管显示内容
                   /* ?此处是本人有疑问的地方,现在可以睡眠了,也可以唤醒 ,但是当RB0没有按下的时候CPU在执行下面的延时,有中断时不能立刻响应数码管不能加1,要等延时走完了才能响应到中断。但是我的目的是只要RB0 没有按下就开始延时4S或者10S后就睡眠,在延时期间只要有中断产生立刻响应中断程序,在从新去开始延时后在睡眠,请问有什么办法解决,程序应该要怎样写是不是可以用定时器的方法,但我不回写,恳请高人指点,能写出此程序已经花了我一个多月的时间了费尽脑汁了,就差一步就完美了。*/
      if(RB0==1)            //延时的目的是能看到数码管的内容,                       
     {
      for(p=0;p<300;p++)     //大约3-4S的时间
      {;}
      }
     PORTC=0X0;             //睡眠前的状态C口为0,关闭输出
     SLEEP();               //睡眠指令
     }
   
}
沙发
ty_fruit007| | 2012-8-16 16:12 | 只看该作者
是不是你int0中断的沿设置有问题呀?可以上升沿,也可以下降沿中断的。
你设置的是:INTEDG=1;                  // 设置触发中断的条件为电平从高到低触发
只有你松开键,从高到底时,才能中断;没有松开手,处于高电平是不能中断的,应该设置为
INTEDG=0;                  // 设置触发中断的条件为电平从低到高触发
一按下键,就高电平,马上中断

使用特权

评论回复
板凳
yewuyi| | 2012-8-16 17:21 | 只看该作者
最烦看别人代码

使用特权

评论回复
地板
songzhijing|  楼主 | 2012-8-17 09:37 | 只看该作者
呵呵。2楼说的确实没错用软件延时是不好,可以用TMR0定时我还不会啊没办法了,谢谢3楼的分析,问题我已经得到解决了,不是你说的那样,是我的中断程序里面没有处理好,在中断后面加一条PORTC=SMG_Font[g_Counter];    P=0;   就可以了,同时把常量数组和P变量放到全局变量就可以了
谢谢各位的解答。

使用特权

评论回复
5
yewuyi| | 2012-8-17 10:15 | 只看该作者
1、你说你没没事把const char SMG_Font[]定义到main()中干什么?这个应该尽量写到函数外面,在函数内部只定义局部变量,类似这种常量,尽量写在函数体外部才便于阅读和引用。
2、在MPLAB+PICC中不需要写#include<16F877A.h> ,只需要在建立项目时选择好芯片型号,然后在源代码中#include 即可。3、__CONFIG (WDTDIS); // 开启看门狗难道的CONFIG就用了一个看门狗?其它都没有了?尽量写全,即使芯片出厂默认配置过了,也尽量把使用到的配置字写全,否则芯片被烧写过的话,用你这个HEX文件再烧写可就未必确定结果了。
4、if(g_Counter==10) //若等于10说明超过9了以后记得把这行代码尽量写成if(g_Counter>=10),具体为什么?懒得解释了,你自己去想把。
5、 TRISB=0X01;
请写成 TRISB=0x01; 具体为什么?懒得解释了,你自己去想把。

。。。其它等等,问题太多,不一而足,真的看不下去了。

使用特权

评论回复
6
songzhijing|  楼主 | 2012-8-17 14:43 | 只看该作者
6楼说的确实没错,但是初学能学到这样我已经很努力了,要不怎么会来请教你们呢,谢谢你们的指导,今后小弟会更加注意和修改,

使用特权

评论回复
7
yewuyi| | 2012-8-17 15:10 | 只看该作者
6楼说的确实没错,但是初学能学到这样我已经很努力了,要不怎么会来请教你们呢,谢谢你们的指导,今后小弟会更加注意和修改,
songzhijing 发表于 2012-8-17 14:43


初学,不在于能些很多行代码,而在于要重点培养自己写出稳定、可靠、可阅读性强的代码,那怕一共只有几百行代码,必须要养成良好的编写习惯,否则以后后患无穷。

使用特权

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

本版积分规则

1

主题

9

帖子

0

粉丝