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