STM32 UART interrupt

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Родился
Сообщения: 11
Зарегистрирован: Сб янв 19, 2013 12:08:27

Сообщение hovercraft »

Здравствуйте. вот сижу полдня не могу понять почему не работают прерывания в uart. микросхема stm32f103rbt6.
хочу сделать прерывания на получение данных. при получении и возникновении прерывания светодиод должен гаснуть.

Код: Выделить всё

#include "stm32f10x.h"
#include "stm32f10x_conf.h"
//Структуры для инициализации GPIOA и USART1
GPIO_InitTypeDef    GPIO_InitStruct;
USART_InitTypeDef    USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef  NVIC_InitStructure;

void Init(void); //Объявление функции инициализации периферии

unsigned char tmp;


void USART1_IRQHandler(void)
{
  GPIO_ResetBits(GPIOC,GPIO_Pin_9); //выключаем светодиод но это событие не наступает
 

  //если причина прерывания окончание приема
  if(USART_GetITStatus(USART1, USART_IT_RXNE))//(USART1->SR & USART_SR_RXNE)!=0)
  {
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    tmp = USART1->DR;                   //прочитать принятый байт
                                   //что-то делаем
  }
 
  //если причина прерывания  окончание передачи
  if( USART_GetITStatus(USART1, USART_IT_TXE))//(USART1->SR & USART_SR_TC)!=0)
  {
		USART_ClearITPendingBit(USART1, USART_IT_TXE);
    
                                   //что-то делаем
  }
}

int main()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	
  Init(); //Вызов функции инициализации периферии
  
  
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
	
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);// прерывание на пришедшие данные в буфер;
//  USART_ITConfig(USART1, USART_IT_TXE, ENABLE); вот здесь стимулятор спотыкается из-за assert
	
	NVIC_EnableIRQ (USART1_IRQn);           //разрешить прерывания от USART1 
	
	GPIO_SetBits(GPIOC,GPIO_Pin_9); //включаем светодиод
	while(1)
  {

		;
  }
}



//Функция инициализации периферии
void Init()
{
  //Включаем тактирование GPIOA, USART1 и альтернативных функций AFIO
  RCC_APB2PeriphClockCmd((RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO), ENABLE);

  //Инициализация вывода PA9 - USART1_Tx
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //Настройки вывода PA9
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //Скорость порта максимальная
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //Режим альтернативной функции, выход Push-Pull
  GPIO_Init(GPIOA, &GPIO_InitStruct); //Заданные настройки сохраняем в регистрах GPIOА

  //Инициализация вывода PA10 - USART1_Rx
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //Настройки вывода PA10
  GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING; //Input floating
  GPIO_Init(GPIOA, &GPIO_InitStruct); //Заданные настройки сохраняем в регистрах GPIOА

  //Инициализация USART1
  USART_InitStruct.USART_BaudRate = 9600; //Скорость обмена 9600 бод
  USART_InitStruct.USART_WordLength = USART_WordLength_8b; //Длина слова 8 бит
  USART_InitStruct.USART_StopBits = USART_StopBits_1; //1 стоп-бит
  USART_InitStruct.USART_Parity = USART_Parity_No ; //Без проверки четности
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Без аппаратного контроля
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Включен передатчик и приемник USART1
  USART_Init(USART1, &USART_InitStruct); //Заданные настройки сохраняем в регистрах USART1

  USART_Cmd(USART1, ENABLE); //Включаем USART1
}
прерывание не срабатывает когда отправляю данные с компьютера
Реклама
Нашел транзистор. Понюхал.
Сообщения: 190
Зарегистрирован: Пт сен 21, 2007 17:53:23
Откуда: Зарайск

Сообщение mrFox »

hovercraft писал(а):не могу понять почему не работают прерывания в uart.
внешне вроде нормально, единственная мысль проверить настройки терминала
если не поможет - внизу рабочий код, правда под stm32f100, но и на 103 должен работать
а прерывание на пустой буфер лучше включать когда есть данные на отправку, иначе прерывание будет вызываться постоянно

Код: Выделить всё

