⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainrc5.c

📁 AVR_Meag8 RC5红外解码程序
💻 C
字号:
//ICC-AVR application builder : 2008-3-19 10:34:54
// Target : M8
// Crystal: 4.0000Mhz
// 作者:Daniel Zhou 
//www.CNCSE.com 
//fsclub@yeah.net
//欢迎修改传播,但请保留作者信息
//说明:用INT0和软延时实现RC5解码,没有使用定时器。忽略了RC5中的第3位控制位。
//USART只在调试使用,正常使用时请注销以节省空间和时间。
//感谢USART.H的作者123_zh。
//fuse bit: 外部晶振4M,记得关闭看门狗。
//LOW bit: EF HIGH bit:D9

#include <iom8v.h>
#include <macros.h>
#include <usart.h>
#define delay_1bit() delay_qbit();delay_qbit();delay_qbit();delay_qbit();
//#define delay_1us() asm("nop");asm("nop");asm("nop");asm("nop");
#define xtal 4
unsigned int IR_OK=0,flag=0;
unsigned int IR_code=0;
unsigned int Lock_temp=0;//未使用

//延时1毫秒
void delay_1ms(void)
{unsigned int i;
 for(i=1;i<(unsigned int)(xtal*143-2);i++);
}

//延时1/4位,时间约420毫秒,改晶振的话必须改上面的预定义XTAL。
//有的文件说如果发射器455KHZ晶振,1位的时间是1.778毫秒,有的说是1.668毫秒,不清楚。
void delay_qbit(void)
{unsigned int i;
 for(i=1;i<(unsigned int)(xtal*60-2);i++);
}

//延时N毫秒
void delay_nms(unsigned int n)
{
  unsigned int i=0;
  for (i=0;i<n;i++)
      delay_1ms();
}
///****
void delay_2us(void)
{
asm("nop");
}
//***/
//延时N微秒	
void delay_nus(unsigned int n)//未使用
{
unsigned int i=0;
unsigned int m=n/2;
for (i=0;i<m;i++)
delay_2us(); 
}

//端口初始化
void port_init(void)
{
 PORTB = 0x00;
 DDRB  = 0x7f; //PB口全部作输出
 PORTC = 0x00; //m103 output only
 DDRC  = 0x7F; //PC口全部作输出
 PORTD = 0x00;
 DDRD  = 0x18; //PD3,PD4作输出
}

//TIMER0 initialize - prescale:8
// desired value: 2250Hz
// actual value: 2252.252Hz (0.1%)
void timer0_init(void)
{
 TCCR0 = 0x00; //stop
 TCNT0 = 0x22; //set count
 //TCCR0 = 0x02; //start timer
}

//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
/**********************
void uart0_init(void)
{
 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC = BIT(URSEL) | 0x06;
 UBRRL = 0x19; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x18;
}
*********************/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
 //external interupt on INT0
 CLI();
 
 //延时0.75位后测PD2是否有高电平
 delay_qbit();
 delay_qbit();
 delay_qbit();


 if((PIND&0b00000100)==0b00000100)
  { //延时半位测PD2是否变高
     delay_qbit();
	 delay_qbit();
	
//延时半位测PD2是否变低,即起始位第二位是否正常
    if((PIND&0b00000100)==0b00000000)
    {
	IR_code=0;

	// 控制码1位
    delay_1bit();
	//控制位没有使用,因为发现遥控器按下时这位不确定,没有价值
	//IR_code=IR_code+((PIND&0b00000100)==0b00000100);
	//接下来控制码5位
    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	//IR_CODE*2其实就是左移一位,再与PIND2引脚上的值相加,得到这一位的数据码,
	//个人觉得用2进制表示好理解,其实就是(PIND&0x04)==0x04
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	//接下来是数据码6位
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	    delay_1bit();
	IR_code=IR_code*2+((PIND&0b00000100)==0b00000100);
	
	IR_OK=1;       //红外正确接收标志
	IR_code^=0xff; //因为红外接收头为反相电平,故得到的红外码是反码,故对其反相得到真正的红外码
	}
	else{};
  }
  else{};
 SEI();
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer0_init();//未使用
 TEST_USART_init();//测试时使用USART

 MCUCR = 0x02;
 GICR  = 0x40;
 TIMSK = 0x00; //timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

void main(void)
{init_devices();
 while(1)
 {

//调试时在USART输出得到的红外码
if(IR_OK=1)
{
	    printf("IR_code:%u",IR_code);
	    printf("\r\n\r\n"); 
		printf("IR_OK:%u",IR_OK);
	    printf("\r\n\r\n"); 
}

//PORTB 用作锁存输出,当收到对应红外信号时,对其进行翻转	
		if(IR_code==1793)//键1对应PB0
		{PORTB^=0b00000001;}
		if(IR_code==1794)//键2对应PB1
		{PORTB^=0b00000010;}
		if(IR_code==1795)//键3对应PB2
		{PORTB^=0b00000100;}
		if(IR_code==1796)//键4对应PB3
		{PORTB^=0b00001000;}
		if(IR_code==1797)//键5对应PB4
		{PORTB^=0b00010000;}
		if(IR_code==1798)//键6对应PB5
		{PORTB^=0b00100000;}
		if(IR_code==1804)//键开关机对应PD3
		{PORTD^=0b00001000;}
		if(IR_code==1805)//键静音对应PD4
		{PORTD^=0b00010000;}
		
//PORTC 用作非锁存输出,当收到对应红外信号时,对其进行置位,否则最后清零。	

//因为要控制H桥,不能同时驱动H两臂,否则会烧管。所以先把两臂清零再置位。	
		if(IR_code==1808)   //PC0和PC1对应音量+和音量-
		{PORTC&=0b11111100;
		 PORTC|=0b00000001;
		}
		else 
		if(IR_code==1809)
		{ PORTC&=0b11111100;
		  PORTC|=0b00000010;
		}
		
		if(IR_code==1824)   //PC2和PC3对应节目+和节目-
		{PORTC&=0b11110011;
		 PORTC|=0b00000100;
		}
		else 
		if(IR_code==1825)
		{ PORTC&=0b11110011;
		  PORTC|=0b00001000;
		}
		if(IR_code==1835)   //PC4和PC5对应微调+和微调-
		{PORTC&=0b11001111;
		 PORTC|=0b00010000;
		}
		else 
		if(IR_code==1836)
		{ PORTC&=0b11001111;
		  PORTC|=0b00100000;
		}
	
//若没收到非锁存相关信号,则把C口清零。
		else if(IR_code==0)
		{PORTC&=0b00000000;}
		
		
		IR_code=0;
		IR_OK=0;
		delay_nms(50);

 }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -