⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm_remote.c

📁 GSM FOR DATA TRANSFER
💻 C
字号:
/* 
 * 080324 - GSM Fernsteuerung
 * 2008
 * Elektor International Media B.V.
 * (C) Florian Sch鋐fer, http://www.blafusel.de
 * Compiler: WinAVR 20060421 with avr-gcc (GCC) 3.4.6
 */

#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include "uart.h"
#include <util/delay.h>		
#include <stdlib.h> 
#include <string.h>
#include <avr/interrupt.h>

#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
#define SMSMODE 0		

void delay_ms(uint16_t);
void uart_init (uint16_t);
uint8_t getSW_TelTyp (void);
uint8_t getSW_ExitTyp (void);
void getSW_BCDTime (void);
uint8_t SMS_send (unsigned char *, unsigned char *, uint8_t);
void getTeilstring (unsigned char *, unsigned char *, uint8_t, char, char);
uint8_t getGPS (void);
void RingDetected (void);
void getGSMcmd (void);
uint8_t getSIMnumber (uint8_t);
void BaudrateGSM (void);
int main(void);

extern uint8_t rbuffcnt;
unsigned char	buffer[170],
				nachricht2[160],
				clipnr[20],
				gpscoord[55],
				tmp[20],		
				tmp2[20];		

volatile uint8_t 	timer_gps=60,		
					timer_rings=0,		
					timer_waitGSM=0,
					cnt_rings=0,
					gps_detect=0,		
					exit1=0,			
					exit2=0,
					exit3=0,
					exit3_time=0,		
					SW_TelTyp,			
					SW_ExitTyp,
					SW_BCDTime,
					alarm = 0;
volatile uint16_t	timer_exit3=0;


void delay_ms(uint16_t ms)
{
	for(uint16_t t=0; t<=ms; t++)
		_delay_ms(1); 
}

ISR (TIMER1_COMPA_vect)		
{
	timer_gps++;
	timer_waitGSM++;
	
	if (cnt_rings)				
		timer_rings++;
	
	if (exit1 == 2)				
	{
		PORTD |= (1<<PD5);		
		exit1=1;				
	}
	else if (exit1 == 1)
	{
		PORTD &= ~(1<<PD5);		
		exit1=0;
	}
	
	if (exit2 == 2)				
	{
		if (SW_ExitTyp)			
		{
			PORTD ^= (1<<PD6);	
			exit2=0;				
		}
		else
		{
			PORTD |= (1<<PD6);		
			exit2=1;				
		}
	}
	else if (exit2 == 1)
	{
		PORTD &= ~(1<<PD6);		
		exit2=0;
	}
	
	if (exit3 == 2)				
	{
		PORTD |= (1<<PD7);		
		exit3=1;				
		timer_exit3=0;			
	}
	else if (exit3 == 1)
	{
		timer_exit3++;			
		if (timer_exit3 >= (uint16_t) (exit3_time * 60))		
		{
			PORTD &= ~(1<<PD7);		
			exit3=0;
		}
	}

	if (gps_detect == 1)		
		PORTB ^= (1<<PB5);					
	if (gps_detect == 2)
		PORTB |= (1<<PB5);					
	

}

ISR (INT1_vect)		
{
	alarm=1;
}

void uart_init (uint16_t baud_rate)
{
	UBRRH=(uint16_t)(UART_BAUD_CALC(baud_rate,F_CPU)>>8);		
	UBRRL=(uint16_t)UART_BAUD_CALC(baud_rate,F_CPU);

	uart_ini();
}

uint8_t getSW_TelTyp (void)
{
	if (PINC & (1 << PINC4))		
		return 0;
	else
		return 1;
}

uint8_t getSW_ExitTyp (void)
{
	if (PINC & (1 << PINC5))		
		return 0;
	else
		return 1;
}

void getSW_BCDTime (void)
{
	uint8_t sw = 0;
	
	if (!(PINC & (1 << PINC0)))
		sw += 1;
	if (!(PINC & (1 << PINC1)))
		sw += 2;
	if (!(PINC & (1 << PINC2)))
		sw += 4;
	if (!(PINC & (1 << PINC3)))
		sw += 8;
	
	switch (sw)
	{
		case 0 : exit3_time = 1; break;
		case 1 : exit3_time = 5; break;
		case 2 : exit3_time = 10; break;
		case 3 : exit3_time = 15; break;
		case 4 : exit3_time = 20; break;
		case 5 : exit3_time = 30; break;
		case 6 : exit3_time = 45; break;
		case 7 : exit3_time = 60; break;
		case 8 : exit3_time = 90; break;
		case 9 : exit3_time = 120; break;
	}
}

