Other Parts Discussed in Thread: LM393,
Hello guys,
I got a problem when using the GPIO Input RISING_EDGE Interrupt.
Tool: IAR Embedded Workbench.
Application: using LM393 Motor Speed Measuring Sensor to get the speed of DC Motor.
Program:
- PF3 is configured as input with rising edge interrupt. It is connected with the digital output of the speed sensor. And “1” corresponds to ~1.25V, “0” <0.25V.
- There is also a timer interrupt: Timer0, subtimer A; periodic interrupt with interrupt for timeout. Display with the red led.
Here is the code:
- Main.c:
#define PART_TM4C123GH6PM
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
//#include "inc/tm4c123gh6pm.h"
#define GPIO_PORTF_DATA_R 0x400253FC // (*((volatile uint32_t *)0x400073FC))
//*****************************************************************************
//
//! This project calculates the speed of motor from signal of infrared sensor.
//! A timer to generate a periodic interrupt defines the sampling time.
//! A GPIO port to generate an interrupt when the DO is high calculates the RPM
//! RPM = count/Ts/20(20 stripes)*60(s/min)
//! speed v (mm/s) = pi*d(unit: mm)*RPM/60
//*****************************************************************************
//*****************************************************************************
//
// Flags that contain the current value of the interrupt indicator.
//
//*****************************************************************************
uint32_t g_ui32Flags = 0;
uint32_t red_led = 0;
//*****************************************************************************
//
// Flags that contain the value of the interrupts of GPIO Input/DO of the sensor.
//
//*****************************************************************************
uint32_t PortFIntFlags = 0;
int count = 0;
int v; // the speed; unit: mm/s; = pi*d*count/Ts(20ms)/20*1000
float pi = 3.14; // 3.14
int d = 66; // unit: mm
int T = 1000; // unit: mm; corresponds to 1/s
int pulsesperturn = 20;
uint32_t period = 32000000;
//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
//*****************************************************************************
//
// The interrupt handler for the timer interrupt.
//
//*****************************************************************************
void
Timer0IntHandler(void)
{
//
// Clear the timer interrupt.
//
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
g_ui32Flags = 1;
//
// Toggle the flag for the timer.
//
// HWREGBITW(&g_ui32Flags, 0) ^= 1;
red_led = ~red_led;
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, red_led);
}
void PortFIntHandler(void){
// PortFIntFlags++;
//
// uint32_t status=0;
//
// status = GPIOIntStatus(GPIO_PORTF_BASE,true);
//
// GPIOIntClear(GPIO_PORTF_BASE,status);
//
// if( (status & GPIO_INT_PIN_3) == GPIO_INT_PIN_3)
// {
// count ++;
// }
if (GPIO_PORTF_DATA_R & 0x08 != 0 )
{
count++;
}
GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_3);
}
//*****************************************************************************
//
// This application calculates the speed of the DC motor
// through the infrared sensor.
//
//*****************************************************************************
int
main(void)
{
//Set the clock to 80Mhz
SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
//*****************************************************************************
// GPIO: pf3 - rising edge
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
SysCtlDelay(3);
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_3);
// GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPD);
GPIOIntRegister(GPIO_PORTF_BASE,PortFIntHandler);
GPIOIntTypeSet(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_FALLING_EDGE);
GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_3);
GPIOIntClear(GPIO_PORTF_BASE, GPIO_INT_PIN_3);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
//Timer0
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
SysCtlDelay(3);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet(TIMER0_BASE, TIMER_A, period);
// Setup the interrupts for the timer timeouts.
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// Enable the timers.
TimerEnable(TIMER0_BASE, TIMER_A);
IntEnable(INT_GPIOF);
IntEnable(INT_TIMER0A);
IntMasterEnable();
while(1)
{
if (g_ui32Flags ==1)
{
// do not process interrupts during calculations
GPIOIntDisable(GPIO_PORTF_BASE, GPIO_INT_PIN_3);
v = (int)1000*pi*d*count/pulsesperturn;
printf("count = %d\n", count);
printf("v = %d\n", v);
count = 0;
g_ui32Flags = 0;
GPIOIntEnable(GPIO_PORTF_BASE, GPIO_INT_PIN_3);
}
}
}
- Startup_ewarm.c(part):
//*****************************************************************************
//
// Int Handler for the applications.
//
//*****************************************************************************
void Timer0IntHandler(void);
void PortFIntHandler(void);
IntDefaultHandler, // Watchdog timer
// IntDefaultHandler, // Timer 0 subtimer A
Timer0IntHandler, // Timer 0 subtimer A
IntDefaultHandler, // Timer 0 subtimer B
IntDefaultHandler, // FLASH Control
// IntDefaultHandler, // GPIO Port F
PortFIntHandler, // GPIO Port F
IntDefaultHandler, // GPIO Port G
Problem:
The variable count is always 0. But the green led blinks with the rotating motor.
I really don’t know what is the problem...
Thank you for your advice and help.
Best regards.
Meidan