Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс. e-mail:jobsmp@pochta.ru |
/*
file: "sms_avr_c"
*/
#include <io2313.h> /* special function register declarations */
#include <string.h> /* special function register declarations */
#include <pgmspace.h>
#include <inavr.h> /* special function register declarations */
#include <stdbool.h> /* special function register declarations */
#include "signal.h" /* special function register declarations */
// http://telesys.ru/wwwboards/mcontrol/2304/messages/732353.shtml
// что написать после #define PGM_P ???????
// так МОРЕ ошибок
#define PGM_P const char _flash*
#include "gsm_avrv4_h.h"
#define nop() {asm("nop");}
bool Alarm = 0;
bool Count_Alr = 0;
bool Rs;
const char __flash szATZ[] = "ATZ\x0d";
const char __flash szATE0[] = "ATE0\x0d";
const char __flash szATCPBS[] = "AT+CPBS=\"SM\"\x0d"; // выбираем записную книжку SIM
const char __flash szATCPBR[] = "AT+CPBR=1\x0d"; // читаем из 1й ячейки SIM
const char __flash szATE1[] = "ATE1\x0d";
const char __flash szATCMGS[] = "AT+CMGS=56\x0d"; // начинаем слать SMS
const char __flash szATD[] = "ATD+37369530761;\x0d"; // вызов
const char __flash szATSMSStart[] = "0011000B91"; // заголовок СМС
//ТРЕВОГА! Ударный дат.
//0011000B919712674523F10008AA2A0422042004150412041E04130410002100200423043404300440043D044B04390020043404300442002E
const char __flash szSMSShock[] = "0008AA2A0422042004150412041E04130410002100200423043404300440043D044B04390020043404300442002E\x1a\x0d";
//ТРЕВОГА! Багажник.
//0011000B919712674523F10008AA2A0422042004150412041E041304100021002000200020002004110430043304300436043D0438043A002E
//ТРЕВОГА!Откр.Багажник
//0011000B919712674523F10008AA2A0422042004150412041E041304100021041E0442043A0440002E04110430043304300436043D0438043A
const char __flash szSMSTrunk[] = "0008AA2A0422042004150412041E041304100021041E0442043A0440002E04110430043304300436043D0438043A\x1a\x0d";
//ТРЕВОГА! Откр. двери.
//0011000B919712674523F10008AA2A0422042004150412041E0413041000210020041E0442043A0440002E002004340432043504400438002E
const char __flash szSMSDoors[] = "0008AA2A0422042004150412041E0413041000210020041E0442043A0440002E002004340432043504400438002E\x1a\x0d";
//ТРЕВОГА! Откр. капот.
//0011000B919712674523F10008AA2A0422042004150412041E0413041000210020041E0442043A0440002E0020043A0430043F043E0442002E
const char __flash szSMSHood[] = "0008AA2A0422042004150412041E0413041000210020041E0442043A0440002E0020043A0430043F043E0442002E\x1a\x0d";
//Внимание! Нет питания
//0011000B919712674523F10008AA2A0412043D0438043C0430043D0438043500210020041D043504420020043F043804420430043D0438044F
const char __flash szSMSPower[] = "0008AA2A0412043D0438043C0430043D0438043500210020041D043504420020043F043804420430043D0438044F\x1a\x0d";
char szSMSRecipientNumber[15] = "+78121234567"; // в полном формате
char Alr = 0;
char S1 = 0;
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)
void main(void)
{
while(1)
{
char i;
char j = 1;
char c;
char nRecv;
unsigned char cp;
unsigned char FirstRun;
unsigned char CountLED;
char* pBuf;
wait_1s(2); // защита от дребезга
DDRB = 0xfc;
PORTB = 0x04;
while(j < 16)
{
wait_1s(1); // защита от дребезга
if(PINB & (1<<PINB1))S1 = S1 | j; else S1 = S1 | (j << 4); //формирование конфигурационног байта S1
PORTB = PORTB << 1;
j = j*2;
}
//----------------------------------------------------------------
Init();
Rs = 0;
Count_Alr = 0;
//----------------------------------------------------------------
if(Send_Receive(szATZ, 0) != 0)
{
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);
nRecv = 0;
pBuf = UART_Recv(&nRecv);
if(nRecv < 12)
{
DiagOut(4); // нет номера
continue;
}
// else DiagOut(nRecv+0x80);
cp = 0;
// 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;
/*
////////////////////////////////////////////////////////////////////////////////////////////////////////
// нашли "+
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] = pBuf[cp+1+12]; // 5
szSMSRecipientNumber[11] = pBuf[cp+1+11]; // 7
szSMSRecipientNumber[12] = 0x46; // F
szSMSRecipientNumber[13] = 0; // EOS
DiagOut(0x82);
cp = 241;
break;
////////////////////////////////////////////////////////////////////////////////////////////////////
*/
}
cp++;
}
if(cp < 220)
{
DiagOut(5); // нет плюса в номере
continue;
}
//===========================================================================
// теперь рабочий цикл
FirstRun = 1;
CountLED = 0;
while(1)
{
while(PIND & (1<<PIND6)) //цикл пока не поставлено на охрану
{
//---------------------------------------------------------------
PORTB = 0xc2;
c = 0;
Alarm = 0;
Alr = 0;
if(Count_Alr){Count_Alr = 0;Rs = 1;break;}
//--------------------------------------------------------------------------
if(FirstRun > 10)
{
PORTB &= ~(1<<PB7);
FirstRun = 1;
}
wait_1ms(100);
PORTB |=(1<<PB7);
FirstRun++;
}
//---------------------------------------------------------------------------
// Возможность полного сброса
if(Rs)
break;
//------------------------------------------------------------------------
//
wait_1ms(50); // защита от дребезга
if(PIND & (1<<PIND6))
continue;
if(FirstRun) // если только что поставили на охрану
{
wait_1s(5); // ждем 10 секунд перед постановкой на охрану
FirstRun = 0;
Count_Alr = 0;
Alr = 0;
}
if(!Alarm)
{
// помигиваем светодиодом-
if(++CountLED & 0x8)
{
PORTB &= ~(1<<PB7);
if(CountLED == 0xF8)Count_Alr = 1; //задержка перед охраной
}
else
PORTB |= (1<<PB7);
}
else
{
PORTB &= ~(1<<PB7); //светод.включен
PORTB |= (1<<PB0); //сирена включена
}
//-----------------------------------------------------------------------------------------------------
// if(Count_Alr) // задержка перед опросом шлейфов
// {
j = 1;
for(i=2; i<6; i++)
{
if(!(PIND & (1<<(i))) && (S1 & j))
{j = j*2; goto n1;}
else if(PIND & (1<<(i)) && (S1 & (j << 4)))
{j = j*2; goto n2;}
else j = j*2;continue;
{
n1: for(c = 0; c<5; c++)
{
wait_1ms(40); // защита от дребезга
if(PIND & (1<<(i)))
break;
} goto m1;
n2: for(c = 0; c<5; c++)
{
wait_1ms(40); // защита от дребезга
if(!(PIND & (1<<(i))))
break;
}
m1: if(c == 5) // все 5 раз шлейф был замкнут на землю
{
Alarm = 1;
PORTB |= (1<<PB7); //
if(i == 4 && !(Alr & 0x02)) // двери - ждем 5 с
{
wait_1s(10);
if(PIND & (1<<PIND6)) // если за это время выключили охрану
Alarm = 0;
else
{
PORTB |= (1<<PB4);
Alr = Alr | 0x02;
SendSMS(i);
}
}
//---------------------------------------------------------------------------------------------------
if(i == 2 && !(Alr & 0x04))
{PORTB |= (1<<PB2);Alr = Alr | 0x04;SendSMS(i);} //ударный датчик
if(i == 3 && !(Alr & 0x08))
{PORTB |= (1<<PB3);Alr = Alr | 0x08;SendSMS(i);} //багажник
if(i == 5 && !(Alr & 0x10))
{PORTB |= (1<<PB5);Alr = Alr | 0x10;SendSMS(i);} //капот
continue;
}
}
}
// }
//-----------------------------------------------------------------------------------------
// проверка питания
if(!(PINB & (1<<PINB6))) // питание
{
wait_1ms(200); // защита от дребезга
wait_1ms(200); // защита от дребезга
wait_1ms(200); // защита от дребезга
// if(bit_is_clear(PINB, 2))
// if(!(PINB & (1<<PINB2)) && !Supply_Alr) // питание
if(!(PINB & (1<<PINB6)) && !(Alr & 0x01)) // питание
{
SendSMS(11); // питание пропало!
// Supply_Alr = 1;
Alr = Alr | 0x01;
// break;
continue;
}
}
}// while(1)
} // while(1)
// return 0;
}
//-------------------------------------------------------------------------------
void Init(void)
{
DDRB = 0x80; // Нога 19 - выход, светодиод
DDRD = 2; // остальные - входы, TX = выход
// PORTB = 0x7f;
// PORTB = 0x84;
PORTB = 0xc2;
PORTD = 0xfd;
// WDTCR = 0x1f;
UART_Init();
}
char Send_Receive(PGM_P pSend, int nBytes)
{
char n;
char timer = 0;
char* pBuf;
UART_ClearRxBuf();
UART_outstr_P(pSend);
// wait_1ms(250);
for(timer = 0; timer < 10; timer++)
{
n = 0;
wait_1ms(150);
// char* pBuf = UART_Recv(&n);
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)
{
// __watchdog_reset(); //Reset WDT
// cbi(PORTB,7);
PORTB &= ~(1<<PB7);
wait_1ms(len-20);
// sbi(PORTB,7);
PORTB |= (1<<PB7);
wait_1ms(len);
n--;
}
wait_1s(1);
}
void SendSMS(char cause)
{
char i;
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
char n = 0;
unsigned char nLoops = 0;
char* p = NULL;
UART_ClearRxBuf();
UART_outstr_P(szATCMGS); // начинаем отправку
while(!n)
{
wait_1ms(100);
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а в конце
////////////////////////////////////////////////////////////////////////////////////////////////////
UART_ClearRxBuf();
UART_outstr_P(szATD); //
////////////////////////////////////////////////////////////////////////////////////////////////////
for(i = 0;i < 5;i++)
{
PORTB |= (1<<PB7);
wait_1ms(100);
PORTB &= ~(1<<PB7);
wait_1ms(100);
}
}
}
}
/*
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<1120; i++)
// inp(PINB);
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);
arRx[posRx] = UDR;
posRx++;
if(posRx >= SIZERX)
posRx--;
}
*/
//----------------------------------------------------
#pragma vector=UART_RX_vect
__interrupt void UsartRxcHandler( void )
{
/* Disable interrupt */
// SREG &= ~(1<<7);
/* Save global interrupt flag */
// Sreg = SREG;
arRx[posRx] = UDR;
posRx++;
if(posRx >= SIZERX)
posRx--;
/* Restore global interrupt flag */
// SREG = Sreg;
/* Enable interrupt */
// SREG ^= (1<<7);
}
//----------------------------------------------------
void UART_Init(void)
/* initialize uart */
{
/* enable RxD/TxD and ints */
// outp((1<<RXCIE)|/*(1<<TXCIE)|*/(1<<RXEN)|(1<<TXEN),UCR);
UCR = (1<<RXCIE)|/*(1<<TXCIE)|*/(1<<RXEN)|(1<<TXEN);
/* set baud rate */
// outp((unsigned char)UART_BAUD_SELECT, UBRR);
UBRR = (unsigned char)UART_BAUD_SELECT;
}
void UART_outstr_P(PGM_P str)
{
unsigned char i = 0;
while(1)
{
// char c = pgm_read_byte(&str[i]);
char c = *((unsigned char __flash*)(&str[i]));
// char c = *(&str[i]);
if(!c)
break;
// outp(c, UDR);
UDR = c;
// loop_until_bit_is_set(USR, UDRE);
while(!(USR & (1<<UDRE)));
i++;
}
}
void UART_outstr(char* psz)
{
unsigned char i = 0;
while(1)
{
char c = psz[i];
if(!c)
break;
// outp(c, UDR);
UDR = c;
// loop_until_bit_is_set(USR, UDRE);
while(!(USR & (1<<UDRE)));
i++;
}
}
char* UART_Recv(char* pnRecv)
{
*pnRecv = posRx;
return arRx;
}
void UART_ClearRxBuf(void)
{
// unsigned char i;
// cli();
__disable_interrupt(); //general interrapt disable
memset(arRx, 0, SIZERX);
/* arRx[0] = 0;
arRx[1] = 0;
arRx[2] = 0;
arRx[3] = 0;
arRx[4] = 0;
arRx[5] = 0;
arRx[6] = 0;
arRx[7] = 0;
arRx[8] = 0;
arRx[9] = 0;
arRx[10] = 0;
arRx[11] = 0;
arRx[12] = 0;
arRx[13] = 0;
arRx[14] = 0;
arRx[15] = 0;
arRx[16] = 0;
arRx[17] = 0;
arRx[18] = 0;
arRx[19] = 0;
arRx[20] = 0;
arRx[21] = 0;
arRx[22] = 0;
arRx[23] = 0;
arRx[24] = 0;
arRx[25] = 0;
arRx[26] = 0;
arRx[27] = 0;
arRx[28] = 0;
arRx[29] = 0;
arRx[30] = 0;
arRx[31] = 0;*/
posRx = 0;
// sei();
__enable_interrupt(); //general interrapt disable
}