Вот стабильно работающий макет прошивы, работающий в течении уже
нескольких суток для такой же платки-донора на 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") // пересброс
}