Nicollo Опубликовано 21 апреля, 2017 Поделиться Опубликовано 21 апреля, 2017 Добрый вечер. Решил недавно поиграться с микроконтроллерами, ибо были в загашнике такие платы: Ппробовал погонять данные по USART. В обычном режиме - все работает нормально, но вот с прерываниями - немного не получается. Я взял пример из стандартной библиотеки, скомпилил, залил и прерывание не срабатывает. #include <stm32f10x.h> #include <misc.h> volatile char received_string[MAX_STRLEN+1]; void Delay(__IO uint32_t nCount) { while(nCount--) { } } void init_USART1(uint32_t baudrate){ GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); USART_InitStruct.USART_BaudRate = baudrate; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStruct); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART1, ENABLE); } void USART_puts(USART_TypeDef* USARTx, volatile char *s){ while(*s){ while( !(USARTx->SR & 0x00000040) ); USART_SendData(USARTx, *s); *s++; } } int main(void) { init_USART1(9600); // initialize USART1 @ 9600 baud USART_puts(USART1, "Init complete! Hello World!\r\n"); // just send a message to indicate that it works while (1){ /* * You can do whatever you want in here */ } } void USART1_IRQHandler(void){ // check if the USART1 receive interrupt flag was set if( USART_GetITStatus(USART1, USART_IT_RXNE) ){ static uint8_t cnt = 0; // this counter is used to determine the string length char t = USART1->DR; // the character from the USART1 data register is saved in t // check if the received character is not the LF character (used to determine end of string) // or the if the maximum string length has been been reached if( (t != '\n') && (cnt < MAX_STRLEN) ){ received_string[cnt] = t; cnt++; } else{ // otherwise reset the character counter and print the received string cnt = 0; USART_puts(USART1, received_string); } } } Решил упростить задачу и поморгать светодиодом: void USART2_IRQHandler(void){ USART_ClearITPendingBit(USART2, USART_IT_TC); USART_ClearITPendingBit(USART2, USART_IT_RXNE); static uint8_t isSet = SET; GPIO_WriteBit(GPIOC , GPIO_Pin_13 , isSet); isSet = !isSet; } Оно в обработчик вообще не попадает. Подскажите, может что не так делаю? Отладчика пока нету, заказал - жду. Есть FTD USB-UART преобразователи, через них прошиваю и проверяю. А еще я в основной цикл добавил постоянную отправку строки, и оно таки прерывается, когда я шлю байт с компа, но в обработчик оно, походу, не попадает. Пробовал на USART2 - такая же фигня. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Mishany Опубликовано 21 апреля, 2017 Поделиться Опубликовано 21 апреля, 2017 (изменено) помимо чтения USART1->DR еще надо и USART1->SR в конце не хватает очистки флага прерывания //очистка флага прерывания USART_ClearITPendingBit(USART1, USART_IT_RXNE); как то так стоит попробовать: void USART1_IRQHandler(void) { if(USART_GetFlagStatus(USART1, USART_IT_RXNE) == SET) { if ((USART1->SR & (USART_FLAG_NE|USART_FLAG_ORE)) == 0) { recive_UART1 = USART1->DR; } //очистка флага прерывания USART_ClearITPendingBit(USART1, USART_IT_RXNE); } } если не заработает смотреть инициализацию слепой или нету)) USART_Init(USART1, &USART_InitStructure); USART_ClearFlag(USART1,USART_FLAG_TC); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_Cmd(USART1, ENABLE); Изменено 21 апреля, 2017 пользователем Mishany 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 7 часов назад, Mishany сказал: //очистка флага прерывания USART_ClearITPendingBit(USART1, USART_IT_RXNE); Зачем? Объяснить можем? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Особенности хранения литиевых аккумуляторов и батареекПотеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 7 minutes ago, dosikus said: Зачем? Объяснить можем? Я читал где-то что неявная очистка статус регистра немного хромает, и для подстаховки рекомендуют сбрасывать бит флага прерывания вручную. 2Mishany: я так делал, не помогло Инициализация у меня есть вот такая: USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); Т.е. я хочу чтоб прерывание сработало ТОЛЬКО на приеме. И мне кажется что прерывание происходит, но в обработчик оно почему-то не попадает 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
BARS_ Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) Только что, dosikus сказал: Зачем? Открываем умный документ и смотрим. Там на чисто англицком сказано, что бит прерывания USART не сбрасывается аппаратно и его требуется сбросить программно (это, кстати, ко многим прерываниям STM относится). В противном случае при попадании в прерывание программа никогда из него не выйдет. Цитата This bit is set by hardware when the content of the RDR shift register has been transferred to the USART_DR register. An interrupt is generated if RXNEIE=1 in the USART_CR1 register. It is cleared by a read to the USART_DR register. The RXNE flag can also be cleared by writing a zero to it. Изменено 22 апреля, 2017 пользователем BARS_ 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) 6 минут назад, Nicollo сказал: Я читал где-то что неявная очистка статус регистра немного хромает, и для подстаховки рекомендуют сбрасывать бит флага прерывания вручную. Где что вы читали ? Кто вообще эту хрень выдвинул? Читайте RM , а не кухаркины статьи RXNE сбрасывается чтением SR с последующим чтением DR . Причем чтение SR происходит при проверке флага. И не надо лепить горбатого - все проверенно и работает BARS_, ту да же - читать RM . Изменено 22 апреля, 2017 пользователем dosikus 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
BARS_ Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 Только что, dosikus сказал: RXNE сбрасывается чтением SR с последующим чтением DR . Тогда читайте даташит ВНИМАТЕЛЬНО. Выше я привел абзац, где черным по белому написано, что RXNE очищается записью нуля в него. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 1 minute ago, BARS_ said: Тогда читайте даташит ВНИМАТЕЛЬНО. Выше я привел абзац, где черным по белому написано, что RXNE очищается записью нуля в него. Тут и вы и он равы Quote It is cleared by a read to the USART_DR register. The RXNE flag can also be cleared by writing a zero to it. Он сам должен сбрасываться, после прочтения USART_DR, ну или также можно вручную сбросить. В любом случае, мою проблему это не решает. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) BARS_, Читаем внимательно - то что нужно выделил Цитата Bit 5 RXNE: Read data register not empty This bit is set by hardware when the content of the RDR shift register has been transferred to the USART_DR register. An interrupt is generated if RXNEIE=1 in the USART_CR1 register.It is cleared by a read to the USART_DR register. The RXNE flag can also be cleared by writing a zero to it. This clearing sequence is recommended only for multibuffer communication. Да для сброса RXNE не надо читать SR , но сбрасывается он чтением DR а также может быть сброшен записью 0 .BARS_, я удивлен тобой , разве можно читать документацию частями???? Nicollo, ваша проблема решается элементарно - выкашивается на SPL и все прекрасно работает. #define USARTCLK 72000000UL #define BAUDRATE 115200UL void USART1_IRQHandler (void) { if(USART1->SR & USART_SR_RXNE) { UsartBuf =USART1->DR; } } void UsartInit(void) { RCC->APB2ENR |=RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; GPIOA->CRH &=~ (GPIO_CRH_CNF10 |GPIO_CRH_CNF9|GPIO_CRH_MODE10); GPIOA->CRH |= GPIO_CRH_CNF10_0 |GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9; USART1->CR1 |= USART_CR1_TE |USART_CR1_RE |USART_CR1_RXNEIE; USART1->BRR =(USARTCLK+BAUDRATE/2)/BAUDRATE; USART1->CR1 |=USART_CR1_UE; NVIC_SetPriority(USART1_IRQn,15); NVIC_EnableIRQ(USART1_IRQn); } void USART_write (char data) { while(!(USART1->SR & USART_SR_TXE)); USART1->DR=data; } void USART_WR_String(const char *s) { int i = 0; while (s [i] != 0) { USART_write (s[i++]); } } Изменено 22 апреля, 2017 пользователем dosikus 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 Причем сброс флага записью 0 рекомендован только при multibuffer communication, а сие доступно только при работе с DMA . 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 23 minutes ago, dosikus said: Nicollo, ваша проблема решается элементарно - выкашивается на SPL и все прекрасно работает. void init_USART1(uint32_t baudrate){ RCC_ClocksTypeDef RCC_ClocksStatus; RCC_GetClocksFreq(&RCC_ClocksStatus); RCC->APB2ENR |=RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN; GPIOA->CRH &=~ (GPIO_CRH_CNF10 |GPIO_CRH_CNF9|GPIO_CRH_MODE10); GPIOA->CRH |= GPIO_CRH_CNF10_0 |GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9; USART1->CR1 |= USART_CR1_TE |USART_CR1_RE |USART_CR1_RXNEIE; USART1->BRR =(RCC_ClocksStatus.PCLK2_Frequency+baudrate/2)/baudrate; USART1->CR1 |=USART_CR1_UE; NVIC_SetPriority(USART1_IRQn,15); NVIC_EnableIRQ(USART1_IRQn); } void USART_write (char data) { while(!(USART1->SR & USART_SR_TXE)); USART1->DR=data; } void USART_WR_String(const char *s) { int i = 0; while (s [i] != 0) { USART_write (s[i++]); } } int main(void) { init_USART1(9600); // initialize USART1 @ 9600 baud RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC , &GPIO_InitStructure); GPIO_WriteBit(GPIOC , GPIO_Pin_13 , RESET); USART_WR_String("Init complete! Hello World!\r\n"); // just send a message to indicate that it works while (1){ /* * You can do whatever you want in here */ } } // this is the interrupt request handler (IRQ) for ALL USART1 interrupts void USART1_IRQHandler(void) { if(USART1->SR & USART_SR_RXNE) { char recive_UART1 = USART1->DR; USART_write(recive_UART1); } } Не интераптит 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Mishany Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 у меня и без выкашивания SPL все прекрасно работает 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 void USART1_IRQHandler(void) { static uint8_t isSet = SET; GPIO_WriteBit(GPIOC , GPIO_Pin_13 , isSet); isSet = !isSet; if(USART1->SR & USART_SR_RXNE) { char recive_UART1 = USART1->DR; USART_write(recive_UART1); } } Сделал даже так, помограть диодом - оно в обработчик даже не заходит 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) 14 минуты назад, Nicollo сказал: Не интераптит А к чему ваши правки ? Подсказываю метод проверки : Создаем проект с моим и неправленным кодом , тактовая чипа должна быть 72МГц если тактовая иная правим здесь #define USARTCLK 72000000UL Подсоединяем через адаптер UART -USB к ББ и добиваемся устойчивого приема на стороне ББ отправляемых нами строк . И только потом пробуем отправить с ББ и брякнуться в прерывании. Да, сперва проверяем адаптер UART -USB замкнув RX и TX адаптера( без подсоединения отлаживаемой платы) и проверяя эхо в терминальной программе. 14 минуты назад, Mishany сказал: у меня и без выкашивания SPL все прекрасно работает А у нас в квартире газ... Изменено 22 апреля, 2017 пользователем dosikus 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 8 minutes ago, dosikus said: Подсоединяем через адаптер UART -USB к ББ и добиваемся устойчивого приема на стороне ББ отправляемых нами строк . И только потом пробуем отправить с ББ и брякнуться в прерывании... Подсоединил, сделал как вы написали, на компе строку получил. прерывание не сработало 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) Сперва Цитата Да, сперва проверяем адаптер UART -USB замкнув RX и TX адаптера( без подсоединения отлаживаемой платы) и проверяя эхо в терминальной программе. Кстати какой адаптер и какая терминальная программа? И здесь крайне желательно наличие лог. анализатора - сокращает подобные танцы с бубном до минимума... Изменено 22 апреля, 2017 пользователем dosikus 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 4 minutes ago, dosikus said: Кстати какой адаптер и какая терминальная программа? Адаптер: FT232RL. PUTTY RX и TX работают. Прием-передачу делал без прерываний в основном цикле - работало без проблем. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 Вы проверили эхо? У меня так же все работает и с прерываниями и с DMA , так что ваша реплика -ниАчем ... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 2 minutes ago, dosikus said: Вы проверили эхо? У меня так же все работает и с прерываниями и с DMA , так что ваша реплика -ниАчем ... Работает эхо, и адаптеры я менял. Оно просто не входит в обработчик, прерывание случается. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) 4 минуты назад, Nicollo сказал: Оно просто не входит в обработчик, прерывание случается. Что сие означает? Как вы это проверяете? Что за IDE? Например Keil - запускаете дебаг , ставите бряк на строку if(USART1->SR & USART_SR_RXNE) Запускаете процесс, жмете кнопку на клаве когда окно putty в фокусе - должно сработать прерывание. Изменено 22 апреля, 2017 пользователем dosikus 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nicollo Опубликовано 22 апреля, 2017 Автор Поделиться Опубликовано 22 апреля, 2017 (изменено) я думаю, я нашел причину. Я использую OpenSTM32 IDE Оно, при создании проекта, само подгружает SPL так вот, там есть файлик: sturtup_stm32.s насколько я понял в нем мапятся прерывания с обработчиками, и он не проинициализирован до конца g_pfnVectors: .word _estack .word Reset_Handler .word NMI_Handler .word HardFault_Handler .word MemManage_Handler .word BusFault_Handler .word UsageFault_Handler .word SVC_Handler .word DebugMon_Handler .word PendSV_Handler .word SysTick_Handler Я скачал библиотеку с сайта и посмотрел в этот файлик, и он немного отличается. Сейчас попытаюсь запустить проект с новой либой. Added: Да, все верно, подменил файл, все заработало. Спасибо всем. Изменено 22 апреля, 2017 пользователем Nicollo 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) я обычно предпочитаю в обработчик писать только это void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); } а остальное уже делать в колбэке. Хотя по сути это одно и то же, но зато вероятность ошибиться меньше. Потому как HAL_UART_IRQHandler все флаги сам позсбрасывает там где надо и вызовет нужный колбэк void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { xQueueSendToBackFromISR( displayQueueHandle, &UART1_rxBuffer, 0 ); } } Изменено 22 апреля, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) Здесь не хватало скорости в прерывание из-за SPL http://www.microchip.su/showpost.php?p=231953&postcount=162 Ну а тем кто пользует калокуб можно только посочувствовать , эта гадость из любого чипа сделает тормоз... Изменено 22 апреля, 2017 пользователем dosikus -1 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 (изменено) Если у вас руки из жопы кодят, то куб то тут при чем? STM1_WIFI_TEST.ZIP Изменено 22 апреля, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dosikus Опубликовано 22 апреля, 2017 Поделиться Опубликовано 22 апреля, 2017 Во первых сперва почитай кого ты в говнокодерстве обвиняешь, а во вторых причем здесь бездумнонатыканнаяхрень в калокубе???? -2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.