📄 irremote._c
字号:
/*
Title: icc-avr irremote
Author: dushibiao
Date: 2007 10 19
Purpose: control your pc use a ir remoter
Frequency: internal 8M
needed
Software: icc-avr to compile
needed
Hardware: AVR mega16 BOARD
Connect: dushibiao@126.com
*/
#include <iom16v.h>
#include <macros.h>
#include "shumaguan.h"
#define IR 2 //PB2,irfrade receive line
#define PIN_RXD 0 //PD0 RXD
#define PIN_TXD 1 //PD1 TXD
#define BAUDRATE 9600 //baudrate
#define F_CPU 8000000 //the frequency of the global clock
volatile unsigned char flag,code;
void delay0_9ms(void)
{
delay_nus(510);
}
//4.5ms
void delay4_5ms(void)
{
delay_nms(4);
delay_nus(320);
}
/*---------------------------------------------------------------------------
function send an unsigned char to the uart
----------------------------------------------------------------------------*/
void put_c(unsigned char c) //发送采用查询方式
{
while( !(UCSRA & (1<<UDRE)) ); //wait until the uart is empty
UDR=c; //write data to uart
}
/*---------------------------------------------------------------------------
fuction initialize the uart unit
----------------------------------------------------------------------------*/
void init_USART(void)//USART 初始化
{
//USART 9600 8, n,1 PC上位机软件(超级终端等)也要设成同样的设置才能通讯
UCSRC = (1<<URSEL) | 0x06;
//异步,8位数据,无奇偶校验,一个停止位,无倍速
/*
UBRRH与UCSRC共用I/O 地址。因此访问该地址时需注意以下问题。
写访问
当在该地址执行写访问时, USART 寄存器选择位(URSEL)控制被写入的寄存器。
若URSEL为0,对UBRRH值更新;若URSEL为1,对UCSRC设置更新
读访问
对UBRRH 或UCSRC 寄存器的读访问则较为复杂。但在大多数应用中,基本不需要读这些寄存器
没有UBRR这个16位寄存器,因为UBRRL(0x09)/UBRRH(0x20)的地址不连续,而且UBRRH跟UCSRC共用地址
*/
//U2X=0时的公式计算
UBRRL= (F_CPU/BAUDRATE/16-1)%256;
UBRRH= (F_CPU/BAUDRATE/16-1)/256;
//U2X=1时的公式计算
//UBRRL= (F_CPU/BAUDRATE/8-1)%256;
//UBRRH= (F_CPU/BAUDRATE/8-1)/256;
//也可根据数据手册的[波特率设置的例子]查得
//UBRRL = 0x2F; //set baud rate lo
//UBRRH = 0x00; //set baud rate hi
UCSRA = 0x00; //无倍速
UCSRB = (1<<RXEN)|(1<<TXEN);
//使能接收,使能发送
}
void main(void)
{
PORTA=0XFF;
DDRA=0XFF; //OUT
PORTB=0XFF;
DDRB=0X03; //PB0,PB1 OUT
PORTC=0XFF;
DDRD =(1<<PIN_TXD); //TXD为输出
init_USART();
MCUCSR &=~(1<<ISC2); //falling edge interrupt
GIFR=(1<<INTF2); //写1清除标志位,在使能中断前最好先把对应的标志位清除,以免误触发
GICR=(1<<INT2); //使能INT2外部中断
SEI(); //使能全局中断
flag=0;
while(1)
{
if(flag==1)
{
display(code);
}
else
{
displayerror();
}
}
}
/**********************************************************************
function: ext2 interrupt service function
**********************************************************************/
#pragma interrupt_handler int2pro: iv_INT2
void int2pro(void) //INT2中断服务程序
{
unsigned char i,j,k,dm=0,aa[2];
for(k=0;k<10;k++) //重复10次,目的是检测在9毫秒内如果出现高电平就退出解码程序
{ //aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
delay0_9ms(); //延时0.9毫秒
if ((PINB&(1<<IR))==(1<<IR))
{k=10;break;} //延时0.9毫秒后判断PB2脚是否出现高电平如果有就退出解码程序
else if(k==9) //重复10次?
{ //bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
while((PINB&(1<<IR))==0); //等待高电平避开9毫秒低电平引导脉冲
delay4_5ms(); //延时4.5毫秒避开4.5毫秒的结果码
/********************************************
//26位的用户码,前13位数据码,后13位数据反码
*********************************************/
for(j=1;j<=26;j++)//每组数据为26位
{
while((PINB&(1<<IR))==0); //
delay0_9ms();
if((PINB&(1<<IR))==(1<<IR))
{
delay_nms(1);
}
/***************************************************
//16位的用户码,前8位数据码,后8位数据反码
****************************************************/
for(i=0;i<2;i++)
{
for(j=1;j<=8;j++)//每组数据为8位
{
while((PINB&(1<<IR))==0); //
delay0_9ms();
if((PINB&(1<<IR))==(1<<IR))
{
delay_nms(1);
dm=dm|0x80;
if(j<8) dm=dm>>1; //数据"1",右移一个"1",一共7次
}
else if(j<8) dm=dm>>1; //数据"0",一共7次
}
aa[i]=dm;
dm=0;
}
if(aa[0]=~aa[1])
{
code=aa[0];
flag=1;
put_c(code);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -