NeoMage 0 11 июня, 2012 Опубликовано 11 июня, 2012 · Жалоба STM32F100 UART1 когда уходит на прерывание - зависает. Точку останова на прерывании не ставиться (IAR 6.21). Если обработчик прерывания оставляю пустым (оставляю только сброс прерывания)- тоже виснет. Причем программа работает, а как только от компьютера отправляю байт контроллеру - он виснет, даже если функция по приему прерывания пустая. Может неправильно биты прерывания сбрасываю и он в цикл уходит? Полная программа во вложении. Помогите пожалуйста. .... инициализация .... ..... USART1->CR1 |= USART_CR1_TE; USART1->CR1 |= USART_CR1_RE; USART1->CR1 |= USART_CR1_RXNEIE; ..... Обработчик прерывания (отправляет/принемает в буфер) .... void USART1_IRQHandler(void) { if((USART1->SR & USART_SR_RXNE)) //Если прием { USART1->SR &= ~USART_SR_RXNE; //сброс флага rx1_buffer[rx1w] = USART1->DR ; // сохраняем байт в буфер if(rx1w >= (RX1_BUFFER_SIZE - 1)) // { rx1w = 0; // } else { rx1w++; // }; }; if((USART1->SR & USART_SR_TXE)) //по опустошению { USART1->SR &= ~USART_SR_TXE; //сброс флага USART1->DR = tx1_buffer[tx1r]; if(tx1r >= (TX1_BUFFER_SIZE - 1)) // { tx1r = 0; // } else { tx1r++; // }; tx1_count++; if(tx1_count == TX1_BUFFER_SIZE) USART1->CR1 &= ~USART_CR1_TXEIE; //Если все отправили - выключаем прерывание на отправку } } USART1.ZIP Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 11 июня, 2012 Опубликовано 11 июня, 2012 · Жалоба Не скажу точно по этому контроллеру, но, как правило, регистра состояния прерывания в самом начале читается в отдельную переменную В конце прерывания нужно еще делать VICVectAddr = 0; /* Acknowledge Interrupt */ но это для ARM7 NXP ну или в любом случае сбрасывать флаг прерывания. Как он сбрасывается - чтением регистра состояния или обнулять нужно конкретные биты - лезем в даташит в VIC Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NeoMage 0 11 июня, 2012 Опубликовано 11 июня, 2012 · Жалоба Написано, что флаг сбрасывается при чтении регистра. Но я его еще на всякий случай сбрасываю: USART1->SR &= ~USART_SR_RXNE; //сброс флага Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 11 июня, 2012 Опубликовано 11 июня, 2012 · Жалоба Но я его еще на всякий случай сбрасываю: USART1->SR &= ~USART_SR_RXNE; //сброс флага Интересно на какой случай? Написано, что флаг сбрасывается при чтении регистра. Так же написано такое: This clearing sequence is recommended only for multibuffer communication. P.S. Интересно что такое "multibuffer communication"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 12 июня, 2012 Опубликовано 12 июня, 2012 · Жалоба У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция. Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 12 июня, 2012 Опубликовано 12 июня, 2012 · Жалоба У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция. Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана. прочь, мухи, прочь! даешь котлеты! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ierofant 0 13 июня, 2012 Опубликовано 13 июня, 2012 (изменено) · Жалоба STM32F100 UART1 когда уходит на прерывание - зависает. Как зависает? Вываливается в Hard Fault или зацикливается в обработчике? Попробуйте считывать статус-регистр в буффер, потом уже с буфера проверять, установлены ли флаги. Вот работающий пример, проверьте, может где-то ошиблись: void init_uart() { RCC->APB2ENR|= RCC_APB2ENR_AFIOEN; // Тактирование альтернативных функций GPIO. RCC->APB2ENR|= RCC_APB2ENR_USART1EN; // Включение тактирования USART1. GPIOA->CRH |= GPIO_CRH_MODE9; // Вывод TX PA.9 - на выход. GPIOA->CRH &=~GPIO_CRH_CNF9; GPIOA->CRH |=GPIO_CRH_CNF9_1; // Альтернативный выход. USART1->CR1 |=(USART_CR1_RE | USART_CR1_TE); // Разрешить выводы RX, TX. // Скорость 9.6 kbps. USARTDIV=FSYS/(16*baud) = 24e6/(16*9600)=156.25 USART1->BRR=(156<<4); // Целая часть коэффициента деления USART1. USART1->BRR|=4; // Дробная часть*16 = 0,25*16 = 4. USART1->CR1 |=USART_CR1_UE; // Включение USART1. USART1->CR1 |=USART_CR1_RXNEIE; // Разрешить прерывания RXNE. NVIC_EnableIRQ(USART1_IRQn); // Разрешить прерывание USART1_IRQn в NVIC. NVIC_SetPriority(USART1_IRQn, 3); //Задать приоритет прерыванию } void USART1_IRQHandler (void) // Обработчик USART1. { uint16_t status = USART1->SR; if (status & USART_SR_RXNE)// Если прерывание по приёму. { .... } else if (status & USART_SR_TXE) // Если прерывание по осовобождению передатчика. { .... } USART1->SR&=~(USART_SR_TXE|USART_SR_RXNE); //очистка флагов } void begin_uart_transm() { USART1->CR1 |=USART_CR1_TXEIE; } Изменено 13 июня, 2012 пользователем ierofant Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NeoMage 0 13 июня, 2012 Опубликовано 13 июня, 2012 · Жалоба У вас как мне кажется USART1_IRQHandler - получился не обработчик, а просто функция. Для того, чтобы она стала обработчиком нужно включить в проект стандартный *.s файл с векторами прерываний, в котором и будет прописано имя USART1_IRQHandler на определенном месте.Он и точку останова не ставит у вас только потому, что компилятор оптимизирует эту процедуру, так как она не вызывается ниоткуда и ни к чему не привязана. kan35, Именно так. Спасибо. Как только добавил startup_stm32f10x_ld_vl.s в проект все заработало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 13 июня, 2012 Опубликовано 13 июня, 2012 · Жалоба kan35, Именно так. Спасибо. Как только добавил startup_stm32f10x_ld_vl.s в проект все заработало. тогда мне непонятно. Зачем подключать s-файл с объявленными именами обработчиков прерывания? разве недостаточно описать функцию с __irq и прописать ее в VIC? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться