I wrote interrupt handler code here. The purpose of my code is to interrupt when I press the button. However, there is a problem. When the button is pressed, it interrupts and enters the handler, but does not increase the Buttonpress. I see the debugger reads buttonpress++, but after exiting the handler, the code freezes when it comes to the switch. Buttonpress = 1 does not happen. What is the reason of this? Do I need to assign the variable differently when assigning it?
Here is my Code :
/* 1 sec is 1600000 */
void delay(volatile uint32_t);
uint32_t ButtonPress = 0;
/* Interrupt Handlers */
void EXTI0_1_IRQHandler(void){
ButtonPress++;
EXTI->RPR1 |= (1U << 1);
}
int main(void) {
uint32_t ButtonPress = 0;
/* Enable GPIOA clock */
RCC->IOPENR |= (1U << 0);
/* Setup PA0 as output */
GPIOA->MODER &= ~(3U << 2*0);
GPIOA->MODER |= (1U << 2*0);
/* Setup PA1 as input */
GPIOA->MODER &= ~(3U << 2*1);
GPIOA->MODER |= (0U << 2*1);
/* External interrupt at PA1 port */
EXTI->EXTICR[0] |= (0U << 8*1);
/* Mask and Rising on Px1 */
EXTI->IMR1 |= (1U << 1);
EXTI->RTSR1 |= (1U << 1);
EXTI->FTSR1 |= (1U << 1);
/* Setup NVIC */
NVIC_SetPriority(EXTI0_1_IRQn, 0);
NVIC_EnableIRQ(EXTI0_1_IRQn);
while(1) {
switch(ButtonPress){
case 0:
/* Turn off LED */
GPIOA->ODR = (0U << 0);
break;
case 1:
/* Turn on LED 2sec interval */
GPIOA->ODR |= (1U << 0);
delay(3200000);
GPIOA->ODR ^= (1U << 0);
delay(3200000);
break;
case 2:
/* Turn on LED 1sec interval */
GPIOA->ODR |= (1U << 0);
delay(1600000);
GPIOA->ODR ^= (1U << 0);
delay(1600000);
break;
case 3:
/* Turn on LED 0.5sec interval */
GPIOA->ODR |= (1U << 0);
delay(800000);
GPIOA->ODR ^= (1U << 0);
delay(800000);
break;
case 4:
/* Turn on LED 0.1sec interval */
GPIOA->ODR |= (1U << 0);
delay(160000);
GPIOA->ODR ^= (1U << 0);
delay(160000);
break;
case 5:
/* Turn on LED */
GPIOA->ODR |= (1U << 0);
break;
case 6:
/* Button Clear */
ButtonPress = 0;
break;
}
}
return 0;
}
void delay(volatile uint32_t s) {
for(; s>0; s--);
}
`
I wrote interrupt handler code here. The purpose of my code is to interrupt when I press the button. However, there is a problem. When the button is pressed, it interrupts and enters the handler, but does not increase the Buttonpress. I see the debugger reads buttonpress++, but after exiting the handler, the code freezes when it comes to the switch. Buttonpress = 1 does not happen. What is the reason of this? Do I need to assign the variable differently when assigning it?
You have declared the ButtonPress variable twice: once in the global scope and once in main. When the interrupt is called, only the global scope version is in scope and therefore that variable is incremented. When it comes to the switch statement in main however, the other variable is in (a smaller) scope and so that variable is used instead. To fix this, you could remove the declaration of ButtonPress at the beginning of main.
Related
I am trying to implement a driver for USART for my board(F746G-Disco). For now, I implement:
#include "UART_DRIVER.h"
#include "stm32f746xx.h"
#include "stm32f7xx_hal.h"
#include "stdint.h"
void uart_gpio_pin_init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA9 FOR USART1 TX AND PB7 FOR USART1 RX
GPIOA->MODER |= (2U << 18); // ALTERNATE FUNCTION
GPIOA->OTYPER |= (1U << 9);
GPIOA->OSPEEDR |= (1U << 19);
GPIOA->PUPDR |= (1U << 19);
GPIOA->AFR[1] |= (7U << 4); // AF7
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIOB->MODER |= (2U << 6);
GPIOB->OTYPER |= (1U << 7);
GPIOB->OSPEEDR |= (1U << 17);
GPIOB->PUPDR |= (1U << 17);
GPIOB->AFR[0] |= (7U << 28); // AF7
}
void uart_init(void) {
uart_gpio_pin_init();
// disable USART
USART1->CR1 = 0x00; // Disable Uart => UE=0
USART1->CR1 &= (~(1U << 28) | ~(1 << 12)); // WORD LENGTH 8-BIT
USART1->CR1 &= ~(1U << 15); // 16BIT OVERSAMPLING
USART1->CR1 &= ~(1U << 10); // PARITY BIT DISABLE
USART1->CR1 |= (1U << 3); // USART1 TRASNMITTER MODE
USART1->CR1 |= (1U << 2); // USART1 RECEIVER MODE
// 115200kpbs BAUD-RATE, SYSTEMCLOCK:168 MHz
USART1->BRR = (0x5B2);
// ENABLE USART1
USART1->CR1 = 0x01;
}
void uart_transmit_data(const char *data) {
for (int var = 0; data[var] != '\0'; ++var) {
USART1->TDR = (uint32_t)data[var];
while((USART1->ISR & USART_ISR_TXE) == 0);
}
}
But the problem is that the value of USART1->CR1 does not change. In the manual, it is said that to have a writable bits, Uart Enable(UE) pin must be 0. I have already did that but still nothing change.
reference manual
datasheet(look page 76 for alternate function mapping)
Solution Edit:
I have solved the problem. The problem is I didn't enable the clock for USART. Once __HAL_RCC_USART1_CLK_ENABLE(); macro is invoked in uart_gpio_pin_init function just before the register adjustments of USART, we get rid of the problem!
The part
// ENABLE USART1
USART1->CR1 = 0x01;
will cancel the bits set in
USART1->CR1 |= (1U << 3); // USART1 TRASNMITTER MODE
USART1->CR1 |= (1U << 2); // USART1 RECEIVER MODE
You may want to use OR instead of simple assignment:
// ENABLE USART1
USART1->CR1 |= 0x01;
The problem is in the code that the USART clock wasn't enabled. Once __HAL_RCC_USART1_CLK_ENABLE(); macro is invoked in uart_gpio_pin_init function just before the register adjustments of USART, we get rid of the problem!
I'm a beginner when it comes to using STM chips, and I have a project where I have to use all three USART terminals in Uvision.
I am using an STM32F103RB chip, and I already got the first two USART_init functions working, but I can't get the third one to work for some reason. I would really appreciate any help
Here are my USART_init functions:
/*----------------------------------------------------------------------------
Initialize UART pins, Baudrate
*----------------------------------------------------------------------------*/
void USART1_Init (void) {
int i;
RCC->APB2ENR |= ( 1UL << 0); /* enable clock Alternate Function */
AFIO->MAPR &= ~( 1UL << 2); /* clear USART1 remap */
RCC->APB2ENR |= ( 1UL << 2); /* enable GPIOA clock */
GPIOA->CRH &= ~(0xFFUL << 4); /* clear PA9, PA10 */
GPIOA->CRH |= (0x0BUL << 4); /* USART1 Tx (PA9) output push-pull */
GPIOA->CRH |= (0x04UL << 8); /* USART1 Rx (PA10) input floating */
RCC->APB2ENR |= ( 1UL << 14); /* enable USART#1 clock */
USART1->BRR = 0x0271; /* 115200 baud # PCLK2 72MHz */
USART1->CR1 = (( 1UL << 2) | /* enable RX */
( 1UL << 3) | /* enable TX */
( 0UL << 12) ); /* 1 start bit, 8 data bits */
USART1->CR2 = 0x0000; /* 1 stop bit */
USART1->CR3 = 0x0000; /* no flow control */
for (i = 0; i < 0x1000; i++) __NOP(); /* avoid unwanted output */
USART1->CR1 |= (( 1UL << 13) ); /* enable USART */
}
/*----------------------------------------------------------------------------
Initialize UART2 pins, Baudrate
*----------------------------------------------------------------------------*/
void USART2_Init (void) {
RCC->APB2ENR |= 1; // enable clock for AF
AFIO->MAPR |= 1<<3; // set USART2 remap
RCC->APB2ENR |= 1<<5; // enable clock for GPIOD
GPIOD->CRL &= ~(0xFF << 20); // Clear PD5, PD6
GPIOD->CRL |= (0x0B << 20); // USART2 Tx (PD5) output push-pull
GPIOD->CRL |= (0x04 << 24); // USART2 Rx (PD6) input floating
RCC->APB1ENR |= 1<<17; // enable clock for USART2
USART2->BRR = 0x138; // set baudrate -115.2kB from 36MHz
USART2->CR1 &= ~(1<<12); // force 8 data bits
USART2->CR2 &= ~(3<<12); // force 1 stop bit
USART2->CR3 &= ~(3<<8); // force no flow control
USART2->CR1 &= ~(3<<9); // force no parity
USART2->CR1 |= 3<<2; // RX, TX enable
USART2->CR1 |= 1<<5; // Rx interrupts if required
NVIC->ISER[1] = (1 << 6); // enable interrupts if required
USART2->CR1 |= 1<<13; // USART enable
}
/*----------------------------------------------------------------------------
Initialize UART3 pins, Baudrate
*----------------------------------------------------------------------------*/
void USART3_Init (void) {
RCC->APB2ENR |= 1; // enable clock for AF
AFIO->MAPR |= 1<<3; // set USART3 remap
RCC->APB2ENR |= 1<<4; // enable clock for GPIOC
GPIOC->CRH &= ~(0xFFUL << 4); /* clear PC10, PC11 */
GPIOC->CRH |= (0x04UL << 8); /* USART3 Rx (PC10) input floating */
GPIOC->CRH |= (0x01UL << 8); /* USART3 Tx (PC11) output push-pull */
RCC->APB1ENR |= 1<<20; // enable clock for USART3
USART3->BRR = 0x138; // set baudrate -115.2kB from 36MHz; USART3
//should have the same baudrate as USART2
USART3->CR1 &= ~(1<<12); // force 8 data bits
USART3->CR2 &= ~(3<<12); // force 1 stop bit
USART3->CR3 &= ~(3<<8); // force no flow control
USART3->CR1 &= ~(3<<9); // force no parity
USART3->CR1 |= 3<<2; // RX, TX enable
USART3->CR1 |= 1<<5; // Rx interrupts if required
NVIC->ISER[1] = (1 << 6); // enable interrupts if required
USART3->CR1 |= 1<<13; // USART enable
}
Your first line for the USART3 initialization is wrong :-)
RCC->APB2ENR |= 1; // enable clock for AF
must be (without a clock the USART doesn't work)
RCC->APB1ENR |= (1<<18); // enable clock for USART
And as an additional hint, do not use all these magic numbers for the bits.
This is much more readable (and the needed defines are already done in the CMSIS:
RCC->APB1ENR |= RCC_APB1ENR_USART3EN; // enable clock for USART
After some research, I found there were more problems than just the clock not being enabled. Below is the complete code of the initialization for UART3 using an STM32F103RB chip
/*----------------------------------------------------------------------------
Initialize UART3 pins, Baudrate
*----------------------------------------------------------------------------*/
void USART3_Init (void) {
RCC->APB2ENR |= 1; // enable clock for AF
AFIO->MAPR |= AFIO_MAPR_USART3_REMAP_PARTIALREMAP; // set USART3 to partical remap to use PC10 and PC11
RCC->APB2ENR |= 1<<4; // enable clock for GPIOC
// since our pins are above 8, we use H instead of L
// since we are using 10 & 11 we will be using bits 8-15 in the CRH register
/* USART3 Tx (PC10) output push-pull */
GPIOC->CRH &= ~(0xFFUL << 8);
GPIOC->CRH |= (0x0BUL << 8);
/* USART3 Rx (PC11) input floating */
GPIOC->CRH |= (0x04UL << 12);
RCC->APB1ENR |= RCC_APB1ENR_USART3EN; /* enable clock for USART3 */
USART3->BRR = 0x138; /* set baudrate -115.2kB from 36MHz */
USART3->CR1 = (( 1UL << 2) | /* enable RX */
( 1UL << 3) | /* enable TX */
( 0UL << 12) ); /* 1 start bit, 8 data bits */
USART3->CR2 = 0x0000; /* 1 stop bit */
USART3->CR3 = 0x0000; /* no flow control */
USART3->CR1 |= 1<<13; /* USART3 enable */
//Configure and enable USART3 interrupt
NVIC->ICPR[USART3_IRQn/32] = 1UL << (USART3_IRQn%32); // clear any previous pending interrupt flag
NVIC->IP[USART3_IRQn] = 0x80; // set priority to 0x80
NVIC->ISER[USART3_IRQn/32] = 1UL << (USART3_IRQn%32); // set interrupt enable bit
USART3->CR1 |= USART_CR1_RXNEIE; // enable USART3 receiver not empty interrupt
}
and the interrupt I used to prove this works looks like this
// UART3 Interupt Handler
void USART3_IRQHandler (void) {
uint8_t inKey3 = (int8_t) (USART3->DR & 0x1FF);
SendCharTo3(inKey3);
if(inKey3 == 0x0D) {
SendCharTo3('\n');
}
}
/*----------------------------------------------------------------------------
SendChar
Write character to Serial Port. for UART 3
*----------------------------------------------------------------------------*/
int SendCharTo3 (uint8_t ch) {
while (!(USART3->SR & USART_SR_TXE));
USART3->DR = ((uint16_t)ch & 0x1FF);
return (ch);
}
I'm running some tests on STM32L152 by trying to control a DC motor speed by selecting 3 different speeds using a push button, as following:
ideal mode, motor is off.
push button pressed, motor runs at speed-1
push button pressed again, motor runs at speed-2
push button pressed again, motor stops.
I've already tried to run the motor directly by setting CCR1 (TIM4), and it works perfectly. so I believe the only issue is with the push button part. here's the code:
#include <stdio.h>
#include "stm32l1xx.h" // Keil::Device:Startup
// initialization of GPIOB, GPIOA & PWM/TIM4
void GPIO_Init()
{
// initialization of GPIOB
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST; /* Reset GPIOB clock */
RCC->AHBENR |= RCC_AHBENR_GPIOBEN; /* Enable GPIOB clock*/
GPIOB->MODER &= ~(0x03 << (2 * 6)); /* Clear bit 12 & 13 Output mode*/
GPIOB->MODER |= 0x01 << (2 * 6); /* set as Output mode*/
GPIOB->OSPEEDR &= ~(0x03 << (2 * 6)); /* 40 MHz speed */
GPIOB->OSPEEDR |= 0x03 << (2 * 6); /* 40 MHz speed*/
GPIOB->PUPDR &= ~(1 << 6); /* NO PULL-UP PULL-DOWN*/
GPIOB->OTYPER &= ~(1 << 6); /* PUSH-PULL*/
GPIOB->AFR[0] |= 0x2 << (4 * 6);
// initialization of GPIOA
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST; /* Reset GPIOA clock*/
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* Enable GPIOA clock*/
GPIOA->MODER &= ~(0x03); /* Clear & set as input*/
GPIOA->OSPEEDR &= ~(0x03); /* 2 MHz speed */
GPIOA->OSPEEDR |= 0x01; /* 2 MHz speed */
GPIOA->PUPDR &= ~(0x03); /* No PULL-UP/DOWN */
GPIOA->OTYPER &= ~(0x1); /* PUSH-PULL */
//initialization of PWM & TIM4
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC = 100;
TIM4->ARR = 414; // F=2.097MHz , Fck= 2097000/(100+1)= 20.762KHz, Tpwm = 0.02, ARR= (Fck x Tpwm)-1
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // 111: PWM mode 1
TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
TIM4->CR1 |= TIM_CR1_ARPE;
TIM4->CCER |= TIM_CCER_CC1E;
TIM4->EGR |= TIM_EGR_UG;
TIM4->SR &= ~TIM_SR_UIF;
TIM4->DIER |= TIM_DIER_UIE;
TIM4->CR1 |= TIM_CR1_CEN;
}
// Delay conf
void setSysTick(void)
{
// ---------- SysTick timer (1ms) -------- //
if (SysTick_Config(SystemCoreClock / 1000))
{
// Capture error
while (1)
{
};
}
}
volatile uint32_t msTicks; //counts 1ms timeTicks
void SysTick_Handler(void)
{
msTicks++;
}
static void Delay(__IO uint32_t dlyTicks)
{
uint32_t curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
int returnVal = 0;
int updatedpress = 0;
int buttonpress() // function to check & add, if the pushbutton is pressed
{
if (GPIOA->IDR & GPIO_IDR_IDR_0) //condition: if PA0 is set
{
Delay(500); // avoid debouncing
if (GPIOA->IDR & GPIO_IDR_IDR_0) //confirm condition: if PA0 is set
{
returnVal = 1 + updatedpress;
while (GPIOA->IDR & GPIO_IDR_IDR_0)
{
}
}
}
return returnVal;
}
int main(void)
{
GPIO_Init();
setSysTick();
while (1)
{
int buttonpress();
updatedpress = returnVal;
if (updatedpress == 1)
TIM4->CCR1 = 30;
else if (updatedpress == 2)
TIM4->CCR1 = 37;
else if (updatedpress == 3)
TIM4->CCR1 = 46;
else if (updatedpress > 3)
returnVal = 0;
}
}
When I run the code, nothing works physiclly. I tried to run the debugger and I found that it exits the buttonpress function immedtialy after reaching
if(GPIOA->IDR & GPIO_IDR_IDR_0)
Any idea why it doesn't work as it should?
The GPIO peripherals are held in reset, you should clear the reset bits:
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST
/* ... */
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST;
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST;
Ok it worked, and here are the corrections made:
1/ PB6 (which is connected to the DC motor) was mistakenly set as output. changed to Alternate Function.
2/ If-Conditions used for comparing the number of button-press and select motor speed is shifted to a separate function called runmotor
3/ The read instruction if(GPIOA->IDR & 0x0001) is moved into the while loop within the main function to ensure a continuous check of the pushbutton condition.
4/ Reset of GPIOs are cleared, as advised by #berendi
here's the updated code:
#include <stdio.h>
#include "stm32l1xx.h" // Keil::Device:Startup
// initialization of GPIOB, GPIOA & PWM/TIM4
void GPIO_Init(){
// initialization of GPIOB
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST; /* Reset GPIOB clock*/
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST; /* Clear Reset */
RCC->AHBENR |= RCC_AHBENR_GPIOBEN; /* Enable GPIOB clock*/
GPIOB->MODER &= ~(0x03 << (2*6)); /* Clear bit 12 & 13 */
GPIOB->MODER |= 0x02 << (2*6); /* set as Alternate function*/
GPIOB->OSPEEDR &= ~(0x03<< (2*6)); /* 40 MHz speed*/
GPIOB->OSPEEDR |= 0x03<< (2*6); /* 40 MHz speed */
GPIOB->PUPDR &= ~(1<<6); /* NO PULL-UP PULL-DOWN*/
GPIOB->OTYPER &= ~(1<<6); /* PUSH-PULL*/
GPIOB->AFR[0] |= 0x2 << (4*6);
// initialization of GPIOA
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST; /* Reset GPIOA clock */
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST; /* Clear Reset */
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* Enable GPIOA clock */
GPIOA->MODER &= ~(0x03); /* Clear & set as input */
GPIOA->OSPEEDR &= ~(0x03); /* 2 MHz speed */
GPIOA->OSPEEDR |= 0x01; /* 2 MHz speed */
GPIOA->PUPDR &= ~(0x03); /* reset PULL-DOWN */
GPIOA->OTYPER &= ~(0x1); /* PUSH-PULL */
//initialization of PWM & TIM4
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC = 100;
TIM4->ARR = 414; // F=2.097MHz , Fck= 2097000/(100+1)= 20.762KHz, Tpwm = 0.02, ARR= (Fck x Tpwm)-1
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // 111: PWM mode 1
TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
TIM4->CR1 |= TIM_CR1_ARPE;
TIM4->CCER |= TIM_CCER_CC1E;
TIM4->EGR |= TIM_EGR_UG;
TIM4->SR &= ~TIM_SR_UIF;
TIM4->DIER |= TIM_DIER_UIE;
TIM4->CR1 |= TIM_CR1_CEN;
}
void setSysTick(void){
// ---------- SysTick timer (1ms) -------- //
if (SysTick_Config(SystemCoreClock / 1000)) {
// Capture error
while (1){};
}
}
volatile uint32_t msTicks; //counts 1ms timeTicks
void SysTick_Handler(void) {
msTicks++;
}
static void Delay(__IO uint32_t dlyTicks){
uint32_t curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
int buttonpress=0;
static void runmotor(void)
{
if (buttonpress ==1){
TIM4->CCR1 = 30;
return;
}
if (buttonpress ==2){
TIM4->CCR1 = 37;
return;
}
if (buttonpress ==3){
TIM4->CCR1 = 46;
return;
}
if (buttonpress > 3){
TIM4->CCR1 = 0;
buttonpress = 0;
return;
}
}
int main(void){
GPIO_Init();
setSysTick();
while (1){
if(GPIOA->IDR & 0x0001)
{
Delay(5);
if(GPIOA->IDR & 0x0001)
buttonpress = buttonpress + 1;
runmotor();
}
}
}
#include <msp430.h>
#define BUTTON BIT3 // Port 1.3
#define REDLED BIT0 // Port 1.0
#define GRNLED BIT6 // Port 1.6
#define ZERO 0x08
#define ONE 0x48
#define TWO 0x09
#define THREE 0x49
int counter = 0;
int main(void) {
// Watchdog setup
WDTCTL = WDTPW + WDTHOLD; // stop watchdog (password + hold counter)
// LED initial setup
P1DIR |= REDLED + GRNLED; // set P1.0 and P1.6 as output (1) pins
P1OUT &= ~REDLED; // Disable REDLED
P1OUT &= ~GRNLED; // Disable GRNLED
// Button setup
P1DIR &= ~BUTTON; // button is an input
P1OUT |= BUTTON; // pull-up resistor
P1REN |= BUTTON; // resistor enabled
P1IE |= 0x08; //P1.3 interrupt enable
P1IES &= ~0x08; //lower edge
P1IFG &= ~0x08; //zero flag
while(1){
}
}
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void){
counter += 1;
counter = (counter % 4);
switch(counter){
case 0:
P1OUT = ZERO;
break;
case 1:
P1OUT = ONE;
break;
case 2:
P1OUT = TWO;
break;
case 3:
P1OUT = THREE;
break;
}
P1IFG &= ~0x08;
}
I can not enter the ınterrup routine .I checked interrup flag ,when I push the button flag will 1 but the leds are not change ,I think that I can not enter interrup.If I can , the led must be changed.What is the wrong ?
Global interrupts are disabled by default on program's startup. You need to add code that sets the global interrupt enable (GIE) bit at the end of main(). The most platform-independent (not really) way to do it is by calling __enable_interrupts() function.
#include <msp430.h>
#include <intrinsics.h>
...
__enable_interrupts();
Alternatively, set the GIE bit directly:
__bis_status_register(GIE);
To check whether interrupts are enabled (not that inside the interrupt handler they always will be disabled by default):
if (__get_SR_register() & GIE) {
printf("interrupts enabled\n");
} else {
printf("interrupts disabled\n");
}
I had set MSP430F5418 P2.5 for high to low transition. But I am getting interrupts for both low-to-high and high-to-low transitions. Please my code snippet below.
P2OUT |= BIT5 /* Enable P2.5 internal resistances */
P2REN |= BIT5 /* Set up P2.5 as pull-Up resistances */
P2IES |= BIT5;
P2IE |= BIT5;
P2IFG &= ~BIT5; /* P2.5 IFG cleared */
#pragma vector=PORT2_VECTOR
__interrupt void port2_interrupt (void)
{
switch (P2IV)
{
case 0x0CU:
{
/* Do something here */
P2IFG &= ~BIT5;
break;
}
default:
{
/* No Action */
break;
}
}
}
Hans, I am not using a switch to assert the pin. It is actually done by another processor. I got a reply In TI (Texas instruments) forum that there could be a hidden high-to-low signal within a low-to-high transition and vice versa.
So, I modified my code as follows and it worked fine.
...
P2OUT |= BIT5 ; /* Enable P2.5 internal resistance */
P2REN |= BIT5; /* Set up P2.5 as pull-up resistance */
P2IES |= BIT5; /* Sets P2IFG for high to low transition */
P2IE |= BIT5; /* P2.5 interrupt enabled */
P2IFG &= ~BIT5; /* P2.5 IFG cleared */
...
#pragma vector=PORT2_VECTOR
__interrupt void port2_isr (void)
{
switch (P2IV)
{
case 0x0CU:
{
TA1CCTL0 &= ~CCIE;
TA1CCR0 = 0U;
TA1CCTL0 |= CCIE;
TA1CCTL0 &= ~CCIFG;
TA1CCR0 = TA1R + 15U;
P2IFG &= ~BIT5;
break;
}
...
...
}
}
#pragma vector = TIMER1_A0_VECTOR /* Timer1_A3 CC0 */
static __interrupt void _timer1_ao_isr (void)
{
TA1CCTL0 &= ~CCIE;
if ((P2IN & BIT5) == 0U)
{
// Got a valid high-to-low assert here!!!
}
}
Not actually an answer, just a suggestion, rename your variables to something more meaningful, two months from now you won't remember that BIT5 is the pin that you check for a high-to-low transition. You can use a define to rename BIT5 to say, HIGH_TO_LOW_PIN. You can do the same thing with the timer setup, refactor it to something more meaningful.