Muy buenos dias a todos en el foro
!!!!
Verán, desde hace unos dias estoy tratando de hacer funcionar la interrupción externa del PIC16F690, con modbus, el fin de esto, es para poder sincronizar la operación del programa, con la red de CA. Hice un programa super simple, para ver si se queda muerto el micro, durante el desarrollo del programa principal, pero valla jajajaja
no he podido pasar de ahi
.
El problema radica en que tan pronto inicia el programa, la red de CA genera la interrupcion y carga los valores, despues, creo que entra el comando
modbus_init(); del
void main() y bueno, hasta ahi llego la interrupción,
nunca mas vuelve a cargar los valores, por lo que me imagino que lo que ha de pasar, es que ha de deshabilitar la interrupción externa o algo asi.Lo compilo en CCS 5.25, usando la liberia del CCS 4.120, esto es porque la del 5.25 no sirve
. Igual, tengo el CCS 4.120, y lo puedo compilar ahi, pero no hay ningun cambio
.
He revisado una sugerencia en el foro, que da
pacalaconcurso en la
respuestra 15, pero ya esta implícita en el codigo que proporciona CCS, asi que bueno
..... De todas formas adjunto la liga
http://www.todopic.com.ar/foros/index.php?topic=5807.15A continuación adjunto el código del 16F690:
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::Configuracion de MCU::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include <16f690.h>
#fuses HS,NOWDT,PROTECT,MCLR
#use delay(clock=20m)
#priority INT_EXT,INT_RDA
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU //use MODBUS_ASCII for ASCII mode
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600
//#define MODBUS_SERIAL_ENABLE_PIN 0 // Controls DE pin for RS485
//#define MODBUS_SERIAL_RX_ENABLE 0 // Controls RE pin for RS485
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#include <modbus_4120.c>
#define MODBUS_ADDRESS 15
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::Variables del MCU::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//entradas tipicas de modbus, cualquier valor de lectura o escritura de algun
//puerto o variable debe de ser guardado en estos registros para que funcione
int8 coils = 0b00000000; //coil 1 es LSB
int8 inputs =0b00000000;//input 1 es LSB
//Registro 1 es 8800, pueden ser guardados como mas convengan decimales, binarios o hexadecimales
int16 hold_regs[] = {0x8800,64,0x6600,0x5500,0x4400,0x3300,0x2200,0x1100};
int16 input_regs[] = {0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800};
int16 event_count = 0;
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::Interrupciones::::::::::::::::::::::::::::::::::::
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#INT_EXT //Interrupción externa.
void cero() //Función de la interrupción externa
{
//*************************************************************************************************
inputs = 0; // Set inicial todos a 0, solo me encargo de ponerlos en 1 en caso que sea necesario.
if(input(PIN_C1)!=1) bit_set(inputs,0);//para arreglo de resistencias pull UP
if(input(PIN_C2)!=1) bit_set(inputs,1);
if(input(PIN_B4)!=1) bit_set(inputs,2);
//**************************************************************************************************
}
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
/*This function may come in handy for you since MODBUS uses MSB first.*/
int8 swap_bits(int8 c)
{
return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
|((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}
#ZERO_RAM
void main()
{
//CONFIGURACION DE PUERTOS
set_tris_a(0b00000100);
output_a(0);
set_tris_c(0b00000110);
output_c(0);
set_tris_b(0b01111111);
output_b(0);
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setup_adc_ports(NO_ANALOGS);
/////////////////////////////////////////////////////////////////////////////////////
//CONFIGURACON DE INTERRUPCION EXTERIOR
enable_interrupts(INT_EXT); //Habilito interrupciones externas
ext_int_edge(H_TO_L); //Primera interrupción se dará en flanco de subida
enable_interrupts(GLOBAL); //Habilito las interrupciones generales
//////////////////////////////////////////////////////////////////////////////////////
modbus_init();
while(TRUE){
while(!modbus_kbhit());
delay_us(50);
//check address against our address, 0 is broadcast
if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 0)
{
switch(modbus_rx.func)
{
case FUNC_READ_COILS: //read coils
case FUNC_READ_DISCRETE_INPUT: //read inputs
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int8 data;
if(modbus_rx.func == FUNC_READ_COILS)
data = coils>>(modbus_rx.data[1]); //move to the starting coil
else
data = inputs>>(modbus_rx.data[1]); //move to the starting input
data = data & (0xFF>>(8-modbus_rx.data[3])); //0 out values after quantity
if(modbus_rx.func == FUNC_READ_COILS)
modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
else
modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
event_count++;
}
break;
case FUNC_READ_HOLDING_REGISTERS:
case FUNC_READ_INPUT_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
if(modbus_rx.func == FUNC_READ_HOLDING_REGISTERS)
modbus_read_holding_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),hold_regs+modbus_rx.data[1]);
else
modbus_read_input_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),input_regs+modbus_rx.data[1]);
event_count++;
}
break;
case FUNC_WRITE_SINGLE_COIL: //write coil
if(modbus_rx.data[0] || modbus_rx.data[3] || modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else if(modbus_rx.data[2] != 0xFF && modbus_rx.data[2] != 0x00)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_VALUE);
else
{
//coils are stored msb->lsb so we must use 7-address
if(modbus_rx.data[2] == 0xFF)
bit_set(coils,modbus_rx.data[1]);
else
bit_clear(coils,modbus_rx.data[1]);
modbus_write_single_coil_rsp(MODBUS_ADDRESS,modbus_rx.data[1],((int16)(modbus_rx.data[2]))<<8);
event_count++;
}
break;
case FUNC_WRITE_SINGLE_REGISTER:
if(modbus_rx.data[0] || modbus_rx.data[1] >= 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
//the registers are stored in little endian format
hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[3],modbus_rx.data[2]);
modbus_write_single_register_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
}
break;
case FUNC_WRITE_MULTIPLE_COILS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
modbus_rx.data[5] = swap_bits(modbus_rx.data[5]);
for(i=modbus_rx.data[1],j=0; i < modbus_rx.data[1]+modbus_rx.data[3]; ++i,++j)
{
if(bit_test(modbus_rx.data[5],j))
bit_set(coils,7-i);
else
bit_clear(coils,7-i);
}
modbus_write_multiple_coils_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
case FUNC_WRITE_MULTIPLE_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
hold_regs[i] = make16(modbus_rx.data[j+1],modbus_rx.data[j]);
modbus_write_multiple_registers_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
default: //We don't support the function, so return exception
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
}
}
}
}
Y aqui esta la
libreria http://www.mediafire.com/file/jepjquxjv12vnu6/modbus_4120.cTambién, aunque en este momento no es muy importante,
el codigo de la libreria presenta problemas en la respuesta de la lectura de las bobinas.
De ante mano les doy las gracias, me disculpo por el inmenso codigo de la libreria jejeje y les deceo un buen dia