/** * Den Testalarm Status auf den Bus senden falls noch nicht gesendet. * * @param newAlarm - neuer Testalarm Status */ void send_obj_test_alarm(__bit newAlarm) { if (testAlarmLocal != newAlarm) { send_obj_value(OBJ_TALARM_BUS); send_obj_value(OBJ_STAT_TALARM); } }
/** * Den Alarm Status auf den Bus senden falls noch nicht gesendet. * * @param newAlarm - neuer Alarm Status */ void send_obj_alarm(__bit newAlarm) { if (alarmLocal != newAlarm) { send_obj_value(OBJ_ALARM_BUS); send_obj_value(OBJ_STAT_ALARM); } }
/** * Die empfangene Nachricht vom Rauchmelder verarbeiten. * Wird von _receive() aufgerufen. */ void rm_process_msg(unsigned char* bytes, unsigned char len) { unsigned char objno, cmd, msgType; unsigned char byteno, mask; answerWait = 0; if (noAnswerCount) { noAnswerCount = 0; set_errcode(errCode & ~ERRCODE_COMM); } msgType = bytes[0]; if ((msgType & 0xf0) == 0xc0) // Com-Objekt Werte empfangen { msgType &= 0x0f; for (cmd = 0; cmd < RM_CMD_COUNT; ++cmd) { if (CmdTab[cmd] == msgType) break; } if (cmd < RM_CMD_COUNT) { objValueCurrent = objValues[cmd]; cmdCurrent = cmd; objValues[cmd] = *(unsigned long*)(bytes + 1); cmdCurrent = RM_CMD_NONE; // Versand der erhaltenen Com-Objekte einleiten. Dazu alle Com-Objekte suchen // auf die die empfangenen Daten passen und diese senden. Sofern sie für // den Versand vorgemerkt sind. for (objno = 0; objno < NUM_OBJS; ++objno, mask <<= 1) { byteno = objno >> 3; mask = pow2[objno & 7]; if (objReadReqFlags[byteno] & mask) { send_obj_value(objno | OBJ_RESPONSE_FLAG); objReadReqFlags[byteno] &= ~mask; } if (objSendReqFlags[byteno] & mask) { send_obj_value(objno); objSendReqFlags[byteno] &= ~mask; } } }
void write_value_req(void) { unsigned char objno; objno=find_first_objno(telegramm[3],telegramm[4]); if (objno==2) { // nur Zeit/Datum senden Objekt if (telegramm[7]==0x81) { //send_dt(1,0); //send_dt(1,1); send_obj_value(0); send_obj_value(1); } } }
void read_value_req(void) { unsigned char objno, objflags; objno=find_first_objno(telegramm[3],telegramm[4]); // erste Objektnummer zu empfangener GA finden if(objno!=0xFF) { // wenn Gruppenadresse gefunden objflags=read_objflags(objno); // Objekt Flags lesen // Objekt lesen, nur wenn read enable gesetzt (Bit3) und Kommunikation zulaessig (Bit2) if((objflags&0x0C)==0x0C) { if (objno==0) send_obj_value(0x40); if (objno==1) send_obj_value(0x41); } } }
void read_value_req(unsigned char objno) // Empfangenes read_value_request Telegramm verarbeiten { /* Hier sicherstellen, dass der Objektwert, der durch read_obj_value() gelesen wird, * aktuell ist. Danach das Senden des Objektes anstossen. */ send_obj_value(objno+64); }
void ft_process_var_frame(void) { unsigned char n; __bit write_ok = 0; if (rsin[0] == 0x68 && rsin[3] == 0x68 && rsin[1] == rsin[2]) { // Multi Byte timer_data = 2; // timer starting data LED if ((rsin[4] & 0xDF) == 0x53) { // send_Udat switch (rsin[5]) // PEI10 message code { case 0x11: // send a telegram on the bus FT_SEND_ACK //while (fb_state != 0); send_obj_value(0); break; case 0xA9: // PEI_switch_request FT_SEND_ACK if (rsin[6] == 0x00 && rsin[8] == 0x34) { if (rsin[7] == 0x12) { if (rsin[9] == 0x56 && rsin[10] == 0x78 && rsin[11] == 0x9A) switch_mode = 0x00; // normal mode if (rsin[9] == 0x56 && rsin[10] == 0x78 && rsin[11] == 0x8A) switch_mode = 0x01; // application layer if (rsin[9] == 0x48 && rsin[10] == 0x88 && rsin[11] == 0x0A) switch_mode = 0x02; // transport layer remote if (rsin[9] == 0x56 && rsin[10] == 0x78 && rsin[11] == 0x0A) switch_mode = 0x03; // transport layer local } if (rsin[7] == 0x18) { if (rsin[9] == 0x56 && rsin[10] == 0x78 && rsin[11] == 0x0A) switch_mode = 0x04; // link layer } } if (rsin[6] == 0x90 && rsin[7] == 0x18 && rsin[8] == 0x34 && rsin[9] == 0x56 && rsin[10] == 0x78 && rsin[11] == 0x0A) { switch_mode = 0x05; // busmonitor mode auto_ack = 0; } else auto_ack = 1; break; case 0x43: // T_connect_request FT_SEND_ACK if (switch_mode == 0x03) { FT_SET_HEADER(0x07, 0x86) rsin[6] = (0x00); rsin[7] = (0x00); rsin[8] = (0x00); rsin[9] = (0x00); rsin[10] = (0x00); ft_send_frame(); } break; case 0x44: // T_Disconcect.req FT_SEND_ACK if (switch_mode == 0x03) { FT_SET_HEADER(rsin[1], 0x88) ft_send_frame(); } break; case 0x41: // T_dataConnected.request FT_SEND_ACK if (switch_mode == TLlocal) { // Transport Layer local switch (rsin[12]) { case 0x03: switch (rsin[13]) { case 0x00: // Read_Mask_Version_Req FT_SEND_T_DATACONNECTED_CONF FT_SET_HEADER(0x0C, 0x89) rsin[6] = (0x00); rsin[7] = (0x00); rsin[8] = (0x00); rsin[9] = (0x00); rsin[10] = (0x00); rsin[11] = (0x63); // DRL Länge 3 Bytes rsin[12] = (0x03); // 03 40 = Read_Mask_Version_res rsin[13] = (0x40); // rsin[14] = (0x00); // Maskenversion 00 21 rsin[15] = (0x21); ft_send_frame(); break; case 0xD5: // Read_Property_Value_Req if (rsin[14] == 0x01 && rsin[15] == 0x05 && rsin[16] == 0x10 && rsin[17] == 0x01) { FT_SEND_T_DATACONNECTED_CONF FT_SET_HEADER(0x0F, 0x89) rsin[11] = 0x66; rsin[13] = 0xD6; rsin[18] = property_5; ft_send_frame(); } break; case 0xD7: // Write_Property_Value_Req if (rsin[14] == 0x01 && rsin[15] == 0x05 && rsin[16] == 0x10 && rsin[17] == 0x01) { FT_SEND_T_DATACONNECTED_CONF if (rsin[18] == 0x01) property_5 = 0x02; else property_5 = 0x01; FT_SET_HEADER(0x0F, 0x89) rsin[11] = 0x66; rsin[13] = 0xD6; rsin[18] = property_5; ft_send_frame(); } break; case 0xD1: // Authorize_Req FT_SEND_T_DATACONNECTED_CONF rsin[4] |= 0x80; // DIR=1 BAU to external device //rsin[4]^=0x20; // toggle FCB FT_SET_HEADER(0x0B, 0x89) rsin[11] = 0x62; // 66 rsin[13] = 0xD2; ft_send_frame(); break; } break; case 0x02: switch (rsin[13] & 0xF0) { case 0x00: // Read_Memory_Req FT_SEND_T_DATACONNECTED_CONF ft_send_Read_Memory_Res((rsin[13] & 0x0F), rsin[14], rsin[15]); break; case 0x80: // Write_Memory_Req EA = 0; //EX1=0; write_ok = 0; while (!write_ok) { START_WRITECYCLE ; for (n = 0; n < (rsin[13] & 0x0F); n++) { WRITE_BYTE(rsin[14], rsin[15]+n, rsin[16+n]); } STOP_WRITECYCLE ; if (!(FMCON & 0x0F)) write_ok = 1;// prüfen, ob erfolgreich geflasht } EA = 1; FT_SEND_T_DATACONNECTED_CONF //EX1=1; break; } } break; } break; case 0xA7: // PEI_identify_request PEI_identify_req(); break; } }
void main(void) { unsigned char n, gateno,tasterpegel=0; __bit q=0, a=0, b=0; __bit wduf ; __bit tastergetoggelt=0; wduf= WDCON&0x02; restart_hw(); // Hardware zuruecksetzen TASTER=0; TR0=1; if (!wduf){// BUS return verzögerung nur wenn nicht watchdog underflow for (n=0;n<50;n++) { // Warten bis Bus stabil TR0=0; // Timer 0 anhalten TH0=eeprom[ADDRTAB+1]; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0=eeprom[ADDRTAB+2]; TF0=0; // Überlauf-Flag zurücksetzen TR0=1; // Timer 0 starten while(!TF0); } } WATCHDOG_INIT WATCHDOG_START restart_app(); // Anwendungsspezifische Einstellungen zuruecksetzen do { WATCHDOG_FEED if(APPLICATION_RUN) { // nur wenn run-mode gesetzt for(gateno=0; gateno<8; gateno++) { // Schleife über 8 Gatter a=(gate_a>>gateno) & 0x01; // Eingang A b=(gate_b>>gateno) & 0x01; // Eingang B switch(eeprom[0xF4+gateno]) { // Gattertyp aus eeprom lesen case 0: // AND q = a & b; break; case 1: // OR q = a | b; break; case 2: // NAND q = ! (a & b); break; case 3: // NOR q = ! (a | b); break; case 4: // EXOR q = a ^ b; break; case 5: // NEXOR q = ! (a ^ b); } if(q!=((gate_q >> gateno)&0x01)) { // Telegramm senden nur wenn sich Zustand geändert hat if(q) gate_q|=1<<gateno; // neuen Zustand von Gatterausgang speichern else gate_q&=0xFF-(1<<gateno); send_obj_value(gateno*3+2); // Telegramm senden } } P0=gate_q; // Ausgänge der Gatter auf LEDs ausgeben } if (RTCCON>=0x80) { RTCCON=0x61;// RTC starten if( connected) // Realtime clock ueberlauf { // wenn connected den timeout für Unicast connect behandeln if(connected_timeout <= 110)// 11x 520ms --> ca 6 Sekunden { connected_timeout ++; } else send_obj_value(T_DISCONNECT);// wenn timeout dann disconnect, flag und var wird in build_tel() gelöscht } else { RTCCON=0x60; // RTC Flag löschen RTCH = 0x01; RTCL = 0x20; // alle 5ms erzeugt in timerflags 10ms am bit 0 RTCCON=0x61;// RTC starten } } if(tel_arrived) { // empfangenes Telegramm abarbeiten tel_arrived=0; process_tel(); } else { for(n=0;n<100;n++); // falls Hauptroutine keine Zeit verbraucht, der PROG LED etwas Zeit geben, damit sie auch leuchten kann } TASTER=1; // Pin als Eingang schalten um Taster abzufragen if(!TASTER){ // Taster gedrückt if(tasterpegel<255) tasterpegel++; else{ if(!tastergetoggelt)status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln tastergetoggelt=1; } } else { if(tasterpegel>0) tasterpegel--; else tastergetoggelt=0; } TASTER=!(status60 & 0x01); // LED entsprechend Prog-Bit schalten (low=LED an) } while(1); }
// ********************** Processing logic ************************* void state_machine(unsigned char objno) { __bit return_knx_send; static unsigned int gira_read_timeout = 0; if (g_state) { if (g_state==0x01) { g_res_pointer = 0; } switch (objno) { case OBJ_SET_ALARM: /* 1Bit Remote alarm */ if (g_state == 0x01) { g_to_knx = g_set_alarm; g_state = 0x05; } break; case OBJ_SET_TALARM: /* 1Bit Remote test */ if (g_state == 0x01) { g_to_knx = g_set_test; g_state = 0x05; } break; case OBJ_NOTUSED2: // Not used object 2 g_state = 0x00; break; case OBJ_NOTUSED3: // Not used object 3 g_state = 0x00; break; case OBJ_SERIAL: /* 4Byte Serialnumber */ rs_send_gira(req[0]); if (g_state == 0x04) { g_to_knx = g_res_conv[1]; g_to_knx <<= 8; g_to_knx |= g_res_conv[2]; g_to_knx <<= 8; g_to_knx |= g_res_conv[3]; g_to_knx <<= 8; g_to_knx |= g_res_conv[4]; g_state++; } break; case OBJ_OPERATING_TIME: /* 4Byte operating time */ rs_send_gira(req[1]); if (g_state == 0x04) { g_to_knx = g_res_conv[1]; g_to_knx <<= 8; g_to_knx |= g_res_conv[2]; g_to_knx <<= 8; g_to_knx |= g_res_conv[3]; g_to_knx <<= 8; g_to_knx |= g_res_conv[4]; g_to_knx >>= 2; g_state++; } break; case OBJ_SMOKEBOX_VALUE: /* 2Byte smokebox value */ rs_send_gira(req[2]); if (g_state == 0x04) { g_to_knx = ((g_res_conv[1]<<8)|g_res_conv[2]); g_state++; } break; case OBJ_POLLUTION: /* 1Byte degree of pollution */ rs_send_gira(req[2]); if (g_state == 0x04) { g_to_knx = g_res_conv[4]; g_state++; } break; case OBJ_BAT_VOLTAGE: /* 2Byte Battery voltage */ rs_send_gira(req[3]); if (g_state == 0x04) { g_to_knx = ((g_res_conv[1]<<8)|g_res_conv[2]); g_to_knx *= 9184; g_to_knx /= 5000; conv_dpt_9_001 (&g_to_knx); g_state++; } break; case OBJ_TEMP1: /* 2Byte Temperature 1 */ rs_send_gira(req[3]); if (g_state == 0x04) { g_to_knx = ((g_res_conv[4]*50)-2000) ; conv_dpt_9_001 (&g_to_knx); g_state++; } break; case OBJ_TEMP2: /* 2Byte Temperature 2 */ rs_send_gira(req[3]); if (g_state == 0x04) { g_to_knx = ((g_res_conv[3]*50)-2000) ; conv_dpt_9_001 (&g_to_knx); g_state++; } break; case OBJ_CNT_SMOKEALARM: /* 1Byte Number of smokealarm */ rs_send_gira(req[2]); if (g_state == 0x04) { g_to_knx = g_res_conv[3]; g_state++; } break; case OBJ_CNT_TEMPALARM: /* 1Byte Number of temperaturealarm */ rs_send_gira(req[4]); if (g_state == 0x04) { g_to_knx = g_res_conv[1]; g_state++; } break; case OBJ_CNT_TESTALARM: /* 1Byte Number of testalarm */ rs_send_gira(req[4]); if (g_state == 0x04) { g_to_knx = g_res_conv[2]; g_state++; } break; case OBJ_CNT_ALARM_WIRE: /* 1Byte Number of alarm wire */ rs_send_gira(req[4]); if (g_state == 0x04) { g_to_knx = g_res_conv[3]; g_state++; } break; case OBJ_CNT_ALARM_WIRELESS: /* 1Byte Number of alarm wireless */ rs_send_gira(req[4]); if (g_state == 0x04) { g_to_knx = g_res_conv[4]; g_state++; } break; case OBJ_CNT_TALARM_WIRE: /* 1Byte Number of testalarm wire*/ rs_send_gira(req[5]); if (g_state == 0x04) { g_to_knx = g_res_conv[1]; g_state++; } break; case OBJ_CNT_TALARM_WIRELESS: /* 1Byte Number of testalarm wireless */ rs_send_gira(req[5]); if (g_state == 0x04) { g_to_knx = g_res_conv[2]; g_state++; } break; case OBJ_STAT_ALARM: /* 1Bit Alarm state */ if (g_state == 0x01) { g_to_knx = g_stat_alarm; g_state = 0x05; } break; case OBJ_STAT_ALARM_CENTRAL: /* 1Bit Alarm state central */ if (g_state == 0x01) { g_to_knx = g_stat_alarm; g_state = 0x05; } break; case OBJ_STAT_ALARM_DELAYED: /* 1Bit Alarm state delayed */ if (g_state == 0x01) { g_to_knx = g_stat_alarm; g_state = 0x05; } break; case OBJ_STAT_TALARM: /* 1Bit Testalarm state */ if (g_state == 0x01) { g_to_knx = g_stat_test; g_state = 0x05; } break; case OBJ_STAT_TALARM_CENTRAL: /* 1Bit Testalarm state central */ if (g_state == 0x01) { g_to_knx = g_stat_test; g_state = 0x05; } break; } // Read answer from GIRA if (g_state == 0x02) { if (RI) { rs_read_gira(g_res); gira_read_timeout = 0; } else { if((gira_read_timeout++)==0x0600) // Read Timeout { rs_send_c(GIRA_ACK); rs_send_c(GIRA_ACK); g_res_pointer = 0; g_state = 0x00; #ifdef SEND_FFFFFFFF_ON_GIRA_COM_ERROR g_state = 0x05; g_to_knx = 0xFFFFFFFF; #endif } } } // Send ACK to GIRA and recalculate data if (g_state == 0x03) { // ACK 1st time rs_send_c(GIRA_ACK); calculate (g_res,g_res_conv); } // Send data to KNX and ACK to Gira second time if data received if (g_state == 0x05) { return_knx_send = send_obj_value(objno); if (!return_knx_send) { // ACK 2nd time - data received if (g_res_pointer) rs_send_c(GIRA_ACK); g_res_pointer = 0; g_state = 0x00; } } }
void main(void) { unsigned char n,cmd,tasterpegel=0; signed char cal; // unsigned int m; static __code signed char __at 0x1BFF trimsave; #ifdef zeroswitch static __code unsigned char __at 0x1BFE phisave={16}; #endif unsigned char rm_count=0; __bit wduf,tastergetoggelt=0; wduf=WDCON&0x02; restart_hw(); // Hardware zuruecksetzen // im folgendem wird der watchdof underflow abgefragt und mit gedrücktem Progtaster // ein resetten der cal Variable veranlasst um wieder per rs232 trimmen zu können. TASTER=1; if(!TASTER && wduf)cal=0; else cal=trimsave; TASTER=0; TRIM = (TRIM+trimsave); TRIM &= 0x3F;//oberen 2 bits ausblenden #ifdef zeroswitch if(phisave<=52) phival=phisave; else phival=16; #endif TR0=1; if (!wduf){// BUS return verzögerung nur wenn nicht watchdog underflow for (n=0;n<50;n++) { // Warten bis Bus stabil TR0=0; // Timer 0 anhalten TH0=eeprom[ADDRTAB+1]; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0=eeprom[ADDRTAB+2]; TF0=0; // Überlauf-Flag zurücksetzen TR0=1; // Timer 0 starten while(!TF0); } } watchdog_init(); watchdog_start(); restart_app(); // Anwendungsspezifische Einstellungen zuruecksetzen if(!wduf)bus_return(); // Aktionen bei Busspannungswiederkehr //...rs_init...(6);im folgenden direkt: /* BRGCON&=0xFE; // Baudrate Generator stoppen // P1M1&=0xFC; // RX und TX auf bidirectional setzen // P1M2&=0xFC; SCON=0x50; // Mode 1, receive enable SSTAT|=0xE0; // TI wird am Ende des Stopbits gesetzt und Interrupt nur bei RX und double TX buffer an BRGCON|=0x02; // Baudrate Generator verwenden aber noch gestoppt BRGR1=0x2f; // Baudrate = cclk/((BRGR1,BRGR0)+16) BRGR0=0xf0; // für 115200 0030 nehmen, autocal: 600bd= 0x2FF0 BRGCON|=0x01; // Baudrate Generator starten */ #ifndef debugmode RS_INIT_600 #else RS_INIT_115200 #endif SBUF=0x55; do { watchdog_feed(); if(APPLICATION_RUN) { // nur wenn run-mode gesetzt if(RTCCON>=0x80) delay_timer(); // Realtime clock Ueberlauf #ifndef zeroswitch if(TF0 && (TMOD & 0x0F)==0x01) { // Vollstrom für Relais ausschalten und wieder PWM ein #ifndef SPIBISTAB TMOD=(TMOD & 0xF0) + 2; // Timer 0 als PWM TAMOD=0x01; TH0=DUTY; #endif TF0=0; #ifndef SPIBISTAB AUXR1|=0x10; // PWM von Timer 0 auf Pin ausgeben #endif PWM=1; // PWM Pin muss auf 1 gesetzt werden, damit PWM geht !!! #ifndef SPIBISTAB #ifndef IO_BISTAB TR0=1; #endif #endif #ifdef IO_BISTAB P0=0;// wenn Bistabile über IO diese ausschalten #endif } #endif #ifdef BUS_DOWN if(TxD){ bus_down(); } #endif if (portchanged)port_schalten(); // Ausgänge schalten // Rückmeldungen senden if(rm_send) { // wenn nichts zu senden ist keine Zeit vertrödeln if(rm_send & (1<<rm_count)) { if(send_obj_value(rm_count + 12)) { // falls erfolgreich, dann nächste rm_send&=(0xFF-(1<<rm_count)); rm_count++; #ifdef MAX_PORTS_8 rm_count&=0x07; #else rm_count&=0x03; #endif } } else { // RM sollte nicht gesendet werden rm_count++; #ifdef MAX_PORTS_8 rm_count&=0x07; #else rm_count&=0x03; #endif } } else rm_count=0; // Immer mal wieder auf Null setzen, damit Reihenfolge von 1 bis 8 geht // portbuffer flashen, Abbruch durch ext-int wird akzeptiert und später neu probiert // T1-int wird solange abgeschaltet, if (fb_state==0 && (TH1<0XC0) && (!wait_for_ack)&& portbuffer!=eeprom[PORTSAVE]) { START_WRITECYCLE; WRITE_BYTE(0x01,PORTSAVE,portbuffer); STOP_WRITECYCLE; } }// end if(runstate... // Telegrammverarbeitung.. if (tel_arrived || tel_sent) { tel_arrived=0; tel_sent=0; process_tel(); } else { for(n=0;n<100;n++); // falls Hauptroutine keine Zeit verbraucht, der PROG LED etwas Zeit geben, damit sie auch leuchten kann } cmd; #ifndef debugmode // Eingehendes Terminal Kommando verarbeiten... if (RI){ RI=0; cmd=SBUF; if(cmd=='c'){ while(!TI); TI=0; SBUF=0x55; } if(cmd=='+'){ TRIM--; cal--; } if(cmd=='-'){ TRIM++; cal++; } if(cmd=='w'){ EA=0; START_WRITECYCLE; //cal an 0x1bff schreiben #ifdef zeroswitch FMADRH= 0x1B; FMADRL= 0xFE; FMDATA= phival; #else FMADRH= 0x1B; FMADRL= 0xFF; #endif FMDATA= cal; STOP_WRITECYCLE; EA=1; //int wieder freigeben } if(cmd=='p')status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln #ifdef zeroswitch if(cmd=='<'){ if (phival){ phival--; TI=0; SBUF=phival; } } if(cmd=='>'){ if(phival<51){ phival++; // TI=0; SBUF=phival; } } #endif if(cmd=='v'){ while(!TI); TI=0; SBUF=VERSION; } if(cmd=='t'){ while(!TI); TI=0; SBUF=TYPE; } #ifdef MAX_PORTS_8 if(cmd >=49 && cmd <= 56){ portbuffer = portbuffer ^ (0x01<< (cmd-49)); port_schalten(); } #else if(cmd >=49 && cmd <= 52){ portbuffer = portbuffer ^ (0x01<< (cmd-49)); port_schalten(); } #endif }//end if(RI... #else //ifndef debugmode DEBUGPOINT; #endif TASTER=1; // Pin als Eingang schalten um Taster abzufragen if(!TASTER){ // Taster gedrückt if(tasterpegel<255) tasterpegel++; else{ if(!tastergetoggelt)status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln tastergetoggelt=1; } } else { if(tasterpegel>0) tasterpegel--; else tastergetoggelt=0; } TASTER=!(status60 & 0x01); // LED entsprechend Prog-Bit schalten (low=LED an) } while(1); }
void main(void) { unsigned char n,cmd,tasterpegel=0; signed char cal; static __code signed char __at 0x1CFF trimsave; unsigned int base; unsigned char pin=0; #ifdef zykls unsigned char tmp,objno,objstate; #else #ifdef zaehler unsigned char objno; #endif #endif __bit wduf,tastergetoggelt=0; wduf=WDCON&0x02; TASTER=1; if(!TASTER && wduf)cal=0; else cal=trimsave; TRIM = (TRIM+trimsave); TRIM &= 0x3F;//oberen 2 bits ausblenden restart_hw(); // Hardware zurücksetzen // rs_init(6); // serielle Schnittstelle initialisieren BRGCON&=0xFE; // Baudrate Generator stoppen P1M1&=0xFC; // RX und TX auf bidirectional setzen P1M2&=0xFC; SCON=0x50; // Mode 1, receive enable SSTAT|=0xE0; // TI wird am Ende des Stopbits gesetzt und Interrupt nur bei RX und double TX buffer an BRGCON|=0x02; // Baudrate Generator verwenden aber noch gestoppt BRGR1=0x2F; // Baudrate = cclk/((BRGR1,BRGR0)+16) BRGR0=0xF0; // für 115200 0030 nehmen, autocal: 600bd= 0x2FF0 BRGCON|=0x01; // Baudrate Generator starten SBUF=0x55; restart_app(); // Anwendungsspezifische Einstellungen zurücksetzen #ifndef IN8_2TE portbuffer=P0; // zunächst keine Änderungen bei Busspannungswiederkehr p0h=portbuffer; #else portbuffer=spi_in_out(); p0h=portbuffer; #endif if(!wduf){ // Verzögerung Busspannungswiederkehr for(base=0;base<=(eeprom[0xD4]<<(eeprom[0xFE]>>4)) ;base++){//faktor startverz hohlen und um basis nach links schieben // start_rtc(130); // rtc auf 130ms RTCCON=0x60; // RTC anhalten und Flag löschen RTCH=0x1D; // reload Real Time Clock für 65ms RTCL=0x40; RTCCON=0x61; // RTC starten while (RTCCON<=0x7F) ; // Realtime clock ueberlauf abwarten // feed the watchdog EA = 0; WFEED1 = 0xA5; WFEED2 = 0x5A; EA=1; // stop_rtc; } } watchdog_init(); watchdog_start(); if(!wduf)bus_return(); // Anwendungsspezifische Einstellungen zurücksetzen TASTER=1; do { // watchdog_feed(); // feed the watchdog EA = 0; WFEED1 = 0xA5; WFEED2 = 0x5A; EA=1; if(APPLICATION_RUN){ #ifndef IN8_2TE p0h=P0; // prüfen ob ein Eingang sich geändert hat #else p0h=spi_in_out(); #endif if (p0h!=portbuffer) { for(n=0;n<8;n++) // jeden Eingangspin einzel prüfen { //if ((((p0h>>n)&0x01) != ((portbuffer>>n)&0x01))&& !(blocked>>n)&0x01) //if ((p0h & bitmask_1[n])!= (portbuffer & bitmask_1[n])&& !(blocked & bitmask_1[n]) ) if (((p0h^portbuffer) & bitmask_1[n])&& !(blocked & bitmask_1[n]) )//kürzeste Version { pin_changed(n); // Änderung verarbeiten } } portbuffer=p0h; // neuen Portzustand in buffer speichern } if (RTCCON>=0x80){ delay_timer(); // Realtime clock ueberlauf } #ifdef zykls for(objno=0;objno<=7;objno++){ tmp=(eeprom[0xD5+(objno*4)]&0x0C);//0xD5/ bit 2-3 zykl senden aktiv objstate=read_obj_value(objno); if (((eeprom[0xCE+(objno>>1)] >> ((objno & 0x01)*4)) & 0x0F)==1){// bei Funktion=Schalten if ((tmp==0x04 && objstate==1)||(tmp==0x08 && objstate==0)|| tmp==0x0C){//bei zykl senden aktiviert n=timercnt[objno]; if ((n & 0x7F) ==0){ // wenn aus oder abgelaufen timercnt[objno] = (eeprom[0xD6+(objno*4)]& 0x3F)+ 0x80 ;//0xD6 Faktor Zyklisch senden x.1 + x.2 )+ einschalten timerbase[objno]=(eeprom[0xF6+((objno+1)>>1)]>>(4*((objno&0x01)^0x01)))&0x07; //Basis zyklisch senden if (n & 0x80){// wenn timer ein war send_obj_value(objno); // Eingang x.1 zyklisch senden } } } else timercnt[objno]=0; } }
void main(void) { unsigned char n; // // Initialisierung // restart_hw(); TASTER=0; // Prog. LED kurz Ein // Warten bis Bus stabil, nach Busspannungswiederkehr for (n = 0; n < 50; n++) { TR0 = 0; // Timer 0 anhalten TH0 = eeprom[ADDRTAB + 1]; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0 = eeprom[ADDRTAB + 2]; TF0 = 0; // Überlauf-Flag zurücksetzen TR0 = 1; // Timer 0 starten while (!TF0) ; } restart_app(); do { // // Hauptverarbeitung // if (APPLICATION_RUN) { if (RI) rm_recv_byte(); if (RTCCON >= 0x80) timer_event(); if (!answerWait) process_alarm_stats(); if (!answerWait) process_objs(); } else if (RTCCON>=0x80 && connected) // Realtime clock ueberlauf { // wenn connected den timeout für Unicast connect behandeln RTCCON=0x61;// RTC flag löschen if(connected_timeout <= 110)// 11x 520ms --> ca 6 Sekunden { connected_timeout ++; } else send_obj_value(T_DISCONNECT);// wenn timeout dann disconnect, flag und var wird in build_tel() gelöscht } // // Empfangenes Telegramm bearbeiten, aber nur wenn wir gerade nichts // vom Rauchmelder empfangen. // if (tel_arrived) // && recvCount < 0) process_tel(); // // Watchdog rücksetzen // EA = 0; WFEED1 = 0xA5; WFEED2 = 0x5A; EA = 1; // // Abfrage des Programmier-Tasters // TASTER = 1; if (!TASTER) { for (n = 0; n < 100; n++) // Entprellen ; while (!TASTER) // Warten bis Taster losgelassen ; status60 ^= 0x81;// Prog-Bit und Parity-Bit im system_state toggeln } TASTER = !(status60 & 0x01);// LED entsprechend Prog-Bit schalten (low=LED an) } while (1); }
void read_value_req(unsigned char objno)// Sendet nach Leseanfrage objektwert auf den BUS { send_obj_value(objno+64); }
void main(void) { unsigned char n,count,cmd,tasterpegel=0; signed char cal; static __code signed char __at 0x1BFF trimsave; __bit tastergetoggelt=0; restart_hw(); // Hardware zuruecksetzen cal=trimsave; TRIM = TRIM+trimsave; //...rs_init...(6);im folgenden direkt: BRGCON&=0xFE; // Baudrate Generator stoppen P1M1&=0xFC; // RX und TX auf bidirectional setzen P1M2&=0xFC; SCON=0x50; // Mode 1, receive enable SSTAT|=0xE0; // TI wird am Ende des Stopbits gesetzt und Interrupt nur bei RX und double TX buffer an BRGCON|=0x02; // Baudrate Generator verwenden aber noch gestoppt BRGR1=0x2f; // Baudrate = cclk/((BRGR1,BRGR0)+16) BRGR0=0xf0; // für 115200 0030 nehmen, autocal: 600bd= 0x2FF0 BRGCON|=0x01; // Baudrate Generator starten SBUF=0x55; TASTER=0; for (n=0;n<50;n++) { // Warten bis Bus stabil TR0=0; // Timer 0 anhalten TH0=eeprom[ADDRTAB+1]; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0=eeprom[ADDRTAB+2]; TF0=0; // Überlauf-Flag zurücksetzen TR0=1; // Timer 0 starten while(!TF0); } count=0; restart_app(); // Anwendungsspezifische Einstellungen zuruecksetzen bus_return(); // Aktionen bei Busspannungswiederkehr do { if(APPLICATION_RUN) { // nur wenn run-mode gesetzt // Helligkeit nachführen if (dimmziel[count]==dimmwert[count]){ if (helligkeit[count]!= dimmwert[count]){ helligkeit[count]=dimmwert[count]; // rs_send(read_obj_value(count+6)); // rs_send(read_objflags(count+6)); if (read_objflags(count+6)&0x40)send_obj_value(count+6); } } if(count<2)count++; else count=0; if (RI){ RI=0; cmd=SBUF; if(cmd=='c'){ while(!TI); TI=0; SBUF=0x55; } if(cmd=='+'){ TRIM--; cal--; } if(cmd=='-'){ TRIM++; cal++; } if(cmd=='w'){ EA=0; START_WRITECYCLE; //cal an 0x1bff schreiben #ifdef zeroswitch FMADRH= 0x1B; FMADRL= 0xFE; FMDATA= phival; #else FMADRH= 0x1B; FMADRL= 0xFF; #endif FMDATA= cal; STOP_WRITECYCLE; EA=1; //int wieder freigeben } if(cmd=='p')status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln if(cmd=='v'){ while(!TI); TI=0; SBUF=VERSION; } if(cmd=='t'){ while(!TI); TI=0; SBUF=TYPE; } }//end if(RI... //if(RTCCON>=0x80) delay_timer(); // Realtime clock Ueberlauf /* if(TF0 && (TMOD & 0x0F)==0x01) { // Vollstrom für Relais ausschalten und wieder PWM ein #ifndef SPIBISTAB TMOD=(TMOD & 0xF0) + 2; // Timer 0 als PWM TAMOD=0x01; TH0=DUTY; #endif TF0=0; #ifndef SPIBISTAB AUXR1|=0x10; // PWM von Timer 0 auf Pin ausgeben #endif PWM=1; // PWM Pin muss auf 1 gesetzt werden, damit PWM geht !!! #ifndef SPIBISTAB TR0=1; #else P0=portbuffer; #endif } */ if (dimmtimervorteiler>=10){//vorteiler wird alle 50µs in softpwm erhöht dimmtimervorteiler-=10;// delay_timer(); }// ergibt eine flanke von 0.50ms if (portchanged)port_schalten(); // Ausgänge schalten // portbuffer flashen, Abbruch durch ext-int wird akzeptiert und später neu probiert // T1-int wird solange abgeschaltet, timeout_count wird ggf. um 4ms (flashzeit) reduziert /* if (fb_state==0 && portbuffer!=eeprom[PORTSAVE]) { ET1=0; START_WRITECYCLE; WRITE_BYTE(0x01,PORTSAVE,portbuffer); STOP_WRITECYCLE; if (timeout_count>120) timeout_count-=120; else timeout_count=0; ET1=1; } */ }// end if(runstate) else if (RTCCON>=0x80 && connected) // Realtime clock ueberlauf { // wenn connected den timeout für Unicast connect behandeln RTCCON=0x61;// RTC flag löschen if(connected_timeout <= 110)// 11x 520ms --> ca 6 Sekunden { connected_timeout ++; } else send_obj_value(T_DISCONNECT);// wenn timeout dann disconnect, flag und var wird in build_tel() gelöscht } n= tx_buffer[(tx_nextsend-1)&0x07];// ist die letzte objno if (tel_arrived || (n<6 && n>8 && tel_sent)) { // tel_arrived=0; tel_sent=0; process_tel(); } TASTER=1; // Pin als Eingang schalten um Taster abzufragen if(!TASTER){ // Taster gedrückt if(tasterpegel<255) tasterpegel++; else{ if(!tastergetoggelt)status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln tastergetoggelt=1; } } else { if(tasterpegel>0) tasterpegel--; else tastergetoggelt=0; } TASTER=!(status60 & 0x01); // LED entsprechend Prog-Bit schalten (low=LED an) // for(n=0;n<100;n++) {} // falls Hauptroutine keine Zeit verbraucht, der LED etwas Zeit geben, damit sie auch leuchten kann // if (status60&0x01)ET0=0; // else ET0=1; } while(1); }
void main(void) { unsigned char n; // // Initialisierung // restart_hw(); TASTER=0; // Prog. LED kurz Ein // Warten bis Bus stabil, nach Busspannungswiederkehr for (n = 0; n < 50; n++) { TR0 = 0; // Timer 0 anhalten TH0 = 0; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0 = eeprom[ADDRTAB + 2]; // Nur Low Byte der PA nutzen, sonst sehr kurze Wartezeit bei 15.15.255 TF0 = 0; // Überlauf-Flag zurücksetzen TR0 = 1; // Timer 0 starten while (!TF0) ; } #ifdef DEVICE_ID_CHECK // Only start if correct application has been loaded for(n = 0; n<=3; n++) { if(eeprom[0x03+n] != dev_application_id[n]) { EA = 0; START_WRITECYCLE; WRITE_BYTE(0x01,0x0D,0xFB); // Indicate Stack Overflow, holds app STOP_WRITECYCLE; EA = 1; break; // Flash just once } } #endif restart_app(); do { // // Hauptverarbeitung // if (APPLICATION_RUN) { if (RI) rm_recv_byte(); if (RTCCON >= 0x80) timer_event(); if (!answerWait) process_alarm_stats(); if (!answerWait) process_objs(); } else if (RTCCON>=0x80 && connected) // Realtime clock ueberlauf { // wenn connected den timeout für Unicast connect behandeln RTCCON=0x61;// RTC flag löschen if(connected_timeout <= 110)// 11x 520ms --> ca 6 Sekunden { connected_timeout ++; } else send_obj_value(T_DISCONNECT);// wenn timeout dann disconnect, flag und var wird in build_tel() gelöscht } // // Empfangenes Telegramm bearbeiten, aber nur wenn wir gerade nichts // vom Rauchmelder empfangen. // if (tel_arrived) // && recvCount < 0) process_tel(); // // Watchdog rücksetzen // EA = 0; WFEED1 = 0xA5; WFEED2 = 0x5A; EA = 1; // // Abfrage des Programmier-Tasters // TASTER = 1; if (!TASTER) { for (n = 0; n < 100; n++) // Entprellen ; while (!TASTER) // Warten bis Taster losgelassen ; status60 ^= 0x81;// Prog-Bit und Parity-Bit im system_state toggeln } TASTER = !(status60 & 0x01);// LED entsprechend Prog-Bit schalten (low=LED an) } while (1); }
// Empfangenes read_value_request Telegramm verarbeiten void read_value_req(unsigned char objno) // Empfangenes read_value_request Telegramm verarbeiten { send_obj_value(objno+64); }
void main(void) { unsigned char n,cmd,tasterpegel=0; signed char cal; static __code signed char __at 0x1BFF trimsave; #ifdef zeroswitch static __code unsigned char __at 0x1BFE phisave; #endif static __code unsigned char __at 0x1BFD blockedsave; unsigned char rm_count=0; __bit wduf,tastergetoggelt=0; wduf=WDCON&0x02; restart_hw(); // Hardware zuruecksetzen // im folgendem wird der watchdog underflow abgefragt und mit gedrücktem Progtaster // ein resetten der cal Variable veranlasst um wieder per rs232 trimmen zu können. TASTER=0; if(!TASTER && wduf)cal=0; else cal=trimsave; TRIM = (TRIM+trimsave); TRIM &= 0x3F;//oberen 2 bits ausblenden #ifdef zeroswitch if(phisave<=36) phival=phisave; else phival=0; #endif TASTER=1; if (!wduf){// BUS return verzögerung nur wenn nicht watchdog underflow for (n=0;n<50;n++) { // Warten bis Bus stabil TR0=0; // Timer 0 anhalten TH0=eeprom[ADDRTAB+1]; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0=eeprom[ADDRTAB+2]; TF0=0; // Überlauf-Flag zurücksetzen TR0=1; // Timer 0 starten while(!TF0); } } WATCHDOG_INIT WATCHDOG_START restart_app(); // Anwendungsspezifische Einstellungen zuruecksetzen if(!wduf)bus_return(); // Aktionen bei Busspannungswiederkehr RS_INIT_600 SBUF=0x55; do { WATCHDOG_FEED //hand =((eeprom[0xE5]& 0xC0)>0); if(APPLICATION_RUN) { // nur wenn run-mode gesetzt /* if (eeprom[0xE5]& 0xC0){ if (((delay_toggle & 0x07)==0x07))handsteuerung(); // Handbetätigung nur jedes 8.mal ausführen } */ if(RTCCON>=0x80) delay_timer(); // Realtime clock Ueberlauf #ifndef zeroswitch if(TF0 && (TMOD & 0x0F)==0x01) { // Vollstrom für Relais ausschalten und wieder PWM ein #ifndef SPIBISTAB TMOD=(TMOD & 0xF0) + 2; // Timer 0 als PWM TAMOD=0x01; TH0=DUTY; #endif TF0=0; #ifndef SPIBISTAB AUXR1|=0x10; // PWM von Timer 0 auf Pin ausgeben #endif PWM=1; // PWM Pin muss auf 1 gesetzt werden, damit PWM geht !!! #ifndef SPIBISTAB TR0=1; #else P0=portbuffer; #endif } #endif if (portchanged)port_schalten(); // Ausgänge schalten /* // Rückmeldungen senden if(rm_send) { // wenn nichts zu senden ist keine Zeit vertrödeln if(rm_send & (1<<rm_count)) { if(send_obj_value(rm_count + 12)) { // falls erfolgreich, dann nächste rm_send&=(0xFF-(1<<rm_count)); rm_count++; #ifdef MAX_PORTS_8 rm_count&=0x07; #else rm_count&=0x03; #endif } } else { // RM sollte nicht gesendet werden rm_count++; #ifdef MAX_PORTS_8 rm_count&=0x07; #else rm_count&=0x03; #endif } } else rm_count=0; // Immer mal wieder auf Null setzen, damit Reihenfolge von 1 bis 8 geht */ // portbuffer flashen, Abbruch durch ext-int wird akzeptiert und später neu probiert // T1-int wird solange abgeschaltet, if (fb_state==0 && (TH1<0XC0) && (!wait_for_ack)&& blocked!=blockedsave) { START_WRITECYCLE; FMADRH= 0x1B; FMADRL= 0xFD; FMDATA= blocked; STOP_WRITECYCLE; } }// end if(runstate... else if (RTCCON>=0x80 && connected) // Realtime clock ueberlauf { // wenn connected den timeout für Unicast connect behandeln RTCCON=0x61;// RTC flag löschen if(connected_timeout <= 110)// 11x 520ms --> ca 6 Sekunden { connected_timeout ++; } else send_obj_value(T_DISCONNECT);// wenn timeout dann disconnect, flag und var wird in build_tel() gelöscht } // Telegrammverarbeitung.. if (tel_arrived ) {//|| tel_sent tel_arrived=0; tel_sent=0; process_tel(); } else { for(n=0;n<100;n++); // falls Hauptroutine keine Zeit verbraucht, der PROG LED etwas Zeit geben, damit sie auch leuchten kann } //DEBUGPOINT cmd; #ifndef debugger // Eingehendes Terminal Kommando verarbeiten... if (RI){ RI=0; cmd=SBUF; if(cmd=='c'){ while(!TI); TI=0; SBUF=0x55; } if(cmd=='+'){ TRIM--; cal--; } if(cmd=='-'){ TRIM++; cal++; } if(cmd=='w'){ EA=0; START_WRITECYCLE; //cal an 0x1bff schreiben #ifdef zeroswitch FMADRH= 0x1B; FMADRL= 0xFE; FMDATA= phival; #else FMADRH= 0x1B; FMADRL= 0xFF; #endif FMDATA= cal; STOP_WRITECYCLE; EA=1; //int wieder freigeben } if(cmd=='p')status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln #ifdef zeroswitch if(cmd=='<'){ if (phival){ phival--; TI=0; SBUF=phival; } } if(cmd=='>'){ if(phival<35){ phival++; // TI=0; SBUF=phival; } } #endif if(cmd=='v'){ while(!TI); TI=0; SBUF=VERSION; } if(cmd=='t'){ while(!TI); TI=0; SBUF=TYPE; } }//end if(RI... #endif TASTER=1; // Pin als Eingang schalten um Taster abzufragen if(!TASTER){ // Taster gedrückt if(tasterpegel<255) tasterpegel++; else{ if(!tastergetoggelt)status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln tastergetoggelt=1; } } else { if(tasterpegel>0) tasterpegel--; else tastergetoggelt=0; } TASTER=!(status60 & 0x01); // LED entsprechend Prog-Bit schalten (low=LED an) } while(1); }
void main(void) { unsigned char n,count,send_nibble=0,pwm0=0,pwm1=0,pwm2=0,prog_button_level=0; signed char cal; static __code signed char __at (0x1BFF) trimsave; __bit prog_button_toggled=0; restart_hw();// Hardware zuruecksetzen #ifdef FB_DEBUG RS_INIT_115200 #else RS_INIT_9600 #endif TI=1; TASTER=0; cal=trimsave; TRIM = TRIM+trimsave; for (n=0;n<50;n++) { // Warten bis Bus stabil TR0=0; // Timer 0 anhalten TH0=eeprom[ADDRTAB+1]; // Timer 0 setzen mit phys. Adr. damit Geräte unterschiedlich beginnen zu senden TL0=eeprom[ADDRTAB+2]; TF0=0; // Überlauf-Flag zurücksetzen TR0=1; // Timer 0 starten while(!TF0); } count=0; restart_app(); // Anwendungsspezifische Einstellungen zuruecksetzen bus_return(); // Aktionen bei Busspannungswiederkehr do { #ifdef FB_DEBUG DEBUGPOINT #endif if(APPLICATION_RUN) { // nur wenn run-mode gesetzt // Helligkeit nachführen if (dimmziel[count]==dimmwert[count]){ if (helligkeit[count]!= dimmwert[count]){ helligkeit[count]=dimmwert[count]; // rs_send(read_obj_value(count+6)); // rs_send(read_objflags(count+6)); if (read_objflags(count+6)&0x40){ send_obj_value(count+6); } } } if(count<2)count++; else count=0; #ifndef FB_DEBUG #ifdef applilpc if (TI){ switch(send_nibble){ case 0: pwm0=dimmpwm[0]; RS_SEND(0x00+(pwm0<<4)); break; case 1: RS_SEND(0x01+(pwm0 & 0xF0)); break; case 2: pwm1=dimmpwm[1]; RS_SEND(0x02+(pwm1<<4)); break; case 3: RS_SEND(0x03+(pwm1 & 0xF0)); break; case 4: pwm2=dimmpwm[2]; RS_SEND(0x04+(pwm2<<4)); break; case 5: RS_SEND(0x05+(pwm2& 0xF0)); break; case 6: RS_SEND(0x06+(portbuffer & 0xF0)); break; default: send_nibble=255; }// ende switch //RI=0; send_nibble++; } // ende if(TI)... #endif #endif // if(RI){ //if(SBUF=='+')dimmziel[0]++; //if(SBUF=='-')dimmziel[0]--; //if(SBUF=='c')rs_send(0x55); // rs_send(helligkeit[SBUF]); // RI=0; // } if(RTCCON>=0x80) delay_timer(); // Realtime clock Ueberlauf /* if(TF0 && (TMOD & 0x0F)==0x01) { // Vollstrom für Relais ausschalten und wieder PWM ein #ifndef SPIBISTAB TMOD=(TMOD & 0xF0) + 2; // Timer 0 als PWM TAMOD=0x01; TH0=DUTY; #endif TF0=0; #ifndef SPIBISTAB AUXR1|=0x10; // PWM von Timer 0 auf Pin ausgeben #endif PWM=1; // PWM Pin muss auf 1 gesetzt werden, damit PWM geht !!! #ifndef SPIBISTAB TR0=1; #else P0=portbuffer; #endif } if (dimmtimervorteiler>=10){//vorteiler wird alle 50µs in softpwm erhöht dimmtimervorteiler-=10;// delay_timer(); }// ergibt eine flanke von 0.50ms */ if (portchanged)port_schalten(); // Ausgänge schalten // portbuffer flashen, Abbruch durch ext-int wird akzeptiert und später neu probiert // T1-int wird solange abgeschaltet, timeout_count wird ggf. um 4ms (flashzeit) reduziert /* if (fb_state==0 && portbuffer!=eeprom[PORTSAVE]) { ET1=0; START_WRITECYCLE; WRITE_BYTE(0x01,PORTSAVE,portbuffer); STOP_WRITECYCLE; if (timeout_count>120) timeout_count-=120; else timeout_count=0; ET1=1; } */ }// end if(runstate) else if (RTCCON>=0x80 && connected) // Realtime clock ueberlauf { // wenn connected den timeout für Unicast connect behandeln RTCCON=0x61;// RTC flag löschen if(connected_timeout <= 110)// 11x 520ms --> ca 6 Sekunden { connected_timeout ++; } else send_obj_value(T_DISCONNECT);// wenn timeout dann disconnect, flag und var wird in build_tel() gelöscht } n= tx_buffer[(tx_nextsend-1)&0x07];// ist die letzte objno if (tel_arrived || (n<6 && n>8 && tel_sent)) { // tel_arrived=0; tel_sent=0; process_tel(); } // ### PROG Button ### TASTER=1; // Pin als Eingang schalten um Taster abzufragen if(!TASTER){ // Taster gedrückt if(prog_button_level<255) prog_button_level++; else{ if(!prog_button_toggled)status60^=0x81; // Prog-Bit und Parity-Bit im system_state toggeln prog_button_toggled=1; } } else { if(prog_button_level>0)prog_button_level--; else prog_button_toggled=0; } TASTER=!(status60 & 0x01); // LED entsprechend Prog-Bit schalten (low=LED an) for(n=0;n<100;n++) {} // falls Hauptroutine keine Zeit verbraucht, der LED etwas Zeit geben, damit sie auch leuchten kann } while(1); }
//const unsigned char __at 0x1CFF PORTSAVE; void main(void) { unsigned char timer_precounter=0; unsigned char n,tasterpegel=0,pin=2; unsigned int base; unsigned char rm_count=0; #ifdef zykls unsigned char objno,tmp,objstate; #endif __bit wduf; __bit tastergetoggelt=0; __bit bus_activ=0; wduf=WDCON&0x02; restart_hw(); // Hardware zuruecksetzen TASTER=0; TR0=1; restart_app(); // Anwendungsspezifische Einstellungen zuruecksetzen if(!wduf){ // Verzögerung Busspannungswiederkehr for(base=0;base<=(eeprom[0xD4]<<(eeprom[0xFE]>>4)) ;base++){//faktor startverz hohlen und um basis nach links schieben // start_rtc(130); // rtc auf 130ms RTCCON=0x60; // RTC anhalten und Flag löschen RTCH=0x1D; // reload Real Time Clock für 65ms RTCL=0x40; RTCCON=0x61; // RTC starten while (RTCCON<=0x7F) ; // Realtime clock ueberlauf abwarten // feed the watchdog EA = 0; WFEED1 = 0xA5; WFEED2 = 0x5A; EA=1; // stop_rtc; } } WATCHDOG_INIT WATCHDOG_START #ifndef debugmode RS_INIT_600 #else RS_INIT_115200 #endif SBUF=0x55; // ################## main loop ######################### do { WATCHDOG_FEED if(APPLICATION_RUN) { // nur wenn run-mode gesetzt p0h=P0 & 0x0C; // prüfen ob ein Eingang sich geändert hat if(!bus_return_ready) { portbuffer=p0h; if(!wduf)bus_return(); // Anwendungsspezifische Einstellungen zurücksetzen bus_return_ready=1; } if (p0h!=portbuffer) { if (((p0h^portbuffer) & bitmask_1[pin])&& !(in_blocked & bitmask_1[pin]) )//kürzeste Version { pin_changed(pin); // Änderung verarbeiten } portbuffer|=(p0h& bitmask_1[pin]); // neuen Portzustand in buffer speichern portbuffer&=(p0h| ~bitmask_1[pin]); // neuen Portzustand in buffer speichern // if(pin==3)pin=2;// maximal 2-3 // else pin=3; // nächsten pin prüfen.. pin^=0x01;// pin ist mit 2 initialisiert somit wird zwischen 2 und 3 hin und hergeschalten } if(RTCCON>=0x80){ RTCCON=0x60; // RTC Flag löschen RTCH=0x0E; //0E reload Real Time Clock RTCL=0xA0; //A0 16ms +precounter x4 RTCCON=0x61; // RTC Flag löschen delay_timer(); // timer handler jedes 4. mal--> 64ms } if(TF0 && (TMOD & 0x0F)==0x01) { // Vollstrom für Relais ausschalten und wieder PWM ein TMOD=(TMOD & 0xF0) + 2; // Timer 0 als PWM TAMOD=0x01; TH0=DUTY; TF0=0; AUXR1|=0x10; // PWM von Timer 0 auf Pin ausgeben PWM=1; // PWM Pin muss auf 1 gesetzt werden, damit PWM geht !!! TR0=1; } if (portchanged)port_schalten(); // Ausgänge schalten // Rückmeldungen senden if(rm_send&0x03) { // wenn nichts zu senden ist keine Zeit vertrödeln if(rm_send & (1<<rm_count)) { if(send_obj_value(rm_count + 16)) { // falls erfolgreich, dann nächste rm_send&=(0xFF-(1<<rm_count)); rm_count^=0x01; } } else { // RM sollte nicht gesendet werden rm_count^=0x01; } } else rm_count=0; // portbuffer flashen, Abbruch durch ext-int wird akzeptiert und später neu probiert // T1-int wird solange abgeschaltet, if (fb_state==0 && (TH1<0XC0) && (!wait_for_ack)&& portbuffer!=PORTSAVE) { START_WRITECYCLE; WRITE_BYTE(0x00,0xFF,portbuffer); STOP_WRITECYCLE; } #ifdef zykls for(objno=2;objno<=3;objno++){ tmp=(eeprom[0xD5+(objno*4)]&0x0C);//0xD5/ bit 2-3 zykl senden aktiv objstate=read_obj_value(objno); if (((eeprom[0xCE+(objno>>1)] >> ((objno & 0x01)*4)) & 0x0F)==1){// bei Funktion=Schalten if ((tmp==0x04 && objstate==1)||(tmp==0x08 && objstate==0)|| tmp==0x0C){//bei zykl senden aktiviert n=timercnt[objno]; if ((n & 0x7F) ==0){ // wenn aus oder abgelaufen timercnt[objno] = (eeprom[0xD6+(objno*4)]& 0x3F)+ 0x80 ;//0xD6 Faktor Zyklisch senden x.1 + x.2 )+ einschalten timerbase[objno]=(eeprom[0xF6+((objno+1)>>1)]>>(4*((objno&0x01)^0x01)))&0x07; //Basis zyklisch senden if (n & 0x80){// wenn timer ein war if(!(in_blocked & bitmask_1[objno])) { while(!send_obj_value(objno));//send_obj_value(objno); // Eingang x.1 zyklisch senden } } } } else timercnt[objno]=0; } }