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
}