?? lyj-v1.0.c
字號:
//ICC-AVR application builder : 2005-4-14 21:26:27
// Target : 電動晾衣架 DC電機+紅外
// Crystal: 8Mhz
/*紅外解碼的方法 NEC格式 upd6121
1、9Ms的高電平啟動頭,然后是4.5Ms的低電平,如果2.25Ms時就有高電平,是持續(xù)信號,不處理
2、然后以一個高電平和一個低電平為1Bit,高電平時間是0.5625Ms=562us,
高低電平時間比為1:1時是Bit1,比為1:3時是Bit0
4、共讀入4Byte共24bit,第12Byte是CustomCode碼和其反碼,第34Byte是DataCode和其反碼
5、CustomCode正確和DataCode效驗正確的話,執(zhí)行
接收器輸出是反相的
100us采樣周期,9Ms=90,4.5Ms=45,高電平=5,低電平最多15
*/
#include <eeprom.h>
#include "config.h"
#include <string.h>
#define VERSION 10
#define CT1H 0x94;//CA01=10ms 最小應(yīng)答間隔
#define CT1L 0x01;//BF34=12ms AF01=15ms 9401=20ms
#define T0N 10
#define LEDON CLR(PORTB,LED);
#define LEDOFF SET(PORTB,LED);
#define CSTOP 1
#define CUP 2
#define CDOWN 3
#define CLAMP 4
#define CDIS 5
//紅外命令按鍵碼
#define IRSTOP 10
#define IRUP 11
#define IRDOWN 7
#define IRLAMP 2
#define IRDIS 14
bit b20ms,bTimer,bCmdOk,bIrCmdOk;
uchar T0Cnt,iCmd;
uchar iPreBit,iHight,iLow,iIrMode;
uchar iBitCount,iIrData[4];
void DelayMs(char);
void DelayUs(uint);
void PortInit(void)
{
PORTB = 0xFD;
DDRB = 0x02;
PORTC = 0x00; //m103 output only
DDRC = 0x7F;
PORTD = 0x9F;
DDRD = 0x60;
}
//Watchdog initialize
// prescale: 2048K
void WdtInit(void)
{
WDR();
WDTCR=(1<<WDTOE)|(1<<WDE);//!!注意:M8的WDT修改要先WDTOE,WDE=1 P42
WDTCR=(1<<WDE)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0);//2.2s
}
void Timer0Init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x64; //set count
TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler Timer0:10
void Timer0(void)
{
TCNT0 = 0x64; //reload counter value 20ms
b20ms=1;
if (--T0Cnt==0)
{T0Cnt=T0N;
bTimer=1;
}
CheckStop();
}
//TIMER1 initialize - prescale:8
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 100uSec
// actual value: 100.000uSec (0.0%)
void Timer1Init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xFF; //setup
TCNT1L = 0x9C;
OCR1AH = 0x00;
OCR1AL = 0x64;
OCR1BH = 0x00;
OCR1BL = 0x64;
ICR1H = 0x00;
ICR1L = 0x64;
TCCR1A = 0x00;
TCCR1B = 0x02; //start Timer
}
#pragma interrupt_handler Timer1:9
void Timer1(void)
{
//TIMER1 has overflowed
TCNT1H = 0xFF; //reload counter high value
TCNT1L = 0x9C; //reload counter low value
CheckIR();//紅外解碼
}
//call this routine to initialize all peripherals
void IoInit(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
PortInit();
WdtInit();
Timer0Init();
Timer1Init();
//ADCSR&=~BIT(ADEN);
MCUCR = 0x00;//int0 low level在掉電模式,低電平觸發(fā)才能喚醒,下跳沿不行
GICR = 0x00;//Int Mask,Int0 disable
TIMSK = 0x05; //timer interrupt Mask: Timer0,1 enable
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void WdtOn()
{
WDR();
WDTCR=0x0f;
}
void WdtOff()
{
CLI();//!!必須,WDTOE置位后必須4個時鐘內(nèi)清 WDE,才能真正關(guān)斷WDT
WDR();
WDTCR |=(BIT(WDTOE)|(BIT(WDE)));
//WDTCR&=~BIT(WDE);//0;//off
WDTCR=0x07;
SEI();
}
void PwrIdle()
{//P30 MCUCR 休眠控制和INT0,1,
MCUCR&=0x0f;
MCUCR |=BIT(SE);
asm("sleep");
}
void PwrDown()
{
MCUCR&=0x0f;
MCUCR |=0x60;//0x60掉電 0x70省電
asm("sleep");
}
//測試紅外輸出
//無信號時有小許干擾輸出,遙控器保持按鍵時有持續(xù)輸出
void TestIR()
{
if ((PIND&(1<<IR))!=0)
{BeepOff();}
else
{BeepOn();}
}
void main(void)
{
IoInit();
SystemIni();
Beep();
while (1)
{
if (bTimer) TimerFunc();
//TestIR();
if (bIrCmdOk) CheckIrCmd();
if (bCmdOk) ReadCmd();
};
}
void ReadCmd()
{
bCmdOk=0;
//Beep();
switch (iCmd)
{
case CSTOP:
MotorStop();
BeepN(2);
break;
case CUP:
MotorUp();
BeepN(1);
break;
case CDOWN:
MotorDown();
BeepN(1);
break;
case CLAMP:
if ((PORTC&(1<<LAMP))==0)
{ LampOn();
BeepN(1);
}
else
{ LampOff();
BeepN(2);
}
break;
case CDIS:
if ((PORTC&(1<<DIS))==0)
{ DisOn();
BeepN(1);
}
else
{ DisOff();
BeepN(2);
}
break;
}
}
//紅外解碼
void CheckIR()
{uchar iNowBit,iPos;
if ((PIND&(1<<IR))>0) iNowBit=0;else iNowBit=1;//先反相
//把信號持續(xù)的處理作為公共處理
if ((iPreBit==1)&&(iNowBit==1))//hight++
{ iHight++;
return;
}
if ((iPreBit==0)&&(iNowBit==0))//low++
{ iLow++;
return;
}
switch (iIrMode)
{
case 0://等待9ms的高電平
if ((iPreBit==0)&&(iNowBit==1))//0->1:start
{ iPreBit=1;
iHight=1;
return;
}
if ((iPreBit==1)&&(iNowBit==0))//1->0
{ iPreBit=0;
if (iHight>85)//9.0ms
{ iIrMode=1;
iLow=1;
iHight=0;
//bCmdOk=1;iCmd=10;//Test..
}
else
{iHight=0;//reset
}
return;
}
break;
case 1://等待4.5ms的低電平
if ((iPreBit==0)&&(iNowBit==1))//0->1
{ iPreBit=1;
if (iLow>40)//4.5ms
{ iIrMode=2;
iBitCount=0;
iIrData[0]=0;iIrData[1]=0;iIrData[2]=0;iIrData[3]=0;
iHight=1;
//bCmdOk=1;iCmd=10;//Test..
}
else
{ iIrMode=0;
//確實只發(fā)送一次,后面的是按鍵保持信號,無按鍵碼信息
}
return;
}
break;
case 2://接收用戶碼和按鍵碼,共32Bit
if ((iPreBit==1)&&(iNowBit==0))//1->0
{ iPreBit=0;
iLow=1;
}
if ((iPreBit==0)&&(iNowBit==1))//0->1
{ iPreBit=1;
//已經(jīng)接收1Bit,根據(jù)占空比判斷01
if (iLow>(iHight+iHight)) iNowBit=0;else iNowBit=1;
//Bit0在前,右移位
iPos=iBitCount/8;
iIrData[iPos]=iIrData[iPos]>>1;
if (iNowBit==1) iIrData[iPos]|=0x80;
iBitCount++;
if (iBitCount>=32)
{ bIrCmdOk=1;
iIrMode=0;
//bCmdOk=1;iCmd=10;//Test..
}
iHight=1;//must!
}
break;
default:
iIrMode=0;
break;
}
}
//對紅外命令判斷操作
void CheckIrCmd()
{uchar i;
bIrCmdOk=0;
if (iIrData[0]!=(~iIrData[1]))
{ return;//custom碼就不對
}
if (iIrData[2]!=(~iIrData[3])) return;//按鍵碼不對
i=iIrData[2]&0x0f;
//BeepN(i&0x0f);
switch (i)
{ case IRSTOP:
bCmdOk=1;iCmd=CSTOP;
break;
case IRUP:
bCmdOk=1;iCmd=CUP;
break;
case IRDOWN:
bCmdOk=1;iCmd=CDOWN;
break;
case IRLAMP:
bCmdOk=1;iCmd=CLAMP;
break;
case IRDIS:
bCmdOk=1;iCmd=CDIS;
break;
}
}
void CheckStop()
{
if (((PIND&(1<<UPX))==0) || ((PIND&(1<<DWNX))==0))
{ MotorStop();
BeepN(2);
}
}
void TimerFunc()
{
bTimer=0;
CPL(PORTB,LED);
//CPL(PORTC,BEEP);
//CPL(PORTC,LAMP);
//CPL(PORTD,DOWN);
WDR();//clear WDT
}
void MotorUp()
{
CLR(PORTD,UP);
SET(PORTD,DOWN);
}
void MotorDown()
{
SET(PORTD,UP);
CLR(PORTD,DOWN);
}
void MotorStop()
{
CLR(PORTD,UP);
CLR(PORTD,DOWN);
}
void LampOn()
{
SET(PORTC,LAMP);
}
void LampOff()
{
CLR(PORTC,LAMP);
}
void LampOnOff()
{
CPL(PORTC,LAMP);
}
void DisOn()
{
SET(PORTC,DIS);
}
void DisOff()
{
CLR(PORTC,DIS);
}
void DisOnOff()
{
CPL(PORTC,DIS);
}
void BeepOn()
{
SET(PORTC,BEEP);
}
void BeepOff()
{
CLR(PORTC,BEEP);
}
void Beep()
{
SET(PORTC,BEEP);
DelayMs(100);
CLR(PORTC,BEEP);
}
void BeepN(uchar n)
{uchar i;
for (i=0;i<n;i++)
{ Beep();
WDR();
DelayMs(100);
}
}
void ReadSN()
{ char Buf[8],i;
EEPROMReadBytes( 0x20, Buf,8 );
}
void WriteSN()
{char Buf[8],i;
EEPROMWriteBytes(0x20, Buf, 8);
}
void SystemIni(void)
{
ReadSN();
T0Cnt=T0N;
}
void DelayMs(char ms)
{char i;
for (i=0;i<ms;i++)
{DelayUs(1000);
}
return;
}
void DelayUs(uint us)
{uint i;
for (i=0;i<us;i++)
{NOP();NOP();NOP();NOP();
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -