Hola de nuevo a todos, paso por aquí para molestarlos, tengo un inconveniente en extraer datos de tramas extensas por medio del protocolo serial con el atmega328p.
Estoy trabajando con un módulo GSM SIM800F, puedo enviar datos a un servidor por el método POST, pero esta vez también quiero usar el GET para realizar un corte y reconexión de energía de una casa desde una página web.
Cuando se usa el GET, el GSM envía una gran cantidad de caracteres al uC y éste tiene que ser capaz de procesar toda la información y depende de uno si desea extraer alguna información, en mi caso dentro de toda esta trama al final llegará la palabra "accion=1," o "accion=0," y tengo que procesar solo el "1" y "0" el resto de caracteres de toda la trama no me interesa.
Estoy trabajando en recepcionar y procesar datos seriales con ayuda del hercules y proteus pero al momento de enviar una gran cantidad de datos al uC no llega a procesar solo procesa cuando le envío pocos datos o bytes.
Estoy usando maquinas de estado para recibir y procesar información, si alguien puede darme una mano o sugerencia para modificar mi código, lo dejaré para que puedan darle un ojo.
La libreria USART :
Estoy trabajando con un módulo GSM SIM800F, puedo enviar datos a un servidor por el método POST, pero esta vez también quiero usar el GET para realizar un corte y reconexión de energía de una casa desde una página web.
Cuando se usa el GET, el GSM envía una gran cantidad de caracteres al uC y éste tiene que ser capaz de procesar toda la información y depende de uno si desea extraer alguna información, en mi caso dentro de toda esta trama al final llegará la palabra "accion=1," o "accion=0," y tengo que procesar solo el "1" y "0" el resto de caracteres de toda la trama no me interesa.
Estoy trabajando en recepcionar y procesar datos seriales con ayuda del hercules y proteus pero al momento de enviar una gran cantidad de datos al uC no llega a procesar solo procesa cuando le envío pocos datos o bytes.
Estoy usando maquinas de estado para recibir y procesar información, si alguien puede darme una mano o sugerencia para modificar mi código, lo dejaré para que puedan darle un ojo.
C:
/*
* Energy.c
*
* Created: 13/12/2020 10:33:05
* Author : Marcelo Higa
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "USART.h"
bool Flag=false;
char Str_data[10];
uint8_t dato;
char Data_Rx;
char DataRx_sim[500];
uint16_t point = 0;
char Str_token1[10];
typedef enum{
Idle=0,
ProcessData,
}state;
state StatePIC; //Estados para procesar la data en el while
typedef enum{
Read_normal=0,
Read_C,
Read_I,
Read_O,
Read_N,
captura_data,
}StateReceiveSerial;
StateReceiveSerial Receive; //Estados para recepcionar datos seriales.
int main(void)
{
sei();
Serial_begin(9600);
StatePIC = Idle;
Receive = Read_normal; //Estados iniciales
DDRB |=(1<<DDB2);
PORTB &= ~(1<<PORTB2);
while (1)
{
switch(StatePIC){
case Idle:
if (Flag==true)
{
StatePIC = ProcessData;
}
break;
case ProcessData:
strcpy(Str_token1,strtok(DataRx_sim,"="));
strcpy(Str_token1,strtok(NULL,","));
dato=atoi(Str_token1);
PORTB = (dato<<PORTB2);
Flag=false;
point=0;
StatePIC=Idle;
memset(DataRx_sim,0,sizeof(DataRx_sim));
sei();
break;
}
}
}
ISR(USART_RX_vect){
Data_Rx = (char)UDR0;
switch(Receive){
case Read_normal:
if (Data_Rx == 'c')
{
Receive = Read_C;
point=0;
}
else
{
DataRx_sim[point] = Data_Rx;
point++;
}
break;
case Read_C:
DataRx_sim[point] = Data_Rx;
if (Data_Rx == 'c')
{
Receive = Read_I;
point++;
}
else
{
Receive = Read_normal;
point = 0;
}
break;
case Read_I:
DataRx_sim[point] = Data_Rx;
if (Data_Rx =='i')
{
Receive = Read_O;
point++;
}
else
{
point=0;
Receive = Read_normal;
}
break;
case Read_O:
DataRx_sim[point] = Data_Rx;
if (Data_Rx =='o')
{
Receive = Read_N;
point++;
}
else
{
point=0;
Receive = Read_normal;
}
break;
case Read_N:
DataRx_sim[point] = Data_Rx;
if (Data_Rx =='n')
{
Receive = captura_data;
point++;
}
else
{
point=0;
Receive = Read_normal;
}
break;
case captura_data:
if (Data_Rx ==',')
{
point=0;
Receive=Read_normal;
Flag=true;
cli(); //Desactivo interrupciones
}
else
{
DataRx_sim[point]=Data_Rx;
point++;
}
break;
}
}
La libreria USART :
C:
///***** Marcelo Higa *****///
//Libreria USART///
#include <avr/io.h>
#define F_CPU 1000000UL
void Serial_begin(uint32_t baudios);
void printc_USART(char c);
void prints_USART(char *p_data);
//---**********************************************************
void Serial_begin(uint32_t baudios){ //9600 bps
uint16_t MyUBRR=0;
DDRD |= (0<<DDD0)|(1<<DDD1); // PD0:Rx->Entrada, PD1:Tx->Salida
UCSR0A |= (1<<U2X0); //Habilito Doble velocidad
UCSR0B |= (1<<RXEN0)|(1<<TXEN0); //Habilito Tx y Rx
UCSR0B |= (1<<RXCIE0); //Habilito interrupcion por recepcion
//Seleciono Modo Asincrono, no paridad, 1 bit Stop, 8 bits Datos
UCSR0C |= (0<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)|(0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);
MyUBRR = (uint16_t) ( ( ( F_CPU / 8 ) / baudios ) -1 ) ;
//Cargo el valor al registro UBRR para generar la velociad de transmision
UBRR0L = MyUBRR;
UBRR0H = (MyUBRR>>8);
}
//Ejemplo: printc('A');
void printc_USART(char c){
while( (UCSR0A & (1<<UDRE0)) == 0); //Espero que el dato se transmita
UDR0 = c;
}
// Ejemplo: prints_USART("Hola mundo AVR");
void prints_USART(char *p_data){
while(*p_data != '\0'){
printc_USART(*p_data);
p_data++;
}
}