PIC16f1937电平变化中断的问题
时间:10-02
整理:3721RD
点击:
我使用了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;
}
}
}
}
现在的问题是:当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;
}
}
}
}
路过
除了程序问题,也要考虑你的电路设计是否合适,你要控制的继电器要控制220v电压,那就要考虑驱动这个继电器的电路是否能正确的驱动这个继电器了 。
谢谢,小编提供的场地。
MICROCHIP 原装正品,另有可替换单片机(无需修改PCB资料,程序可共用PIC的) 有用到的兄弟多多支持! 电话13430885511(微信同号),QQ2355910801