rosso 0 1 марта, 2010 Опубликовано 1 марта, 2010 · Жалоба Здравствуйте! Работаю на плате TE-STM32F103, использую IAR 5.30, j-link и стандартную библиотеку от ST, в частности, пример из этой библиотеки по работе с UARTом через прерывания, в котором я оставил только USART1, чтобы обмениваться данными с компьютером. После запуска программы как только случается первое прерывание, программа зависает, если верить дебаггеру, то в обработчик прерывания даже и не заходит. Если писать обработку через polling, то все работает. Подскажите, пожалуйста, в чем проблема, буду очень благодарен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 1 марта, 2010 Опубликовано 1 марта, 2010 · Жалоба Текст вашей программы или проект целиком присоедините к своему сообщению. Телепатические сеансы или "пыточные" процедуры вопрошающих обычно занимают довольно много времени. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rosso 0 2 марта, 2010 Опубликовано 2 марта, 2010 (изменено) · Жалоба Основной код программы /* 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) { } } } Просто я подумал, что код почти такой же, как в примере... Видно, мне надо меньше думать Изменено 2 марта, 2010 пользователем Rosso Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 2 марта, 2010 Опубликовано 2 марта, 2010 · Жалоба А у вас случаем не C++? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rosso 0 3 марта, 2010 Опубликовано 3 марта, 2010 · Жалоба Нет, не С++, просто С. Посмотрел регистры NVIC, после инициализации ставится единица и в SETENA, и в CLRENA. Так должно быть? Сегодня попробовал запустить библиотечный пример с передачей по SPI Simplex_Inturrupt, не изменяя его совсем, ведет себя аналогично. Инициализация проходит, при первом прерывании программа виснет Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 3 марта, 2010 Опубликовано 3 марта, 2010 · Жалоба На вид криминала нет. Единственное предположение - не цепляются вектора прерываний, и программа попадает на заглушки. Давайте прицепляйте проект целиком, и озвучьте средство разработки (отладочная плата, компилятор). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rosso 0 3 марта, 2010 Опубликовано 3 марта, 2010 · Жалоба Вот проект, плата TE-STM32F103, среда разработки IAR 5.30, компилятор, видимо, ICC 5.30.0.21174. В прошлый раз, когда программа попадала на заглушки, я в дебаггере это видел, хотя это, наверно, не аргумент, это было на другой плате. USART_Interrupt.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 4 марта, 2010 Опубликовано 4 марта, 2010 · Жалоба У меня к сожалению нет IAR, так что могу судить только на глаз. Вроде всё нормально. А плата вообще работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rosso 0 4 марта, 2010 Опубликовано 4 марта, 2010 · Жалоба Плата работает. По крайней мере программы, работающие без прерываний, выполняются без ошибок. Ничего конкретного проверить не могу, так как нет доступа к плате до конца недели. Это может быть как-то связано с настройками компилятора или с загрузчиком? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gr9 0 13 марта, 2010 Опубликовано 13 марта, 2010 · Жалоба Я обычно перед выходом из прерывания добавляю команду сброса флага, который вызвал это прерывание. В данном случае это было бы USART_ClearITPendingBit(USART1, USART_IT_RXNE); В противном случае программа зациклится на прерывании. Попробуйте, может поможет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nilll 0 23 июня, 2012 Опубликовано 23 июня, 2012 · Жалоба Проблема следующем. Хочу организовать между платой 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) { } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться