?? main.c
字號:
/******************************************
電風扇遙控主程序 V1.0 2006/08/8
作者: 王冠明
目標MCU:MEGA8 外部晶振:4M
編譯:ICCAVR6.13A
1.RC5碼解碼
2.自然風產生
3.獲得同步后,每1/2周期檢測,讀取到的電平就是數據了---反相 0就是1,1就是0。
******************************************/
#include <iom8v.h>
#include <macros.h>
#include <stdlib.h>
#include "TEST_USART.h"
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
typedef signed char int8;
typedef signed int int16;
typedef signed long int32;
#define BIT_SET(a,b) a|=BIT(b)
#define BIT_CLR(a,b) a&=~BIT(b)
#define BIT_INV(a,b) a^=BIT(b)
#define BIT_STATUS(a,b) a&BIT(b)
#define BUZZER_ON() PORTD&=~BIT(PD4)
#define BUZZER_OFF() PORTD|=BIT(PD4)
#define SCR1_ON() PORTD&=~BIT(PD5)
#define SCR1_OFF() PORTD|=BIT(PD5)
#define SCR2_ON() PORTD&=~BIT(PD6)
#define SCR2_OFF() PORTD|=BIT(PD6)
#define SCR3_ON() PORTD&=~BIT(PD7)
#define SCR3_OFF() PORTD|=BIT(PD7)
uint8 renovate;//顯示更新
uint8 LED;
uint8 KEY;
uint8 BUZZER_time;
uint8 estate;
uint8 timing;
uint16 IR_code_old;
uint16 IR_code_old_time;
uint8 nature_sign;//自然風
uint16 nature_time;
uint8 career;
uint16 LED_time;
uint16 nature2_time;
uint8 career2;
uint8 career2_ONOFF;
//系統初版始化
void intit(void)
{
//看門狗
WDR(); //喂狗
WDTCR=BIT(WDCE)|BIT(WDE);
WDTCR=BIT(WDE)|BIT(WDP2)|BIT(WDP1); //使能watchdog,1024K分頻,典型溢出時間5V時1S
DDRD|=BIT(PD7)|BIT(PD6)|BIT(PD5)|BIT(PD4);
PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5)|BIT(PD4);
PORTB|=BIT(PB0); //IR
DDRC|=BIT(PC2); //COM
//T2初始化 顯示用
//OCR2=156; //10mS 4M
OCR2=78; //5mS 4M
TIMSK=BIT(OCIE2); //比較匹配中斷使能
TCCR2=BIT(WGM21)|BIT(CS22)|BIT(CS21);//256分頻CTC模式
//T1初始化 紅外解碼用
TCCR1B=BIT(ICNC1)|BIT(WGM12)|BIT(CS10);//噪聲抑制 下降沿觸發 CTC(模式4) 1分頻
TIMSK|=BIT(TICIE1);//輸入捕捉中斷使能
SEI(); //開全局中斷
}
/****************************************************************************
* 名稱: LED_KEY(void)
* 功能: 數碼管,LED 顯示驅動,按鍵讀取
* 入口參數:
* 出口參數:
****************************************************************************/
void LED_KEY(void)
{
uint8 i;
static uint8 com;
static uint8 KEY_life[3];//按鍵壽命
if(renovate==0) return;
//按鍵讀取
DDRC&=~(BIT(PC5)|BIT(PC4)|BIT(PC3));
PORTC|=BIT(PC5)|BIT(PC4)|BIT(PC3);
PORTC&=~BIT(PC2);
NOP();
NOP();
for(i=0;i<3;i++)
{
if((PINC&BIT(i+3))==0)
{
if(KEY==0)
{
KEY_life[i]++;
if(KEY_life[i]>50) KEY=i+1;
}
}
else
{
KEY_life[i]=0;
if(KEY==(i+1)) KEY=10;
}
}
//顯示
if(LED_time>0)
{
PORTC|=BIT(PC2);
if((LED&BIT(com))&BIT(com))
{
DDRC|=BIT(com+3);
PORTC&=~BIT(com+3);
}
}
if(++com>2) com=0;
renovate=0;
}
/****************************************************************************
* 名稱: timer2_comp_isr(void)
* 功能: T2比較匹配中斷處理
* 入口參數:
* 出口參數:
****************************************************************************/
#pragma interrupt_handler timer2_comp_isr:iv_TIMER2_COMP
void timer2_comp_isr(void)
{
static uint16 minute;
renovate=1;
//蜂鳴
if(BUZZER_time>0)
{
BUZZER_time--;
BUZZER_ON();
}
else BUZZER_OFF();
if(IR_code_old_time>0)
{
IR_code_old_time--;
if(IR_code_old_time==0) IR_code_old=0xffff;
}
if(nature_time>0) nature_time--;
if(nature2_time>0) nature2_time--;
if(LED_time>0) LED_time--;
if(++minute==12000) //一分鐘
{
minute=0;
if(timing>0)
{
timing--;
if(timing==0) KEY=10;
}
}
}
/*------------------------------------------------------------------------------
模塊名稱:PB0(ICP)引腳下降沿捕捉中斷程序
RC5碼
____
| |
|___|
|<-bit->|
遙控器晶振455,一個bit=1.778ms CPUclck 4M 7112
紅外接收器輸出是反相的
------------------------------------------------------------------------------*/
#define bit 7112
uint16 IR_code;//紅外遙控鍵碼
uint8 OK_read;//讀碼完畢標志
uint8 sign; //半位記錄
uint8 sign_i;
#pragma interrupt_handler timer1_capt_isr:iv_TIMER1_CAPT
void timer1_capt_isr(void)
{
OCR1A=bit/4; //第一次中斷bit/4
TCNT1=0;
TIFR|=BIT(OCF1A);
TIMSK&=~BIT(TICIE1);//清輸入捕捉中斷使能
TIMSK|=BIT(OCIE1A);//輸出比較 A 匹配中斷使能
sign=1;
sign_i=1;
}
//定時器T1匹配中斷A服務程序
#pragma interrupt_handler timer1_compa_isr:iv_TIMER1_COMPA
void timer1_compa_isr(void)
{
static uint8 times;//記錄捕捉次數
OCR1A=bit/2;
switch (sign_i)
{
case 0:
if(PINB&BIT(PB0)) sign=1;
else sign=0;
sign_i=1;
break;
case 1:
sign_i=0;
sign<<=1;
if(PINB&BIT(PB0)) sign|=1;
IR_code<<=1;
if(sign==0B10) IR_code|=1;
times++;
if(times>13)
{
times=0;
OK_read=1;
IR_code&=0xfff;
TIFR|=BIT(ICF1);
TIMSK|=BIT(TICIE1);//輸入捕捉中斷使能
TIMSK&=~BIT(OCIE1A);//清輸出比較 A 匹配中斷使能
}
if((sign==0B11)||(sign==0B00)) //錯誤重啟
{
times=0;
TIFR|=BIT(ICF1);
TIMSK|=BIT(TICIE1);//輸入捕捉中斷使能
TIMSK&=~BIT(OCIE1A);//清輸出比較 A 匹配中斷使能
}
break;
}
}
//工作轉換
void SYS(void)
{
if((KEY!=0)&&(OK_read!=0)) OK_read=0;
switch (KEY)
{
case 0:
if(OK_read)
{
LED_time=6000;
IR_code_old_time=100;
OK_read=0;
estate=IR_code&0x7ff;
if(IR_code!=IR_code_old)
{
switch (estate)
{
case 1: //1檔
PORTD=(PORTD|(BIT(PD7)|BIT(PD6)))&(~BIT(PD5));
BUZZER_time=10;
career=1;
nature_time=20000;
career2_ONOFF=1;
LED|=BIT(2);
break;
case 2: //2檔
PORTD=(PORTD|(BIT(PD7)|BIT(PD5)))&(~BIT(PD6));
BUZZER_time=10;
career=2;
nature_time=20000;
career2_ONOFF=1;
LED|=BIT(2);
break;
case 3: //3檔
PORTD=(PORTD|(BIT(PD6)|BIT(PD5)))&(~BIT(PD7));
BUZZER_time=10;
career=3;
nature_time=20000;
career2_ONOFF=1;
LED|=BIT(2);
break;
case 0: //0
case 12: //開關
PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
BUZZER_time=10;
timing=0;
nature_sign=0;
career=0;
LED=0;
break;
case 34: //自然風
switch (nature_sign)
{
case 0:
nature_sign++;
nature_time=10000;
LED|=BIT(1);
break;
case 1:
nature_sign++;
nature_time=10000;
career2_ONOFF=1;
if(career==0)
{
PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
PORTD&=~BIT(5);
}
LED|=BIT(1);
break;
case 2:
nature_sign=0;
PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
if(career>0) PORTD&=~BIT(career+4);
LED&=~BIT(1);
break;
}
BUZZER_time=10;
break;
case 38: //定時
if(timing<180)
{
timing+=30;
BUZZER_time=10;
LED|=BIT(0); //定時指示
}
break;
case 16: //音+
break;
case 17: //音-
break;
case 32: //頻+
break;
case 33: //頻-
break;
}
}
IR_code_old=IR_code;
}
break;
case 1: PORTD=(PORTD|(BIT(PD7)|BIT(PD6)))&(~BIT(PD5));//按鍵1檔
career=0;
timing=0;
nature_sign=0;
LED=0;
break;
case 2: PORTD=(PORTD|(BIT(PD7)|BIT(PD5)))&(~BIT(PD6));//按鍵2檔
career=0;
timing=0;
nature_sign=0;
LED=0;
break;
case 3: PORTD=(PORTD|(BIT(PD6)|BIT(PD5)))&(~BIT(PD7));//按鍵3檔
career=0;
timing=0;
nature_sign=0;
LED=0;
break;
case 10:
PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
career=0;
timing=0;
nature_sign=0;
LED=0;
KEY=0;
break;
}
}
//自然風
void nature(void)
{
if(nature2_time==0)
{
nature2_time=rand()%150+200;
career2++;
}
if(career2>3) career2=1;
if(nature_time==0)
{
nature_time=rand()%12000+2000;
switch (nature_sign)
{
case 1:
if(career>0)
{
if(PORTD&BIT(career+4)) PORTD&=~BIT(career+4);
else PORTD|=BIT(career+4);
}
break;
case 2:
PORTD|=BIT(PD7)|BIT(PD6)|BIT(PD5);
if(career2_ONOFF==1) career2_ONOFF=0;
else
{
career2_ONOFF=1;
PORTD&=~BIT(career2+4);
}
break;
}
}
}
//主程序
void main(void)
{
uint8 i;
intit();
TEST_USART_init();
LED_time=6000;
BUZZER_time=10;
KEY=10;
while(1)
{
WDR(); //看門狗計數清零
LED_KEY();
SYS();
nature();
// if(OK_read==1) //調試用
// {
// printf("%u",IR_code);
// printf("\r\n\r\n");
// OK_read=0;
// IR_code=0;
// }
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -