3324|7

5

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

PIC16f1937电平变化中断问题 [复制链接]

我使用了RB0,RB1, RB2, RB3作为电平变化中断管脚,当RB0按下时,使得继电器1闭合(由RD0控制,继电器1控制交流220v电路的通断),当RB2按下时,使得继电器1断开,当RB2按下时,使得继电器2闭合(由RD1控制,继电器2控制交流220v电路的通断),当RB3按下时,使得继电器2断开.
现在的问题是:当RB0和RB2按下时,大约50%的概率不能使得继电器1、2闭合,程序是否有需要改进的地方

谢谢大家!

我的程序如下:

//*******************************************************************//
//                          系统初始化
//*******************************************************************//
void System_Init(void)
{
    OSCCON = 0b01101000;            //内部4MHz,不使能4xPLL
    OSCTUNE= 0b00000000;            //出厂校准
    //  PORTA用于读取端口的电平
    TRISA  = 0b00111111;            //RA0-RA5输入、RA6-RA7输出
    ANSELA = 0b00000000;            //RA0-RA7均为数字I/O
      LATA   = 0x00;                    //用于向端口写数据


    TRISB  = 0b00011111;            //RB0-RB4输入,RB5-RB7输出
    ANSELB = 0b00000000;            //RB0-RB7均为数字I/O
      LATB   = 0x00;                    //用于向端口写数据
    WPUB   = 0b00000000;            //无上拉
    IOCBN  = 0b00001111;            //检测RB0-RB3下降沿,会产生中断
   

    TRISC  = 0b00000000;            //RC0-RC7输出
    LATC   = 0x00;                    //用于向端口写数据


    TRISD  = 0b00111100;            //RD0-RD1输出,RD2-RD5输入,RD6-RD7输出
    ANSELD = 0b00000000;            //RD0-RD7均为数字I/O
    LATD   = 0x00;                    //用于向端口写数据

   
    TRISE  = 0b00000000;            //RE0-RE2输出
    ANSELE = 0b00000000;            //RE0-RE2均为数字I/O
    WPUE   = 0b00000000;            //无上拉
    LATE   = 0x00;                    //用于向端口写数据
}
   

//*******************************************************************//
//                             中断程序部分
//*******************************************************************//
void interrupt portb_int(void)
{
    if(IOCIE && IOCIF && IOCBF0)
    {
        RB0;
        IOCBF0 = 0;            //清中断标志位
        RD0 = 0;            //继电器1断电
        RD1 = 0;            //继电器2断电
        IOCBF0_FLAG = 1;    //设置标志
    }
    else if(IOCIE && IOCIF && IOCBF1)
    {
        RB1;
        IOCBF1 = 0;            //清中断标志位
        RD1 = 0;            //继电器2断电
        RD0 = 1;            //继电器1上电
        IOCBF1_FLAG = 1;    //设置标志
    }
    else if(IOCIE && IOCIF && IOCBF2)
    {
        RB2;
        IOCBF2 = 0;            //清中断标志位
        RD1 = 0;            //继电器2断电
        RD0 = 0;            //继电器1断电
        IOCBF2_FLAG = 1;    //设置标志
    }
    else if(IOCIE && IOCIF && IOCBF3)
    {
        RB3;
        IOCBF3 = 0;            //清中断标志位
        RD0 = 0;            //继电器1断电
        RD1 = 1;            //继电器2上电
        IOCBF3_FLAG = 1;    //设置标志
    }
}



//*******************************************************************//
//                             主程序部分
//*******************************************************************//

void main(void)
{
    __delay_ms(100);
    System_Init();          //系统初始化
    IOCIE = 1;                //电平变化中断使能
    GIE = 1;                //总中断允许

    IOCBF0 = 0;
    IOCBF1 = 0;
    IOCBF2 = 0;
    IOCBF3 = 0;
    IOCBF4 = 0;

    while(1)
    {        
        if(RA1 == 0)//手动模式
        {

            if(IOCBF0_FLAG == 1)
            {
                RD0 = 0;//继电器1断电
                RD1 = 0;//继电器2断电
                IOCBF0_FLAG = 0;
            
            }   
            else if(IOCBF1_FLAG == 1)
            {
                RD1 = 0;//继电器2断电
                RD0 = 1;//继电器1上电
                IOCBF1_FLAG = 0;
            
            }
            else if(IOCBF2_FLAG == 1)
            {
                RD1 = 0;//继电器2断电
                RD0 = 0;//继电器1断电
                IOCBF2_FLAG = 0;
               
            }
            else if(IOCBF3_FLAG == 1)
            {
                RD0 = 0;//继电器1断电
                RD1 = 1;//继电器2上电
                IOCBF3_FLAG = 0;
            
            }
        }
    }
}

最新回复

直接回复问题,帮助网友解决问题,就是最好的支持了。  详情 回复 发表于 2016-7-21 10:05
点赞 关注
 

回复
举报

3471

帖子

13

TA的资源

五彩晶圆(高级)

沙发
 
首先保证逻辑清晰合理。两个io控制一个继电器的状态。每次都应该判断两个io是哪种组合。并且要知道上一个状态,再决定是否执行动作。 两个继电器要分开处理。
另外,读按键是要去抖的。不然,很容易误动作。
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
ienglgge 发表于 2016-6-30 20:12
首先保证逻辑清晰合理。两个io控制一个继电器的状态。每次都应该判断两个io是哪种组合。并且要知道上一个状 ...

我的程序是两个io控制两个继电器

读按键怎样去抖?中断是单片机自己判断的,在程序的哪里添加去抖程序?

谢谢!
 
 
 

回复

3471

帖子

13

TA的资源

五彩晶圆(高级)

4
 
用一个变量记录当前状态。得到中断的数据,不要立即执行,延时判断,状态不变,再执行。
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

5
 
ienglgge 发表于 2016-7-2 22:04
用一个变量记录当前状态。得到中断的数据,不要立即执行,延时判断,状态不变,再执行。

你说的这个得到中断的数据是指什么?去抖是在while(1)里面做吗?

点评

两个方法去抖: 1.软件,在中断作个标志位,在主程序中判断下相应管脚状态并延时 2.硬件,在开关两端并联电容,并在中断程序再增加引脚的电平判断功能.  详情 回复 发表于 2016-7-5 17:52
 
 
 

回复

638

帖子

2

TA的资源

版主

6
 
sihhepl 发表于 2016-7-4 05:34
你说的这个得到中断的数据是指什么?去抖是在while(1)里面做吗?

两个方法去抖:
1.软件,在中断作个标志位,在主程序中判断下相应管脚状态并延时
2.硬件,在开关两端并联电容,并在中断程序再增加引脚的电平判断功能.
 
 
 

回复

9

帖子

0

TA的资源

一粒金砂(初级)

7
 
PIC 代理 提供技术支持哟

点评

直接回复问题,帮助网友解决问题,就是最好的支持了。  详情 回复 发表于 2016-7-21 10:05
 
个人签名MICROCHIP IR代理 QQ776514862
 
 

回复

2万

帖子

74

TA的资源

管理员

8
 
michael88888888 发表于 2016-7-21 09:18
PIC 代理 提供技术支持哟

直接回复问题,帮助网友解决问题,就是最好的支持了。
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表