TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jadacuor en 05 de Julio de 2010, 00:29:48
-
hola a todos, debido a las varias malas experiencias que he tenido al momento de pasar un programa perfectamente funcional en pic16f877a a pic18f452 he decidido crear este post, primero que todo para saber si soy el unico que ha tenido esta clase de inconvenientes y si a alguien mas le ha pasado pues, compartir experiencias y/o posibles soluciones.
a modo de ejemplo cuando intento hacer una interrupcion externa en pic18f452 este no reconoce la interrupcion y cuando la reconoce se queda enclavado, si pruebo con 16f877a todo funciona perfectamente....
bueno espero que alguien ya le haya pasado algo parecido y que pueda ayudarme, ademas porque estoy haciendo un trabajo que tengo que entregar mañana lunes y se me acaba de quemar el unico pic16f877a que tengo y hoy no puedo conseguir otro, la unica esperanza es hacer funcionar el programa en el pic18f452 que me queda.....
muchas gracias
-
No es normal que te funcione, son arquitecturas distintas, pinouts diferentes, no tienen los mismos periféricos.
Lo raro es que hayas conseguido que alguna vez furule bien.
-
Yo no he tenido problema al migrar códigos de un 16F a un 18F ....
Hay que tener un poco de cuidado al migrar el código de una familia a la otra, ya que, como dice el Mr. Nocturno, son arquitecturas diferentes ... pero una vez solucionado eso, todo te debe funcionar bien.
Saludos
-
gracias por responder, si me han funcionado algunos programas en 18f452 que hice normalmente para 16f877a con tan solo cambiar #include <16f877a.h> por #include <18f452.h> y agregar los fuses necesarios. el problema radica en que la interrupcion externa por rb0 no me funciona, asi sea un programa sencillo si podrias ayudarme con algun ejemplo de interrupcion externa que funcione con 18f452 me seria de gran ayuda...
este es el programa que hice y que funciona perfectamente con pic16f877a
//#include <16f877a.h>
#include <18f452.h>
#device ADC=10
#fuses XT,NOWDT,NOPUT,NOLVP,NOWRT,NOPROTECT
#use delay(clock=4000000)
#include <lcd.c>
#use fast_io(B)
#byte portb = 6
#bit rb7 = 6.7
#bit rb0 = 6.0
#bit intf = 0x0b.1
int count=0;
int x=0;
int1 i=0;
int16 adc,set;
float temp,tmax,tmin,tref,tprom;
#int_EXT
EXT_isr()
{i=rb0;
while(!i)
{i=rb0;
x++;
if(x==3){
x=0;
tref = tref+0.25;
if(tref>40)
{tref=35;}}
lcd_gotoxy(1,1);
lcd_putc("Tref = ");
lcd_gotoxy(1,2);
printf(lcd_putc," %4.2f%cC ",tref,223);
delay_ms(300);}
x=0;
delay_ms(400);
}
#int_TIMER0
void TIMER0_isr()
{set_timer0(3400);
set_adc_channel(0);
delay_us(40);
adc = read_adc();
if(adc>20 && adc<144)
{count++;
temp =temp + (500.00*adc/1024.0);
if(count==6)
{tprom =temp/6.00;
temp=0;count=0;}
}
}
void main()
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);
set_timer0(3400);
SETUP_ADC(ADC_CLOCK_INTERNAL);
SETUP_ADC_PORTS(ALL_ANALOG);
SET_ADC_CHANNEL(0);
delay_us(40);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_EXT);
ext_int_edge(H_TO_L);
lcd_init();
output_b(0);
lcd_putc("\f");
tref=37.5;
temp=0;
while(true)
{
tmax=tref+0.3;
tmin=tref-0.3;
if(tprom>tref)
{output_low(PIN_C3);output_low(PIN_C2);}
if(tprom<=tmin)
{output_high(PIN_C3);output_high(PIN_C2);}
if(tprom>=tmax)
{output_low(PIN_C3);output_low(PIN_C2);}
lcd_gotoxy(1,1);
lcd_putc("Temp = ");
lcd_gotoxy(1,2);
printf(lcd_putc," %4.2f%cC ",tprom,223);
delay_ms(300);
}
}
-
No lo he revisado a fondo, pero veo que defines el puerto B en la dirección 6, y en el 18F no está en esa dirección. Mira en la datasheet cuál es su dirección correcta y cámbiala, a ver si así lo arreglas.
-
disculpame por escribir en mayusculas pero MUCHISIMAS GRACIAS, ese era el problema en el 18f452 el puerto b esta en la direccion 0xf81, ese problema lo habia tenido infinitas veces y siempre optaba por dejar el codigo en el pic16 porque nadie me habia podido ayudar a solucionar el problema pero esta vez si se pudo, muchisimas gracias
-
Me alegro
-
Hola.
Hay funciones que se encargan de acceder a esas direcciones ... podrían usarse para tener menos problemas:
value = getenv (cstring);
Syntax:
value = getenv (cstring);
Parameters:
cstring is a constant string with a recognized keyword
Returns:
A constant number, a constant string or 0
Function:
This function obtains information about the execution environment. The following are recognized keywords. This function returns a constant 0 if the keyword is not understood.
FUSE_SET:fffff
fffff Returns 1 if fuse fffff is enabled
FUSE_VALID:fffff
fffff Returns 1 if fuse fffff is valid
INT:iiiii
Returns 1 if the interrupt iiiii is valid
ID
Returns the device ID (set by #ID)
DEVICE
Returns the device name string (like "PIC16C74")
CLOCK
Returns the MPU FOSC
ICD
Returns 1 if the ICD=TRUE Mode is active
VERSION
Returns the compiler version as a float
VERSION_STRING
Returns the compiler version as a string
PROGRAM_MEMORY
Returns the size of memory for code (in words)
STACK
Returns the stack size
SCRATCH
Returns the start of the compiler scratch area
DATA_EEPROM
Returns the number of bytes of data EEPROM
EEPROM_ADDRESS
Returns the address of the start of EEPROM. 0 if not supported by the device.
READ_PROGRAM
Returns a 1 if the code memory can be read
PIN:pb
Returns a 1 if bit b on port p is on this part
ADC_CHANNELS
Returns the number of A/D channels
ADC_RESOLUTION
Returns the number of bits returned from READ_ADC()
ICD
Returns a 1 if this is being compiled for a ICD
SPI
Returns a 1 if the device has SPI
USB
Returns a 1 if the device has USB
CAN
Returns a 1 if the device has CAN
I2C_SLAVE
Returns a 1 if the device has I2C slave H/W
I2C_MASTER
Returns a 1 if the device has I2C master H/W
PSP
Returns a 1 if the device has PSP
COMP
Returns a 1 if the device has a comparator
VREF
Returns a 1 if the device has a voltage reference
LCD
Returns a 1 if the device has direct LCD H/W
UART
Returns the number of H/W UARTs
AUART
Returns 1 if the device has an ADV UART
CCPx
Returns a 1 if the device has CCP number x
TIMERx
Returns a 1 if the device has TIMER number x
FLASH_WRITE_SIZE
Smallest number of bytes that can be written to FLASH
FLASH_ERASE_SIZE
Smallest number of bytes that can be erased in FLASH
BYTES_PER_ADDRESS
Returns the number of bytes at an address location
BITS_PER_INSTRUCTION
Returns the size of an instruction in bits
RAM
Returns the number of RAM bytes available for your device.
SFR:name
Returns the address of the specified special file register. The output format can be used with the preprocessor command #bit. name must match SFR denomination of your target PIC (example: STATUS, INTCON, TXREG, RCREG, etc)
BIT:name
Returns the bit address of the specified special file register bit. The output format will be in “address:bit”, which can be used with the preprocessor command #byte. name must match SFR.bit denomination of your target PIC (example: C, Z, GIE, TMR0IF, etc)
PIN:PB
Returns 1 if PB is a valid I/O PIN (like A2)
Saludos
-
Hola jadacuor, aparte de las recomendaciones acertadas de Nocturno y MLO__, te recomendaría echar una mirada al código en tus rutinas de interrupción. Es más recomendable poner dentro de una interrupción una condición lógica, de modo que cuando se dispare esta active una rutina externa o si es del caso, instrucciones que no impliquen demoras como las que veo que tienes. Te lo digo porque veo algunas intrucciones delay() en tus interrupciones que seguramente te deben estar generando avisos de advertencia al compilar algo asi como: "Interrupts disabled during call to prevent re-entrancy".
Suerte con tu trabajo y un saludo.
-
Para que tu codigo sea portable, como el de una libreria por ejemplo, puedes evitar el uso de la directiva 'bit'.
Como dijo nocturno 'son arquitecturas distintas'.
Lo que haces en la linea '#bit puertox = m.n' por ejemplo, es restringir tu codigo a arquitecturas donde puertox esta en m.n, luego, si un usuario de tu libreria, o porque no tu mismo, hace algo como 'include <libreria>', tiene que modificar dicha definicion (algo feo si se trata de una libreria).
Accede a los puertos con output_high, output_low, input, etc. y no deberias tener problemas para migrar del 16f877 al 18f442, a no ser que estes utilizando alguna caracteristica muy particular de derminada arquitectura.
Si bien existen marcadas diferencias, es muy linda la compatibilidad pin-a-pin entre estos micros.
-
muchas gracias a todos por las recomendaciones, las tendre en cuenta. y como dice bmb, al compilar me aparece "Interrupts disabled during call to prevent re-entrancy" y no he podido quitarlo, asi que agradezco quien pueda orientarme en ello... muhcas gracias
-
puede ser q aun tengas delays dentro de las interrupciones