|
STM32, USART на прерываниях и очередях, проблемы с передачей, Портится очередь |
|
|
|
Jan 20 2012, 14:14
|

Участник

Группа: Участник
Сообщений: 21
Регистрация: 28-04-08
Из: Раменсбург
Пользователь №: 37 126

|
Есть проектик, STM32F10*, FreeRTOS 7.1.0 USART реализован на прерываниях и очередях, по примеру из FreeRTOS С приемом все хорошо, а вот при передаче через некоторое время работы "портятся" данные. Свиду - сдвигаются указатели на голову и хвост в очереди. В данный момент пройтись отладчиком возможности нет. Выписал код в минипрогу, ошибка повторяется. Через некоторое, рандомное время, вместо "Hello World!\n" становится, например "rlWorld!\no Wo", потом еще что-нибудь и т.д. CODE #include "stm32f10x.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h"
static xQueueHandle USART1_TxQueue;
uint8_t USART1_PutChar( uint8_t cOutChar ) { uint8_t xReturn;
if( xQueueSend( USART1_TxQueue, &cOutChar, 10 ) == pdPASS ) { xReturn = pdPASS; USART_ITConfig( USART1, USART_IT_TXE, ENABLE ); } else { xReturn = pdFAIL; }
return xReturn; }
void USART1_PutString( const uint8_t * pcString ) { uint8_t *pxNext;
pxNext = ( uint8_t * ) pcString; while( *pxNext ) { USART1_PutChar( *pxNext ); pxNext++; } }
void HelloWorldTask(void *pvParameters) { for(;;) { USART1_PutString("Hello World!\n"); vTaskDelay( 1000 ); } }
void USART1_IRQHandler( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; uint8_t cChar;
if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET ) { if( xQueueReceiveFromISR( USART1_TxQueue, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) { USART_SendData( USART1, cChar ); } else { USART_ITConfig( USART1, USART_IT_TXE, DISABLE ); } } portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); }
int main(void) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure;
/* Enable USART1 GPIO clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
/* Enable UART1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
/* Configure USART1 Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 parameters 115200 8n1 noHW Tx+Rx*/ USART_InitStructure.USART_BaudRate = 115200; 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; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE);
/* Create TxQueue for USART1 */ USART1_TxQueue = xQueueCreate( 256, ( unsigned portBASE_TYPE ) sizeof( uint8_t ) );
USART1_PutString("Program started!\n"); USART1_PutString("================\n");
xTaskCreate(HelloWorldTask, "HelWor", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
vTaskStartScheduler();
for(;;) { } }
Сообщение отредактировал asdus - Jan 20 2012, 14:16
--------------------
Секс - классная штука. Как ни крути...
|
|
|
|
|
 |
Ответов
|
Jan 30 2012, 15:08
|

Участник

Группа: Участник
Сообщений: 21
Регистрация: 28-04-08
Из: Раменсбург
Пользователь №: 37 126

|
Обязательно перепишу на DMA, как только, так сразу :) Для истории пишу свой код целиком, на неэффективных прерываниях и очередях :) Как-нибудь при случае замеряю загрузку ЦП. Работает на STM32F100RB (STM32VLDISCOVERY) И не забываем запустить шулдер до использования) хотя у меня работало и до включения, но не протестировано на стабильность. CODE #include <stm32f10x.h> #include <FreeRTOS.h> #include <queue.h>
static xQueueHandle MODBUS_RxQueue; static xQueueHandle MODBUS_TxQueue;
void MODBUS_Init( void ) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure;
/* Create Rx/Tx Queues */ MODBUS_RxQueue = xQueueCreate( 256, sizeof( uint32_t ) ); MODBUS_TxQueue = xQueueCreate( 256, sizeof( uint32_t ) ); /* Enable GPIOA clock (for USART1 TX=PA9, RX=PA10) */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); /* Enable AFIO clock (for USART1 TX) */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE ); /* Enable UART1 clock */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE ); /* Select NVIC Preemption Priority Group 4 (for FreeRTOS) */ NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); /* Configure USART1 GPIO PINs (TX=PA9, RX=PA10) */ /* Configure USART1 Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init( GPIOA, &GPIO_InitStructure ); /* Configure USART1 Rx as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init( GPIOA, &GPIO_InitStructure ); /* Configure USART1 parameters 115200 8n1 noHW Tx+Rx*/ USART_InitStructure.USART_BaudRate = 115200; 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; USART_Init( USART1, &USART_InitStructure ); USART_ITConfig( USART1, USART_IT_RXNE, ENABLE ); USART_Cmd( USART1, ENABLE ); }
uint8_t MODBUS_GetChar( uint8_t *pcRxedChar ) { if( xQueueReceive( MODBUS_RxQueue, pcRxedChar, 0 ) ) { return pdTRUE; } else { return pdFALSE; } }
void MODBUS_PutString( const uint8_t * pcString ) { uint8_t *pxNext;
pxNext = ( uint8_t * ) pcString; while( *pxNext ) { MODBUS_PutChar( *pxNext ); pxNext++; } }
uint8_t MODBUS_PutChar( uint8_t cOutChar ) { uint8_t xReturn;
if( xQueueSend( MODBUS_TxQueue, &cOutChar, 10 ) == pdPASS ) { xReturn = pdPASS; USART_ITConfig( USART1, USART_IT_TXE, ENABLE ); } else { xReturn = pdFAIL; }
return xReturn; }
void USART1_IRQHandler( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; uint8_t cChar;
if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET ) { if( xQueueReceiveFromISR( MODBUS_TxQueue, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) { USART_SendData( USART1, cChar ); } else { USART_ITConfig( USART1, USART_IT_TXE, DISABLE ); } } if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET ) { cChar = USART_ReceiveData( USART1 ); xQueueSendFromISR( MODBUS_RxQueue, &cChar, &xHigherPriorityTaskWoken ); } portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); }
--------------------
Секс - классная штука. Как ни крути...
|
|
|
|
Сообщений в этой теме
asdus STM32, USART на прерываниях и очередях, проблемы с передачей Jan 20 2012, 14:14 kan35 Во первых, вы начинаете использовать queue до стар... Jan 21 2012, 15:58 asdus Цитата(kan35 @ Jan 21 2012, 19:58) Во пер... Jan 22 2012, 19:53 kan35 Смущает вот что:
бит TXE выставляется когда
Цитата... Jan 23 2012, 06:56 asdus Цитата(kan35 @ Jan 23 2012, 10:56) Смущае... Jan 24 2012, 08:04 Bass С позволения ТС, задам вопрос здесь, чтобы темы не... Jan 25 2012, 09:48 Gunner QUOTE (Bass @ Jan 25 2012, 13:48) Проблем... Jan 25 2012, 14:38 MALLOY2 Есть такая беда у FreeRTOS нельзя при создании сем... Jan 25 2012, 16:08 Bass Ага, нашел сам макрос vSemaphoreCreateBinary, в ко... Jan 25 2012, 18:11 diwil ээээ... как показывает практика - использование оч... Jan 27 2012, 07:37
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|