//红外发射电路及程序的说明:
//1.电路采用三个红外发射管并联的形式,通过脉冲发射的方式,电流可以达到100mA的样子,发射距离最大可达10m.
//2.调制载波为38KHz,占空比为50%,通过定时器中断0的方式实现,故需定时为13us触发一次中断。调制信号通过对定时器0的中断次数
//计数来发射时间,通过状态机的理念实现。
//3.时钟的同步通过开始后的通信校准时间、调时时的按键键码发射、每一天校准一次时间来实现。
//4.在该电路中实现遥控器调时、定时的功能。
#include<stdio.h>
#include<string.h>
#define F_CPU 8000000 // 定义CPU频率为8MHz
#include<util/delay.h>
#include<avr/io.h>
#include<avr/iom16.h>
#include<avr/interrupt.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define delay_us(x) _delay_us(x) //延时x us
#define delay_ms(x) _delay_ms(x) //延时x ms
#define error 0
#define ok 1
//****************************/
// 参数宏定义
//****************************/
volatile uint time; //接收时两个下降沿之间的时间间隔
volatile uchar flag_red_read=0; //接收数据中断标识符
// uchar data_read[4]={0x00,0x00,0x00,0x00}; //接收的四个字节的数据
uchar data,data1,flag; //接收到的数据内容、接收成功标志
//****************************/
// 宏定义区
//****************************/
volatile uchar year=0,month=0,day=0,hour=0,min=0,second=0,temprature=0;
volatile uchar flag_mode=0,flag_alarm=0;
//*********************************************
// 共阴数码管对应表0-F
//*********************************************
uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//该电路中用的为共阳数码管,故使用时需取反
//******************************/
// 端口宏定义
//******************************/
#define RCK_SET PORTA|= (1<<PA0) //LED控制
#define RCK_CLR PORTA&=~(1<<PA0)
#define SRCK_SET PORTA|= (1<<PA1)
#define SRCK_CLR PORTA&=~(1<<PA1)
#define DATA_SET PORTA|= (1<<PA2)
#define DATA_CLR PORTA&=~(1<<PA2)
#define DATA_IO PORTB //数码管数据端口
#define DULA_CLR PORTD&=~(1<<PD1)
#define DULA_SET PORTD|= (1<<PD1)
#define WELA_CLR PORTD&=~(1<<PD0)
#define WELA_SET PORTD|= (1<<PD0)
#define L9_CLR PORTD&=~(1<<PD2)
#define L9_SET PORTD|= (1<<PD2)
#define L10_CLR PORTD&=~(1<<PD3)
#define L10_SET PORTD|= (1<<PD3)
#define L11_CLR PORTD&=~(1<<PD4)
#define L11_SET PORTD|= (1<<PD4)
#define L12_CLR PORTD&=~(1<<PD5)
#define L12_SET PORTD|= (1<<PD5)
#define BELL_SET PORTC&=~(1<<PC0)
#define BELL_CLR PORTC|= (1<<PC0)
//****************************/
// 功能子程序
//****************************/
//显示日期和温度程序
void display_1(uchar dat1,uchar dat2,uchar dat3,uchar dat4)
{
uchar t;
WELA_SET; //显示20
DATA_IO=0x00;
WELA_CLR;
L9_SET;
L10_CLR;
L11_CLR;
L12_CLR;
DULA_SET;
DATA_IO=~table[2];
DULA_CLR;
delay_us(100);
WELA_SET;
DATA_IO=0x00;
WELA_CLR;
L9_CLR;
L10_SET;
L11_CLR;
L12_CLR;
DULA_SET;
DATA_IO=~table[0];
DULA_CLR;
delay_us(100);
WELA_SET; //显示年(dat1)
DATA_IO=0x00;
WELA_CLR;
L9_CLR;
L10_CLR;
L11_SET;
L12_CLR;
DULA_SET;
t=dat1>>4;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
WELA_SET;
DATA_IO=0x00;
WELA_CLR;
L9_CLR;
L10_CLR;
L11_CLR;
L12_SET;
DULA_SET;
t=dat1&0x0f;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
L9_CLR; //显示月(dat2)
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x01;
WELA_CLR;
DULA_SET;
t=dat2>>4;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
L9_CLR;
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x02;
WELA_CLR;
DULA_SET;
t=dat2&0x0f;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
L9_CLR; //显示“-”
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x04;
WELA_CLR;
DULA_SET;
DATA_IO=0xbf;
DULA_CLR;
delay_us(100);
L9_CLR; //显示日(dat3)
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x08;
WELA_CLR;
DULA_SET;
t=dat3>>4;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
L9_CLR;
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x10;
WELA_CLR;
DULA_SET;
t=dat3&0x0f;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
L9_CLR; //显示空格
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x20;
WELA_CLR;
DULA_SET;
DATA_IO=0xff;
DULA_CLR;
delay_us(100);
L9_CLR; //显示温度(dat4)
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x40;
WELA_CLR;
DULA_SET;
t=dat4>>4;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
L9_CLR;
L10_CLR;
L11_CLR;
L12_CLR;
WELA_SET;
DATA_IO=0x80;
WELA_CLR;
DULA_SET;
t=dat4&0x0f;
DATA_IO=~table[t];
DULA_CLR;
delay_us(100);
}
//用LED显示 时、分、秒
void display_2(uchar dat1,uchar dat2,uchar dat3)
{
uchar i,t,num[72]={0,0};
t=(dat1>>4)*10+(dat1&0x0f); //将时(dat1)转换为LED显示
if((t%12)!=0)
{
num[(t%12)-1]=1;
}
else
{
num[11]=1;
}
t=(dat2>>4)*10+(dat2&0x0f); //将分(dat2)转换为LED显示
if(t<57)
{
num[t+15]=1;
}
else
{
switch(t)
{
case 57: num[12]=1;break;
case 58: num[13]=1;break;
case 59: num[14]=1;break;
case 60: num[15]=1;break;
default: break;
}
}
t=(dat3>>4)*10+(dat3&0x0f); //将秒(dat2)转换为LED显示
if(t<57)
{
num[t+15]=1;
}
else
{
switch(t)
{
case 57: num[12]=1;break;
case 58: num[13]=1;break;
case 59: num[14]=1;break;
case 60: num[15]=1;break;
default: break;
}
}
for(i=72;i>0;i--) //显示数据
{
if(num[i-1])
{
DATA_SET;
}
else
{
DATA_CLR;
}
SRCK_CLR;
SRCK_SET;
}
RCK_CLR;
RCK_SET;
}
//调时及初始化时的显示(关闭LED,数码管显示“-”)
void display_3(void)
{
uchar i;
for(i=72;i>0;i--) //关闭所有LED
{
DATA_CLR;
SRCK_CLR;
SRCK_SET;
}
RCK_CLR;
RCK_SET;
L9_SET;
L10_SET;
L11_SET;
L12_SET;
WELA_SET;
DATA_IO=0xFF;
WELA_CLR;
DULA_SET;
DATA_IO=0xbf;
DULA_CLR;
}
/*
//显示一个字节数据
void display(uchar dat)
{
uchar t,temp;
temp=dat;
WELA_SET;
DATA_IO=0x00;
WELA_CLR;
L9_CLR;
L10_CLR;
L11_SET;
L12_CLR;
DULA_SET;
// t=temp/10;
t=temp>>4;
DATA_IO=~table[t];
DULA_CLR;
delay_ms(5);
WELA_SET;
DATA_IO=0x00;
WELA_CLR;
L9_CLR;
L10_CLR;
L11_CLR;
L12_SET;
DULA_SET;
// t=temp%10;
t=temp&0x0f;
DATA_IO=~table[t];
DULA_CLR;
delay_ms(5);
}
void display_1(uchar dat)
{
uchar t,temp;
temp=dat;
WELA_SET;
DATA_IO=0x00;
WELA_CLR;
L9_SET;
L10_CLR;
L11_CLR;
L12_CLR;
DULA_SET;
// t=temp/10;
t=temp>>4;
DATA_IO=~table[t];
DULA_CLR;
delay_ms(5);
WELA_SET;
DATA_IO=0x00;
WELA_CLR;
L9_CLR;
L10_SET;
L11_CLR;
L12_CLR;
DULA_SET;
// t=temp%10;
t=temp&0x0f;
DATA_IO=~table[t];
DULA_CLR;
delay_ms(5);
}*/
//显示
void display_num(void)
{
uchar i,num[72]={0,0};
static uchar dis_num=0;
num[dis_num]=1;
for(i=72;i>0;i--) //关闭所有LED
{
if(num[i-1])
{
DATA_SET;
}
else
{
DATA_CLR;
}
SRCK_CLR;
SRCK_SET;
}
RCK_CLR;
RCK_SET;
dis_num++;
if(dis_num==72)
{
dis_num=0;
}
delay_ms(10);
}
//接收红外数据数据
uchar red_read_byte(void)
{
static uchar read_state=0,k=0;
static uchar data_read[4];
switch(read_state)
{
case 0:if(time>18500&&time<21700) //头信号
{
read_state=1;
}
else
{
read_state=0;
return error;
}
break;
case 1:if(time>1550&&time<2000) //"0"信号
{
data_read[0]=data_read[0]>>1;
data_read[0]=data_read[0]&0x7f;
k++;
}
else
{
if(time>3800&&time<4300) //“1”信号
{
data_read[0]=data_read[0]>>1;
data_read[0]|=0x80;
k++;
}
else
{
k=0;
read_state=0;
return error;
}
}
if(k==8)
{
read_state=2;
k=0;
}
break;
case 2:if(time>1550&&time<2000) //"0"信号
{
data_read[1]=data_read[1]>>1;
- 1
- 2
前往页