?? 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 + -