STM32F407VG UART interrupt problem
Postat: 6 juni 2015, 23:43:50
Jag har problem med att interrupten för UART6, (Receive Data register not empty interrupt) inte riktigt fungerar i alla lägen.
Ibland fungerar den klockrent. Men andra gånger så reagerar den inte alls.
Det jag gör med interrupten är att lagra meddelanden som jag tar in på UARTEN, och lagra detta i en buffert.
Provade sedan att göra samma sak, fast utan interrupten, och då fungerar det..
Är det någon som kan tänka sig ha någon aning vad som kan vara fel?
CMGF_1b() är den funktion där detta sköts utan interrupt, medan CMGF_1() är den som sköts med interrupt.
Konstiga att innan detta så görs samma sak med interrupt för en annan funktion AT(), och där strular det inte..
Ibland fungerar den klockrent. Men andra gånger så reagerar den inte alls.
Det jag gör med interrupten är att lagra meddelanden som jag tar in på UARTEN, och lagra detta i en buffert.
Provade sedan att göra samma sak, fast utan interrupten, och då fungerar det..
Är det någon som kan tänka sig ha någon aning vad som kan vara fel?
CMGF_1b() är den funktion där detta sköts utan interrupt, medan CMGF_1() är den som sköts med interrupt.
Konstiga att innan detta så görs samma sak med interrupt för en annan funktion AT(), och där strular det inte..
Kod: Markera allt
/*************************************************************
* File: main.c
*
* Description:
* Main program and configuration
*
*************************************************************/
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_pwr.h"
#include "stm32f4xx_usart.h"
#include "misc.h"
#include "stm32f4xx_syscfg.h"
/******************
* Static function
******************/
static void OtherGPIO_Configuration(void);
static void TIM3_Configuration(void);
static void Wait_Time(uint32_t, uint32_t);
#define UNIT_us 1
#define UNIT_ms 1000
#define UNIT_s 1000000
static void USART6_Configuration(void);
static int AT(void);
#define RX_DATA_BUFF_SIZE 250
static int Rx_Data_Cnt =0;
static char Rx_Data_Buff[RX_DATA_BUFF_SIZE];
static void Prints_Uart6(char *Text_String, int Max_Length);
static signed int Find_String(char *a,int a_offset,int a_max,char *b,int b_offset,int b_max);
static int CMGF_1(void);
static int CMGF_1b(void);
static void CMGR(char Pos);
/*************************************************************
* Function: main
*
* Description:
* Main program
*
*************************************************************/
int main(void)
{
OtherGPIO_Configuration();
USART6_Configuration();
TIM3_Configuration();
//GPIO_SetBits(GPIOD, GPIO_Pin_15); // Blue LED
while( 1 != AT() ){ Wait_Time(300,UNIT_ms); } // Test communication.
;
USART_ITConfig(USART6, USART_IT_RXNE, DISABLE); // Receive Data register not empty interrupt.
//CMGR_1();
while( 1 != CMGF_1b() ){ Wait_Time(300,UNIT_ms); } // Switch to SMS text-mode. DEBUG!
//while( 1 != AT() ){ Wait_Time(300,UNIT_ms); } // Test communication.
// CMGR('1');
while(1){;}
Wait_Time(500, UNIT_ms); // Wait for response.
//while(RESET == GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) ){;}
USART_ITConfig(USART6, USART_IT_RXNE, DISABLE); // Receive Data register not empty interrupt.
/*
{
int i=0;
for(i=0; i <= Rx_Data_Cnt; i++)
{
USART_SendData(USART6,Rx_Data_Buff[i]);
Wait_Time(5, UNIT_us); //Delay to make transmission work properly! (Min 1 us)
while(RESET == USART_GetFlagStatus(USART6, USART_FLAG_TC)){;} // Wait until TX is ready again.
}
}
*/
while(1){}// END OF MAIN HERE! --------------------------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------------------
void Prints_Uart6(char *Text_String, int Max_Length)
{
int i=0;
Wait_Time(10,UNIT_ms); // To avoid UART hangs itself.
while( 0 != *Text_String && (i < Max_Length) )
{
USART_SendData(USART6,*Text_String);
Wait_Time(5, UNIT_us); //Delay to make transmission work properly! (Min 1 us)
while(RESET == USART_GetFlagStatus(USART6, USART_FLAG_TC)){;} // Wait until TX is ready again.
Text_String++;
i++;
}
}
//--------------------------------------------------------------------------------------------
signed int Find_String(char *a,int a_offset,int a_max,char *b,int b_offset,int b_max)
{
/* Search for string 'a' in string 'b' , if found: returns positive offset to after the found string. If not found: returns '-1'. */
int ai =0, bi =0, match_cnt = 0; // Init state.
ai= (ai + a_offset); // Correct for wanted offset.
bi= (bi + b_offset); // --//--
while(1)
{
if(a[ai] == b[bi])
{
match_cnt++;
if(match_cnt == a_max){return match_cnt;} // Found string a in b!
if( (bi >= b_max) || (ai >= a_max) ){return -1;} // Failed to find string a in b.
ai++;
bi++;
}
else
{
if(bi >= b_max){return -1;} // Failed to fin string a in b.
match_cnt = 0; // Reset of counter, because a not equal to b!
bi++;
}
}
}
//--------------------------------------------------------------------------------------------
int AT(void)
{
Rx_Data_Cnt =0; // Reset Rx Data Buffer Counter. (Rx_Data_Buff)
Prints_Uart6("AT\r\n\0", 10);
Wait_Time(300, UNIT_ms);
if( Rx_Data_Cnt > 0 && 0 < Find_String("OK",0,2,Rx_Data_Buff,0,Rx_Data_Cnt)){return 1;}
else{return 0;}
}
//--------------------------------------------------------------------------------------------
int CMGF_1b(void)
{
Rx_Data_Cnt =0; // Reset Rx Data Buffer Counter. (Rx_Data_Buff)
Prints_Uart6("AT+CMGF=1\r\n\0", 10);
/* Wait number of micro-seconds that loaded into counter. */
TIM_SetAutoreload(TIM2, (800*UNIT_ms) );
TIM_SetCounter(TIM2,0); // TimerX Counter setup.
TIM_ClearFlag(TIM2,TIM_FLAG_Update); // TimerX Counter flag setup.
while(SET != (TIM_GetFlagStatus(TIM2,TIM_FLAG_Update)) ) // Do this until flag is set.
{
if (SET == USART_GetFlagStatus(USART6, USART_FLAG_RXNE) )
{
Rx_Data_Buff[Rx_Data_Cnt] = USART_ReceiveData(USART6);
Rx_Data_Cnt++;
}
}
;
if( Rx_Data_Cnt > 0 && 0 < Find_String("OK",0,2,Rx_Data_Buff,0,Rx_Data_Cnt)){return 1;}
else{return 0;}
}
//--------------------------------------------------------------------------------------------
int CMGF_1(void)
{
Rx_Data_Cnt =0; // Reset Rx Data Buffer Counter. (Rx_Data_Buff)
Prints_Uart6("AT+CMGF=1\r\n\0", 15);
Wait_Time(1, UNIT_s);
if( Rx_Data_Cnt > 0 && 0 < Find_String("OK",0,2,Rx_Data_Buff,0,( Rx_Data_Cnt + 1))){return 1;}
else{return 0;}
}
//--------------------------------------------------------------------------------------------
void CMGR(char Pos)
{
Rx_Data_Cnt =0; // Reset Rx Data Buffer Counter. (Rx_Data_Buff)
Prints_Uart6("AT+CMGR=", 15);
Prints_Uart6(&Pos, 1);
Prints_Uart6("\r\n\0", 5);
Wait_Time(650, UNIT_ms);
}
//--------------------------------------------------------------------------------------------
void USART6_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* Enable USART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
/* Connect PC6 to USART1_Tx */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
/* Connect PC7 to USART1_Rx */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
/* Configure USART6 Tx, and Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* USART configuration */
USART_OverSampling8Cmd(USART6, ENABLE); // 8x UART oversampling.
USART_OneBitMethodCmd(USART6, DISABLE); // One-bit sampling, majority vote fron three samples.
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART6, &USART_InitStructure);
/* Enable USART */
USART_Cmd(USART6, ENABLE);
USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); // Receive Data register not empty interrupt.
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//--------------------------------------------------------------------------------------------
void TIM3_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM3 Clock enable.
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65000;
TIM_TimeBaseStructure.TIM_Prescaler = 12;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Load TimeBase settings.
TIM_ARRPreloadConfig(TIM2, ENABLE); // Auto Reload Preload.
TIM_UpdateDisableConfig(TIM2, DISABLE); // UDIS-bit, Update Event (UEV), when timer register overflow.
/* Configures the TIMx Update Request Interrupt source. */
TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Global); // Source of update is counter overflow/underflow.
/* TIM3 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
//--------------------------------------------------------------------------------------------
static void Wait_Time(uint32_t reload, uint32_t suffix)
{
/* Wait number of micro-seconds that loaded into counter. */
TIM_SetAutoreload(TIM2, (reload*suffix) );
TIM_SetCounter(TIM2,0); // TimerX Counter setup.
TIM_ClearFlag(TIM2,TIM_FLAG_Update); // TimerX Counter flag setup.
while(SET != (TIM_GetFlagStatus(TIM2,TIM_FLAG_Update)) ){;} // Do this until flag is set.
}
//--------------------------------------------------------------------------------------------
/*************************************************************
* Function: GPIO_Configuration
*
*************************************************************/
static void OtherGPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO clock's used here */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_15; // LED.
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_0; // Push-button. (Normaly low with pulldown)
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//--------------------------------------------------------------------------------------------
void USART6_IRQHandler(void)
{
int tmp;
if (SET == USART_GetFlagStatus(USART6, USART_FLAG_ORE) ) {GPIO_SetBits(GPIOD, GPIO_Pin_15); }
if (SET == USART_GetFlagStatus(USART6, USART_FLAG_NE) ) {GPIO_SetBits(GPIOD, GPIO_Pin_15); }
if (SET == USART_GetFlagStatus(USART6, USART_FLAG_FE) ) {GPIO_SetBits(GPIOD, GPIO_Pin_15); }
if (SET == USART_GetFlagStatus(USART6, USART_FLAG_PE) ) {GPIO_SetBits(GPIOD, GPIO_Pin_15); }
if (RESET == USART_GetFlagStatus(USART6, USART_FLAG_RXNE) ) // Is it a R-interrupt?
{
GPIO_SetBits(GPIOD, GPIO_Pin_15);
return; // If not..
}
//Rx_Data_Buff[Rx_Data_Cnt]=USART_ReceiveData(USART6);
if(Rx_Data_Cnt < RX_DATA_BUFF_SIZE) // Prevents Buffer overrun.
{
Rx_Data_Buff[Rx_Data_Cnt]=USART_ReceiveData(USART6);
Rx_Data_Cnt++;
}
else { tmp=USART_ReceiveData(USART6); } // Don't trash last byte in buffer if it's full.
USART_ClearITPendingBit(USART6, USART_IT_RXNE); // Clear interrupt flag
}