Да вот, собственно, и весь код...
//////////////////////////////////////////////////////////////////////////// #define VER 2 // Telit 868 МГц #define INTERVAL 160 // 2 минут * количество 0.75 тиков в минуту = 80 #define IDS1 0x265a // ID "земляного" датчика #define IDS2 0x264F // ID "воздушного" датчика #define IDB 0x1F11 // 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 HTTPOK2 0x036A //#define HTTPOK 0x036B // Inovetica #define HTTPOK 0x036B //SWEB //#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 cnt_t=0; 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 char cnt_err; unsigned char fl_hand_pump=0; unsigned char fl_hand_vent=0; unsigned short bat1; // напряжение батареи 1 unsigned short bat2; // напряжение батареи 2 unsigned short imp1; // импеданс 1 unsigned short imp2; // импеданс 2 signed char tm1; // температура 1 signed char tm2; // температура 2 //volatile unsigned short deb_code = 0; //for debug2 //volatile unsigned char fl_code =0; //for debug2 struct { unsigned short id; // ID датчика unsigned short bat; // напряжение батареи unsigned short imp; // импеданс signed char tm; // температура unsigned char xxx[3] ; } rec_rx; void work_sens(void) { char len; WDTCTL = WDT_ARST_1000;// пересброс wdt if (FL_CC) { CLR_FL_CC; len=8; if(RFReceivePacket((char*)&rec_rx,(char*)&len)) { if (len==7) { 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, если температура упадет } if (rec_rx.id == IDB) { if ((rec_rx.imp==333) && (rec_rx.tm==0)) { fl_hand_vent=0; fl_hand_pump=0; P1OUT&=~BIT0; // выключить насос вручную P2OUT&=~BIT2; // выключим вентилятор } if ((rec_rx.imp==334) && (rec_rx.tm==0)) { fl_hand_pump=1; P1OUT|=BIT0; // включить насос вручную, } if ((rec_rx.imp==335) && (rec_rx.tm==0)) { fl_hand_vent=1; P2OUT|=BIT2; // вентилятор включен } } //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) { //////////////// настроим последовательный порт////////////////////////////// UCA0STAT=0; // c загрузчиком датчиков сбросим uart UCA0CTL1 |= UCSWRST; // c загрузчиком датчиков сбросим uart 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(15);// здесь пауза 10 сек P2OUT&=~BIT1; // включить стабилизатор 3.9В init_uart(); delay(3); cnt_err=0; } void init_modem(void) { command("AT", 2, OK); command("AT", 2, OK); command("AT+CGDCONT=1,\"IP\",\"internet\"",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,\"simcon.xyz\"", 20, CONNECT)) if (command("AT#SD=1,0,80,\"goodwin.ru\"", 20, CONNECT)) //SWEB { delay(2); sprintf(httpstr,"GET /test.php?temp=%d,%u,%u,%d,%u,%u,%u,%u, HTTP/1.0\r\nHost: goodwin.ru\r\n\r\n",tm1,imp1,bat1,tm2,imp2,bat2,pump,vent); // //SWEB cnt_s_pump=0; cnt_s_vent=0; // fl_code=1; //debug2 rez = command(httpstr, 40, HTTPOK); delay(2); if (rez) { // deb_code=333; //debug2 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; UCA0CTL0=0; UCA0CTL1=0; UCA0MCTL=0; UCB0CTL0=0; UCB0CTL1=0; P1REN=0; P2REN=0; P1SEL=0; P1SEL2=0; IE2=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) WDTCTL = WDT_ARST_1000; // Reset Watchdog Timer to 3 s CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 65210; TACTL = TASSEL_2 + MC_2; // SMCLK, contmode __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(); // обнуление данных после успешной посылки cnt_err=0; delay(INTERVAL); // интервал * 0.75 сек. } else { delay(4); // повторить попытку отправки через 3 сек. cnt_err++; if (cnt_err> 10) { reset_modem(); init_modem(); } } } } #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 ) { // deb_code= code; // debug2 //if (fl_code==1)deb_code= code; //fl_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") // пересброс } // Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A (void) { CCR0 += 65210; // Add Offset to CCR0 cnt_t++; if (cnt_t==92) { cnt_t=0; ////// // P1OUT ^= 0x01; // Toggle P1.0 Тест ///// if (timeout) timeout--; if (del_075) del_075--; if(!fl_hand_pump) { if (pump){pump--;P1OUT|=BIT0;} // насос включен, если установлено время else P1OUT&=~BIT0; // выключим насос после окончания времени } else pump=0; if(!fl_hand_vent) { if (vent){vent--;P2OUT|=BIT2;} // вентилятор включен, если установлено время else P2OUT&=~BIT2; // выключим вентилятор } else vent=0; } }
-
- Надо мной смеются что я не могу (да и не пытаюсь) отучить себя от "корпоративная мультизадачность" вместо "кооперативная". Но тут, смотри - "имперская"! :) (вместо императивная) Cкpипaчпророк(183 знак., 02.06.2024 08:33)
- Спасибо, мне нравится такая реализация. Меньше бы было процессов, пожалуй, позаимствовал бы подход. - vesago(02.06.2024 07:36)