#include
<18F26K22.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(internal=16MHz)
#define PIN_RTS PIN_B4
#define PIN_SCL PIN_C3
#define PIN_SDA PIN_C4
#DEFINE desocupado 0
#DEFINE esperando_address 1
#DEFINE esperando_evento 2
#DEFINE esprando_comando 3
#DEFINE esperando_fecha_hora 4
#DEFINE esperando_contadores 5
#DEFINE esperando_comando 6
#DEFINE esperando_respuesta_comando 7
#DEFINE buffer_leght 64
#use rs232(baud=19200, parity=N, xmit=PIN_B6, rcv=PIN_B7, bits=8, stream=COM1, UART1)
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, stream=XBEE, enable=PIN_RTS, UART2)
#use i2c(Master,Fast,sda=PIN_SDA,scl=PIN_SCL,force_hw)
int1 MDC=0;
int8 dato;
int1 haydato=0;
int8 buffer[buffer_leght]; //buffer secundario, lo uso para trabajar las tramas
int8 i_buffer=0;
int16 temp;
int8 CRC_MSB;
int8 CRC_LSB;
int8 meters[32];
int8 date[7];
int8 current[4];
int8 bill2[4];
int8 bill5[4];
int8 bill10[4];
int8 bill20[4];
int8 bill50[4];
int8 bill100[4];
int8 billtotal[4];
int8 com1_comando;
int8 com1_status;
int8 com1_address;
int8 com1_address_desconocido;
int8 buffer_com1[128]; //buffer circular (donde recibo todo lo de la USART 1)
int8 inew=0; //vectores de dato nuevo y dato viejo
int8 iold=0;
void recibe_com1(unsigned int8 d){ //agrega dato al buffer circular y chequea si se desbordo
buffer_com1[inew] = d;
++inew;
if(inew>=128)inew=0;
if (inew==iold){
fputs("DEBUG: buffer_com1 overflow",COM1
); }
}
unsigned int1 dato_buffer_com1(void){ //funcion para consultar si hay bytes para procesaren el buffer
if(inew!=iold){
return(true);
}
else return(false);
}
unsigned int8 siguiente_dato_com1(void){ // funcion que devuelve el byte mas viejo para ser preocesado
unsigned int8 temp;
temp=buffer_com1[iold];
++iold;
if(iold>=128)iold=0;
return (temp);
}
void reinicia_buffer(void){ //llena un buffer con 0xFF y pone a 0 el indice
unsigned int8 i; //no se si tiene sentido llenarlo con 0xff no he utilizado
i_buffer=0; //en ninguna parte de mi codigo aun
for(i=0;i<buffer_leght;i++){
buffer[i]=0xff;
}
}
int1 check_crc(unsigned char *p, int8 len){ //funcion para chequeo de CRC
unsigned int16 crcval=0x00;
register unsigned int16 c,q;
unsigned int8 x=len-1;
for (;x;x--){
c=*p++;
q=(crcval ^ c) & 017;
crcval = (crcval>>4) ^ (q*010201);
q=(crcval ^ (c>>4)) & 017;
crcval = (crcval>>4) ^ (q*010201);
}
CRC_MSB=(crcval>>8) & 0xff;
CRC_LSB=crcval & 0xff;
if(CRC_MSB == buffer[len] && CRC_LSB == buffer[len-1]){
return (true);
}
else {
return(false);
}
}
void guarda_datos(unsigned char *p, unsigned int8 from, unsigned int8 to){
for(;from<=to;from++){ //funcion que utilizo cada vez que leo una trama completa y el CRC esta bien,
*p++=buffer[from]; //para guardar los datos en su correspondiente variables
}
}
void recibe_trama(void) { //funcion que llamo cuando detecto que los datos son un POSIBLE TRAMA.
//chequeo que trama es y si corresponde a una trama conocida ejecuto acciones correspondientes
buffer[i_buffer] = dato;
++i_buffer;
if (buffer[0]==0x00 && com1_status==esperando_fecha_hora){
if(i_buffer>1){
if (buffer[1]==0x7f){
if(i_buffer==11){
com1_status=desocupado;
if (check_crc(&buffer[0],10)){
guarda_datos(&date,2,8);
for(int8 x=0;x<7;x++){
}
if (inew >= iold){
if (inew
-iold
>5) fprintf(COM1
,"Datos en Buffer: %u\n\r",inew
-iold
); }
else {
if (127-iold
+inew
>5) fprintf(COM1
,"Datos en Buffer: %u\n\r",127-iold
+inew
); }
}
else {
fprintf(COM1
,"Error CRC Date. \n\r"); }
}
return;
}
else {com1_status=desocupado;}
}
return;
}
else if (buffer[0]==0x01){
if(i_buffer>1){
switch(buffer[1]){
case 0x1c:
if(i_buffer==36){
com1_status=desocupado;
if (check_crc(&buffer[0],35)){
guarda_datos(&meters,2,33);
for(int8 x=0;x<32;x++){
}
}
else {
fprintf(COM1
,"Error CRC Meters. \n\r"); }
}
break;
case 0x1a:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(¤t,2,5);
for(int8 x=0;x<4;x++){
}
if (inew >= iold){
if (inew
-iold
>5) fprintf(COM1
,"Datos en Buffer: %u\n\r",inew
-iold
); }
else {
if (127-iold
+inew
>10) fprintf(COM1
,"Datos en Buffer: %u\n\r",127-iold
+inew
); }
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x32:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(&bill2,2,5);
if (inew >= iold){
if (inew
-iold
>5) fprintf(COM1
,"Datos en Buffer: %u\n\r",inew
-iold
); }
else {
if (127-iold
+inew
>10) fprintf(COM1
,"Datos en Buffer: %u\n\r",127-iold
+inew
); }
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x33:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(&bill5,2,5);
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x34:
if(i_buffer==8){
com1_status=desocupado;
guarda_datos(&bill10,2,5);
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x35:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(&bill20,2,5);
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x36:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(&bill50,2,5);
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x37:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(&bill100,2,5);
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
case 0x46:
if(i_buffer==8){
com1_status=desocupado;
if (check_crc(&buffer[0],7)){
guarda_datos(&billtotal,2,5);
}
else {
fprintf(COM1
,"Error CRC Current. \n\r"); }
}
break;
default:
fprintf(COM1
,"80 01 %X\n\r",buffer
[1]); com1_status=desocupado;
break;
}
}
}
else {com1_status=desocupado;}
}
#INT_EXT
void EXT_isr(void)
{
MDC=1;
disable_interrupts(INT_EXT);
}
#INT_RDA //aun no laimplemente, pero por esta usart me comunico por 485 con otrodispositivo que recolecta datos
void RDA_isr(void) //recibire poleos consultado si hay nuevos datos y le enviare los mismos si es que hay.
{
}
#INT_TBE
void TBE_isr(void) // no se si la voy a utilizar.. sera factible ?
{
}
#INT_TBE2
void TBE2_isr(void)
{
}
#INT_RDA2
void RDA2_isr(void)
{
recibe_com1
(fgetc(XBEE
));
// fputc(fgetc(XBEE),COM1);
}
void main(){
disable_interrupts(INT_TIMER0);
disable_interrupts(INT_TIMER1);
disable_interrupts(INT_TIMER2);
disable_interrupts(INT_TIMER3);
disable_interrupts(INT_RDA);
disable_interrupts(INT_TBE);
disable_interrupts(INT_TBE2);
disable_interrupts(INT_RDA2);
disable_interrupts(INT_EXT);
ext_int_edge( H_TO_L ); // Sets up EXT
enable_interrupts(GLOBAL);
reinicia_buffer();
com1_status=desocupado;
enable_interrupts(INT_RDA2);
while(TRUE) {
if (dato_buffer_com1()){ // SI HAY DATOS PARA PROCESAR
dato = siguiente_dato_com1();
if(com1_status==desocupado && dato==0x80){ // SI ES PRIMER DATO Y ES 0X80, ESPERAMOS EL ADDRESS
com1_status = esperando_address;
}
else if(com1_status==esperando_address){ // SI ESPERABAMOS EL ADDRESS, COMPROBAMOS...
com1_address = dato;
if(com1_address==0x81){ // SI EL ADDRESS ES 0X81 (ADDRESS ORED), ESPERAMOS UN EVENTO
com1_status = esperando_evento;
}
else if(com1_address==0x01){ // SI EL ADDRESS ES 0X01 (ADDRESS), ESPERAMOS UN COMANDO
com1_status = esperando_comando;
}
else if(com1_address==0x00){ // SI EL ADDRESS ES 0X00 (BROADCAST), ESPERAMOS FECHA Y HORA
com1_status = esperando_fecha_hora;
reinicia_buffer();
buffer[0] = 0x00;
i_buffer=1;
// fprintf(COM1,"\n\r01 80 00 \n\r");
// fprintf(COM1,"80 00 - fecha/hora\n\r");
}
else {
com1_status=desocupado;
com1_address_desconocido++; // SI RECIBIMOS OTRO ADDRESS ES DESCONOCIDO !!!! QUE HACER ?
}
}
else if (com1_status==esperando_comando){ // SI ESPERABAMOS UN COMANDO, LO GUARDAMOS Y ESPERAMOS LA RESPUESTA
com1_comando = dato;
com1_status = esperando_respuesta_comando;
reinicia_buffer();
}
else if (com1_status==esperando_respuesta_comando){
recibe_trama();
}
else if (com1_status==esperando_fecha_hora){
recibe_trama();
}
else if (com1_status==esperando_evento){
if (dato != 0x00) {
fprintf(COM1
,"Evento: %X\n\r",dato
); //RECIBIENDO EVENTO }
if (inew >= iold){
if (inew
-iold
>5) fprintf(COM1
,"Datos en Buffer: %u\n\r",inew
-iold
); }
else {
if (127-iold
+inew
>10) fprintf(COM1
,"Datos en Buffer: %u\n\r",127-iold
+inew
); }
com1_status=desocupado;
}
MDC=0;
}
}
}