// port_mode const
#define GPIO_Mode_IN        0
#define GPIO_Mode_OUT_10Mhz 1
#define GPIO_Mode_OUT_2Mhz  2
#define GPIO_Mode_OUT_50Mhz 3
// port_cnf digital mode
#define GPIO_Cnf_PP     0
#define GPIO_Cnf_OK     1
#define GPIO_Cnf_DEV_PP 2
#define GPIO_Cnf_DEV_OK 3
// port_cnf analog mode
#define GPIO_Cnf_ADC    0
#define GPIO_Cnf_noPU   1
#define GPIO_Cnf_PU     2

#define _GPIO_DEF2MASK_H(port,port_pin_no,port_mode,port_cnf) \
		( (port_mode|(port_cnf<<2)) << ((port_pin_no-8)*4) )
#define GPIO_DEF2MASK_H(port_def) _GPIO_DEF2MASK_H(port_def)

#define USART1_TX_PIN A, 9,GPIO_Mode_OUT_50Mhz,GPIO_Cnf_DEV_PP
#define USART1_RX_PIN A,10,GPIO_Mode_IN,GPIO_Cnf_noPU

char usart_buff_rx[20];
volatile uint8_t usart_buff_rx_pos = 0;
char usart_buff_tx[20];
volatile uint8_t usart_buff_tx_pos = 0;
volatile uint8_t usart_buff_txe_pos = 0;

#define baudrate 115200
void init_usart(void)
{
  RCC->APB2ENR |= RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA;
  GPIOA->CRH |= GPIO_DEF2MASK_H(USART1_TX_PIN) | GPIO_DEF2MASK_H(USART1_RX_PIN);
  USART1->BRR = (cpu_clock + baudrate/2 ) / baudrate;
//  USART1->CR2 = 0; // USART_CR2_STOP_X  00 - 1bit
//  USART1->CR3 = 0;
  USART1->CR1 |= USART_CR1_RXNEIE; // прерывание по приему данных
  USART1->CR1 |= USART_CR1_UE; // USART Enable
  USART1->CR1 |= USART_CR1_TE|USART_CR1_RE;
  NVIC_EnableIRQ (USART1_IRQn);           //разрешить прерывания от USART1
}
void usart_send_buff(char *str)
{
  if( 0 != *str && usart_buff_txe_pos < 20 )
  {
    for( ; 0 != *str && usart_buff_txe_pos < 20; str++ ) usart_buff_tx[usart_buff_txe_pos++] = *str;
    USART1->CR1 |= USART_CR1_TXEIE;
  }
}
void USART1_IRQHandler(void)
{
  unsigned char tmp; char st[2];
  //если причина прерывания окончание приема
  if((USART1->SR & USART_SR_RXNE)!=0)
  {
    tmp = USART1->DR;                   //прочитать принятый байт
    if('\n' == USART1->DR || '\r' == USART1->DR)
    {
      usart_buff_rx[usart_buff_rx_pos] = 0;
      usart_send_buff("\r\n");
      if( 0 == strcmp("ls",usart_buff_rx) )
        usart_send_buff("usart\r\n");
      usart_buff_rx_pos = 0;
    } else {
      st[0] = usart_buff_rx[usart_buff_rx_pos++] = tmp;
      if( usart_buff_rx_pos >= 20 ) usart_buff_rx_pos = 19;
      st[1] = 0;
      usart_send_buff( st );
    }
  }
  //если причина прерывания  окончание передачи
  if((USART1->SR & USART_SR_TXE)!=0)
  {
    USART1->SR &= ~USART_SR_TXE;         //очистить флаг
    if( usart_buff_tx_pos < usart_buff_txe_pos )
      USART1->DR = usart_buff_tx[usart_buff_tx_pos++];
    else {
      USART1->CR1 &= ~USART_CR1_TXEIE;
      usart_buff_txe_pos = 0;
      usart_buff_tx_pos = 0;
    }
  }
  //если причина прерывания  окончание передачи
  if((USART1->SR & USART_SR_TC)!=0)
  {
    USART1->SR &= ~USART_SR_TC;         //очистить флаг
  }
  return;
}

int main()
{
  RCC->APB2ENR |= RCC_APB2Periph_AFIO;
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

  RCC->APB2ENR |= RCC_APB2Periph_GPIOB;
  RCC->APB2ENR |= RCC_APB2Periph_GPIOA;

  init_usart();
  while(1)  ;
}
Реклама
Ответить

Вернуться в «ARM»