专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
51单片机
关于使用AVR mega64的中断方式对PT2262解码的疑惑?
2019-07-15 07:40
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
5625
0
961
本人初次接触AVR,在使用MEGA64对无线编码器PT2262进行软件解码的时候,明明接收到字码了,但是解码时碰到几个问题,一是解码反应异常,按下遥控器的时候硬件有时反应有时不反应,有时没按下也出现反应。二是没法接收第二组字码,因为要保证安全性,项目要求接收到2组相同字码才进行处理,但是程序却总是跑不到!
单片机
晶振频率:4Mhz。
编码器震荡电阻:3.3M欧。
用示波器观察得到同步码起始高电平持续时间约为360us,低电平10500us.数据码“1”高电平持续为1ms,低电平持续为200us.“0”反之!
相关代码如下:(开发环境:IAR (iar for avr))
1.寄存器设置:
EICRA=0x0E; //INT0为下降沿触发 ,INT1为上升沿触发 //CAN中断下降沿触发比较好用,无线呼叫由上升沿触发
EICRB=0x00;
EIMSK=0x03; //外部中断INT0,外部中断1使能
复制代码
2.定时器中断为:
#pragma vector=
ti
MER3_OVF_vect //中断入口地址
__interrupt void timer3_ovf_isr(void)
{
#if defined(main_can) //主机用于对无线呼叫器的外来脉冲进行时长计数
TCNT3H=0xFF; //定时器值(100us)4M主时钟8分频后100us的定时初值
TCNT3L=0xCD;
if((PIND&0x02)==0x02) //如果引脚为高电平
Wireless_Rec.high_Counter++;
else if((PIND&0x02)==0) //引脚低电平
Wireless_Rec.low_Counter++;
if(Wireless_Rec.high_Counter>=240) //万一计数溢出情况下
{
Wireless_Rec.high_Counter=0;
}
else if(Wireless_Rec.low_Counter>=240)
{
Wireless_Rec.low_Counter=0;
}
#else //分机用于数码管显示
TCNT3H=Timer3ValueH; //定时器值
TCNT3L=Timer3ValueL;
Smg.Display(); //数码管显示
#endif
}
复制代码
3.中断服务函数:
// 外部中断1,设为无线呼叫接收中断
#pragma vector=INT1_vect //中断入口地址
__interrupt void ext_int1_isr(void)
{
#if defined(main_can) //主机
static unsigned char i=0;
static unsigned char status = 0; //接收状态
static char startflag=0; //开始储存脉宽标志位
if(startflag) //一开始有效时这是字码的第二个上升沿,这时计数得到的是同步码的电平脉宽。同理可得数据码!
{
switch(status)
{
case 0:
if( ((Wireless_Rec.high_Counter>2)&&(Wireless_Rec.high_Counter<5))&&((Wireless_Rec.low_Counter>80)&&(Wireless_Rec.low_Counter<120)))
{
Wireless_Rec.high_Counter=0;
status = 1; //接收到同步码(高低电平约为400和1100us)
}
else
{
Wireless_Rec.high_Counter=0; //高电平计数清零(每来一次上升沿清零一次)
Wireless_Rec.low_Counter=0; //低电平计数清零; //防止杂乱电波高电平触发外部中断的影响
// startflag = 0; //清计数,继续接收!(防止杂乱电波高电平触发外部中断的影响)
status = 0; //继续接收
}
break;
case 1:
Wireless_Rec.wireless_data[i] = Wireless_Rec.high_Counter; //储存高电平
Wireless_Rec.high_Counter=0;
i++;
if( i == 23 ) //已接受足够字节数(0-23,一共24 bit的数据)
{
Wireless_Rec.rec_flag = 1; //接收成功
status = 0; //回到初始接收状态
startflag=0; //清零开始标志位
i=0;
EIMSK=0x01; //屏蔽外部中断1
TASK_EN(JIEMA); //开启解码任务
}
break;
default: break;
}
}
else //接收码的第一个上升沿作为开始接收脉宽检测的启动标志
{
Wireless_Rec.high_Counter=0; //高电平计数清零(每来一次上升沿清零一次)
Wireless_Rec.low_Counter=0; //低电平计数清零
startflag = 1; //开始处理标志位置1
}
#else //从机
#endif
}
复制代码
4.解码函数:
//PT2262解码
void data_decode(void) //无线数据解码
{
unsigned char i,cord;
unsigned long value;
unsigned long lastvalue=0x00201314; //设置比较值
if(Wireless_Rec.rec_flag) //接收完毕
{
// Relay2_closure; //测试用,有反应,但是不灵敏。
for(i=0;i<24;i++)
{
cord=Wireless_Rec.wireless_data[i];
if(cord>8) value|=0x00800000; //脉宽大于100us*8=800us,加上堆栈出栈时间,能够大于这个时间说明是逻辑电平“1”。
value>>=1;
}
if(i>=24)
{
if(value==lastvalue) //确保接收到2次同样的字码
{
// Relay1_closure; //继电器闭合(test) 程序跑不到这里
Wireless_Rec.Success=1; //接收成功
PT2262Code=value; //保存最新数据,解码成功
Wireless_Rec.rec_flag=0; //清除接收成功标志位
}
else
{
Relay1_closure; //继电器闭合(test) //有反应,但是不灵敏
lastvalue=value; //否则保存最新的一组数据,继续解码
Wireless_Rec.rec_flag=0; //清除标志位,继续接收
EIFR=(1<<INTF1); //在重新使能外部中断1之前要先清标志位
EIMSK=0x03; //重新开启外部中断1屏蔽位,继续接收下一组字码。
}
}
}
if(Wireless_Rec.Success)
{
// deal_data( ); //转到函数处理
}
else
{
Wireless_Rec.rec_flag=0; //清除标志位,继续接收
EIFR=(1<<INTF1); //在重新使能外部中断1之前要先清标志位
EIMSK=0x03; //打开屏蔽位,继续接收下一组字码。
}
TASK_DISEN(JIEMA); //关闭自己
}
复制代码
因为接收都无法得到两次相同的字码,所以一直都没法转到处理函数。但我觉得程序没问题了呀,为什么效果总是不理想?(本人编程水平不怎样,万望海涵)
发送
看不清?
0条回答
一周热门
更多
>
相关问题
【东软载波ESF0654 PDS开发板活动】开箱
1 个回答
东软载波ESF0654 PDS开发板外部中断
1 个回答
东软载波ESF0654 PDS开发板高级控制定时器AD16C4T
1 个回答
用串口调试助手为什么只能在hex模式接收发送而在文本模式不行
9 个回答
触摸芯片SC02B/SC04B在地砖灯的设计方案
1 个回答
东软载波ESF0654 PDS开发板串口USART0代码分享
1 个回答
普通32位单片机使用linux的应用代码
5 个回答
东软载波ESF0654 PDS开发板AT24C04的调试
9 个回答
相关文章
51单片机与蓝牙模块连接
0个评论
51单片机的硬件结构
0个评论
基于51单片机的无线遥控器制作
0个评论
51单片机 AD转换
0个评论
51单片机数码管递增显示
0个评论
如何实现对单片机寄存器的访问
0个评论
基于51单片机的指纹密码锁
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
51单片机
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
一周热门 更多>