Вот стабильно работающий макет прошивы, работающий в течении уже
нескольких суток для такой же платки-донора на MSP, присопливленной
пятью проводками в модем Telit GL 868 Dual. Регулярно отправляет
данные с двух беспроводных датчиков скрипту на HTTP сервере,
получает в ответ уставку температуры включения вентилятора(если
необходимо изменить дефолтную) и рулит им. Получает оттуда же в
заданное время команду включения полива на XX минут. Хоть без
крутого парсинга, но
вполне уже созрела для испытаний "курятника". Из за лени применил sprintf() и прошива увеличилась вдвое - до 3.5 кб :) Осталось протянуть трубы и прикрутить PHP скрипт на сервер для вывода графиков, чтобы приступить к настройке и доводке ;)
///////////////////////////////////////////////////////////////////////////// #define VER 1 // Telit 868 МГц #define INTERVAL 5 * 75 // 5 минут * количество тиков в минутц - 75 #define IDS1 0x0076 // ID "воздушного" датчика #define IDS2 0x265a // ID "земляного" датчика //#define RF_POWER 0x40 // -5 dBm //#define RF_POWER 0x80 // 4 dBm //#define RF_POWER 0xC0 // 12 dBm #define RF_POWER 0x50 // 0 dBm #define OK 0x009A #define ACT 0x027D #define REG 0x0233 #define CONNECT 0x020A #define HTTPOK 0x036B //#define NOACT 0x027C //#define NOREG1 0x0232 //#define NOREG2 0x0234 #define T_ON 25 // температура включения вентилятора по-умолчанию #define TIMEV 100 // время выключения вентилятора * 0.75 сек //////////tst///////////////////// // 3.5V LF oscillator // 20C - 10.14 kHz //-10C - 9.17 kHz //+45C - 11.29 kHz ////////////////////////////////// #include <string.h> #include "io430.h" #include "cc110X.h" #include "stdio.h" #pragma diag_suppress=Pa082 void reset_modem(void);// void init_modem(void); // void debug(unsigned int c); // #pragma location=0x1000 __no_init const unsigned short MY_ID; // серийный номер по адресу 0x1000 volatile unsigned int code =0; volatile unsigned char cnt_ch; volatile unsigned int timeout =0; volatile unsigned int del_075; volatile unsigned int pattern =0; volatile unsigned int pump =0; volatile unsigned int vent =0; volatile unsigned int tON_vent; volatile unsigned int cnt_s_pump=0; volatile unsigned int cnt_s_vent=0; unsigned short bat1; // напряжение батареи 1 unsigned short bat2; // напряжение батареи 2 unsigned char imp1; // импеданс 1 unsigned char imp2; // импеданс 2 signed char tm1; // температура 1 signed char tm2; // температура 2 struct { unsigned short id; // ID датчика unsigned short bat; // напряжение батареи unsigned char imp; // импеданс signed char tm; // температура unsigned char xxx[3] ; } rec_rx; void work_sens(void) { char len; if (FL_CC) { CLR_FL_CC; len=7; if(RFReceivePacket((char*)&rec_rx,(char*)&len)) { if (len==6) { if (rec_rx.id == IDS1) { bat1=rec_rx.bat; imp1=rec_rx.imp; tm1=rec_rx.tm; } if (rec_rx.id == IDS2) { bat2=rec_rx.bat; imp2=rec_rx.imp; tm2=rec_rx.tm; if(tm2 > tON_vent) vent=TIMEV; // включить вентилятор // сам выключится через TIMEV, если температура упадет } } //debug(rec_rx.imp + (rec_rx.tm<<8)); //debug(rec_rx.id); } TI_CC_SPIStrobe(TI_CCxxx0_SRX); // перезапустим прием } } void clear_data(void) // обнуление данных { bat1=imp1=tm1=0; bat2=imp2=tm2=0; } void delay(unsigned int del) { del_075=del; while(del_075) work_sens(); } void soft_reset(void) { WDTCTL = WDT_MRST_0_064; while(1); } void putchr(char c) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = c; } void Send_UART(char * byte) { for (;*byte;++byte) putchr (*byte); putchr(13); } void init_uart(void) { //////////////// настроим последовательный порт////////////////////////////// P1SEL |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD P1SEL2 |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 65; // 8MHz 9600 UCA0BR1 = 3; // 8MHz 9600 UCA0MCTL|= UCBRS0; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt } void debug(unsigned int c) { char i; #define z 34*8 // 28800 P2OUT|=BIT2; //1 __delay_cycles(z); P2OUT&=~BIT2; //0 //startt __delay_cycles(z); for (i=0;i<8;i++) { if (c & 1) P2OUT|=BIT2; //1 else P2OUT&=~BIT2; //0 c=c>>1; __delay_cycles(z); } P2OUT|=BIT2; //1 stop __delay_cycles(104*8); P2OUT&=~BIT2; //0 //startt __delay_cycles(z); for (i=0;i<8;i++) { if (c & 1) P2OUT|=BIT2; //1 else P2OUT&=~BIT2; //0 c=c>>1; __delay_cycles(z); } P2OUT|=BIT2; //1 stop __delay_cycles(104*8); } int command(char * str, unsigned int time, unsigned int patt) { code=0; cnt_ch=0; timeout=time; pattern=patt; Send_UART(str); while(timeout) { work_sens(); if (pattern==0) return(1); } if (cnt_ch==0) { reset_modem(); init_modem(); } return(0); } void rf_recal(void) // рекалибровка радио { TI_CC_SPISetup(); TI_CC_On(); // инициализация радио TI_CC_SPIStrobe(TI_CCxxx0_SRX); // перезапустим прием CLR_FL_CC; } void reset_modem(void) { IE2 &= ~UCA0RXIE; // Didable USCI_A0 RX interrupt P1SEL&= ~(BIT1 + BIT2) ; // переключим в режим GPIO // P1.1 = RXD, P1.2=TXD P1SEL2&= ~(BIT1 + BIT2) ; // переключим в режим GPIO // P1.1 = RXD, P1.2=TXD UCA0CTL1=0; // выключить UART P2OUT|=BIT1; // выключить стабилизатор 3.9В P1OUT&=~BIT2; // Port ноги TXD = 0; delay(3);// здесь пауза 3 сек P2OUT&=~BIT1; // включить стабилизатор 3.9В init_uart(); delay(3); } void init_modem(void) { command("AT", 2, OK); command("AT", 2, OK); command("AT+CGDCONT=1,\"IP\",\"internet.beeline.ru\"",2,OK); command("AT#HTTPCFG=0",2,OK); command("AT#DTMF=0", 2, OK); command("AT+CLIP=0", 2, OK); } char http_send(void) { int rez = 0; char httpstr[100]; if (command("AT+CREG?", 2, REG)) { if (command("AT#SGACT?", 2, ACT) == 0) command("AT#SGACT=1,1", 20, OK); if (command("AT#SGACT?", 2, ACT) != 0) { delay(2); if (command("AT#SD=1,0,80,\"********.ru\"", 20, CONNECT)) { delay(2); sprintf(httpstr,"GET /data_msg.php?temp=%d,%u,%u,%d,%u,%u,%u,%u, HTTP/1.0\r\nHost: ********.ru\r\n\r\n",tm1,imp1,bat1,tm2,imp2,bat2,pump,vent); cnt_s_pump=0; cnt_s_vent=0; rez = command(httpstr, 30, HTTPOK); delay(2); if (rez) { if (cnt_s_pump > 10) pump=(cnt_s_pump-10)*75; // время полива в минутах * (0.75 сек * 75 = 60 сек) if (cnt_s_vent > 10) tON_vent=(cnt_s_vent-10)+20; // температура включения вентилятора } } } } return(rez); } int main( void ) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_8MHZ; // Set DCO 8 MHz DCOCTL = CALDCO_8MHZ; P2SEL=0; //отключим кварц // запретим возможно использованную ранее в загрузчике периферию////// __disable_interrupt(); TA0CTL=0; TA1CTL=0; UCA0CTL1=0; UCB0CTL1=0; P1REN=0; P2REN=0; ///////////////////////////////////////////////////////// // это для "Telit" GL 868 dual // P1.0 - выход реле 1 (out, 0) // P1.1 - RX (in) // P1.2 - TX (out, 1) // P2.1 - reset модем (out, 0) (при сбросе контроллера НЕ сбрасываем модем) // P2.2 - выход реле 2 (out, 0) P1OUT = 0x1E; // 0001 1110 P1DIR = 0xBD; // 1011 1101 // биты 2,3,4 вывод единицы, бит 1 вход с подтяжкой к 1 - для RX, бит 1 - реле 1=0 P1REN |= BIT6; // подтянем вход MISO к земле P2OUT = 0x50; // 0101 0000 P2DIR = 0x57; // 0101 0111 // для cc1101 ///////////////////////////////////////////////////////////////// BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO (ACLK) IE1 |= WDTIE; // Enable WDT interrupt WDTCTL = WDT_ADLY_250; // Set Watchdog Timer to exactly 0.75 s __enable_interrupt(); tON_vent=T_ON; clear_data(); // обнуление данных rf_recal(); init_uart(); delay(3); init_modem(); //------------------------------------------------------------ /// MAIN LOOP ////// while (1) { if(http_send()) // посылка отправлена { rf_recal(); // здесь периодическая рекалибровка радио clear_data(); // обнуление данных после успешной посылки delay(INTERVAL); // интервал * 0.75 сек. } else delay(2); // повторить попытку отправки через 1.5 сек. } } //------------------------------------------------------------ #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { if (timeout) timeout--; if (del_075) del_075--; if (pump){pump--;P1OUT|=BIT0;} // насос включен, если установлено время else P1OUT&=~BIT0; // выключим насос после окончания времени if (vent){vent--;P2OUT|=BIT2;} // вентилятор включен, если установлено время else P2OUT&=~BIT2 // выключим вентилятор } #pragma vector=USCIAB0RX_VECTOR __interrupt void usart_interrupt(void) { unsigned char ch; ch = UCA0RXBUF; cnt_ch++; if (ch!=0x0A) { if (ch==0x0D) { if (code !=0 ) { //debug(code); if (code == pattern) pattern=0; code=0; } } else code=(code+ch); if(ch == '}') cnt_s_pump++; // считаем количество символов "}" в ответе PHP скрипта сервера if(ch == '{') cnt_s_vent++; // считаем количество символов "{" в ответе PHP скрипта сервера } } #pragma vector=NMI_VECTOR __interrupt void nmi_interrupt(void) { soft_reset();// пересброс // ((void (*)())0x170)(); // Invalid fetch ("call #0170h") // пересброс }