📄 my89c52.c
字号:
/****************************************************************************************************************
* 本程序完成前面板的LED显示及接收遥控器,通过串行口与主cpu通讯
*
* 2002/12/12 修改定时器1中断与外部中断,指定寄存器数组以减少指令
遥控器的循环左移改用_crol_函数以减少指令
LED显示函数的循环右移改为_cror函数,而不是用语句<<
*2003/03/20 修改程序以适合大显前面板
*2006/06/16 修改遥控器放在中断1 的放口上,串口输出的码改为10个字节
****************************************************************************************************************/
#include <reg52.h> //跟据型号自己改 PHILIPS
#include <intrins.h>
unsigned char data int_timer=0, INT_TIMES=0 ; //中断时间间隔与中断次数
unsigned char data LED_TIMES=0;
unsigned char data Remote_data[4]; //含客户码1,客户码2,遥控码1,遥控码2
unsigned char data CUSTOM_CODE, POWER_KEY;
unsigned char data Repeate_key=0;
unsigned char data repeate_time=0; //计算repeate与head间的时间间隔
unsigned char bdata Remote_flag=0 ;
sbit Head_ok=Remote_flag^7; //遥控器头部是否正确,1----正确,0----不正确
sbit Remote_OK= Remote_flag^6; //遥控器是否完成的判断
sbit Temp_data=Remote_flag^0; //临时存放一位数据
//sbit Stand_by=Remote_flag^5; //Sdand_by状态标志位
sbit Close_Clock=Remote_flag^4 ; //0---显示过时间,1---第一次显示时间
sbit outbuf_flag=Remote_flag^3; //输出缓冲区非空标志 有=1
sbit inbuf_flag=Remote_flag^2; //接收缓冲区非空标志 有=1
sbit Boot_flag=Remote_flag^1; //启动标志
//sbit RepT_over=Remote_flag^4 ; //repeate_time溢出标志
unsigned char data uart_tx_data[10];
unsigned char data uart_rx_data[8];
unsigned char uart_tx_p=0;
unsigned char uart_rx_p=0;
void send_remote(void);
void remote_wrong(void);
unsigned char mrab1(unsigned char *init); //取1---15间的随机数
void timer_init();
void serial_init ();
void send_key(unsigned char kye_board);
void Keyboard_deay(void);
void head_wait(void);
void send_repeat(void);
void main(void)
{
//unsigned char i;
Boot_flag=0; //表示正地启动
outbuf_flag=0;
timer_init();
serial_init ();
//EX0=1; //允许外部中断
//IT0=1; //中断0为低电平
EX1=1; //允许外部中断
IT1=1; //中断1为低电平
ES=1; //允许串口中断
EA=1;
P0=0x00;
P0=0xFF;
while(Boot_flag)
{
/* 向5518发送一个查询客户码的命令,同时也告知5518自己准备好了*/
uart_tx_data[0]=0x5A;
uart_tx_data[1]=0x5A;
uart_tx_data[2]=0x08; //四号命令
uart_tx_data[3]=0x00;
uart_tx_data[4]=0x00;
uart_tx_data[5]=0x00;
uart_tx_data[6]=0x00;
uart_tx_data[7]=0x00;
uart_tx_data[8]=0x00;
uart_tx_data[9]=0x00;
uart_tx_p=0;
//uart_tx_data[7]=mrab1(&RAB_INIT);
// for(i=0;i<7;i++) uart_tx_data[i]=uart_tx_data[i]^led_table[uart_tx_data[7]];
SBUF= uart_tx_data[uart_tx_p];
uart_tx_p++;
// if(uart_tx_p>7) uart_tx_p=0;
Keyboard_deay();
}
while(1)
{
#if 0
switch(P2)
{
case 0xDF: //right
Keyboard_deay();
if(P2==0xDF) send_key(0xDF); //send_key(0xDF);
break;
case 0xEF: //left
Keyboard_deay();
if(P2==0xEF) send_key(0xEF); //send_key(0xEF);
break;
case 0xF7: //up
Keyboard_deay();
if(P2==0xF7) send_key(0xF7); //send_key(0xF7);
break;
case 0xFB: //down
Keyboard_deay();
if(P2==0xFB) send_key(0xFB); //send_key(0xFB);
break;
case 0xFD: //menu
Keyboard_deay();
if(P2==0xFD) send_key(0xFD); //send_key(0xFD);
break;
case 0xFE: //OK
Keyboard_deay();
if(P2==0xFE) send_key(0xFE); //send_key(0xFE);
break;
}
#endif
}
}
void Keyboard_deay(void)
{
unsigned short i=0;
for(i=0;i<0xCFFF;i++){}
}
void timer_init()
{
TMOD = 0x12; /* 定时器0工作在模式1---0001,16位的定时器,定时器工作在方式2*/
/* 定时器0,0.1mS中断一次,这里单片机晶体振荡频率为27MHZ*/
TH0=0x1E; //0xE9;
TL0=0x1E; // 0xE9;
/* 定时器1, 4mS中断一次,这里单片机晶体振荡频率为27MH*/
TH1=0xDC; /* (65536-TH1TL1)*12/27MHz */
TL1=0xD7;
/* 定时器2, 用做串行口的婆特率发生器,9600*/
// T2CON=0x30;
// RCAP2H=0xFF;
// RCAP2L=0x7A;
ET0=1; //定时器0中断允许
//TR0=1; //定时器0开始工作
ET1=1; //定时器1中断允许
TR1=1; //定时器1禁止开始工作
// ET2=1; //定时器2中断允许
// TR2=1; //定时器2开始工作
}
void timer1(void) interrupt 3 using 2 //定时器1 中断程序
{
LED_TIMES++; // 4ms
repeate_time++; // 4ms
if(LED_TIMES==250)
{
// seconde++; // 1秒钟
if(outbuf_flag)
{
outbuf_flag=0;
P0=0xFF;
}
else{
outbuf_flag=1;
P0=0x00;
}
LED_TIMES=0;
}
TH1=0xDC;
TL1=0xD7;
TF1=0; //清除定时器中断标志
}
void timer0(void) interrupt 1 //定时器0 TH 中断程序
{
TF0=0; //清除定时器中断标志
/* 定时器1, 0.1mS中断一次,这里单片机晶体振荡频率为27MHZ */
int_timer++; // 0.1ms, 100uS
}
void Remote(void) interrupt 2 using 1 //遥控接收程序
{
INT_TIMES++; //中断次数加一次,以控制数据的位数
if(Head_ok) //判断9mS的头码是否通过?通过则解码
{
if(INT_TIMES>=33) send_remote(); //一个遥控中断总数为34次完成
else{
if(int_timer<=4) remote_wrong();
if((int_timer>4)&&(int_timer<13)) Temp_data=0;
if((int_timer>=13)&&(int_timer<=20)) remote_wrong();
if((int_timer>20)&&(int_timer<24)) Temp_data=1;
if(int_timer>=24) remote_wrong();
if((int_timer>118)&&(int_timer<=138)) head_wait();
Remote_data[(INT_TIMES-1)/8]=_crol_(Remote_data[(INT_TIMES-1)/8],1);
if(Temp_data) Remote_data[(INT_TIMES-1)/8]=Remote_data[(INT_TIMES-1)/8]|Temp_data;
int_timer=0;
}
}
else{ //判断头码
if((int_timer>100)&&(int_timer<=112))
{
if(Repeate_key==0)
{
if((repeate_time>24)&&(repeate_time<30))
{
Repeate_key++;
}
}
if(Repeate_key>0)
{
if((repeate_time>24)&&(repeate_time<32))
{
Repeate_key++;
if(Repeate_key==3) //重复5次算一次
{
send_repeat(); //11.2mS, reapter
Repeate_key=0;
}
}
}
repeate_time=0;
}
if((int_timer>118)&&(int_timer<=138)) //9ms+4.5ms=13.5mS
{
Remote_data[0]=0x00;
Remote_data[1]=0x00;
Remote_data[2]=0x00;
Remote_data[3]=0x00;
Head_ok=1;
int_timer=0;
INT_TIMES=0;
repeate_time=0;
}
if(int_timer<89) // next interrupt
{
int_timer=0;
INT_TIMES=0;
//Repeate_key=0;
TR0=1;
}
else remote_wrong();
}
}
void remote_wrong(void)
{
int_timer=0;
INT_TIMES=0;
Head_ok=0;
}
void head_wait(void)
{
int_timer=0;
INT_TIMES=0;
Head_ok=1;
repeate_time=0;
Repeate_key=0;
}
void send_repeat(void)
{
Head_ok=0;
repeate_time=0;
int_timer=0;
uart_tx_data[0]=0xA5;
uart_tx_data[1]=0x08;
uart_tx_data[2]=Remote_data[0];
uart_tx_data[3]=Remote_data[1];
uart_tx_data[4]=Remote_data[2];
uart_tx_data[5]=Remote_data[3];
uart_tx_data[6]=0x00;
uart_tx_data[7]=0x00;
uart_tx_data[8]=0x00;
uart_tx_data[9]=0x00;
uart_tx_p=0;
SBUF= uart_tx_data[uart_tx_p];
uart_tx_p++;
INT_TIMES=0;
TR0=0;
}
void send_remote(void)
{
//unsigned char i;
Head_ok=0;
repeate_time=0;
Repeate_key=0;
uart_tx_data[0]=0xA5;
uart_tx_data[1]=0x08;
uart_tx_data[2]=Remote_data[0];
uart_tx_data[3]=Remote_data[1];
uart_tx_data[4]=Remote_data[2];
uart_tx_data[5]=Remote_data[3];
uart_tx_data[6]=0x00;
uart_tx_data[7]=0x00;
uart_tx_data[8]=0x00;
uart_tx_data[9]=0x00;
// uart_tx_data[7]=mrab1(&RAB_INIT);
// for(i=0;i<7;i++) uart_tx_data[i]=uart_tx_data[i]^led_table[uart_tx_data[7]];
uart_tx_p=0;
SBUF= uart_tx_data[uart_tx_p];
uart_tx_p++;
INT_TIMES=0;
int_timer=0;
TR0=0;
}
/**************************************************************************************************************************************************************************
** 2002.12.02用此设置计算机接收到9600的数据
**************************************************************************************************************************************************************************/
void serial_init () //串口初始化 0xfd=19200,0xfa=9600,0xf4=4800,0xe8=2400,0xd0=1200
{
SCON = 0x50; /* mode 1: 8-bit UART, enable receiver */
PCON |= 0x00;
ES=1; //串行中断允许
/*定时器2工作在模式2用来产生波特率,不产生中断,12M频率,则TH1=0xFA SMOD=1*/
// TH2=RCAP2H=0xFF; //27MHz,9600bps下的时钟
// TL2=RCAP2L=0xA8; //27MHz,9600bps下的时钟
TH2=RCAP2H=0xFF; //27MHz,38400bps下的时钟
TL2=RCAP2L=0xEB; //27MHz,38400bps下的时钟
ET2=0; //定时器2的中断是被禁止的
T2CON=0x34; //0011,0100, 设为波特率发生器,并启动定时器2
}
serial () interrupt 4 //串口中断处理
{
if (TI )
{
TI = 0;
if (uart_tx_p<10)
{
SBUF= uart_tx_data[uart_tx_p]; //未发送完继续发送
uart_tx_p++; //最后传出去的字节位置加一
}
}
else if (RI)
{
RI = 0;
if(uart_rx_p<7)
{
uart_rx_data[uart_rx_p]= SBUF; //放入数据
uart_rx_p++; //最后放入的位置加一
}
else{ //接收完8个数据
// uart_rx_data[0]=uart_rx_data[0]^led_table[uart_rx_data[7]];
// uart_rx_data[1]=uart_rx_data[1]^led_table[uart_rx_data[7]];
uart_rx_p=0;
if((uart_rx_data[0]==0x5A)&&(uart_rx_data[1]==0x5A))
{
switch(uart_rx_data[2])
{
case 0x01: //节目号
break;
case 0x02: //时间
break;
case 0x03:
break;
case 0x04:
break;
case 0x05: //回传数据
break;
default:
break;
}
}
}
}
}
void send_key(unsigned char kye_board) //发送按键
{
//unsigned char i;
uart_tx_data[0]=0xA5;
uart_tx_data[1]=0x08;
uart_tx_data[2]=kye_board;
uart_tx_data[3]=0x00;
uart_tx_data[4]=0xFF;
uart_tx_data[5]=0x00;
uart_tx_data[6]=0x00;
uart_tx_data[7]=0x00;
uart_tx_data[8]=0x00;
uart_tx_data[9]=0x00;
uart_tx_p=0;
SBUF= uart_tx_data[uart_tx_p];
uart_tx_p++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -