📄 main.c
字号:
PORTA = 0XFF; //输出高电平
PACONH = 0X00; //再把PA口设置为开漏输入
PACONL = 0X00; //上拉有效
PAPUR = 0XFF;
// PORTC=PORTC|0X01;//PC0 high ->
PORTC=PORTC&0XFB;//portc2 low ,all LED off,portc will not affect scan
LAST_KEY_VALUE=0;
KEY1_OFFSET=255;
KEY2_OFFSET=255;
// NOW_KEY_VALUE=CONSTANT_2;
KEY_COUNT=0;//how many key-press
// CYC_PB=0x7f;//01111111
// current_row=0;
// current_column=0;
current_key_value=0;
// 0_row=0;
// GF_9=0;
PORTB=0XFE;
CYC_PB =1;
for ( i = 0 ; i < 8 ; i++)
{
//bit scan start
//; rotate clockwise
DELAY_A();
//scan
//COLUMN =0;
pa_value=PORTA;
CYC_PA=1;
if ( pa_value != 0XFF )//write the key value
{
for(j=0;j<8;j++)
{
if ( ( CYC_PA & pa_value ) == 0 )
{
//current_column=i;
KEY_COUNT++;
current_key_value=i*8+j;
if( KEY_COUNT==1 )
{
KEY1_OFFSET=current_key_value;
LAST_KEY_VALUE=KEY1_OFFSET;
}
if( KEY_COUNT==2 )
{
KEY2_OFFSET=current_key_value;
}
}
CYC_PA<<=1;
}
}
CYC_PB<<=1;
PORTB=~CYC_PB;
}
/* //PORTB_HIGH();
if((KEY_COUNT==2)&&((KEY1_OFFSET==stuck_key)||(KEY2_OFFSET==stuck_key)))//如果有两个键按下且其中一个键是卡键则调整值
{
if(KEY1_OFFSET==stuck_key)
{
KEY1_OFFSET=KEY2_OFFSET;
}
LAST_KEY_VALUE=KEY1_OFFSET;
KEY2_OFFSET=255;
}//以下几个ELSE IF语句为套数的切换
if(KEY_COUNT==0)//如果第一次扫描只有一个卡键,说明卡键不卡了则卡键变量值为255。
{
stuck_key=255;
// LAST_KEY_VALUE=KEY1_OFFSET;
}
else if((KEY_COUNT==1)&&(KEY1_OFFSET==stuck_key))
{
KEY1_OFFSET=255;
LAST_KEY_VALUE=0;
}
*/
// first_scan_flag=1;
PORTB=last_pb;//恢复PB口值
PORTC=last_pc;//恢复PC口值
//
}
/*
void LOAD_TIMER2(void)
{
}
*/
/*
void KEYSCAN(void)//the next keyscan
{
KEY1_OFFSET=CONSTANT_2;
KEY2_OFFSET=CONSTANT_2;
BIT_SCANKEY();
KYE_NUMBER();
}
*/
void DELAY_100MS(void) //machine cycle = 1/3us if Oscillator is 12MHz around 100ms
{
for (m = 0; m < 3000; m ++)
{
;
}
}
void DELAY_12MS(void) //其实是12MS machine cycle = 1/3us if Oscillator is 12MHz around 100ms
{
for (m = 0; m < 1000; m ++)
{
;
}
}
void DELAY_A (void)//around 1ms
{
for (m = 0; m < 30; m ++)
{
;
}
}
void delay_65ms(void)//come to idel mode
{
TL2=0;
TH2=0;
TR2=1;
ET2=1;
CACON_VALUE=0x03;//00000011
PCON=PCON|0X01;
TR2=0;
ET2=0;
}
/*
void delay_30ms(void)
{
TL2=0;
TH2=128;
TR2=1;
ET2=1;
CACON_VALUE=0x03;//00000011
PCON=PCON|0X01;
TR2=0;
ET2=0;
}
*/
void pa_int_enable(void)
{
PAPND = 0X00;//clear interrupt flag
PAINT = 0XFF;//interrupt enable
EX0=1; //port a interrupt enable
} //}
void pa_int_disenble(void)
{ //{
PAPND = 0X00;
PAINT = 0X00;
EX0=0;
}
void all_mode_led_light_3_second(void)
{
unsigned char idata i;
PORTC=(PORTC|0x04);//portc2 high
PORTB = 0x0f;
for(i=0;i<50;i++)
{
delay_65ms();
}
PORTB = 0xff;
}
void turn_off_portb_led_2_second(void)//当前套灯暗2S
{
unsigned char idata i;
PORTC=(PORTC|0x04);//portc2 high
PORTB = 0xff;
for(i=0;i<30;i++)
{
delay_65ms();
}
}
void turn_on_portb_led(char value)//打开PORTB口灯
{
PORTC=(PORTC|0x04);//portc2 high
last_pb=value;
PORTB = value;//portb low
}
void turn_off_portb_led(void)//关闭PORTB口所有灯
{
PORTC=(PORTC|0x04);//portc2 high
last_pb=0xff;
PORTB = 0xff;//portb low
}
void wait_for_key_release(void)
{
while(LAST_KEY_VALUE==KEY1_OFFSET)//waiting for release this key
{
BIT_SCANKEY();
delay_65ms();
}
}
//--------------------------------------
// Main
//--------------------------------------
void main(void)
{
#ifndef CHIP
P2 = 0;
#endif
SP = 0xDF;
#ifdef CHIP
CHIP_MODE=0;
#else
CHIP_MODE=1;
#endif
#ifdef FREQ_4MHZ
DIVL = 0x78; // SDIV=10101,DIVH=00h
DIVH = 0xA8;
#endif
#ifdef FREQ_12MHZ
DIVL = 0x68;
DIVH = 0xA9;
#endif
DELAY_100MS(); //; make sure power line stable before application starts
INIT_BEFORE_SCAN();
//{
while(1)
{
loop: turn_off_portb_led();//为TV套是如果有发码则关闭当前套指示灯。
KEY_DETECTED=0;//emulator routine cycle waiting for key press flag
PORTC=PORTC&0xFB;//PC2 to low ,portc0 to low ,turn off all light
PORTC=PORTC|0x01;//PC2 to low ,portc0 to low ,turn off all light
PORTB = 0X00;
// TR1=0;
// ET1=0;
// TR0=0;
// ET0=0;
TR2=0;
ET2=0;
pa_int_enable();// PORTA_INT_ENABLE();
if(CHIP_MODE==1)//emulator mode
{
// EMULATOR_MODE_A();
while(KEY_DETECTED==0) {};
}
else
{
PCON=02;//bit 1 -> Stop mode, all external interrupt should be level triggered to exit stop mode
}
pa_int_disenble();
PORTC=PORTC|0X05;//PC2 一直是高电平,PC0也置高
// first_scan_flag=0;
// set=0;
// last_led_value=0xbf;//1011 1111
// last_pb=0xbf;
BIT_SCANKEY();//get KEY_COUNT,KEY1_OFFSET,KEY2_OFFSET
//-------------------------------------------------------------------
if(KEY1_OFFSET==0)//RC MODE键
{
turn_on_portb_led(last_led_value);
wait_for_key_release();
for ( i = 0 ; i < 300 ; i++ )//delay 3.5s
{
DELAY_12MS();
BIT_SCANKEY();
// turn_on_current_led();//在键盘扫描处关闭了指示灯,故该处再次打开
if(KEY1_OFFSET == 0)//还是1键
{
i=0;//start from 0s
set++;
if(set>=4)
{
set=0;
}
first_set: if(set==0)
{
if(memory_channel[0]==0)
{
set++;
}
else
{
last_led_value=0x7f;
}
}
if(set==1)
{
if(memory_channel[1]==0)
{
set++;
}
else
{
last_led_value=0xbf;
}
}
if(set==2)
{
if(memory_channel[2]==0)
{
set++;
}
else
{
last_led_value=0xdf;
}
}
if(set==3)
{
if(memory_channel[3]==0)
{
set++;
if(set>=4)
{
set=0;
goto first_set;
}
}
else
{
last_led_value=0xef;
}
}
turn_on_portb_led(last_led_value);//0111 1111,light the firsr light
SRAM_TO_FLASH(10,set);
SRAM_TO_FLASH(11,0x90);
}
else if((KEY1_OFFSET != 0)&&(KEY1_OFFSET != 255))//中间有其他按键,退出,进入发送
{
goto sent;
}
wait_for_key_release();
}
goto loop;
}
else if(KEY1_OFFSET!=255)
{
sent: press=0;
toggle=~toggle;
TH2=TIME_4MS;
TL2=TIME_4MS;
TR2=1;
ET2=1;
// TR1=0;//开定时器
// ET1=0;//在发码前不能开中断
sent_flash=0;
press_time=0;
end_flag=0;
while(LAST_KEY_VALUE==KEY1_OFFSET)
{
if(KEY2_OFFSET!=255)//two key press delay
{
turn_off_portb_led();//双键时指示灯熄灭
if(((KEY1_OFFSET==1)&&(KEY2_OFFSET==18))||((KEY1_OFFSET==18)&&(KEY2_OFFSET==1)))
{
for ( i = 0 ; i < 40 ; i++ )//delay 3ms
{
delay_65ms();
BIT_SCANKEY();
if(((KEY1_OFFSET==1)&&(KEY2_OFFSET==18))||((KEY1_OFFSET==18)&&(KEY2_OFFSET==1)))
{
continue;
}
else
{
goto sent;
}
}
all_mode_led_light_3_second();
turn_off_portb_led();//双键时指示灯熄灭
wait_for_key_release();
j=0;
for ( i = 0,k=0 ; i < 150 ; i++,k++ )//delay 10s
{
delay_65ms();
BIT_SCANKEY();
if(k<=4)
{
turn_on_portb_led(last_led_value);//在键盘扫描处关闭了指示灯,故该处再次打开
}
else
{
turn_off_portb_led();
}
if(k>=8)
{
k=0;
}
if(j==3)//enter 3 number
{
valid_code=0;
locate_channel=temp_number[0]*100+temp_number[1]*10+temp_number[2];
if((set==0)&&((locate_channel>=101)&&(locate_channel<=111)))
{
valid_code=1;
memory_channel[set]=locate_channel-101;
}
else if((set==1)&&((locate_channel>=201)&&(locate_channel<=210)))
{
valid_code=1;
memory_channel[set]=locate_channel-190;
}
else if((set==2)&&((locate_channel>=301)&&(locate_channel<=302)))
{
valid_code=1;
memory_channel[set]=locate_channel-280;
}
else if((set==3)&&(locate_channel==401))
{
valid_code=1;
memory_channel[set]=locate_channel-378;
}
else if(locate_channel==0)//000三位代码也是有效的
{
valid_code=1;
memory_channel[set]=locate_channel;
}
if(valid_code==1)//代码有效
{
temp_data_flash=(unsigned char)memory_channel[set];
SRAM_TO_FLASH(2*set,temp_data_flash);
temp_data_flash=(unsigned char)(memory_channel[set]>>8);
SRAM_TO_FLASH(2*set+1,temp_data_flash);
SRAM_TO_FLASH(8,0x90);//用户已操作标志。
turn_on_portb_led(last_led_value);//代码输入正确后当前套指示灯长亮10S
//******如果四套设备代码都是零则是不允许的,第一套变成默认值。*****//
if((memory_channel[0]==0)&&(memory_channel[1]==0)&&(memory_channel[2]==0)&&(memory_channel[3]==0))
{
memory_channel[0]=7;
temp_data_flash=(unsigned char)memory_channel[0];
SRAM_TO_FLASH(0,temp_data_flash);
temp_data_flash=(unsigned char)(memory_channel[0]>>8);
SRAM_TO_FLASH(1,temp_data_flash);
}
for(i=0;i<150;i++)
{
delay_65ms();
BIT_SCANKEY();
if(KEY1_OFFSET==0)//如果是RC MODE 键则切换到其他套重新输入代码
{
goto repeat;
}
}
goto loop;
}
else//当前套灯暗2S后继续输入代码。
{
turn_off_portb_led_2_second();
i=0;
j=0;
k=0;
}
}
if(( KEY1_OFFSET>=2 ) && ( KEY1_OFFSET<=10 ) )//数字键1-9
{
i=0;
temp_number[j++]=KEY1_OFFSET-1;
}
else if(KEY1_OFFSET==12) //数字键0
{
i=0;
temp_number[j++]=0;
}
else if(KEY1_OFFSET==0)//该键RC MODE 键
{
repeat: j=0;//切换到其他套时重新输入3位代码。
i=0;//start from 0s
set++;
if(set>=4)
{
set=0;
}
get_last_led_value();
turn_on_portb_led(last_led_value);//0111 1111,light the firsr light
}
else if(KEY1_OFFSET!=255)//其他键
{
i=0;
}
wait_for_key_release();
}
goto loop;
}
while(KEY2_OFFSET!=255)
{
TR2=0;
ET2=0;
BIT_SCANKEY();
delay_65ms();
TR2=1;
ET2=1;
}
}
press_time++;
// init_timer0();
SEND_CODE();
TR2=0;
ET2=0;
BIT_SCANKEY();
TR2=1;
ET2=1;
if(LAST_KEY_VALUE==KEY1_OFFSET)//the key is pressed all the same
{
press=1;
}
if(press_time==300)//按住30S进入掉电模式。
{
// stuck_key=KEY1_OFFSET;//保存卡键的值。
return;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -