基于AVR单片机的红外接收程序设计
2020-04-04 来源:elecfans
使用一体化的红外接收头,直接就解码出来了,平时红外接收头输出的是高电平,当有红外数据的时候,就会根据发送的红外数据有相应的电平转换。大家可以随便找个遥控板,测一下红外接收波形,看看高低电平的表示,便于计数及接收步骤。这次用的遥控板的红外协议是这样的:
0.6ms高电平+0.48ms低电平表示0,接收解码出来是0.6ms低电平+0.48ms高电平。
0.6ms高电平+1.66ms低电平表示1,接收解码出来是0.6ms低电平+1.66ms高电平。
调制38kHz,占空比1/3.
遥控发送数据先是9ms高电平,4.5ms低电平,然后是两个字节的识别码,接着是一个字节的数据和一个字节的数据反码。
单片机解码0和1只用计数接收到的低电平长度就行了。
具体的程序如下:
//interrp.c
#include
#include “interrp.h”
void Interrp_int0_init(void)
{
SREG=0X80;
GICR|=(1《MCUCR=0X00;//0X00低电平中断;0x01:电平变化中断;
//0x02:下降沿;0x03:上升沿;
}
void Interrp_int1_init(void)
{
SREG=0X80;
GICR|=(1《MCUCR=0X08;//0X00低电平中断;0x04:电平变化中断;
//0x08:下降沿;0x0c:上升沿;
}
void Interrp_int0_stop(void)
{
GICR&=~(1《}
void Interrp_int1_stop(void)
{
GICR&=~(1《}
//main.c
#include
#include “mytype.h”
#include “uart.h”
#include “interrp.h”
#include “timer.h”
#define IR 2
#define PIN4 PIND
#define DDR4 DDRD
#define in_IR (PIN4&(1《
uint8 code_0,code_1,data_0,data_1;
uint8 table[16]={“0123456789abcdef”};
#pragma interrupt_handler IR_init:2
void IR_init(void)
{uint8 i;
Interrp_int0_stop();//关中断。
i=Data_dec();//红外数据检测。
if(i==0)
{
Send_abyte(table[TCNT1/4096]);
Send_abyte(table[TCNT1%4096/256]);
Send_abyte(table[TCNT1%256/16]);
Send_abyte(table[TCNT1%16]);
Prints(“Error”,1);
}
code_0=0;
code_1=0;
data_0=0;
data_1=0;
DelayXms(100);
Interrp_int0_init();
}
uint8 Data_dec(void)
{
uint8 i;
while(in_IR==0);//等待红外输入变高。
TImer1_init();//定时器计数开始。
while(in_IR);//等待红外输入变低。
TImer1_stop();//定时计数停止。
if((TCNT1《26980)|(TCNT1》34980))
return 0; //4.5ms红外起始接受检测,不对返回0.
for(i=0;i《8;i++)
{
while(in_IR==0);//等待红外输入高。
TImer1_init();//定时计数开始。
while(in_IR);//等待红外输入变低。
TImer1_stop();//定时计数停止。
/*Send_abyte(table[TCNT1/4096]);
Send_abyte(table[TCNT1%4096/256]);
Send_abyte(table[TCNT1%256/16]);
Send_abyte(table[TCNT1%16]);
Send_abyte(‘ ’);*/
if((TCNT1《4400)&&(TCNT1》3400))
;
else
code_0=(code_0+(1《} //地址码接受;
for(i=0;i《8;i++)
{
while(in_IR==0);
Timer1_init();
while(in_IR);
Timer1_stop();
if((TCNT1《4400)&&(TCNT1》3400))
;
else
code_1=(code_1+(1《} //地址码接受;
for(i=0;i《8;i++)
{
while(in_IR==0);
Timer1_init();
while(in_IR);
Timer1_stop();
if((TCNT1《4400)&&(TCNT1》3400))
;
else
data_0=(data_0+(1《} //数据码接受;
for(i=0;i《8;i++)
{
while(in_IR==0);
Timer1_init();
while(in_IR);
Timer1_stop();
if((TCNT1《4400)&&(TCNT1》3400))
;
else
data_1=(data_1+(1《} //数据反码接受;
Data_process();
}
void Data_process(void)//发送接受数据到串口。
{
Send_abyte(table[code_0/16]);
Send_abyte(table[code_0%16]);
Send_abyte(‘ ’);
Send_abyte(table[code_1/16]);
Send_abyte(table[code_1%16]);
Send_abyte(‘ ’);
Send_abyte(table[data_0/16]);
Send_abyte(table[data_0%16]);
Send_abyte(‘ ’);
Send_abyte(table[data_1/16]);
Send_abyte(table[data_1%16]);
Send_abyte(10);
Send_abyte(13);
}
void main(void)
{
DDR4&=~(1《Uart_init();
Prints(“System init.。.”,1);
Interrp_int0_init();
while(1);
}
上一篇:AVR单片机的主要特性及应用解析
下一篇:AVR单片机的复位操作方法解析
- 基于 Microchip AVR DA MCU 的带加热 HoD 离手检测+触摸多功能方向盘方案
- Microchip推出AVR® DU系列USB单片机,支持增强型代码保护和高达15W 的 功率输出
- 贸泽电子开售面向工业和汽车应用的Microchip Technology AVR64EA 8位AVR MCU
- 天龙DENON AVR-1507功放机内部拆解
- AVR32 MCU上的ABDAC外设音频播放设计
- AVR基础知识:ATMEGA的SPI总线 - 第1部分
- AVR基础知识:ATMEGA的SPI总线 - 第2部分
- 使用AVR微控制器控制GSM模块实现发送和接收短信
- 如何使用USBASP烧写器和Atmel Studio 7.0对AVR微控制器进行编程
- 使用AVR微控制器Atmega16连接伺服电机的方法