/* file: "main._c" */ #include #include #include #include #include #include "uart.h" #define nop() {asm("nop");} const char szATZ[] PROGMEM = "ATZ\x0d"; const char szATE0[] PROGMEM = "ATE0\x0d"; const char szATCPBS[] PROGMEM = "AT+CPBS=\"SM\"\x0d"; // выбираем записную книжку SIM const char szATCPBR[] PROGMEM = "AT+CPBR=1\x0d"; // читаем из 1й ячейки SIM const char szATE1[] PROGMEM = "ATE1\x0d"; const char szATCMGS[] PROGMEM = "AT+CMGS=56\x0d"; // начинаем слать SMS const char szATSMSStart[] PROGMEM = "0011000B91"; // заголовок СМС //ТРЕВОГА! Ударный дат. //0011000B919712674523F10008AA2A0422042004150412041E04130410002100200423043404300440043D044B04390020043404300442002E const char szSMSShock[] PROGMEM = "0008AA2A0422042004150412041E04130410002100200423043404300440043D044B04390020043404300442002E\x1a\x0d"; //ТРЕВОГА! Багажник. //0011000B919712674523F10008AA2A0422042004150412041E041304100021002000200020002004110430043304300436043D0438043A002E //ТРЕВОГА!Откр.Багажник //0011000B919712674523F10008AA2A0422042004150412041E041304100021041E0442043A0440002E04110430043304300436043D0438043A const char szSMSTrunk[] PROGMEM = "0008AA2A0422042004150412041E041304100021041E0442043A0440002E04110430043304300436043D0438043A\x1a\x0d"; //ТРЕВОГА! Откр. двери. //0011000B919712674523F10008AA2A0422042004150412041E0413041000210020041E0442043A0440002E002004340432043504400438002E const char szSMSDoors[] PROGMEM = "0008AA2A0422042004150412041E0413041000210020041E0442043A0440002E002004340432043504400438002E\x1a\x0d"; //ТРЕВОГА! Откр. капот. //0011000B919712674523F10008AA2A0422042004150412041E0413041000210020041E0442043A0440002E0020043A0430043F043E0442002E const char szSMSHood[] PROGMEM = "0008AA2A0422042004150412041E0413041000210020041E0442043A0440002E0020043A0430043F043E0442002E\x1a\x0d"; //Внимание! Нет питания //0011000B919712674523F10008AA2A0412043D0438043C0430043D0438043500210020041D043504420020043F043804420430043D0438044F const char szSMSPower[] PROGMEM = "0008AA2A0412043D0438043C0430043D0438043500210020041D043504420020043F043804420430043D0438044F\x1a\x0d"; char szSMSRecipientNumber[15] = "+78121234567"; // в полном формате void SendSMS(char cause); void Init(void); char Send_Receive(PGM_P pSend, int nBytes); // nBytes = 0 - тогда посылать до конца строки=0 void DiagOut(unsigned char n); void wait_1ms(unsigned char ms); void wait_1s(unsigned char s); /* Возврат Send_Receive: 0 = OK 1 = ERROR 2 = timeout 3 - неизвестное сообщение */ int main(void) { Init(); DiagOut(1); while(1) { wait_1ms(250); if(Send_Receive(szATZ, 0) != 0) { char i=8; while(i--) wait_1ms(250); DiagOut(2); continue; } // else DiagOut(0x82); if(Send_Receive(szATE0, 0) != 0) DiagOut(2); //================AT+CPBS="SM"===получаем доступ к сим ====== if(Send_Receive(szATCPBS, 0) != 0) DiagOut(3); // else DiagOut(0x83); // получим ответ типа OK //================AT+CPBR=1 ===читаем из 1 ячейки ====== UART_ClearRxBuf(); UART_outstr_P(szATCPBR); // получим ответ типа +CPBR: 1,"+79217444347",145," "\x0dOK wait_1ms(250); wait_1ms(250); char nRecv = 0; char* pBuf = UART_Recv(&nRecv); if(nRecv < 12) { DiagOut(4); // нет номера continue; } // else DiagOut(nRecv+0x80); unsigned char cp = 0; while(pBuf[cp]) { if(pBuf[cp]=='O') { DiagOut(4); cp = 240; // признак ошибки break; } if(pBuf[cp]=='B') // +CPBR { DiagOut(0x81); break; } cp++; } if(cp > 128) continue; // ошибка while(pBuf[cp]) { if(pBuf[cp]=='\"' && pBuf[cp+1]=='+'/* && pBuf[cp+13]=='\"'*/) { // нашли "+ szSMSRecipientNumber[0] = pBuf[cp+1+2]; // 8 szSMSRecipientNumber[1] = pBuf[cp+1+1]; // 7 szSMSRecipientNumber[2] = pBuf[cp+1+4]; // 2 szSMSRecipientNumber[3] = pBuf[cp+1+3]; // 1 szSMSRecipientNumber[4] = pBuf[cp+1+6]; // 0 szSMSRecipientNumber[5] = pBuf[cp+1+5]; // 9 szSMSRecipientNumber[6] = pBuf[cp+1+8]; // 4 szSMSRecipientNumber[7] = pBuf[cp+1+7]; // 3 szSMSRecipientNumber[8] = pBuf[cp+1+10]; // 6 szSMSRecipientNumber[9] = pBuf[cp+1+9]; // 5 szSMSRecipientNumber[10] = 0x46; // F szSMSRecipientNumber[11] = pBuf[cp+1+11]; // 7 szSMSRecipientNumber[12] = 0; // EOS DiagOut(0x82); cp = 241; break; } cp++; } if(cp < 220) { DiagOut(5); // нет плюса в номере continue; } // теперь рабочий цикл unsigned char FirstRun = 1; unsigned char CountLED = 0; while(1) { while(bit_is_set(PIND, 6)) { if(FirstRun > 100) { cbi(PORTB,7); FirstRun = 1; } wait_1ms(100); sbi(PORTB,7); FirstRun++; } wait_1ms(50); // защита от дребезга if(bit_is_set(PIND, 6)) continue; if(FirstRun) // если только что поставили на охрану { wait_1s(10); // ждем 10 секунд перед постановкой на охрану FirstRun = 0; } // помигиваем светодиодом if(++CountLED & 0x8) cbi(PORTB,7); else sbi(PORTB,7); // опрос шлейфов char i; for(i=2; i<6; i++) { if(bit_is_clear(PIND, i)) { char c; for(c = 0; c<5; c++) { wait_1ms(40); // защита от дребезга if(bit_is_set(PIND, i)) break; } if(c == 5) // все 5 раз шлейф был замкнут на землю { if(i == 4) // двери - ждем 5 с { wait_1s(5); if(bit_is_set(PIND, 6)) // если за это время выключили охрану continue; // ничего не посылаем } SendSMS(i); continue; } } } if(bit_is_clear(PINB, 2)) // питание { wait_1ms(200); // защита от дребезга wait_1ms(200); // защита от дребезга wait_1ms(200); // защита от дребезга if(bit_is_clear(PINB, 2)) { SendSMS(11); // питание пропало! continue; } } }// while(1) } // while(1) return 0; } void Init(void) { DDRB = 0x80; // Нога 19 - выход, светодиод DDRD = 2; // остальные - входы, TX = выход PORTB = 0x7f; PORTD = 0xfd; UART_Init(); } char Send_Receive(PGM_P pSend, int nBytes) { char timer = 0; UART_ClearRxBuf(); UART_outstr_P(pSend); // wait_1ms(250); for(timer = 0; timer < 10; timer++) { char n = 0; wait_1ms(150); char* pBuf = UART_Recv(&n); if(strchr(pBuf, 0x0d)) // если есть конец строки { if(strstr(pBuf, "OK")) return 0; if(strstr(pBuf, "ERROR")) return 1; return 3; // неизвестная ошибка } } return 2; // timeout } // старший бит указывает на то, что вспышки д.б. короткими void DiagOut(unsigned char n) { unsigned char len = 150; if(n&0x80) len = 50; while(n&0x7f) { cbi(PORTB,7); wait_1ms(len-20); sbi(PORTB,7); wait_1ms(len); n--; } wait_1s(1); } void SendSMS(char cause) { PGM_P psz = NULL; switch(cause) { case 2: // удар psz = szSMSShock; break; case 3: // багажник psz = szSMSTrunk; break; case 4: // двери psz = szSMSDoors; break; case 5: // капот psz = szSMSHood; break; case 11: // пропало питание psz = szSMSPower; break; default: break; } if(psz) // если аргумент правильный { // отправляем SMS UART_ClearRxBuf(); UART_outstr_P(szATCMGS); // начинаем отправку char n = 0; unsigned char nLoops = 0; char* p = NULL; while(!n) { wait_1ms(10); p = UART_Recv(&n); // от трубы должен прийти знак ">" if(++nLoops > 150) { DiagOut(2); // нет подтверждения от трубы break; } } if(*p != '>' && p[1] != '>' && p[2] != '>') { DiagOut(3); // нет подтверждения от трубы } else { UART_outstr_P(szATSMSStart); // 0001000B91 UART_outstr(szSMSRecipientNumber); // номер подготовлен заранее UART_outstr_P(psz); // строка СМС подготовлена заранее, 0х1а в конце cbi(PORTB,7); wait_1s(150); wait_1s(150); sbi(PORTB,7); } } } /* void SendStr(char * s) { while(pgm_read_byte(s)) Send(pgm_read_byte(s++)); } */ void wait_1ms(unsigned char ms) { while(ms) { short int i; for(i=0; i<560; i++) inp(PINB); ms--; } } void wait_1s(unsigned char sec) { while(sec) { wait_1ms(250); wait_1ms(250); wait_1ms(250); wait_1ms(250); sec--; } } #define SIZERX 32 char arRx[SIZERX]; unsigned char posRx = 0; // прерывание происходит по приходу байта SIGNAL(SIG_UART_RECV) { arRx[posRx] = inp(UDR); posRx++; if(posRx >= SIZERX) posRx--; } void UART_Init(void) /* initialize uart */ { /* enable RxD/TxD and ints */ outp((1<