初级会员
- 积分
- 89
- 金钱
- 89
- 注册时间
- 2017-7-9
- 在线时间
- 14 小时
|
3金钱
我delay延时了10秒,10秒内触发串口中断没问题,但10秒内触发外部中断,就不行了,无论之后怎么触发外部中断都没反应,但串口接收还可以,请问这是为什么呢?有解决办法吗?不胜感激!
//有人进门发送协议:ff ff 01 fc fc
//设防接受协议:ff 0a 01 fc fc
//取消设防协议:ff 0a 00 fc fc
#define MAIN_Fosc 11059200L //定义主时钟
#include "15W4KxxS4.H"
#define uint unsigned int
#define uchar unsigned char
//#define BAUD 9600 // 波特率
#define BAUD 2400 // 波特率
//串口初始化相关
#define S3_S 0x02
//串口中断相关
bit busy;
uchar temp1; //接收缓冲区
uchar mode[5]; //接收指令存放区
uchar uart3_rflage;
#define S3RI 0x01
#define S3TI 0x02
//发送指令
uchar youren[5]={0xff,0xff,0x01,0xfc,0xfc}; //有人指令
uchar num=0; //串口数据长度,数组位
/**********************
引脚别名定义
***********************/
sbit rs485_dr=P3^5; //使能控制485收发芯片使能引脚
sbit led6=P0^6; //蓝色LED用IO口P06
sbit led7=P0^7; //红色LED用IO口P07
sbit beep=P0^3; //BEEP
sbit red=P0^2; //red light
sbit green=P0^4; //green light
bit HW1,HW2; //红外1和2的标志
bit sf=0; //1为设防,0为不设防
bit sf_mode; //接收完一帧指令后的标志
/**************************************
功能描述:外部中断服务程序
入口参数:无
返回值:无
***************************************/
void delay_ms(uint x)
{
uint j,i;
for(j=0;j<x;j++)
{
for(i=0;i<1100;i++);
}
}
void WAI_INIT(void)
{
//外部中断0的初始化配置
IE0 = 0; //将INT0中断请求标志位清"0"
EX0 = 1; //使能INT0中断允许位
IT0 = 1; //选择INT0为下降沿触发方式
EA = 1; //允许总中断
//外部中断1的初始化配置
IE1 = 0; //将INT1中断请求标志位清"0"
EX1 = 1; //使能INT1中断允许位
IT1 = 1; //选择INT1为下降沿触发方式
EA = 1; //允许总中断
}
void INT0_int (void) interrupt INT0_VECTOR
{
HW1=1;
}
void INT1_int (void) interrupt INT1_VECTOR
{
HW2=1;
}
/***************************************************************************
* 描 述 : 串口3初始化函数
* 入 参 : 无
* 返回值 : 无
**************************************************************************/
void Uart3_Init(void)
{
P_SW2|=S3_S;//串口3引脚p00,p01映射到引脚p50,p51
S3CON=0x50; //8位UART T3作为波特率发生器 运行串口3接收数据
T3H=(65536-(MAIN_Fosc/12/4/BAUD))/256; //初值
T3L=(65536-(MAIN_Fosc/12/4/BAUD))%256;
T4T3M = 0x08; //允许定时器3运行
IE2 |= 0x08; // 串口3中断打开
EA=1; //总中断打开
}
/***************************************************************************
* 描 述 : 串口3中断服务函数
* 入 参 : 无
* 返回值 : 无
**************************************************************************/
void Uart3() interrupt 17
{
IE2 &= 0xF7; // 串口3中断关闭
if(S3CON & S3RI) //如果接收完
{
S3CON &= ~S3RI; //接收中断标志清0
temp1 = S3BUF; //数据缓存
uart3_rflage = 1; //串口接收标识符置1
mode[num]=temp1; //加上这一条,接收数据后,返回的数据变长了,
temp1=0;
if(mode[0]==0xff) //如果包头为0xff,则继续接收
{
if(num==4)
{
led6=~led6;
sf_mode=1; //接受完一帧的数据标志
num=0; //清楚接收的数组位
}
else num++;
}
else mode[0]=0; //如果包头不为0xff,清掉,此时数据变为00 0a 00(或01) fc fc
}
if(S3CON & S3TI) //如果发送完
{
T3H=(65536-(MAIN_Fosc/12/4/BAUD))/256;
T3L=(65536-(MAIN_Fosc/12/4/BAUD))%256;
S3CON &= ~S3TI; //发送中断标志清0
busy=0; //发送完,就不busy了
}
IE2 |= 0x08; // 串口3中断打开
}
//串口发送函数
void SendDataByUart3(uchar dat)
{
while(busy); //不busy就可以发送下一个了
ACC=dat;
busy=1; //准备要发送了,先告诉别人我在忙
S3BUF=ACC;
}
void SendStringByUart3(char *s)
{
uchar i=5;
// while(*s) //指针指向地方有多少个字节发多少个
while(i--) //只允许发5个字节
{
SendDataByUart3(*s++); //单个字节发送
}
}
//void jiaoyan() //接受数据校验
//{
// uchar i;
// if((mode[0]!=0xff)&&(mode[4]!=0xfc))
// {
// num=0;
// for(i=0;i<5;i++)
// {
// mode[i]=0;
// }
// }
//}
int setmode() //设防模式选择
{
if(sf_mode=1)
{
sf_mode=0;
switch(mode[2])
{
case 0x01:return 1; //遇到return立即结束当前函数,所以不用break;设防,返回1
case 0x00:return 0; //不设防,返回0
}
}
else return 0; //没接收有效指令,返回0
}
/***********************
功能描述:主函数
入口参数:无
返回值:无
************************/
int main()
{
/////////////////////////////////////////////////
//注意: STC15W4K32S4系列的芯片,上电后所有与PWM相关的IO口均为
// 高阻态,需将这些口设置为准双向口或强推挽模式方可正常使用
//相关IO: P0.6/P0.7/P1.6/P1.7/P2.1/P2.2
// P2.3/P2.7/P3.7/P4.2/P4.4/P4.5
/////////////////////////////////////////////////
// P0M1 &= 0x3F; P0M0 &= 0x3F; //设置P0.6、P07为准双向口(led灯,测试用)
P0M1 &= 0x23; P0M0 &= 0x23; //设置P0.6、P07为准双向口(led灯,测试用),P0.2、P03 、P04为准双向口(继电器用)
P3M1 = 0; P3M0 = 0; //设置P3.0~P3.7为准双向口
P5M1 = 0; P5M0 = 0; //设置P5.0~P5.7为准双向口
rs485_dr=0; //控制485接收
WAI_INIT(); //外部中断初始化
Uart3_Init(); //串口初始化
while (1)
{
if(HW1==1&&HW2==0) //进门
{
delay_ms(180);
if(HW1==1&&HW2==1)
{
HW1=0; //外部中断标志1清零
HW2=0; // 外部中断标志1清零
rs485_dr=1; //控制485发送
SendStringByUart3(youren);//发送指令
SendStringByUart3(mode);//发送指令
delay_ms(5); //缓冲,延时等485发送完(必须加,因为485发送停止位只发到一半,延时等发完另一半)
rs485_dr=0; //控制485接收
led7=~led7;
if(setmode()) //如果是设防模式,setmode()=1;则开启警报灯蜂鸣器并延时3秒
{
EX0=0; //关闭外部中断0
EX1=0; //关闭外部中断1
red=0;
green=0;
beep=0;
delay_ms(10000);
EX0=1; //打开外部中断0
EX1=1; //打开外部中断0
red=1;
green=1;
beep=1;
}
}
}
else if(HW1==0&&HW2==1) //出门
{
HW2=0; //出门,被首先触发的外部中断2清零
delay_ms(350);//触发外部中断2的路人(出门)必须在该延时内触发外部中断1
HW1=0; //若上面延时内被人触发外部中断1,清掉外部中断0内的标志
}
}
}
|
|