uint8_t SMS_send (unsigned char *zielnr, unsigned char *nachricht, uint8_t typ)
{
	uint8_t	anz_septents = 0,	
			anz_bytes = 1,		
			i = 0,
			shift = 0,	
			erg=1;
	char 	zeichen1 = 0, 
			zeichen2 = 0;
	
	while (nachricht[anz_septents] != 0)		
	{
		nachricht2[anz_bytes] = (nachricht[anz_septents]&0x7F) >> shift;
		if (shift != 0)
			nachricht2[anz_bytes-1] |= (nachricht[anz_septents]&((1<<shift)-1)) << (8-shift);
		shift++;
		anz_septents++;
		if (shift == 8)
			shift=0;
		else
			anz_bytes++;
	}
	nachricht2[0] = anz_septents;		
	
	while (zielnr[i] !=0)		
	{
		if (zielnr[i+1] == 0)		
			tmp[i] = 'F';		
		else
			tmp[i] = zielnr[i+1];
		tmp[i+1] = zielnr[i];
		i += 2;
	}
	tmp[i] = 0;			

    if (typ == 0)			
		sprintf(tmp2, "at+cmgs=");		
	else if (typ == 1)		
		sprintf(tmp2, "at+cmgw=");		
    uart_puts(tmp2);					

    sprintf(tmp2, "%i\r\n", (anz_bytes+(i/2)+7));		
    uart_puts(tmp2);					

	while(ser_getc()!=' ');				
	
	sprintf(tmp2, "00");				
    uart_puts(tmp2);					
	sprintf(tmp2, "11");				
    uart_puts(tmp2);					
	sprintf(tmp2, "00");				
    uart_puts(tmp2);					
	if(tmp[i-2] == 'F')				
		i--;
	sprintf(tmp2, "%02X91", i);		
    uart_puts(tmp2);					
	sprintf(tmp2, tmp);			
    uart_puts(tmp2);					
	sprintf(tmp2, "00");				
    uart_puts(tmp2);					
	sprintf(tmp2, "00");				
    uart_puts(tmp2);					
	sprintf(tmp2, "AA");				
    uart_puts(tmp2);					
	for (anz_septents = 0;anz_septents<anz_bytes;anz_septents++)
	{
		sprintf(tmp2, "%02X", nachricht2[anz_septents]);
		uart_puts(tmp2);					
	}
    sprintf(tmp2, "%c",0x1A);			
    uart_puts(tmp2);					
	
	while (ser_getc() != 10);		
	do
	{
		zeichen2 = ser_getc();		
		if ((zeichen2 == 'R') && (zeichen1 == 'E'))	
		{
			erg = 1;		// Mistake
		}
		if ((zeichen2 == 'G') && (zeichen1 == 'M'))	
		{
			erg = 0;		// OK
			while (ser_getc() != 10);	
			while (ser_getc() != 10);	
		}
		zeichen1 = zeichen2;
	}
	while (zeichen1 != 10);		
	return erg;
}

void getTeilstring (unsigned char *dest, unsigned char *from, uint8_t pos, char compare1, char compare2)
{
	uint8_t	detect=0,			
			cnt=0;
	
	while (*from != '\0')		
	{
		if (*from == compare1)
			cnt++;				
		if (cnt == pos)			
		{
			compare1=compare2;	
			if (detect == 0)	
				detect = 1;		
			else				
			{					
				*dest = *from;
				dest++;			
			}
		}
		from++;					
	}
	*dest = '\0';				
}

