Да вот, собственно, и весь код...
////////////////////////////////////////////////////////////////////////////
#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)