Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Buenas a todos.
Otra vez tengo un poquito de tiempo (de 6 mese en 6 meses saco un par de dias) y he vuelto a retomar un anteanteproyecto de placa que quiero hacer (la misma de todas las dudas que he ido posteando tiempo atras) tengo problemas con un programa en CCS version 3.222 para un 16F877 y es una tonteria pero no veo el fallo, resulta que lo que quiero es cambiar el estado de dos pines del puerto D de dicho pic, y resulta que he usado varias intrucciones para probar y me pasa algo muy raro y es que en lineas de programa consecutivas cambio el estado del pin 5 del puerdo D (Lo ativo por alta, lo pongo a uno) y en la siguiente linea repito la operacion para el pin 7 del mismo puerto, pero al llegar a esta linea el pin 7 se activa y se desactiva el 5, he probado varias intrucciones y la unica solucion que he encontrado para acceder a nivel de bit a sido haciendolo con una variable intermedia, por ejemplo ponia lo siguiente
bit_set(PORTD,5);
bit_set(PORTD,7);
y al llegar a la segunda linea el pin 5 cambia a valer 0 y el 7 a valer 1, cuando lo que deberia de hacer es mantenerse a 1 los dos bit, todo esto lo he ido programando en CCS y lo he corrido paso a paso bajo simulacion en el Proteus, asi que no se si realmente hago algo mal, es el CCS lo que falla o es el Proteus, no lo he podido probar en Hardware porque no dispongo del Micro en este momento, aqui dejo el codigo donde aparece lo que me ha funcinado (pero no me gusta porque no creo que sea la mejor forma de hacerlo, me ha recordado a horrores al asm cojo una variable a modo acumulador, la modifico y luego la saco por el Puerto) como se puede ver he dejado tambien enmascarados como si fueran comentarios:
// bit_set(PORTD,5);
// bit_set(PORTD,7);
algunos de los otros modos y en todos he obtenido resultados identicos, a ver si algun alma caritativa me puede iluminar un poquito sobre estos misterios que siempre se me escapan.
GRACIAS #include <16F877A>
#fuses XT,NOWDT
#use delay (clock=1000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
#byte PORTA=0x05
#byte PORTB=0x06
#byte PORTC=0x07
#byte PORTD=0x08
#byte PORTE=0x09
#BIT D5=0X08.5
#BIT D7=0X08.7
int arranque=0;
int numero_piso=0;
int subida=0;
int bajada=0;
int piso_pulsado=0;
int variable=0;
int lectura_A=1;
int puertod=0;
#int_rb
VOID interrupcion()
{ lectura_A=PORTB;
if(INPUT(PIN_B4))
{
bit_clear(PORTD,5);
bit_clear(PORTD,7);
bit_set(PORTE,2);
// delay_ms(1500);
bit_clear(PORTE,2);
lectura_A=0;
}
if (INPUT(PIN_B5))
{
bit_clear(PORTA,1);
bit_clear(PORTA,2);
}
}
void main(void)
{
disable_interrupts(GLOBAL);
set_tris_a(0b111111);
set_tris_b(0b11111111);
set_tris_c(0b11111111);
set_tris_d(0b00011111);
set_tris_e(0b000);
PORTD=0;
PORTE=0;
enable_interrupts(int_rb);
enable_interrupts(int_ext);
enable_interrupts(GLOBAL);
do
{
if (arranque==0)
{
//bit_set(PORTD,7);
//bit_set(PORTD,5);
//Output_high(PIN_D5);
//Output_high(PIN_D7);
//D5=1;
//D7=1;
bit_set(puertod,7);
bit_set(puertod,5);
PORTD=puertod;
while (lectura_A|=0)
{}
arranque=1;
}
// Delay_ms(5000);
bit_set(PORTE,0);
if (input(pin_c0))
{
variable=porta;
rotate_right(&variable,1);
rotate_right(&variable,1);
rotate_right(&variable,1);
bit_clear(variable,3);
bit_clear(variable,4);
bit_clear(variable,5);
portb=variable;
delay_ms(1000);
}
}WHILE(TRUE);
} // Fin
vcs, a ver si puedo ayudarte con algunas ideas:
1. No uses bit_set, es mucho más cómodo
output_bit(PIN_D7, 1); // que pone el pin D7 a 1.
output_bit(PIN_D7, 0); //como puedes imaginar lo pone a 0.
2. si decides usar output_bit, no hace falta que trabajes con el registro TRIS, ya lo hace CCS por ti
3. para hacer un bucle infinito, lo mejor es usar
while(1)
{...}
ó:
for( ; ; )
{...}
4. En Proteus creo que no es un problema, pero en los circuitos reales, cuando tienes activo el LVP sin usarlo, suele funcionar cuando quiere y normalmente por "imposición de manos" ja ja ja... es una entrada al aire muy peligrosa, escribe este Fuse:
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
Muchas gracias por la respuesta:
He usado las intrucciones
Output_bit(PIN_D7,1);
Output_bit(PIN_D5,1);
y he obtenido exactamente el mismo resultado cuando el programa se encuentra sobre la linea output_bit(PIN_D7,1) pone a uno el pin 7 del puerto D y al pasar por la siguiente linea Output_bit(PIN_D5,1);
pone a cero pin 7 😯 y activa el 5, no tiene sentido, si estoy usando un comando de bit no sé porque ataca a todo el puerto, en principio pensé que podia ser el proteus pero le he cargado en lugar del archivo cof y la fuente directamente el archivo Hexadecimal y hace lo mismo lo que me hace pensar que es una limitacion o error de la version de compilador que uso.
En cuanto a lo del bucle infinito hago
while (lectura_A|=0)
porque quiero que se quede ahi el programa hasta que no salte una interrupcion, y en luego en cuerpo de la interrupcion cambio esa variable para que al volver el programa continue, aun asi gracias por el consejo.
y en cuanto a #FUSES NOLVP ya lo he corregido, menos mal que me comentaste esto sino dentro de un tiempo cuando lo tenga tostado en el PIC podria estar dandome de cabezazos contra la mesa para saber que es lo estaba pasando.
UN saludo
PD: Que version del CCS usais??
Prueba a sustituir esas funciones por unas como éstas:
output_high(PIN_D7); // Para poner el PIN D7 a nivel alto
output_low(PIN_D7); // Para poner el PIN D7 a nivel bajo
Saludos
Asias, ya lo probe, y mas cosas, en el codigo del primer post que puse estan todas las pruebas que hice, y con identico resultado, aun asi gracias por el aporte