STM32L1 Problema de interrupción USART

1

Estoy tratando de usar el kit de descubrimiento stm32l152 para comunicarme usando usart. Aunque puedo enviar datos en tx (verifico esto a través de la PC), no pude activar la función de interrupción cuando recibo los datos (los envío a través de la PC y también hago cortocircuitos y depuración de tx y rx). El archivo main.c es como abajo. Intenté y examiné muchos ejemplos en Internet (incluso no relacionados directamente con stm32l1 para entender lo que sucede con el brazo) pero no pude encontrar el problema. ¿Cuál podría ser el problema?

Por cierto, estoy usando IAR como IDE. Cuando agrego un punto de interrupción dentro de la función de interrupción (USART3_IRQHandler) y ejecuto, alerta IAR: no se pudieron establecer uno o más puntos de interrupción y se han deshabilitado, y deshabilito el punto de interrupción dentro de la función de interrupción.

#include "main.h"


void DelaySW(uint32_t delay);
void RCC_Config(void);
GPIO_InitTypeDef GPIO_InitStructure; 
USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;   
USART_ClockInitTypeDef USART_ClockInitstructure;    
uint16_t receivedData;


void USART3_IRQHandler(void)
{
  while(1)
  {
    while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
    USART_SendData(USART3, 'c');
  }    
}


int main(void)
{
  RCC_Config();

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  /* Alternate function conf */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3 );
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3 );
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_USART3 );
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_USART3 );
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_USART3 );


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  USART_ClockInitstructure.USART_Clock   = USART_Clock_Disable ;
  USART_ClockInitstructure.USART_CPOL    = USART_CPOL_Low ;
  USART_ClockInitstructure.USART_LastBit = USART_LastBit_Enable;
  USART_ClockInitstructure.USART_CPHA    = USART_CPHA_1Edge;


  /* USART conf */

  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(USART3, &USART_InitStructure);
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); 
  USART_ClockInit(USART3, &USART_ClockInitstructure);
  NVIC_Init(&NVIC_InitStructure); 


  USART_Cmd(USART3, ENABLE);

  while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
  USART_SendData(USART3, 'c');
  while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
  USART_SendData(USART3, 'c');
  while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
  USART_SendData(USART3, 'c');
  while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
  USART_SendData(USART3, 'c');
  while (USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
  USART_SendData(USART3, 'c');
    while(1);
}

void DelaySW(uint32_t delay)
{
  uint32_t i=10000;

  for(;delay > 0; delay--){
  for(;i>0;i--)
  ;
  }
}

void RCC_Config(void)
{ 
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  /* Allow access to the RTC */
  PWR_RTCAccessCmd(ENABLE);

  /* Reset Backup Domain */
  RCC_RTCResetCmd(ENABLE);
  RCC_RTCResetCmd(DISABLE);

  /*!< LSE Enable */
  RCC_LSEConfig(RCC_LSE_ON);

  /*!< Wait till LSE is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {}
  /*!< LCD Clock Source Selection */
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
}

#ifdef  USE_FULL_ASSERT

  /**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
  void assert_failed(uint8_t* file, uint32_t line)
  {
    /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* Infinite loop */
    while (1);
  }

#endif
    
pregunta Bilal

1 respuesta

1

Sospecho que el enlazador no se está comportando correctamente.

Cada IDE tiene su propia forma de lidiar con las interrupciones, pero generalmente hay un archivo llamado "algo_que_contiene_interrupciones.c" con todas las declaraciones de las funciones de interrupción. El programador solo tiene que completar su propio código y el enlazador se encarga del resto.

Sin duda, dar un buen comienzo a la función es un buen comienzo, pero al ver que solo incluyó "main.h", estoy bastante seguro de que no es tan fácil.

Lo que está sucediendo ahora es que el compilador es lo suficientemente inteligente como para comprender que "USART3_IRQHandler" nunca se llama, por lo que en realidad no lo compila, por lo que es claramente imposible agregar un punto de interrupción en un fragmento de código que no existe .

Solo intente llamar al ISR una vez que esté en su servidor principal, si IAR deja de quejarse, probablemente tenga razón. Tenga en cuenta que tiene un tiempo (1); declaración en la función, así que nada más funcionará, solo tendrá su punto de interrupción de trabajo.

    
respondido por el Vladimir Cravero

Lea otras preguntas en las etiquetas