uint8_t getGPS (void)
{
	uint8_t	i,
			u=0,
			gps_dect=0,
			byte;

	timer_gps = 0;
	while (timer_gps < 20)		
	{
		if (!(PIND & (1 << PIND2)))		
		{
			_delay_us (52);		
			_delay_us (52);		

			_delay_us (52);		
			_delay_us (52);

			_delay_us (52);		
			_delay_us (52);

			byte=0;
			for (i=0; i <= 7; i++)		
			{
				if (PIND & (1 << PIND2))
					byte |= (1 << i);

				_delay_us (52);		
				_delay_us (52);

				_delay_us (52);		
				_delay_us (52);
			}
			
			if (gps_dect)
			{
				buffer[u]=byte;
				u++;

				if (byte == '\n')
				{
					buffer[u-2]='\0';	
					u=0;
					byte=0;
					
					if (strncmp  (buffer, "$GPRMC", 6) == 0)		
					{
						getTeilstring (tmp, buffer, 2, ',', ',');		
						if (tmp[0] == 'V')
						{
							gps_detect=1;
							sprintf (gpscoord, "*GPS INVALID*");
						}
						else
						{
							gps_detect=2;
							sprintf (gpscoord, "*GPS OK*");
						}
						
						getTeilstring (tmp, buffer, 1, ',', ',');		// = UTC Time
						sprintf (gpscoord, "%s %c%c:%c%c:%c%c", gpscoord, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]);		// "hh:mm:ss "
						
						getTeilstring (tmp, buffer, 4, ',', ',');		// = Hemisphere
						sprintf (gpscoord, "%s %s", gpscoord, tmp);
						getTeilstring (tmp, buffer, 3, ',', ',');		// = Latitude (e.g. 5256.0361)
						sprintf (gpscoord, "%s%c%c\x24%c%c%c%c%c%c%c ", gpscoord, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8]);

						getTeilstring (tmp, buffer, 6, ',', ',');		// = Hemisphere
						sprintf (gpscoord, "%s %s", gpscoord, tmp);
						getTeilstring (tmp, buffer, 5, ',', ',');		// = Longitude (e.g. 01248.0766)
						sprintf (gpscoord, "%s%c%c%c\x24%c%c%c%c%c%c%c", gpscoord, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9]);

					}	
					
				}
			}
			if (byte == 10)		
			{
				gps_dect=1;
			}
		} 
	}
	timer_gps=0;
	if (gps_dect)
		return 0;
	else
	{
		PORTB &= ~(1<<PB5);		
		gps_detect=0;
		sprintf (gpscoord, "* NO GPS");		return 1;
	}
}

void RingDetected (void)
{
	uint8_t	u=0;

	if (SW_TelTyp)		
	{
		getTeilstring (tmp, buffer, 2, '+', ',');		

		if (tmp[0] != '\0')		
		{
			u=strlen(tmp);			
			if (tmp[u-1] == '"')	
			{
				tmp[u-1] = '\0';	
			}

			u=1;
			while (!getSIMnumber(u))	
			{
				u++;
				if (strcmp  (tmp, clipnr) == 0)
				{
					cnt_rings++;		
					break;
				}
			}
		}
	}
	else
	{
		cnt_rings++;
	}
}

void getGSMcmd (void)
{
	uint8_t i=0;

	timer_waitGSM=0;
	while (1)
	{
		if (rbuffcnt)
		{
			buffer[i] = ser_getc();
			if (buffer[i] == 10)			
			{
				buffer[i] = '\0';		
				if ((SW_TelTyp && strncmp(buffer, "+CLIP", 5) == 0) || (!SW_TelTyp && strncmp(buffer, "RING", 4) == 0))	 	
				{	
					RingDetected();			
				}
				break;
			}
			i++;
		}
		if (timer_waitGSM >= 5)		
			break;
	}
}

uint8_t getSIMnumber (uint8_t index)
{
	uint8_t i,u=0;

	for (i=1; i<=2; i++)	
	{
		uart_puts ("AT+CPBR=");		
		uart_putc (index + 0x30);	
		uart_puts ("\r");			
		getGSMcmd();getGSMcmd();

		if (buffer[0] == '+')		
		{
			getTeilstring (clipnr, buffer, 2, '+', ',');		
			
			u=strlen(clipnr);			
			if (clipnr[u-1] == '"')		
			{
				u--;					
				clipnr[u]='\0';
			}
			
			getGSMcmd();	
			getGSMcmd();	

			if (u>0)		
				u=0;
			else
				u=1;
		}
		else
			u=1;	
	}
	return u;
}

