This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
hiiii all,
i enabled falling edge interrupt on port f. there i am counting by timer. now when i use this count outside ISR (i mean in main), program goes in fault ISR. kindly give suggestions.
Regards
prashant
Hello Prashant
A lot of things can go wrong, if we do not know the application code you have written?
Regards
Amit
#include<inc/tm4c123gh6pm.h> #include <stdint.h> #include <stdbool.h> #include "inc/hw_gpio.h" #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "driverlib/pin_map.h" #include "driverlib/gpio.h" #include "driverlib/pwm.h" #include "driverlib/adc.h" #include "driverlib/sysctl.h" #include<driverlib/interrupt.h> #include<driverlib/timer.h> void PortFIntHandler(void); void PortFInit(void); volatile unsigned long ui32Loop,Count; volatile unsigned long Old_Count,Elapsed_Count; volatile unsigned long New_Count=0; float freq,speed,speedref,error; volatile unsigned long ha,hb,hc; int main(void){ error=0.00; speedref=1200.00; SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlDelay(3); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); SysCtlDelay(3); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlDelay(3); GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_1|GPIO_PIN_2); GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); SysCtlDelay(3); TimerDisable(TIMER0_BASE,TIMER_A); TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP); TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00FFFFFF); TimerEnable(TIMER0_BASE, TIMER_A); PortFInit(); // initialize GPIO Port F interrupt while(1) { ha=GPIOPinRead(GPIO_PORTA_BASE,GPIO_PIN_5) & 0x20; hb=GPIOPinRead(GPIO_PORTA_BASE,GPIO_PIN_6) & 0x40; hc=GPIOPinRead(GPIO_PORTA_BASE,GPIO_PIN_7) & 0x80; speed=speed+1; if(ha==0x20 && hb==0x40 && hc==0x80) //111 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, false); } if(ha!=0x20 && hb!=0x40 && hc!=0x80) //000 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, false); } if(ha==0x20 && hb==0x40 && hc!=0x80) //110 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, GPIO_PIN_3); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, GPIO_PIN_2); } if(ha!=0x20 && hb==0x40 && hc!=0x80) //010 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, GPIO_PIN_1); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, GPIO_PIN_3); } if(ha!=0x20 && hb==0x40 && hc==0x80) //011 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, GPIO_PIN_1); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, GPIO_PIN_2); } if(ha!=0x20 && hb!=0x40 && hc==0x80) //001 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, GPIO_PIN_0); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, GPIO_PIN_2); } if(ha==0x20 && hb!=0x40 && hc==0x80) //101 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, GPIO_PIN_0); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, GPIO_PIN_1); } if(ha==0x20 && hb!=0x40 && hc!=0x80) //100 { GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_1, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_0, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3, false); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_2, false); GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_2, GPIO_PIN_2); GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_1, GPIO_PIN_1); } } } void PortFInit(void){ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); SysCtlDelay(3); GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3); GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4 GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE); IntEnable(INT_GPIOF); GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4); } void PortFIntHandler(void){ GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4 Old_Count=New_Count; New_Count=TimerValueGet(TIMER0_BASE, TIMER_A); if(New_Count>Old_Count) { Elapsed_Count=New_Count-Old_Count; freq=79901869.00/Elapsed_Count; speed=freq*15.00; } }
hiii amit
i have attached file.
regards
prashant
Hello Prashant,
Thanks for the code. I was expecting some sort of explanation as to what works and what does not work.
I can spend all day understanding the code, and not have an answer. So help from you in explaining (comment in code most welcome) will be useful.
Regards
Amit
hiii amit
this is my simplified code. whenever i use any variable from ISR, it enters in fault ISR. here all variables are global variable.
//a square wave input is given to PortF pin 4. this program measures input signal frequency. int main(void){ SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //timer initialization SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); SysCtlDelay(3); TimerDisable(TIMER0_BASE,TIMER_A); TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC_UP); TimerLoadSet(TIMER0_BASE, TIMER_A, 0x00FFFFFF); TimerEnable(TIMER0_BASE, TIMER_A); PortFInit(); // initialize GPIO Port F interrupt while(1) { speed=freq*15.00; //when i dont use this line, code works } } void PortFInit(void){ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); SysCtlDelay(3); GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_4); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_3); GPIO_PORTF_PUR_R |= 0x10; // enable weak pull-up on PF4 GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_4,GPIO_FALLING_EDGE); IntEnable(INT_GPIOF); GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_4); } void PortFIntHandler(void){ GPIO_PORTF_ICR_R = 0x10; // acknowledge flag4 Old_Count=New_Count; New_Count=TimerValueGet(TIMER0_BASE, TIMER_A); if(New_Count>Old_Count) { Elapsed_Count=New_Count-Old_Count; freq=79901869.00/Elapsed_Count; } }
regards
prashant
Hello Prashant,
I hope you realize that the Timer will roll over and it could be possible that the New_Count can be less than Old_Count yielding a -ve number. When the Fault does occur did you check what the value for the two variables. Does it occur on the very first computation or it happens randomly?
Regards
Amit
Hi Amit
I know that the timer will roll over, thats why i used an "if condition" there. and also at the very first time if it gives negative value, whats the problem. actually when i calculated "freq" in portf ISR the program is working fine. but when i use that variable in mains, it goes in ISR. it is happening at very first time itself. can we use a variable outside ISR? it is a global variable.
Thanks
Prashant
Hello Prashant,
Attached is the file I have used from your code. I am using the TM4C123 LaunchPad, so use the SW1 to generate the Pulses and after trying for more than 2 minutes of presses, I could not get it to Fault Handler.
Also since you intend to use float values, I would suggest that you enable the FPU as well.
Lastly, assume the condition where the value rolled over twice and the NewValue is greated than OldValue. In this case the computation "logically" is incorrect. You have no mechanism in place to detect the same. I can understand the case where the input pulse is like 1MHz and this condition will not happen, but the code should have more fail safes than just a single if condition.
Regards
Amit
Hii amit,
sorry for late response. Did you use any variable in Main() which was calculated in ISR? i enabled FPU as well but it is not working at all. same problem.
regards prashant
Hello Prashant,
I used the program just as you had sent in the first post
Regards
Amit
Hii amit.
let me explain you a bit more. I am giving a pulse to PA5. and giving same pulse to PF4. now i am calculating frequency by portF interrupt handler. but you are giving a single pulse to PF4 (switch press). So for you its working but in my case it is not working. what may be the reason? sorry for inconvenience caused by me.
thanks
regards
prashant
Hello Prashant,
What is the frequency of the pulses? If the idea is to measure the Pulse Frequency then wouldn't it be better to use the Timer in Input Edge Time Mode.
Following Recent Post meant to do the same.
http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/374380.aspx
Regards
Amit
hii amit
frequency of the pulses in 300Hz. but i found that problem is different. I am using a floating point variable in if else condition. but now i tried again by converting them into unsigned long. program is going in fault ISR. but i found something interesting. when i run program using "step into" it works perfectly fine. what may be the problem?
speedref=1000.00; hh=(int)speedref; if(hh!=3000) { a=1; }
regards
prashant
Hello Prashant
What is the NVIC_FAULTSTAT and NVIC_FAULTADDR values when the Fault ISR is executed?
Regards
Amit
hii amit
NVIC_FAULTSTAT = 0x40000000
NVIC_HFAULT_STAT_FORCED = 1 other two are zero
NVIC_FAULTADDR = 0xE000EDF8
prashant
Hello Prashant,
The bit in the NVIC_FAULTSTAT that you have mentioned is a reserved bit. It cannot be set. Are you sure that it is address 0xE000ED28.
Regards
Amit