1 /*------------------------------------------- 2 Function name: main.c 3 Designed By: Milo Lu 4 Version: 2020-11-21 5 1. adapted,first functional draft. 6 Description: 7 1. K1 project 8 2. SC8P1153A 9 // SC8P1153A 10 // --------------- 11 // LEARN_S3-PA0-| |-PA1 12 // LED,PB7-| |-PA2 13 // ON_S1,PB6-|RST |-PA3 14 // VCC-| |-GND 15 // PB5-| |-PB0-OFF_S2 16 // PB4-| |-PB1-SDA 17 // DATA,PB3-| |-PB2-SCL 18 // --------------- 19 -------------------------------------------*/ 20 21 22 #include <sc.h> //sc library,system search h file automatically. 23 24 //----------- My Define ----------------- 25 #define Button1_S1 PORTB6 // input 26 #define Button2_S2 PORTB0 // input 27 #define Button3_S3 PORTA0 // input 28 29 #define DIR_OUTPUT 0 //Output direction 30 #define DIR_INPUT 1 //Input direction 31 #define SDA_DIR TRISB1 //DIR 32 #define SDA PORTB1 33 #define SCL PORTB2 // output 34 35 #define LED_4 PORTB7 // output,0=led on,1=led off 36 #define DATA_IN PORTB3 // input, modulation output 37 #define RELAY_CTL PORTA2 // output, relay control 38 39 40 //----------- My variable parameters ------- 41 unsigned char My_Mode; 42 unsigned char Inching_Trigger; 43 unsigned char RX_Delay; 44 unsigned char START_RX; 45 unsigned char CMD_VALUE; 46 unsigned char My_Led_Blink; 47 unsigned char My_Led_Delay; 48 unsigned char RemoteID_Index; //0xFB,one remote included 3bytes,there could be 83 pcs remotes stored in the abstract. 49 unsigned char Device_Sys_Mode;//0xFE, high 4bits:range=0-2:0 NORMAL,1 XOR,2 INCHING. Low 4bits=CONNECT_CMD 50 51 unsigned int My_Remot0ID; 52 unsigned int Learn_Time_ms; 53 unsigned int DATA_RECEIVED; 54 55 //------------- delay about 5us ----------- 56 void delay5us() 57 { 58 asm("nop"); 59 asm("nop"); 60 asm("nop"); 61 asm("nop"); 62 asm("nop"); 63 asm("nop"); 64 } 65 void delayms(unsigned char ms) 66 { 67 unsigned char i,j; 68 69 for(i=0;i<ms;i++) 70 { 71 for(j=0;j<200;j++) 72 delay5us(); 73 asm("clrwdt"); 74 } 75 } 76 77 //--------- iic bus for 24C02 ------------- 78 void iic_start()//SDA falling when SCL is high 79 { 80 SDA_DIR = DIR_OUTPUT; 81 SDA = 1; 82 asm("nop");asm("nop"); 83 SCL = 1; 84 delay5us(); 85 SDA = 0; 86 delay5us(); 87 SCL = 0; 88 } 89 void iic_stop()//SDA rise when SCL is high 90 { 91 SDA_DIR = DIR_OUTPUT; 92 SDA = 0; 93 asm("nop"); 94 SCL = 1; 95 delay5us(); 96 SDA = 1; 97 delay5us(); 98 SCL = 0; 99 } 100 void iic_ack() 101 { 102 SCL = 0; 103 asm("nop");asm("nop");asm("nop"); 104 SCL = 1; 105 delay5us(); 106 SCL = 0; 107 asm("nop");asm("nop"); 108 } 109 void iic_NoAck() 110 { 111 SDA_DIR = DIR_OUTPUT; 112 SDA = 1; 113 asm("nop");asm("nop");asm("nop"); 114 SCL = 1; 115 delay5us(); 116 SCL = 0; 117 asm("nop");asm("nop"); 118 } 119 void iic_write_byte(unsigned char u8_value) 120 { 121 unsigned char i; 122 SDA_DIR = DIR_OUTPUT; 123 for(i=0;i<8;i++) 124 { 125 SCL = 0; 126 delay5us(); 127 if(u8_value&0x80) SDA = 1; 128 else SDA = 0; 129 delay5us(); 130 SCL = 1; 131 delay5us(); 132 u8_value<<=1; 133 } 134 SCL = 0; 135 delay5us(); 136 SDA = 1; 137 } 138 unsigned char iic_read_byte() 139 { 140 unsigned char i,ret_val=0; 141 SDA_DIR = DIR_INPUT; 142 SDA = 1; 143 for(i=0;i<8;i++) 144 { 145 SCL = 0; 146 delay5us(); 147 SCL = 1; 148 delay5us(); 149 ret_val<<=1; 150 if(SDA) 151 ret_val |= 1; 152 } 153 return ret_val; 154 } 155 void iic_write_byte_to_addr(unsigned char addr,unsigned char val) 156 { 157 iic_start(); 158 iic_write_byte(0xa0); 159 iic_ack(); 160 iic_write_byte(addr); 161 iic_ack(); 162 iic_write_byte(val); 163 iic_ack(); 164 iic_stop(); 165 } 166 unsigned char iic_read_byte_from_addr(unsigned char addr) 167 { 168 unsigned char ret_val; 169 iic_start(); 170 iic_write_byte(0xa0); 171 iic_ack(); 172 iic_write_byte(addr); 173 iic_ack(); 174 iic_start(); 175 iic_write_byte(0xa1); 176 iic_ack(); 177 ret_val = iic_read_byte(); 178 SCL = 0; 179 iic_NoAck(); 180 iic_stop(); 181 return ret_val; 182 } 183 184 /******************************************* 185 ** Main Function 186 ********************************************/ 187 void main(void) 188 { 189 //------------ My static variable --------- 190 static unsigned char Btn1_Debouncing,Btn2_Debouncing; 191 //------------- variable ----------- 192 unsigned char tmp,j; 193 unsigned int i; 194 195 //---------- System Start ---------- 196 asm("nop"); 197 asm("clrwdt"); 198 199 //-------- System Init ------------- 200 OPTION_REG =0; //Fdev for TMR0 201 OSCCON = 0XF1; //8M 202 203 //---------- PORTA PORTB Init ------------- 204 // pull-up and pull-down resistor 205 // Bit7~Bit4--pull up resistor;Bit3~Bit0--pull down resistor;0=disable;1=enable 206 UPDOWNA = 0B00010100; //PA0 pull-up,PA2 pull-down registor enable 207 // Bit7~Bit0--pull-up registor. enable;1=enable;0=disable. 208 WPUB = 0B01001001; //PB6,PB3,PB0 pull-up registor enable 209 // Bit7~Bit0--pull-down registor enable;1=enable;0=disable. 210 PDCONB = 0b00000000; //PB disable all pull-down registor 211 // Bit7~Bit0--output open enable;1=enable;0=disable 212 ODCONB = 0B00000000; //None enable 213 //IO input output direction option--0=Output;1=Input 214 TRISA = 0B00000001; //PA0=Input;Others=Output 215 TRISB = 0B01111001; //PB1=Output,Others=Input 216 SDA = 0; //PB1 = 0 217 RELAY_CTL = 0; 218 219 //------- RAM Data from 24C02 ------- 220 //iic_write_byte_to_addr(0xFD,0x28); //test 221 RemoteID_Index = iic_read_byte_from_addr(0xFB); 222 if(RemoteID_Index >= 48)//address index:a class is combined of:[2bytes id+1byte(high 4bits=mode,low 4bits=command)]*16=48bytes 223 RemoteID_Index = 0; 224 225 My_Remot0ID = iic_read_byte_from_addr(0); //id high byte 226 My_Remot0ID<<=8; 227 My_Remot0ID |=iic_read_byte_from_addr(1); //id low byte 228 Device_Sys_Mode = iic_read_byte_from_addr(2);//high 4bits = mode and low 4bits = command 229 230 DATA_RECEIVED = 0; //clear RF data buffer 231 My_Mode = 0; //mode for key option 232 233 //------------- TIMER0 -------------- 234 TMR0 = 0; // CNT++ = 1us 235 OPTION_REG = 0x00; // Focs/4 236 TMR0PRD = 50; // Load default value interrupt trigger per 50us 237 238 //----------- Interrupt ------------------ 239 INTCON = 0x00; //Disable Gobal interrupt 240 IOCB = 0B00001000; // Enable level PB3 change interrupt 241 OSCCON |= 0X01; //TIMER0 Start... 242 INTCON = 0xA8; //TIMER0 Interrupt enable,PORTB Level changed interrupt enable 243 244 while(1) 245 { 246 asm("clrwdt"); 247 248 //--------- Button1--Connect Key Press down ----------- 249 if(!Button1_S1) 250 { 251 if(Btn1_Debouncing < 250) Btn1_Debouncing++;//do not block cpu but only bit delay. 252 else if(Btn1_Debouncing == 250) 253 { 254 if(!Button1_S1) 255 { 256 RELAY_CTL = 1; 257 Btn1_Debouncing++; 258 } 259 } 260 } 261 else if(Btn1_Debouncing != 0) Btn1_Debouncing =0; 262 263 //------------ Button2--Disconnect Key Press down ------------ 264 if(!Button2_S2) 265 { 266 if(Btn2_Debouncing < 250) Btn2_Debouncing++;//do not block cpu but only bit delay. 267 else if(Btn2_Debouncing == 250) 268 { 269 if(!Button2_S2) 270 { 271 RELAY_CTL = 0; 272 Btn2_Debouncing++; 273 } 274 } 275 } 276 else if(Btn2_Debouncing != 0) Btn2_Debouncing =0; 277 278 //------------ Button3--Learn Key Press down ---------------------- 279 //-- 1.click enter normal learn mode; Led blinks once per 1.2s 280 //-- 2.click enter XOR learn mode; Led blinks twice per 1.2s 281 //-- 3.click enter inching learn mode; Led blinks 3 times per 1.2s 282 //-- 4.click repeat (goto step 1). 283 //-- 5.press down for more than 9s,clear ids, modes and commands. 284 //----------------------------------------------------------------- 285 switch(My_Mode&0x0F) 286 { 287 case 0: //key press down 288 { 289 if(!Button3_S3) 290 { 291 delayms(20); //delay block CPU. 292 if(!Button3_S3) 293 { 294 GIE = 0; //Critical code for Learn_Time_ms 295 if((My_Mode&0xF0)==0) //first time press down 296 { 297 Learn_Time_ms = 900; //learn mode confirn time:learn mode<3s, reset mode>9s 298 My_Mode = 0x11; //high 4bits means mode,low bit mean step 299 } 300 else if((My_Mode&0xF0)==0x20) //press down again in learn mode(NORMAL) 301 { 302 My_Mode = 0x21; //wait for key release 303 } 304 else if((My_Mode&0xF0)==0x30) //press down again in learn mode(XOR) 305 { 306 My_Mode = 0x31; //wait for key release 307 } 308 else if((My_Mode&0xF0)==0x40) //press down again in learn mode(XOR) 309 { 310 My_Mode = 0x41; //wait for key release 311 } 312 else 313 { 314 My_Mode = 0x01; 315 } 316 RX_Delay = 300; 317 GIE = 1; //exit critical code for Learn_Time_ms 318 } 319 } 320 break; 321 } 322 case 1: //key release 323 { 324 if(Button3_S3) 325 { 326 delayms(20); //delay block CPU. 327 if(Button3_S3) 328 { 329 GIE = 0; //Critical code for Learn_Time_ms 330 if(((My_Mode&0xF0)==0x10) && (Learn_Time_ms >= 600)) //sigle click 331 { 332 Learn_Time_ms = 2000; //Time out 333 My_Mode = 0x20; //learn mode(NORMAL) 334 } 335 else if(((My_Mode&0xF0)==0x20)&&(Learn_Time_ms)) //last mode is NORMAL 336 { 337 Learn_Time_ms = 2000; 338 My_Mode = 0x30; //Learn mode(XOR) 339 } 340 else if(((My_Mode&0xF0)==0x30)&&(Learn_Time_ms)) //last mode is XOR 341 { 342 Learn_Time_ms = 2000; 343 My_Mode = 0x40; //Learn mode(INCHING) 344 } 345 else if(((My_Mode&0xF0)==0x40)&&(Learn_Time_ms)) //last mode is INCHING 346 { 347 Learn_Time_ms = 0; //Time out 348 My_Mode = 0x00; //exit learn mode(NORMAL)-->repeat 349 } 350 else 351 { 352 My_Mode=0x00; 353 } 354 RX_Delay = 300; 355 GIE = 1; //exit critical code for Learn_Time_ms 356 } 357 } 358 else if((!Button3_S3)&&(My_Mode&0x10)) 359 { 360 if(Learn_Time_ms == 0) //key press down for more than 9 seconds,reset remote ID 361 { 362 GIE = 0; //disable interrupt 363 //----- reset RAM -------- 364 RemoteID_Index = 0; 365 My_Remot0ID = 0; 366 //----- reset ROM ------- 367 iic_write_byte_to_addr(0xFB,RemoteID_Index); 368 for(i=0;i<200;i++)delay5us(); 369 asm("clrwdt"); 370 for(tmp=0;tmp<48;tmp++) 371 { 372 iic_write_byte_to_addr(tmp,0x00); 373 for(i=0;i<200;i++)delay5us(); //a delay should be add. 374 asm("clrwdt"); 375 } 376 //------ indication ----- 377 My_Mode=0x01; 378 RX_Delay = 300; 379 My_Led_Blink = 6; //led blinks 380 GIE = 1; //interrupt enable 381 } 382 } 383 break; 384 } 385 } 386 //---------------- Paraser ------------------ 387 if(DATA_RECEIVED!=0) 388 { 389 GIE = 0; //enter critical code to avoid data crash,which from RF modulation 390 if(Learn_Time_ms) //learn mode 391 { 392 tmp = My_Mode&0xF0; 393 if(tmp == 0x20 || tmp == 0x30 || tmp == 0x40) //Learn mode 0x20=Normal,0x30=OXR,0x40=Inching 394 { 395 Device_Sys_Mode=tmp; //mode 396 Device_Sys_Mode|=CMD_VALUE; //command 397 My_Remot0ID = DATA_RECEIVED; //id 398 tmp = (DATA_RECEIVED>>8); //High byte first,store in ROM 399 iic_write_byte_to_addr(RemoteID_Index,tmp); 400 for(i=0;i<200;i++)delay5us(); 401 asm("clrwdt"); 402 403 tmp = DATA_RECEIVED&0x00FF; //Low byte second 404 RemoteID_Index ++; 405 iic_write_byte_to_addr(RemoteID_Index,tmp); 406 for(i=0;i<200;i++)delay5us(); 407 asm("clrwdt"); 408 409 RemoteID_Index ++; //mode and command 410 iic_write_byte_to_addr(RemoteID_Index,Device_Sys_Mode); 411 for(i=0;i<200;i++)delay5us(); 412 asm("clrwdt"); 413 414 RemoteID_Index ++; //address index 415 iic_write_byte_to_addr(0xFB,RemoteID_Index); 416 for(i=0;i<200;i++)delay5us(); 417 asm("clrwdt"); 418 419 if(RemoteID_Index >= 48) //Remote Number Max 8,save 420 RemoteID_Index = 0; 421 422 My_Led_Blink = 10; 423 RX_Delay = 300; 424 My_Mode = 0; 425 Learn_Time_ms = 0; //Exit learn mode 426 } 427 } 428 else //CMD from Remote 429 { 430 //it is faster to get id from RAM than ROM. 431 if(DATA_RECEIVED == My_Remot0ID) 432 { 433 tmp = 0; 434 j = Device_Sys_Mode & 0xF0; 435 if(j == 0x20 || j == 0x30 || j==40); 436 else 437 { 438 My_Remot0ID = 0; 439 tmp = 1; 440 } 441 } 442 else //read from ROM 443 { 444 for(tmp=0,j=0;tmp<16;tmp++) 445 { 446 i=iic_read_byte_from_addr(j); //id high 8bits 447 i<<=8; 448 j++; 449 i|=iic_read_byte_from_addr(j); //id low 8bits 450 j++; 451 Device_Sys_Mode = iic_read_byte_from_addr(j);//mode and command 452 j++; 453 asm("clrwdt"); 454 if(DATA_RECEIVED == i) 455 { 456 tmp = 0; 457 break; 458 } 459 } 460 } 461 if(!tmp ) //id active 462 { 463 tmp = Device_Sys_Mode&0xF0; //mode 464 j = Device_Sys_Mode&0x0F; //command 465 switch (tmp) 466 { 467 case 0x20: //Normal 468 { 469 if(CMD_VALUE == j) 470 { 471 RELAY_CTL = 1; 472 } 473 else 474 { 475 RELAY_CTL = 0; 476 } 477 if(My_Led_Blink == 0) My_Led_Blink = 1; 478 break; 479 } 480 case 0x30: //XOR 481 { 482 if(CMD_VALUE == j) 483 { 484 RELAY_CTL ^= 1; 485 RX_Delay = 300; //delay to avoid repeat 486 if(My_Led_Blink == 0) My_Led_Blink = 1; 487 } 488 489 break; 490 } 491 case 0x40: //Inching 492 { 493 if(CMD_VALUE == j) 494 { 495 RELAY_CTL = 1; 496 Inching_Trigger = 50; //500ms 497 if(My_Led_Blink == 0) My_Led_Blink = 1; 498 } 499 break; 500 } 501 default: 502 { 503 break; 504 } 505 } 506 } 507 } 508 GIE = 1; //exit critical code to open the receiver. 509 DATA_RECEIVED = 0; 510 } 511 } 512 } 513 514 /******************************************* 515 ** Timer0 PB interrupt 516 ** Timer=50us 517 ** PB0 interrupt 518 ** RF data received 519 ********************************************/ 520 void interrupt Isr_Routine() 521 { 522 static unsigned int id,tmp; 523 static unsigned char bits_of_byte,TAR_50us,SysTick; 524 static unsigned long one_byte; 525 unsigned char IO_State; 526 if(T0IF) //TIMER0 Interrupt 527 { 528 T0IF = 0; 529 if(SysTick++ >= 200) // 200*50us = 10ms 530 { 531 if(My_Led_Blink != 0) 532 { 533 if(My_Led_Delay++ < 5) 534 LED_4 = 0; 535 else if(My_Led_Delay < 20) 536 LED_4 = 1; 537 else 538 { 539 My_Led_Delay = 0; 540 My_Led_Blink--; 541 } 542 } 543 else if(Learn_Time_ms >= 1) 544 { 545 if((My_Mode&0xF0)==0x20) //blinks once 546 { 547 if(My_Led_Delay++ < 10) 548 LED_4 = 0; 549 else if(My_Led_Delay < 120) 550 LED_4 = 1; 551 else 552 My_Led_Delay = 0; 553 } 554 else if((My_Mode&0xF0)==0x30) //blinks twice 555 { 556 if(My_Led_Delay++ < 10) 557 LED_4 = 0; 558 else if(My_Led_Delay < 20) 559 LED_4 = 1; 560 else if(My_Led_Delay < 30) 561 LED_4 = 0; 562 else if(My_Led_Delay < 120) 563 LED_4 = 1; 564 else 565 My_Led_Delay = 0; 566 } 567 else if((My_Mode&0xF0)==0x40) //blinks 3 568 { 569 if(My_Led_Delay++ < 10) 570 LED_4 = 0; 571 else if(My_Led_Delay < 20) 572 LED_4 = 1; 573 else if(My_Led_Delay < 30) 574 LED_4 = 0; 575 else if(My_Led_Delay < 40) 576 LED_4 = 1; 577 else if(My_Led_Delay < 50) 578 LED_4 = 0; 579 else if(My_Led_Delay < 120) 580 LED_4 = 1; 581 else 582 My_Led_Delay = 0; 583 } 584 Learn_Time_ms--; 585 586 } 587 else if(Learn_Time_ms==1) 588 { 589 LED_4 = 1; 590 Learn_Time_ms--; 591 } 592 if(Inching_Trigger > 1) 593 { 594 Inching_Trigger--; 595 } 596 else if(Inching_Trigger==1) 597 { 598 RELAY_CTL = 0; 599 Inching_Trigger--; 600 } 601 if(RX_Delay!=0) 602 RX_Delay--; 603 SysTick = 0; 604 } 605 TAR_50us++; 606 } 607 if(PBIF) //PORTB Interrupt 608 { 609 PBIF = 0; 610 611 //---------------------------------------------------------------------------- 612 // RF Data Format:NRZ Encoder 613 // 1B = 1000usH+300usL; 0B = 300usH+1000usL; T = 1300us 614 // ASM Modulation 615 //---------------------------------------------------------------------------- 616 IO_State = (unsigned char)DATA_IN; 617 if(IO_State) // Low to high transition 618 { 619 // Low state time is upper than 1.5ms,OR Paraser busy, data crash, retry again 620 if((TAR_50us >= 30)||(DATA_RECEIVED!=0)||(RX_Delay!=0)) 621 { 622 START_RX = 0; 623 } 624 TAR_50us = 0; 625 } 626 else // High to low transition 627 { 628 if(!START_RX) // The first header doesn't receive 629 { 630 if((TAR_50us > 14)&&(TAR_50us < 30)) // 1.5ms > T > 0.7ms 631 { 632 one_byte = 1; 633 bits_of_byte = 1; 634 START_RX = 1; 635 } 636 } 637 else // The second header received, 638 { // start to get RF data 639 if((TAR_50us >4)&&(TAR_50us< 12)) //0 600us > T > 200us 640 { 641 one_byte <<=1; 642 bits_of_byte++; 643 } 644 else if((TAR_50us > 14)&&(TAR_50us < 30)) // 1.5ms > T > 0.7ms 645 { 646 one_byte<<=1; 647 one_byte+=1; 648 bits_of_byte++; 649 } 650 else 651 { 652 START_RX = 0x00; // data crash, retry again 653 } 654 if(bits_of_byte >= 24) // got one byte, got id 655 { 656 CMD_VALUE = (one_byte&0x0F); //lowest 4 bits are command 657 one_byte>>=4; 658 tmp = one_byte; 659 if(id != tmp) 660 { 661 id = tmp; //got new id 662 } 663 else //at least 2 times get the same id 664 { 665 DATA_RECEIVED = id; //load RF data 666 } 667 START_RX = 0x00; // Receiving repeat 668 one_byte = 0; 669 bits_of_byte = 0; 670 } 671 } 672 TAR_50us = 0; 673 } 674 } 675 }
Received 1248 code from Remote