//=========================
//Project: PWM generation for STEP motor control
//Author: Leo.Tseng
//Date: 2011/12/21
//MCU: W78E054D
//CRYSTAL: 25Mhz
//Description: Use uart for input/output, set boudrate=9600,
// Press "a" to increase PWM high duty, Press "d" to
// decrease PWM high duty.
// PWM will control 3-wire step motor.
//=========================
#include <reg52.h>
#include <stdio.h>
void uart_initinal(int baudrate);
int TIMES=65536; // 16bit counter
int FREQ=10400; // 200HZ = 10400 機械週期
int PWMHIGH=2080; // 高電位佔20%=10400*0.2=2080個機械週期
int PWMLOW=8320; // 低電位佔80%=10400*0.8=8320個機械週期
int PERIOD,n_SCAN;
char ch;
sbit SCAN0 = P1^2;
sbit SCAN1 = P1^3;
sbit SCAN2 = P1^4
//------------------------------------------------
//MAIN C function
//------------------------------------------------
void main (void)
{
uart_initinal(9600); // 起始 UART 設定,baudrate=9600
//PWMOUT = 0;
TMOD = (TMOD & 0xF0) | 0x01; // 設定 T/C0 Mode
PERIOD = TIMES-PWMHIGH;
TH0 = PERIOD/256;
TL0 = PERIOD%256;
ET0 = 1; // 致能 Timer 0 Interrupts
TR0 = 1; // 啟動 Timer 0 計時
EA = 1; // 全部致能始動
SCAN0 = 1;
// PWMOUT1 = 1;
// PWMOUT2 = 1;
printf("按 ""a"" 增加PWM工作週期20%%,按 ""d"" 減少PWM工作週期20%%\n"); // 顯示操作訊息
//printf("Press ""a"" to increase duty cycle, ""d"" to decrease duty cycle\n"); // 顯示操作訊息
while (1)
{
switch (ch=_getkey())
{
// 增加高電位20/%
case 'A': //
case 'a':if(PWMHIGH==300) //
PWMHIGH=2080;
else if(PWMHIGH <= 6240)
PWMHIGH+=2080;
else if(PWMHIGH >= 8320)
PWMHIGH=10100; // 最高duty cycle限制97%
PWMLOW=FREQ-PWMHIGH;
//printf("a_PWMHIGH is %u\n",PWMHIGH);
break;
// 減少高電位20/%
case 'D': //
case 'd':if(PWMHIGH==10100) //
PWMHIGH=8320;
else if(PWMHIGH >= 4160)
PWMHIGH-=2080;
else if(PWMHIGH <= 2080)
PWMHIGH=300; // 最低duty cycle限制97%
PWMLOW=FREQ-PWMHIGH;
//printf("d_PWMHIGH is %u\n",PWMHIGH);
break;
default: break;
}
}
}
//UART副程式使用timer1
void uart_initinal(int baudrate)
{
PCON = 0x00; // PCON: if SMOD=1(b7), Baud Rate is Doubled
SCON = 0x52; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = (TMOD & 0x0f) | 0x20; // TMOD: timer 1, mode 2, 8-bit reload; keeps timer0 default.
TH1 = 256-(25000000/372/baudrate); // TH1: reload value for baud @ 25MHz, TH=0xF9
//TH1= 256-(11059200/384/baudrate);
TR1 = 1; // TR1: timer 1 run
//TI = 1; // TI: set TI to send first char of UART
}
//計時器0中斷1
void timer0_ISR(void) interrupt 1
{
if((SCAN0==1)&&(SCAN1==1)&&(SCAN2==1)&&(n_SCAN==0))
{
TR0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN0=0;
}
else if((SCAN0==0)&&(SCAN1==1)&&(SCAN2==1)&&(n_SCAN==0))
{
TR0=0;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN0=1;
n_SCAN=1;
}
if((SCAN1==1)&&(SCAN0==1)&&(SCAN2==1)&&(n_SCAN==1))
{
TR0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN1=0;
}
else if((SCAN1==0)&&(SCAN0==1)&&(SCAN2==1)&&(n_SCAN==1))
{
TR0=0;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN1=1;
n_SCAN=2;
}
if((SCAN2==1)&&(SCAN0==1)&&(SCAN1==1)&&(n_SCAN==2))
{
TR0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN2=0;
}
else if((SCAN2==0)&&(SCAN0==1)&&(SCAN1==1)&&(n_SCAN==2))
{
TR0=0;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
SCAN2=1;
n_SCAN=0;
}
}
===================================================================
2011年12月20日 星期二
2011年12月8日 星期四
NEC protocol IR remote TX program
//=========================
//Project: NEC protocol TX
//Author: Leo.Tseng
//Date: 2011/12/09
//MCU: W78E054D
//CRYSTAL: 25Mhz
//Description: Use uart for input/output, set boudrate=9600,
// Press Keypad to transmit NEC protocol code
// SW20=0x08E647B8, power key.
// SW15=0x08E618E7, channel up.
// SW19=0x08E610EF, channel down.
//=========================
#include <reg52.h>
#include <stdio.h>
void uart_initinal(int boudrate);
int PERIOD,i;
unsigned KEY,temp;
unsigned long ir_data;
sbit PWMOUT = P3^2;
//sbit PWMOUT1 = P2^0;
//sbit PWMOUT2 = P2^1;
sbit SCAN0 = P2^7; // KEY SCAN0
sbit SCAN1 = P2^6; // KEY SCAN1
sbit SCAN2 = P2^5; // KEY SCAN2
sbit SCAN3 = P2^4; // KEY SCAN3
sbit DET3 = P2^3; // KEY DETECT0, always high
sbit DET2 = P2^2; // KEY DETECT2
sbit DET1 = P2^1; // KEY DETECT1
sbit DET0 = P2^0; // KEY DETECT0
//副程式宣告
void TIMER1_initinal(int baudrate);
void delay (int j);
void NEC_LEADER_CODE(void);
void NEC_low(void);
void NEC_high(void);
void NEC_stop(void);
//------------------------------------------------
//MAIN C function
//------------------------------------------------
void main (void)
{
uart_initinal(9600); // 起始 UART 設定,baudrate=9600
TMOD = (TMOD & 0xF0) | 0x02; // 設定 T/C0 Mode
PERIOD = 200;
TH0 = PERIOD;
TL0 = TH0;
// ET0 = 1; // 致能 Timer 0 Interrupts
// TR0 = 1; // 啟動 Timer 0 計時
EA = 1; // 全部致能始動
PWMOUT = 0;
SCAN0=0;
SCAN1=SCAN2=SCAN3=1;
DET3=DET2=DET1=DET0=1;
//ir_data = 0x1067E21D; // for transmission 1
//ir_data = 0xB847E608; // for transmission 2
printf("NEC編碼紅外線發射程式\n"); // 顯示操作訊息
while (1)
{
if((P2&0x0F)!=0x0F) // 偵測是否按按鍵?
{
temp=P2&0xFF; // 第一次儲存按鍵值
delay(6000); // 延遲 0.48us*6000=2.88ms,防彈跳調整
KEY=P2&0xFF; // 第二次讀取按鍵值
if(KEY&&temp) // 判別是否為按鍵
{
/*
ET0 = 1;
TR0 = 1;
// ***** transmission 1 *****
NEC_LEADER_CODE();
NEC_low();NEC_low();NEC_low();NEC_high(); // 1:0001 > 8
NEC_low();NEC_low();NEC_low();NEC_low(); // 0:0000 > 0
NEC_low();NEC_high();NEC_high();NEC_low(); // 6:0110 > 6
NEC_low();NEC_high();NEC_high();NEC_high(); // 7:0111 > E
NEC_high();NEC_high();NEC_high();NEC_low(); // E:1110 > 7
NEC_low();NEC_low();NEC_high();NEC_low(); // 2:0010 > 4
NEC_low();NEC_low();NEC_low();NEC_high(); // 1:0001 > 8
NEC_high();NEC_high();NEC_low();NEC_high(); // D:1101 > B
NEC_stop(); // 停止位元
//PWMOUT=0;
ET0 = 0;
TR0 = 0;
delay(11030); // 補足108ms
//ET0 = 1;
//TR0 = 1;
*/
switch(KEY)
{
case 0x7B: printf("SW20 pressed, code=0x7B\n");
ir_data = 0xB847E608; // SW20,等於 0x08E647B8
break;
case 0x7D: printf("SW15 pressed, code=0x7D\n");
ir_data = 0xE718E608; // SW15,等於 0x08E618E7
break;
case 0x7E: printf("SW19 pressed, code=0x7E\n");
ir_data = 0xEF10E608; // SW19,等於 0x08E610EF
break;
default: break;
}
// ******* transmission 2 ********
NEC_LEADER_CODE();
for(i=0;i<32;i++ )
{
if(ir_data & 0x0001)
{
//printf("1"); // 除錯用
NEC_high();
}
else
{
//printf("0"); // 除錯用
NEC_low();
}
ir_data=ir_data>>1;
}
NEC_stop();
//PWMOUT=0;
ET0 = 0;
TR0 = 0;
delay(11030); // 補足108ms
//ET0 = 1;
//TR0 = 1;
}
}
}
}
//UART副程式使用timer1
void uart_initinal(int boudrate)
{
PCON = 0x00; // PCON: if SMOD=1(b7), Baud Rate is Doubled
SCON = 0x52; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = (TMOD & 0x0f) | 0x20; // TMOD: timer 1, mode 2, 8-bit reload; keeps timer0 default.
TH1 = 256-(25000000/372/boudrate); // TH1: reload value for baud @ 25MHz, TH=0xF9
TR1 = 1; // TR1: timer 1 run
//TI = 1; // TI: set TI to send first char of UART
}
//計時器0中斷1, 產生38Khz 載波
void timer0_ISR(void) interrupt 1
{
PWMOUT^=1; // 設為高電位
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT^=1; // 設為低電位
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
//PWMOUT&=1;
}
void delay (int j)
{
while(j)
j--;
}
// NEC前導碼: 9ms高電位, 4.5ms低電位
void NEC_LEADER_CODE(void)
{
ET0=1;
TR0=1;
//PWMOUT1=1; // 除錯用
delay(336);
// PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
delay(1170);
}
// NEC碼0: 0.56ms高電位, 0.56ms低電位
void NEC_low(void)
{
ET0=1;
TR0=1;
//PWMOUT1=1; // 除錯用
delay(19);
//PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
delay(140);
}
// NEC碼1: 0.56ms高電位, 1.69ms低電位
void NEC_high(void)
{
ET0=1;
TR0=1;
//PWMOUT1=1; // 除錯用
delay(19);
//PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
delay(440);
}
// NEC碼,停止位元: 0.56ms高電位
void NEC_stop(void)
{
ET0 = 1;
TR0 = 1;
//PWMOUT1=1; // 除錯用
delay(19);
//PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
}
// ===== Test Result ========================
SW19, Code : 0x08E610EF
SW20, Code : 0x08E647B8
//Project: NEC protocol TX
//Author: Leo.Tseng
//Date: 2011/12/09
//MCU: W78E054D
//CRYSTAL: 25Mhz
//Description: Use uart for input/output, set boudrate=9600,
// Press Keypad to transmit NEC protocol code
// SW20=0x08E647B8, power key.
// SW15=0x08E618E7, channel up.
// SW19=0x08E610EF, channel down.
//=========================
#include <reg52.h>
#include <stdio.h>
void uart_initinal(int boudrate);
int PERIOD,i;
unsigned KEY,temp;
unsigned long ir_data;
sbit PWMOUT = P3^2;
//sbit PWMOUT1 = P2^0;
//sbit PWMOUT2 = P2^1;
sbit SCAN0 = P2^7; // KEY SCAN0
sbit SCAN1 = P2^6; // KEY SCAN1
sbit SCAN2 = P2^5; // KEY SCAN2
sbit SCAN3 = P2^4; // KEY SCAN3
sbit DET3 = P2^3; // KEY DETECT0, always high
sbit DET2 = P2^2; // KEY DETECT2
sbit DET1 = P2^1; // KEY DETECT1
sbit DET0 = P2^0; // KEY DETECT0
//副程式宣告
void TIMER1_initinal(int baudrate);
void delay (int j);
void NEC_LEADER_CODE(void);
void NEC_low(void);
void NEC_high(void);
void NEC_stop(void);
//------------------------------------------------
//MAIN C function
//------------------------------------------------
void main (void)
{
uart_initinal(9600); // 起始 UART 設定,baudrate=9600
TMOD = (TMOD & 0xF0) | 0x02; // 設定 T/C0 Mode
PERIOD = 200;
TH0 = PERIOD;
TL0 = TH0;
// ET0 = 1; // 致能 Timer 0 Interrupts
// TR0 = 1; // 啟動 Timer 0 計時
EA = 1; // 全部致能始動
PWMOUT = 0;
SCAN0=0;
SCAN1=SCAN2=SCAN3=1;
DET3=DET2=DET1=DET0=1;
//ir_data = 0x1067E21D; // for transmission 1
//ir_data = 0xB847E608; // for transmission 2
printf("NEC編碼紅外線發射程式\n"); // 顯示操作訊息
while (1)
{
if((P2&0x0F)!=0x0F) // 偵測是否按按鍵?
{
temp=P2&0xFF; // 第一次儲存按鍵值
delay(6000); // 延遲 0.48us*6000=2.88ms,防彈跳調整
KEY=P2&0xFF; // 第二次讀取按鍵值
if(KEY&&temp) // 判別是否為按鍵
{
/*
ET0 = 1;
TR0 = 1;
// ***** transmission 1 *****
NEC_LEADER_CODE();
NEC_low();NEC_low();NEC_low();NEC_high(); // 1:0001 > 8
NEC_low();NEC_low();NEC_low();NEC_low(); // 0:0000 > 0
NEC_low();NEC_high();NEC_high();NEC_low(); // 6:0110 > 6
NEC_low();NEC_high();NEC_high();NEC_high(); // 7:0111 > E
NEC_high();NEC_high();NEC_high();NEC_low(); // E:1110 > 7
NEC_low();NEC_low();NEC_high();NEC_low(); // 2:0010 > 4
NEC_low();NEC_low();NEC_low();NEC_high(); // 1:0001 > 8
NEC_high();NEC_high();NEC_low();NEC_high(); // D:1101 > B
NEC_stop(); // 停止位元
//PWMOUT=0;
ET0 = 0;
TR0 = 0;
delay(11030); // 補足108ms
//ET0 = 1;
//TR0 = 1;
*/
switch(KEY)
{
case 0x7B: printf("SW20 pressed, code=0x7B\n");
ir_data = 0xB847E608; // SW20,等於 0x08E647B8
break;
case 0x7D: printf("SW15 pressed, code=0x7D\n");
ir_data = 0xE718E608; // SW15,等於 0x08E618E7
break;
case 0x7E: printf("SW19 pressed, code=0x7E\n");
ir_data = 0xEF10E608; // SW19,等於 0x08E610EF
break;
default: break;
}
// ******* transmission 2 ********
NEC_LEADER_CODE();
for(i=0;i<32;i++ )
{
if(ir_data & 0x0001)
{
//printf("1"); // 除錯用
NEC_high();
}
else
{
//printf("0"); // 除錯用
NEC_low();
}
ir_data=ir_data>>1;
}
NEC_stop();
//PWMOUT=0;
ET0 = 0;
TR0 = 0;
delay(11030); // 補足108ms
//ET0 = 1;
//TR0 = 1;
}
}
}
}
//UART副程式使用timer1
void uart_initinal(int boudrate)
{
PCON = 0x00; // PCON: if SMOD=1(b7), Baud Rate is Doubled
SCON = 0x52; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = (TMOD & 0x0f) | 0x20; // TMOD: timer 1, mode 2, 8-bit reload; keeps timer0 default.
TH1 = 256-(25000000/372/boudrate); // TH1: reload value for baud @ 25MHz, TH=0xF9
TR1 = 1; // TR1: timer 1 run
//TI = 1; // TI: set TI to send first char of UART
}
//計時器0中斷1, 產生38Khz 載波
void timer0_ISR(void) interrupt 1
{
PWMOUT^=1; // 設為高電位
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT^=1; // 設為低電位
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
PWMOUT&=1;
//PWMOUT&=1;
}
void delay (int j)
{
while(j)
j--;
}
// NEC前導碼: 9ms高電位, 4.5ms低電位
void NEC_LEADER_CODE(void)
{
ET0=1;
TR0=1;
//PWMOUT1=1; // 除錯用
delay(336);
// PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
delay(1170);
}
// NEC碼0: 0.56ms高電位, 0.56ms低電位
void NEC_low(void)
{
ET0=1;
TR0=1;
//PWMOUT1=1; // 除錯用
delay(19);
//PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
delay(140);
}
// NEC碼1: 0.56ms高電位, 1.69ms低電位
void NEC_high(void)
{
ET0=1;
TR0=1;
//PWMOUT1=1; // 除錯用
delay(19);
//PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
delay(440);
}
// NEC碼,停止位元: 0.56ms高電位
void NEC_stop(void)
{
ET0 = 1;
TR0 = 1;
//PWMOUT1=1; // 除錯用
delay(19);
//PWMOUT1=0; // 除錯用
ET0 = 0;
TR0 = 0;
}
// ===== Test Result ========================
SW15, Code : 0x08E618E7
2011年12月5日 星期一
Key pad detect program
//=========================
//Project: Key pad detect program
//Author: Leo.Tseng
//Date: 2011/12/06
//MCU: W78E054D
//CRYSTAL: 25Mhz
//Description: Use uart for output, set boudrate=9600,
// Decode KEY pad, this program could support
// 4X4 KEY pad array.
//=========================
#include <reg52.h>
#include <stdio.h>
// 變數宣告
sbit UP = P1^2; // LED1
sbit DOWN = P1^3; // LED2
sbit LEFT = P1^4; // LED3
sbit RIGHT = P1^5; // LED4
sbit SCAN0 = P2^7; // KEY SCAN0
sbit SCAN1 = P2^6; // KEY SCAN1
sbit SCAN2 = P2^5; // KEY SCAN2
sbit SCAN3 = P2^4; // KEY SCAN3
sbit DET3 = P2^3; // KEY DETECT0, always high
sbit DET2 = P2^2; // KEY DETECT2
sbit DET1 = P2^1; // KEY DETECT1
sbit DET0 = P2^0; // KEY DETECT0
int n_SCAN;
int TIMES=65536; // 16位元計數器
int PWMHIGH=1;
int PWMLOW=50000;
int PERIOD;
unsigned KEY,temp;
//副程式宣告
void TIMER1_initinal(int baudrate);
void delay (int j);
//主程式開始
void main(void)
{
TIMER1_initinal(9600); // 使用UART,baudrate=9600
PERIOD=TIMES-PWMHIGH;
TMOD = (TMOD & 0xF0) | 0x01; // Set T/C0 Mode
TH0= PERIOD/256; // load sampleing rate
TL0= PERIOD%256; //
ET0 = 1; // Enable Timer 0 Interrupts
TR0 = 1; // Start Timer 0 Running
EA = 1; // Global Interrupt Enable
printf("\n7 KEY Detect Program\n\n");
SCAN0=SCAN1=SCAN2=SCAN3=1;
DET3=DET2=DET1=DET0=1; // 設定成輸入pin
n_SCAN=0;
UP=DOWN=LEFT=RIGHT=0;
while(1)
{
if((P2&0xFF)!=0xFF) // 偵測是否按按鍵?
{
temp=P2&0xFF; // 第一次儲存按鍵值
delay(6000); // 延遲 0.48us*6000=2.88ms,防彈跳調整
KEY=P2&0xFF; // 第二次讀取按鍵值
if (KEY&&temp) // 判別是否為同一鍵
{
delay(6000);
switch(KEY)
{
case 0x7B: printf("SW20 pressed, code=0x7B\n");
UP^=1;
break;
case 0x7D: printf("SW15 pressed, code=0x7D\n");
LEFT^=1;
break;
case 0x7E: printf("SW19 pressed, code=0x7E\n");
UP=DOWN=LEFT=RIGHT=1;
break;
case 0xBD: printf("SW14 pressed, code=0xBD\n");
DOWN^=1;
break;
case 0xBE: printf("SW18 pressed, code=0xBE\n");
DOWN^=!(UP^=1); // binary down counter
LEFT^=(!DOWN && !UP);
RIGHT^=(!LEFT && !DOWN && !UP);
break;
case 0xDE: printf("SW17 pressed, code=0xDE\n");
DOWN^=UP^=1; // binary up counter
LEFT^=(DOWN && UP);
RIGHT^=(LEFT && DOWN && UP);
break;
case 0xEE: printf("SW16 pressed, code=0xEE\n");
RIGHT^=1;
break;
default: break;
}
//delay(6000);
}
}
}
}
//UART副程式
void TIMER1_initinal(int baudrate)
{
PCON = 0x00; // PCON: if SMOD=1(b7), Baud Rate is Doubled
SCON = 0x52; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit reload
//TH1 = 256-(11059200/384/baudrate); // TH1: reload value for baud @ 11.0592MHz, TH=0xFD
TH1 = 256-(25000000/372/baudrate); // TH1: reload value for baud @ 25MHz, TH=0xF9
TR1 = 1; // TR1: timer 1 run
//TI = 1; // TI: set TI to send first char of UART
}
//計時器0中斷1
void timer0_ISR(void) interrupt 1
{
if((SCAN0==1)&&(SCAN1&&SCAN2&&SCAN3)&&(n_SCAN==0))
{
TR0=0;
SCAN0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN0==0)&&(SCAN1&&SCAN2&&SCAN3)&&(n_SCAN==0))
{
TR0=0;
n_SCAN=1; // 準備掃瞄列1
SCAN0=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
if((SCAN1==1)&&(SCAN0&&SCAN2&&SCAN3)&&(n_SCAN==1))
{
TR0=0;
SCAN1=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN1==0)&&(SCAN0&&SCAN2&&SCAN3)&&(n_SCAN==1))
{
TR0=0;
n_SCAN=2; // 準備掃瞄列2
SCAN1=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
if((SCAN2==1)&&(SCAN0&&SCAN1&&SCAN3)&&(n_SCAN==2))
{
TR0=0;
SCAN2=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN2==0)&&(SCAN0&&SCAN1&&SCAN3)&&(n_SCAN==2))
{
TR0=0;
n_SCAN=3; // 準備掃瞄列3
SCAN2=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
if((SCAN3==1)&&(SCAN0&&SCAN1&&SCAN2)&&(n_SCAN==3))
{
TR0=0;
SCAN3=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN3==0)&&(SCAN0&&SCAN1&&SCAN2)&&(n_SCAN==3))
{
TR0=0;
n_SCAN=0; // 準備掃瞄列0
SCAN3=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
}
void delay (int j)
{
while(j)
j--;
}
//======== CONSOLE MESSAGE =======
7 KEY Detect Program
SW20 pressed, code=0x7B
SW14 pressed, code=0xBD
SW15 pressed, code=0x7D
SW16 pressed, code=0xEE
SW17 pressed, code=0xDE
SW18 pressed, code=0xBE
SW19 pressed, code=0x7E
//Project: Key pad detect program
//Author: Leo.Tseng
//Date: 2011/12/06
//MCU: W78E054D
//CRYSTAL: 25Mhz
//Description: Use uart for output, set boudrate=9600,
// Decode KEY pad, this program could support
// 4X4 KEY pad array.
//=========================
#include <reg52.h>
#include <stdio.h>
// 變數宣告
sbit UP = P1^2; // LED1
sbit DOWN = P1^3; // LED2
sbit LEFT = P1^4; // LED3
sbit RIGHT = P1^5; // LED4
sbit SCAN0 = P2^7; // KEY SCAN0
sbit SCAN1 = P2^6; // KEY SCAN1
sbit SCAN2 = P2^5; // KEY SCAN2
sbit SCAN3 = P2^4; // KEY SCAN3
sbit DET3 = P2^3; // KEY DETECT0, always high
sbit DET2 = P2^2; // KEY DETECT2
sbit DET1 = P2^1; // KEY DETECT1
sbit DET0 = P2^0; // KEY DETECT0
int n_SCAN;
int TIMES=65536; // 16位元計數器
int PWMHIGH=1;
int PWMLOW=50000;
int PERIOD;
unsigned KEY,temp;
//副程式宣告
void TIMER1_initinal(int baudrate);
void delay (int j);
//主程式開始
void main(void)
{
TIMER1_initinal(9600); // 使用UART,baudrate=9600
PERIOD=TIMES-PWMHIGH;
TMOD = (TMOD & 0xF0) | 0x01; // Set T/C0 Mode
TH0= PERIOD/256; // load sampleing rate
TL0= PERIOD%256; //
ET0 = 1; // Enable Timer 0 Interrupts
TR0 = 1; // Start Timer 0 Running
EA = 1; // Global Interrupt Enable
printf("\n7 KEY Detect Program\n\n");
SCAN0=SCAN1=SCAN2=SCAN3=1;
DET3=DET2=DET1=DET0=1; // 設定成輸入pin
n_SCAN=0;
UP=DOWN=LEFT=RIGHT=0;
while(1)
{
if((P2&0xFF)!=0xFF) // 偵測是否按按鍵?
{
temp=P2&0xFF; // 第一次儲存按鍵值
delay(6000); // 延遲 0.48us*6000=2.88ms,防彈跳調整
KEY=P2&0xFF; // 第二次讀取按鍵值
if (KEY&&temp) // 判別是否為同一鍵
{
delay(6000);
switch(KEY)
{
case 0x7B: printf("SW20 pressed, code=0x7B\n");
UP^=1;
break;
case 0x7D: printf("SW15 pressed, code=0x7D\n");
LEFT^=1;
break;
case 0x7E: printf("SW19 pressed, code=0x7E\n");
UP=DOWN=LEFT=RIGHT=1;
break;
case 0xBD: printf("SW14 pressed, code=0xBD\n");
DOWN^=1;
break;
case 0xBE: printf("SW18 pressed, code=0xBE\n");
DOWN^=!(UP^=1); // binary down counter
LEFT^=(!DOWN && !UP);
RIGHT^=(!LEFT && !DOWN && !UP);
break;
case 0xDE: printf("SW17 pressed, code=0xDE\n");
DOWN^=UP^=1; // binary up counter
LEFT^=(DOWN && UP);
RIGHT^=(LEFT && DOWN && UP);
break;
case 0xEE: printf("SW16 pressed, code=0xEE\n");
RIGHT^=1;
break;
default: break;
}
//delay(6000);
}
}
}
}
//UART副程式
void TIMER1_initinal(int baudrate)
{
PCON = 0x00; // PCON: if SMOD=1(b7), Baud Rate is Doubled
SCON = 0x52; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit reload
//TH1 = 256-(11059200/384/baudrate); // TH1: reload value for baud @ 11.0592MHz, TH=0xFD
TH1 = 256-(25000000/372/baudrate); // TH1: reload value for baud @ 25MHz, TH=0xF9
TR1 = 1; // TR1: timer 1 run
//TI = 1; // TI: set TI to send first char of UART
}
//計時器0中斷1
void timer0_ISR(void) interrupt 1
{
if((SCAN0==1)&&(SCAN1&&SCAN2&&SCAN3)&&(n_SCAN==0))
{
TR0=0;
SCAN0=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN0==0)&&(SCAN1&&SCAN2&&SCAN3)&&(n_SCAN==0))
{
TR0=0;
n_SCAN=1; // 準備掃瞄列1
SCAN0=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
if((SCAN1==1)&&(SCAN0&&SCAN2&&SCAN3)&&(n_SCAN==1))
{
TR0=0;
SCAN1=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN1==0)&&(SCAN0&&SCAN2&&SCAN3)&&(n_SCAN==1))
{
TR0=0;
n_SCAN=2; // 準備掃瞄列2
SCAN1=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
if((SCAN2==1)&&(SCAN0&&SCAN1&&SCAN3)&&(n_SCAN==2))
{
TR0=0;
SCAN2=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN2==0)&&(SCAN0&&SCAN1&&SCAN3)&&(n_SCAN==2))
{
TR0=0;
n_SCAN=3; // 準備掃瞄列3
SCAN2=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
if((SCAN3==1)&&(SCAN0&&SCAN1&&SCAN2)&&(n_SCAN==3))
{
TR0=0;
SCAN3=0;
PERIOD = TIMES-PWMLOW;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
else if((SCAN3==0)&&(SCAN0&&SCAN1&&SCAN2)&&(n_SCAN==3))
{
TR0=0;
n_SCAN=0; // 準備掃瞄列0
SCAN3=1;
PERIOD = TIMES-PWMHIGH;
TH0= PERIOD/256;
TL0= PERIOD%256;
TR0=1;
}
}
void delay (int j)
{
while(j)
j--;
}
//======== CONSOLE MESSAGE =======
7 KEY Detect Program
SW20 pressed, code=0x7B
SW14 pressed, code=0xBD
SW15 pressed, code=0x7D
SW16 pressed, code=0xEE
SW17 pressed, code=0xDE
SW18 pressed, code=0xBE
SW19 pressed, code=0x7E
訂閱:
文章 (Atom)