void BaudrateGSM (void)
{
	uint16_t baudrate=9600;
	uint8_t i=0;

	timer_waitGSM=0;
	uart_init(baudrate);
	uart_puts ("AT\r");		

	while (1)
	{
		if (rbuffcnt)
		{
			buffer[i] = ser_getc();
			if (buffer[i] == 10)			
			{
				buffer[i+1]='\0';
				buffer[i+2]='\0';
			}
			if ((i >= 2) && (buffer[i-1] == 'O') && (buffer[i] == 'K'))	
				break;
			
			i++;
		}
		if (timer_waitGSM >= 5)	
		{
			switch (baudrate)
			{
				case 4800  : baudrate = 9600; break;
				case 9600  : baudrate = 19200; break;
				case 19200 : baudrate = 38400; break;
				case 38400 : baudrate = 57600; break;
				case 57600 : baudrate = 4800; break;
			}
			i=0;
			timer_waitGSM=0;
			uart_init(baudrate);
			uart_puts ("AT\r\n");		
		}
	}
	getGSMcmd();		
	for (i=0; i<=70; i++)			
	{
		PORTB ^= (1<<PB5);		
		delay_ms(35);
	}
	PORTB &= ~(1<<PB5);			
}

int main(void)
{
	uint8_t	i;
	
	
	uart_ini();
	DDRC &= ~(1 << DDC0) & ~(1 << DDC1) & ~(1 << DDC2) & ~(1 << DDC3) & ~(1 << DDC4) & ~(1 << DDC5);		// PORTC Input (Switch)
	PORTC |= (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5);				// PORTC Input with internal pull-up resistors activated
	DDRD &= ~(1 << DDD2); 									// PORTD Input RxD GPS
	DDRD |= (1 << DDD5) | (1 << DDD6) | (1 << DDD7);		// PORTD as Output (Relays)
	DDRB |= (1 << DDB5);									// PORTB as Output (GPS LED)
	
	MCUCR |= (1 << ISC10);				
	GICR |= (1 << INT1);				
	
	TIMSK |= (1 << OCIE1A);				
	OCR1A = (uint16_t)(F_CPU/256);		
	sei();								
	TCCR1B |= (1 << WGM12);				
	TCCR1B |= (1 << CS12);				

	SW_TelTyp = getSW_TelTyp();			
	SW_ExitTyp = getSW_ExitTyp();
	getSW_BCDTime();

	BaudrateGSM();
	uart_puts ("ATE0\r");			
	getGSMcmd();getGSMcmd();		
	uart_puts ("AT+CLIP=1\r");		
	getGSMcmd();getGSMcmd();		
	uart_puts ("AT+CPBS=\"SM\"\r");
	getGSMcmd();getGSMcmd();

	while(1)
	{	
		if (rbuffcnt)		
		{
			getGSMcmd();
		}
		else	
		{
			if (timer_gps >= 60)		
				i = getGPS();

			if (alarm)	
			{
				i = getSIMnumber (1);	
				if (!i)		
				{
					sprintf (buffer, "** ALARM ** GSM Remote Switcher %s", gpscoord);
					do
					{
						i = SMS_send (clipnr, buffer, SMSMODE);
					} while (i);			
					alarm=0;
				}
			}
		}

		if (timer_rings >= 90)		
		{
			if (!SW_TelTyp)		
				cnt_rings--;
		
			switch (cnt_rings)
			{
				case 1 : 	exit1=2;		
							break;
				case 2 : 	exit2=2;		
							break;
				case 3 : 	exit3=2;	
							break;

				case 4 :	i=0;
							if (!SW_TelTyp)	
							{
								i = getSIMnumber (1);	
							}
							if (!i)	
							{
								sprintf (buffer, "Status: TelTyp:%i Exit2Typ:%i Time:%imn Exit1:%i Exit2:%i Exit3:%i %s", SW_TelTyp, SW_ExitTyp, exit3_time, (PORTD >> PD5) & 1, (PORTD >> PD6) & 1, (PORTD >> PD7) & 1, gpscoord);
								do
								{
									i = SMS_send (clipnr, buffer, SMSMODE);
								} while (i);
							}
							break;
				default:	break;
			}
			cnt_rings=0;
			timer_rings=0;
		}
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -