Перейти к содержанию
    

USART stm32

Здравствуйте!

Работаю на плате TE-STM32F103, использую IAR 5.30, j-link и стандартную библиотеку от ST,

в частности, пример из этой библиотеки по работе с UARTом через прерывания, в котором я оставил

только USART1, чтобы обмениваться данными с компьютером.

После запуска программы как только случается первое прерывание, программа зависает,

если верить дебаггеру, то в обработчик прерывания даже и не заходит. Если писать обработку через polling,

то все работает.

Подскажите, пожалуйста, в чем проблема, буду очень благодарен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Текст вашей программы или проект целиком присоедините к своему сообщению. Телепатические сеансы или "пыточные" процедуры вопрошающих обычно занимают довольно много времени.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Основной код программы

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define BUFFER_SIZE   100

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
vu8 RxBuffer[bUFFER_SIZE];
vu8 RxCounter = 0; 

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);

/* Private functions ---------------------------------------------------------*/

/**
 * @brief  Main program
 * @param  None
 * @retval : None
 */
int main(void)
{
 /* System Clocks Configuration */
 RCC_Configuration();

 /* NVIC configuration */
 NVIC_Configuration();

 /* Configure the GPIO ports */
 GPIO_Configuration();

/* USART1 configuration ------------------------------------------------------*/

 USART_InitStructure.USART_BaudRate = 57600;
 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;

 /* Configure USART1 */
 USART_Init(USART1, &USART_InitStructure);

 /* Enable USART1 Receive interrupt */
 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

 /* Enable the USART1 */
 USART_Cmd(USART1, ENABLE);

 while (1)
 {
 }
}

/**
 * @brief  Configures the different system clocks.
 * @param  None
 * @retval : None
 */
void RCC_Configuration(void)
{
 /* Setup the microcontroller system. Initialize the Embedded Flash Interface,  
    initialize the PLL and update the SystemFrequency variable. */
 SystemInit();

 /* Enable USART1, GPIOA, and AFIO clocks */
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA
                        | RCC_APB2Periph_AFIO, ENABLE);
}

/**
 * @brief  Configures the different GPIO ports.
 * @param  None
 * @retval : None
 */
void GPIO_Configuration(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;

 /* Configure USART1 Rx (PA.10) as input floating */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(GPIOA, &GPIO_InitStructure);

 /* Configure USART1 Tx (PA.09) as alternate function push-pull */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**
 * @brief  Configures the nested vectored interrupt controller.
 * @param  None
 * @retval : None
 */
void NVIC_Configuration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure;

 /* Enable the USART1 Interrupt */
 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
}

Код обработчика прерывания

void USART1_IRQHandler(void)
{
  extern vu8 RxBuffer[]; 
  extern vu8 RxCounter;
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    /* Read one byte from the receive data register */
    RxBuffer[RxCounter++] = USART_ReceiveData(USART1);
    USART_SendData(USART1, RxBuffer[RxCounter - 1]);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
    {
    }
  }
}

Просто я подумал, что код почти такой же, как в примере... Видно, мне надо меньше думать

Изменено пользователем Rosso

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, не С++, просто С.

Посмотрел регистры NVIC, после инициализации ставится единица и в SETENA, и в CLRENA.

Так должно быть?

Сегодня попробовал запустить библиотечный пример с передачей по SPI Simplex_Inturrupt,

не изменяя его совсем, ведет себя аналогично. Инициализация проходит, при первом

прерывании программа виснет

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На вид криминала нет. Единственное предположение - не цепляются вектора прерываний, и программа попадает на заглушки.

Давайте прицепляйте проект целиком, и озвучьте средство разработки (отладочная плата, компилятор).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот проект, плата TE-STM32F103, среда разработки IAR 5.30, компилятор, видимо, ICC 5.30.0.21174.

В прошлый раз, когда программа попадала на заглушки, я в дебаггере это видел, хотя это, наверно,

не аргумент, это было на другой плате.

 

USART_Interrupt.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня к сожалению нет IAR, так что могу судить только на глаз. Вроде всё нормально. А плата вообще работает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Плата работает. По крайней мере программы, работающие без прерываний, выполняются

без ошибок. Ничего конкретного проверить не могу, так как нет доступа к плате

до конца недели.

Это может быть как-то связано с настройками компилятора или с загрузчиком?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я обычно перед выходом из прерывания добавляю команду сброса флага, который вызвал это прерывание. В данном случае это было бы

 

USART_ClearITPendingBit(USART1, USART_IT_RXNE);

 

В противном случае программа зациклится на прерывании. Попробуйте, может поможет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проблема следующем. Хочу организовать между платой stm32f103 и sim900d по usart1 обмен.

 

Все хорошо, но никак не хочет работать прерывание по приему. По передачи работает. По приему цикл вставлял даже while(1) {}, и ниче не зависает.

 

Вот код:

 

/*----------------------------------------------------------------------------
* Name:    Usart.c
* Purpose: USART usage for STM32
* Note(s): 
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use this software.
*
* This software is supplied "AS IS" without warranties of any kind.
*
* Copyright © 2011 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------*/

#include <stdio.h>
#include "STM32F10x.h"

int r = 0;

/*----------------------------------------------------------------------------
 Notes:
 The length of the receive and transmit buffers must be a power of 2.
 Each buffer has a next_in and a next_out index.
 If next_in = next_out, the buffer is empty.
 (next_in - next_out) % buffer_size = the number of characters in the buffer.
*----------------------------------------------------------------------------*/
#define TBUF_SIZE   256	     /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/
#define RBUF_SIZE   256      /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/

/*----------------------------------------------------------------------------

*----------------------------------------------------------------------------*/
#if TBUF_SIZE < 2
#error TBUF_SIZE is too small.  It must be larger than 1.
#elif ((TBUF_SIZE & (TBUF_SIZE-1)) != 0)
#error TBUF_SIZE must be a power of 2.
#endif

#if RBUF_SIZE < 2
#error RBUF_SIZE is too small.  It must be larger than 1.
#elif ((RBUF_SIZE & (RBUF_SIZE-1)) != 0)
#error RBUF_SIZE must be a power of 2.
#endif

/*----------------------------------------------------------------------------

*----------------------------------------------------------------------------*/
struct buf_st {
 unsigned int in;                        /* Next In Index                    */
 unsigned int out;                       /* Next Out Index                   */
 char buf [RBUF_SIZE];                   /* Buffer                           */
};

static struct buf_st rbuf = { 0, 0, };
#define SIO_RBUFLEN ((unsigned short)(rbuf.in - rbuf.out))

static struct buf_st tbuf = { 0, 0, };
#define SIO_TBUFLEN ((unsigned short)(tbuf.in - tbuf.out))

static unsigned int tx_restart = 1;       /* NZ if TX restart is required     */

/* Тупая задежка */
void Delay(uint32_t Val) 
{
Val = Val * 10000;
 for( ; Val != 0; Val--) 
 {
   __nop();
 }
}

/*----------------------------------------------------------------------------
 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                        */
                  (   1UL <<  5) |       /* enable RXNE Interrupt            */
                  (   1UL <<  7) |       /* enable TXE Interrupt             */
                  (   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            */

 NVIC_EnableIRQ(USART1_IRQn);
 USART1->CR1  |= ((   1UL << 13) );      /* enable USART                     */
}


/*----------------------------------------------------------------------------
 USART1_IRQHandler
 Handles USART1 global interrupt request.
*----------------------------------------------------------------------------*/
void USART1_IRQHandler (void) {
 volatile unsigned int IIR;
 struct buf_st *p;
   IIR = USART1->SR;
   if (IIR & USART_SR_RXNE) {            /* read interrupt                   */
     USART1->SR &= ~USART_SR_RXNE;	      /* clear interrupt                  */

     p = &rbuf;

     if (((p->in - p->out) & ~(RBUF_SIZE-1)) == 0) {
       p->buf [p->in & (RBUF_SIZE-1)] = (USART1->DR & 0x1FF);
       p->in++;
     }
   }

   if (IIR & USART_SR_TXE) {
     USART1->SR &= ~USART_SR_TXE;	      /* clear interrupt                    */

     p = &tbuf;

     if (p->in != p->out) {
       USART1->DR = (p->buf [p->out & (TBUF_SIZE-1)] & 0x1FF);
       p->out++;
       tx_restart = 0;
     }
     else {
       tx_restart = 1;
       USART1->CR1 &= ~USART_SR_TXE;     /* disable TX IRQ if nothing to send  */
     }
   }
}

/*------------------------------------------------------------------------------
 buffer_Init
 initialize the buffers
*------------------------------------------------------------------------------*/
void buffer_Init (void)
{
 tbuf.in = 0;                            /* Clear com buffer indexes           */
 tbuf.out = 0;
 tx_restart = 1;

 rbuf.in = 0;
 rbuf.out = 0;
}

/*------------------------------------------------------------------------------
 SenChar
 transmit a character
*------------------------------------------------------------------------------*/
int SendChar(int c)
{
 struct buf_st *p = &tbuf;

 if (SIO_TBUFLEN >= TBUF_SIZE)           /* If the buffer is full              */
   return (-1);                          /* return an error value              */

 p->buf [p->in & (TBUF_SIZE - 1)] = c;   /* Add data to the transmit buffer.   */
 p->in++;

 if (tx_restart) {                       /* If TX interrupt is disabled        */
   tx_restart = 0;                       /*     enable it                      */
   USART1->CR1 |= USART_SR_TXE;          /* enable TX interrupt                */
 }

 return (0);
}

void SendString(uint8_t *s)
{
 while (*s != '\0')
 {
   SendChar(*s);
   s ++;
 }
}

/*------------------------------------------------------------------------------
 GetKey
 receive a character
*------------------------------------------------------------------------------*/
int GetKey (void) {
 struct buf_st *p = &rbuf;

 if (SIO_RBUFLEN == 0)
   return (-1);

 return (p->buf [(p->out++) & (RBUF_SIZE - 1)]);
}

/*----------------------------------------------------------------------------
 MAIN function
*----------------------------------------------------------------------------*/
int main (void)
{
char c;

 buffer_Init();                          /* init RX / TX buffers             */
 USART1_Init();

RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //Затактировали порт
 GPIOC->CRH &= ~GPIO_CRH_CNF8;       //определили режим работы.
 GPIOC->CRH |= GPIO_CRH_MODE8_0;     //определили направление.

 GPIOC->BSRR =GPIO_BSRR_BR8;         // Установили 0.
Delay(1000);
 GPIOC->BSRR =GPIO_BSRR_BS8;         //Установили на выводе 1
Delay(2000);
 GPIOC->BSRR =GPIO_BSRR_BR8;         // Установили 0.
Delay(3000);
 GPIOC->BSRR =GPIO_BSRR_BS8;         //Установили на выводе 1
Delay(7000);

SendString("AT\r\n");
Delay(200);

 while (1) {

 }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...