Amigos una vez mas recurro a ustedes y sus conocimientos, tengo el siguiente problema:
- Tengo un programa que lee el encoder de un motor, el software lleva la cuenta del encoder y la muestra por un display lcd, a su vez activa ciertas puertas al momento de llegar a cierto punto de la cuenta. El encoder se lee por RB0 y RB1, hasta ahi va todo de perillas, a continuacion les muestro el codigo.
esto lo he probado en protoboard y anda todo muy bien, de hecho mejor de lo que esperaba
El problema que tengo aparece cuando agrego una nueva interrupcion externa, esta se hace por RB2 y esta configurada H_to_L, lo he probado en proteus y funciona pero al grabarla en el micro y llevarlo al proto no anda, el micro simplemente no prende, no se enciende el display y no enciende los led piltos que tengo configurados, a continuacion les dejo el codigo con la interrupcion RB2 agregada
Descarte problemas de conexion ya que solo hay que agregar una entrada mas y eso anda bien, la verdad ya no se que hacer, ojala me puedan ayudar, saludos y gracias desde ya.
- Tengo un programa que lee el encoder de un motor, el software lleva la cuenta del encoder y la muestra por un display lcd, a su vez activa ciertas puertas al momento de llegar a cierto punto de la cuenta. El encoder se lee por RB0 y RB1, hasta ahi va todo de perillas, a continuacion les muestro el codigo.
Código:
#Include <18F452.h>
#Fuses XT, NOWDT, NOPROTECT, NOLVP, BROWNOUT
#use Delay(Clock = 4000000)
#include <LCD.c>
#use fast_io(A) // configura como deben ser tratado los registros TRIS
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#Byte PortA = 0xF80
#Byte PortB = 0xF81
#Byte PortC = 0xF82
#Byte PortD = 0xF83
void led (void);
void led1(void);
void led2(void);
// ------ Variable Global ------
int16 cont=3000;
int temp = 0; // Esta variable ha de ser global porque su valor lo
int flag_temp;
int reset;
// Por tanto declaramos esta variable antes la interrupción
// y de "void main".
Void Main(){ // Inicio y configuración.
lcd_init();
Port_B_Pullups(FALSE); // Configuración para el PIC 18F452.
Setup_ADC_Ports(NO_ANALOGS); // Sin comparadores ni ADCs, todo digital, etc...
Setup_adc(ADC_CLOCK_DIV_2);
Setup_spi(SPI_SS_DISABLED);
Setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
Setup_timer_2(T2_DISABLED,0,1);
set_timer1(3036);
Enable_Interrupts(Int_Ext); // Activar Interrupción Externa a través de RB0.
Ext_Int_Edge(L_TO_H); // Inicialmente detectar interrupción por flanco de subida
enable_interrupts(INT_TIMER1);
Enable_Interrupts(GLOBAL); // Interrupciones Generales Activadas.
set_tris_A(0b00000000);
set_tris_B(0b11111111);
set_tris_C(0b00000000);
output_A(0);
output_C(0);
// ---------- Programa Principial ----------
While (True){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
while((cont>3003)&&(cont<=3150)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
led();
}
bit_clear(PORTC,0);
flag_temp = 1;
if ((cont<=2995)&&(cont>=2870)&&(flag_temp==1)){
enable_interrupts(INT_TIMER1);
}
//inicia temporizador 10seg por interrupcion (definir un flag_temp que de cero cuando se cumplan 10 segundos)
while((cont<2995)&&(cont>=2865)&&(flag_temp==1)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
bit_set(PORTA,1);
delay_ms(100);
bit_set(PORTA,0);
led1();
}
disable_interrupts(INT_TIMER1);
output_low(PIN_C1);
while((cont<=2995)&&(cont>=2870)&&(flag_temp==0)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont); //ver posicion de encoder por LCD
bit_clear(PORTA,1);//saco alimentacion
delay_ms(100);
reset=1;
led2();
}
output_low(PIN_C2);
if((cont>=2997)&&(cont<=3000)&&(reset==1)){
bit_clear(PORTA,0);//reestablesco el sentido de giro
delay_ms(200);
cont=3000;
reset=0;
}
}
}
#int_TIMER1
void TIMER1_isr(void) {
temp++;
if (temp >= 20){
flag_temp=0;
temp=0;
}
set_timer1(3036);
}
#INT_EXT // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()
{
// CCS se encarga de desactiva automáticamente cualquier interrupción.
// No hace falta guardar contextos de registros.
If (Bit_Test(PortB, 0)) // Si RB0 se ha puesto a 1 (flanco de subida),
{
Ext_Int_Edge(H_TO_L); // entonces activar la siguiente interrupción por flanco de
// bajada.
If (Bit_Test(PortB, 1)) // Si RB1 está a 1,
{
cont++; // entonces incrementar una unidad el valor de cont.
}
}
Else // Si RB0 se ha puesto a 0 (flanco de bajada),
{
Ext_Int_Edge(L_TO_H); // entonces activar la siguiente interrupción por flanco de
// subida.
If (Bit_Test(PortB, 1)) // Si RB1 está 1,
{
cont--; // entonces decrementar una unidad el valor de cont.
}
}
}
void led(){
delay_ms(100);
output_toggle(PIN_C0);
}
void led1(){
output_toggle(PIN_C1);
}
void led2(){
output_toggle(PIN_C2);
}
esto lo he probado en protoboard y anda todo muy bien, de hecho mejor de lo que esperaba
El problema que tengo aparece cuando agrego una nueva interrupcion externa, esta se hace por RB2 y esta configurada H_to_L, lo he probado en proteus y funciona pero al grabarla en el micro y llevarlo al proto no anda, el micro simplemente no prende, no se enciende el display y no enciende los led piltos que tengo configurados, a continuacion les dejo el codigo con la interrupcion RB2 agregada
Código:
#Include <18F452.h>
#Fuses XT, NOWDT, NOPROTECT, NOLVP, BROWNOUT
#use Delay(Clock = 4000000)
#include <LCD.c>
#use fast_io(A) // configura como deben ser tratado los registros TRIS
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#Byte PortA = 0xF80
#Byte PortB = 0xF81
#Byte PortC = 0xF82
#Byte PortD = 0xF83
// ------ Variable Global ------
int16 cont=3000;
int temp = 0; // Esta variable ha de ser global porque su valor lo
int flag_temp;
int reset; // usaremos en la interrupción y en el programa principal.
int boton=0;
int comprobacion; // Por tanto declaramos esta variable antes la interrupción
// y de "void main".
void led (void);
void led1(void);
void led2(void);
void emergencia (void);
Void Main(){ // Inicio y configuración.
lcd_init();
Port_B_Pullups(FALSE); // Configuración para el PIC 18F452.
Setup_ADC_Ports(NO_ANALOGS); // Sin comparadores ni ADCs, todo digital, etc...
Setup_adc(ADC_CLOCK_DIV_2);
Setup_spi(SPI_SS_DISABLED);
Setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
Setup_timer_2(T2_DISABLED,0,1);
set_timer1(3036);
enable_interrupts(INT_RB);
Enable_Interrupts(INT_EXT); // Activar Interrupción Externa a través de RB0.
Ext_Int_Edge(L_TO_H); // Inicialmente detectar interrupción por flanco de subida.
enable_interrupts(INT_EXT2_H2L );
Enable_Interrupts(GLOBAL); // Interrupciones Generales Activadas.
set_tris_A(0b00000000);
set_tris_B(0b11111111);
set_tris_C(0b00000000);
output_A(0);
output_C(0);
// ---------- Programa Principial ----------
While (True){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
while((cont>3003)&&(cont<=3150)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
led();
}
bit_clear(PORTC,0);
flag_temp = 1;
if ((cont<=2995)&&(cont>=2870)&&(flag_temp==1)){
enable_interrupts(INT_TIMER1);
}
//inicia temporizador 10seg por interrupcion (definir un flag_temp que de cero cuando se cumplan 10 segundos)
while((cont<2995)&&(cont>=2865)&&(flag_temp==1)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
bit_set(PORTA,1);
delay_ms(100);
bit_set(PORTA,0);
led1();
}
disable_interrupts(INT_TIMER1);
output_low(PIN_C1);
while((cont<=2995)&&(cont>=2870)&&(flag_temp==0)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont); //ver posicion de encoder por LCD
bit_clear(PORTA,1);//saco alimentacion
delay_ms(100);
reset=1;
led2();
}
output_low(PIN_C3);
if((cont>=2997)&&(cont<=3000)&&(reset==1)){
bit_clear(PORTA,0);//reestablesco el sentido de giro
delay_ms(200);
cont=3000;
reset=0;
}
}
}
// --------- Interrupción ---------
#int_ext2
void RB2 (){
output_low(PIN_A0);
output_low(PIN_A1);
while((Bit_Test(PortB, 2)==0)&&(boton<=100)){
boton++;
}
comprobacion=1;
while ((Bit_Test(PortB, 2)==0)&&(comprobacion==1)&&(Bit_Test(PortB, 3)==0)){
output_low(PIN_C0);
output_low(PIN_C1);
output_low(PIN_C3);
bit_set(PORTC,3);
emergencia();
}
while ((Bit_Test(PortB, 2)==0)&&(comprobacion==1)&&(Bit_Test(PortB, 3)==1)){
if((Bit_Test(PortB, 4)==1)){
bit_clear(PORTA,2);
}
output_high(PIN_A2);
}
bit_clear(PORTC,4);
bit_clear(PORTC,2);
comprobacion=0;
boton=0;
}
#int_TIMER1
void TIMER1_isr(void) {
temp++;
if (temp >= 20){
flag_temp=0;
temp=0;
}
set_timer1(3036);
}
#INT_EXT // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()
{
// CCS se encarga de desactiva automáticamente cualquier interrupción.
// No hace falta guardar contextos de registros.
If (Bit_Test(PortB, 0)) // Si RB0 se ha puesto a 1 (flanco de subida),
{
Ext_Int_Edge(H_TO_L); // entonces activar la siguiente interrupción por flanco de
// bajada.
If (Bit_Test(PortB, 1)) // Si RB1 está a 1,
{
cont++; // entonces incrementar una unidad el valor de cont.
}
}
Else // Si RB0 se ha puesto a 0 (flanco de bajada),
{
Ext_Int_Edge(L_TO_H); // entonces activar la siguiente interrupción por flanco de
// subida.
If (Bit_Test(PortB, 1)) // Si RB1 está 1,
{
cont--; // entonces decrementar una unidad el valor de cont.
}
}
}
/*Al finalizar la interrupción CCS se encarga de volver a poner automáticamente
la badera INTF = 0 ---> borra la interrupción para poder permitir la siguiente;
no hemos de hacer nada por nuestra parte.*/
void led(){
delay_ms(100);
output_toggle(PIN_C0);
}
void led1(){
output_toggle(PIN_C1);
}
void led2(){
output_toggle(PIN_C2);
}
void emergencia(void){
//bit_set(PORTC,4);
bit_set(PORTA,0);
bit_set(PORTA,1);
}
Descarte problemas de conexion ya que solo hay que agregar una entrada mas y eso anda bien, la verdad ya no se que hacer, ojala me puedan ayudar, saludos y gracias desde ya.