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