📄 mainrc5.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 + -