|
|
View previous topic :: View next topic |
Author |
Message |
ErickCuevas
Joined: 23 Mar 2017 Posts: 4 Location: Guanajuato
|
External Interrupts |
Posted: Thu Mar 23, 2017 5:34 pm |
|
|
Hi guys:
I've just started working with microcontrollers and we're learning how to make external interrupts work out.
Allegedly, this is supposed to function as it is written but it does anything.
This code modifies the velocity of how the leds change, it is done with a potentiometer. It goes from 10us to 1s per Led, that part works pretty good but when we try to change the sequence nothing happens.
I know the code looks pretty cheap but we're on the road to learn how to do this and improve.
If anyone could help me to understand where is my mistake, I'd be very thankful. Please!
Code: | #include <18f4550.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on 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)
#fuses INTRC_IO //Internal RC Osc, no CLKOUT
#use delay(internal=8Mhz)
#use standard_io(B) //Habilitar puerto B
#define use_portd_lcd TRUE
#define LCD_RS PIN_D0
#define LCD_E PIN_D1
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
#include <lcd1.c>
double ciclos, N=0;
float lectura,tiempo;
int i=0, entrada=1;
#INT_EXT
void EXT_isr(void) //Inicio la interrupcion externa
{
if(entrada<5) //4casos
{
++entrada;
}
else
{
entrada=0;
}
}
#INT_TIMER1
void TIMER1_isr() //Inicio interrupcion interna
{
lectura=read_adc(); //lectura digital del pot
delay_us(1);
ciclos=(3.90234375)*(lectura); //relacion entre el numero de ciclos y el tiempo
if(N>=ciclos) //
{
N=0; //Valor inicial de N
i++; //Incremento para las secuencias de leds
}
N=N+1; //Va aumentando el numero de ciclos
set_timer1(0xFC18);//le pone un valor al timer dentro de la variable y cuando se desborda llama a la interrupcion
}
void main()
{
port_B_pullups(0xFF); //Se habilitan las resistencias internas del puerto B
setup_oscillator(osc_8mhz|osc_intrc); //Se habilita el oscilador interno
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); //Configuracion del timer1 para interrupcion interna
enable_interrupts(INT_TIMER1); //Se habilitan interrupciones internas por timer 1
enable_interrupts(INT_EXT); //Se habilitan interrupciones externas
enable_interrupts(GLOBAL);
set_tris_d(0x00);//Se habilita puerto D como salidas
set_tris_c(0x00);//Se habilitan puerto C como salidas
set_tris_b(0xff); //Puerto B como entradas
lcd_init(); //Se inicia la LCD
//!//float read;
//!//int salida=0;
setup_adc(ADC_CLOCK_INTERNAL); //Se habilita el reloj ADC interno para lectura digital del puerto analogico
set_adc_channel(0);//Se lee desde el puerto A0
setup_adc_ports(ALL_ANALOG); //Todos los pines A como analogicos
delay_us(15); //Tiempo de de espera de 15us
//set_timer1(0xFFEC); //65516, asà comienza desde los 10us
while(TRUE)
{
switch(entrada) //Inicio de switch con la variable entrada de las interrupciones externas
{
case 1:
if(i>7) //Reinicia la variable, solo para la primera secuencia
{
i=0;
}
if(i==0) //------------------------------------------------------------------Secuencia 1
{
output_high(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==1)
{
output_low(PIN_C2);
output_high(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==2)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_high(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==3)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_high(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==4)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_high(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==5)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_high(PIN_C6);
output_low(PIN_C7);
}
if(i==6)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_high(PIN_C7);
} //-----------------------------------------------------Secuencia 1
tiempo=N*(0.001);
printf(lcd_putc, "tiempo:%04f", tiempo); //Impresion enn lcd del tiempo en el que se encuentra
break;
case 2:
if(i==12) //Reinicia la variable, para las demas secuencias
{
i=0;
}
if(i==0) //------------------------------------------------------------------Secuencia2
{
output_high(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==1)
{
output_low(PIN_C2);
output_high(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==2)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_high(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==3)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_high(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==4)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_high(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==5)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_high(PIN_C6);
output_low(PIN_C7);
}
if(i==6)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_high(PIN_C7);
}
if(i==7)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_high(PIN_C6);
output_low(PIN_C7);
}
if(i==8)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_high(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==9)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_high(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==10)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_high(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==11)
{
output_low(PIN_C2);
output_high(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==12)
{
output_high(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
} //-------------------------------------------------------------------------Secuencia2
break;
case 3:
if(i==12) //Reinicia la variable, para las demas secuencias
{
i=0;
}
if(i==0) //------------------------------------------------------------------Secuencia3
{
output_high(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==1)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==2)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==3)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==4)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==5)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_low(PIN_C7);
}
if(i==6)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==7)
{
output_low(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==8)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==9)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==10)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==11)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==12)
{
output_low(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_high(PIN_C7);
} //-----------------------------------------------------------------------Secuencia3
break;
case 4:
if(i==12) //Reinicia la variable, para las demas secuencias
{
i=0;
}
if(i==0) //------------------------------------------------------------------Secuencia4
{
output_high(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==1)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==2)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==3)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==4)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==5)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_low(PIN_C7);
}
if(i==6)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_high(PIN_C7);
}
if(i==7)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_high(PIN_C6);
output_low(PIN_C7);
}
if(i==8)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_high(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==9)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_high(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==10)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_high(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==11)
{
output_high(PIN_C2);
output_high(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
}
if(i==12)
{
output_high(PIN_C2);
output_low(PIN_C1);
output_low(PIN_C0);
output_low(PIN_D2);
output_low(PIN_D3);
output_low(PIN_C6);
output_low(PIN_C7);
} //----------------------------------------------------------------------Secuencia4
break;
default:
entrada=0;
delay_ms(1000); //Espera entre cada secuencia
break;
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 23, 2017 7:58 pm |
|
|
What does your external interrupt circuit look like ? It should be similar
to the schematic below. Pin B0 is held at a logic high level by the pullup.
When you press the button it goes to a logic low level.
Code: |
+5v
|
<
> 4.7K
< ___ Switch
To | _|_|_
PIC -----------------o o------
pin B0 |
--- GND
-
|
You didn't set the edge for the external interrupt. It defaults to the rising
edge. The push-button circuit is intended to work with the falling edge.
Example of selecting the falling edge for the External interrupt:
Code: | ext_int_edge(H_TO_L); |
|
|
|
ErickCuevas
Joined: 23 Mar 2017 Posts: 4 Location: Guanajuato
|
|
Posted: Thu Mar 23, 2017 8:21 pm |
|
|
Let me try that and I'll let you know what happens, thank you so much for your time. |
|
|
ErickCuevas
Joined: 23 Mar 2017 Posts: 4 Location: Guanajuato
|
|
Posted: Thu Mar 23, 2017 9:10 pm |
|
|
PCM programmer wrote: | What does your external interrupt circuit look like ? It should be similar
to the schematic below. Pin B0 is held at a logic high level by the pullup.
When you press the button it goes to a logic low level.
Code: |
+5v
|
<
> 4.7K
< ___ Switch
To | _|_|_
PIC -----------------o o------
pin B0 |
--- GND
-
|
You didn't set the edge for the external interrupt. It defaults to the rising
edge. The push-button circuit is intended to work with the falling edge.
Example of selecting the falling edge for the External interrupt:
Code: | ext_int_edge(H_TO_L); |
|
I did what you said but now it only does the second sequence, I wrote the missing line and put the push in that position. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1357
|
|
Posted: Fri Mar 24, 2017 6:58 am |
|
|
I think you should take a step back and start a new side project that just lets you play with the external interrupt. Don't include all the LED code, just a few small bits to test out the external interrupt. Get your example paired down to something manageable. Get that working and then you can integrate it into your actual code. At that point you will know the issue comes from the logic and not the external interrupt if you still have trouble.
As an aside, you can clean up a lot of the LED code by making a function like this:
Code: |
void set_leds(unsigned int8 mask){
output_bit(PIN_C2,bit_test(mask,6));
output_bit(PIN_C1,bit_test(mask,5));
output_bit(PIN_C0,bit_test(mask,4));
output_bit(PIN_D2,bit_test(mask,3));
output_bit(PIN_D3,bit_test(mask,2));
output_bit(PIN_C6,bit_test(mask,1));
output_bit(PIN_C7,bit_test(mask,0));
}
|
Then you can just call that with a bit mask to set the LED's appropriately
You can even get fancy then and make a table of all your patterns:
Code: |
#define NUM_PATTERN_SETS 5
#define MAX_SET_SIZE 13
unsigned int8 pattern_table[NUM_PATTERN_SETS][MAX_SET_SIZE] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 },
/*do other patterns..I got too lazy to fill in the rest*/
};
|
At that point you can use your logic to choose the right indices for the pattern you want and just do a call to set_leds() passing in an element from that table:
Code: |
set_leds(pattern_table[entrada][i]);
|
That said, you do have a lot of logic issues in your code as well as possibly some interrupt vs main code variable sharing timing issues. You have a lot of situations where you either don't update your LED's anymore or you repeat the same pattern multiple times in a row. Also, I think your timer interrupt is probably too complex. There is a lot of slow things happening in there that shouldn't be (ADC reads, floating point math, etc.). There are better ways to do that. As it stands now, you'll have a lot of bugs to fill out. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Fri Mar 24, 2017 8:13 am |
|
|
a comment..
Whenever using 'push buttons' you need to 'debounce' the signal. Add a small value cap, say .1 mfd, in parallel with the switch. It along with the pullup will dampen the scratchy noise generated by the switch.
if you have access to an oscilloscope, attach and SEE what it looks like.
Where you can get into 'trouble' is having a noisey push button and a very fast PIC. The PIC sees the PB, triggers the ISR,carrys on, the PB still sends a 'false' closure, PIC see this as another signal, ISR fires.......In the good old days of 2Mhz CPUs this wasn't a problem... but a PIC at 64 MHz......it can be |
|
|
ErickCuevas
Joined: 23 Mar 2017 Posts: 4 Location: Guanajuato
|
|
Posted: Mon Mar 27, 2017 6:34 pm |
|
|
Thank you all for your help, it finally worked. I can't thank you enough |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|