Перейти к содержанию
    

ur4lvn

Участник*
  • Постов

    52
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о ur4lvn

  • Звание
    Участник
    Участник
  • День рождения 10.09.1958

Контакты

  • Сайт
    Array
  • ICQ
    Array

Информация

  • Город
    Array
  1. Да,сорри. Буферы по 2К // Буфер приема сырых данных: uint8_t modem_buffer[MODEM_RX_BUFLEN]; __IO uint8_t* modem_buffer_head; __IO uint8_t* modem_buffer_tail; // Буфер передачи uint8_t modem_tx_buffer[MODEM_TX_BUFLEN]; __IO uint8_t* modem_tx_head; __IO uint8_t* modem_tx_tail; // Буфер приема сырых данных: uint8_t pilot_buffer[PILOT_RX_BUFLEN]; __IO uint8_t* pilot_buffer_head; __IO uint8_t* pilot_buffer_tail; // Буфер передачи uint8_t pilot_tx_buffer[PILOT_TX_BUFLEN]; __IO uint8_t* pilot_tx_head; __IO uint8_t* pilot_tx_tail; Инициализация портов HAL_UART_MspInit( &modem_port ); modem_port.Instance = USART2; modem_port.Init.BaudRate = MODEM_BAUDRATE; // 57600 modem_port.Init.WordLength = UART_WORDLENGTH_8B; modem_port.Init.StopBits = UART_STOPBITS_1; modem_port.Init.Parity = UART_PARITY_NONE; modem_port.Init.Mode = UART_MODE_TX_RX; modem_port.Init.HwFlowCtl = UART_HWCONTROL_NONE; modem_port.Init.OverSampling = UART_OVERSAMPLING_16; if( HAL_UART_Init( &modem_port ) != HAL_OK ) ErrorHandler(); HAL_NVIC_SetPriority( USART2_IRQn, 15, 0 ); HAL_NVIC_EnableIRQ( USART2_IRQn); HAL_UART_MspInit( &ptm_port ); ptm_port.Instance = USART6; ptm_port.Init.BaudRate = AP_TM1_BAUDRATE; //1M5 ptm_port.Init.WordLength = UART_WORDLENGTH_8B; ptm_port.Init.StopBits = UART_STOPBITS_1; ptm_port.Init.Parity = UART_PARITY_NONE; ptm_port.Init.Mode = UART_MODE_TX_RX; ptm_port.Init.HwFlowCtl = UART_HWCONTROL_NONE; ptm_port.Init.OverSampling = UART_OVERSAMPLING_16; if( HAL_UART_Init( &ptm_port ) != HAL_OK ) ErrorHandler(); HAL_NVIC_SetPriority( USART6_IRQn, 15, 0 ); HAL_NVIC_EnableIRQ( USART6_IRQn); Создание задач и очередей #define MAX_PENDING_PACKETS (32) #define configMINIMAL_STACK_SIZE ((portBASE_TYPE) 128) xTaskCreate ( pilotGateKeeper, "p gate", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, pilotGateKeeperHandle ); xTaskCreate ( modemGateKeeper, "modem gate", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, modemGateKeeperHandle ); pilotQueue = xQueueCreate ( MAX_PENDING_PACKETS, sizeof(packet_t) ); modemQueue = xQueueCreate ( MAX_PENDING_PACKETS, sizeof(packet_t) ); Гейткиперы почти одинаковы,вот один из них /* * Получив сообщение из очереди,берем оттуда адрес начала пакета в сыром буфере, * его длину, и дописываем в кольцевой буфер передачи порта.Оттуда он будет выдан в * прерывании передачи **/ void modemGateKeeper ( void* pvParameters ) { uint16_t len; uint16_t idx; uint8_t* src; packet_t packet; // Инициализация буферов modem_buffer_head = modem_buffer_tail = (uint8_t*)&modem_buffer; modem_tx_head = modem_tx_tail = (uint8_t*)&modem_tx_buffer; // Разрешаем прерывания приема символов,передатчик уже включен при инициализации порта modem_port.Instance->CR1 |= USART_CR1_RXNEIE; while(1) { xQueueReceive ( modemQueue, &packet, portMAX_DELAY ); { //SEGGER_SYSVIEW_PrintfHost("%d",packet.origin); //SEGGER_SYSVIEW_PrintfHost("MQ = %d",uxQueueMessagesWaiting(modemQueue) ); len = packet.len; src = packet.head; if(packet.origin == PILOT_CHANNEL ) { for(idx = 0; idx < len;idx++) { *modem_tx_tail = *src; modem_tx_tail++; if(modem_tx_tail == (uint8_t*)&modem_tx_buffer + MODEM_TX_BUFLEN) modem_tx_tail = (uint8_t*)&modem_tx_buffer; src++; if(src == (uint8_t*)&pilot_buffer + PILOT_RX_BUFLEN ) src = (uint8_t*)&pilot_buffer; } // разрешаем передачу modem_port.Instance->CR1 |= USART_CR1_TXEIE; } } } Обработчики прерываний - то же /* * Обработчик прерываний приема/передачи символов порта модема. ***/ void USART2_IRQHandler(void) { uint8_t current_symbol; packet_t packet; uint8_t* src; uint8_t* last_symbol; uint16_t idx; uint32_t state = modem_port.Instance->SR; portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; // Передача символа по указателю на голову буфера if( ( state & USART_SR_TXE ) && (modem_port.Instance->CR1 & USART_CR1_TXEIE) ) { modem_port.Instance->DR = *modem_tx_head++; if(modem_tx_head == (uint8_t*)&modem_tx_buffer + MODEM_TX_BUFLEN ) modem_tx_head = (uint8_t*)&modem_tx_buffer; if(modem_tx_head == modem_tx_tail) { modem_port.Instance->CR1 &= ~USART_CR1_TXEIE; SEGGER_SYSVIEW_PrintfHost("Mdone"); } } /* Указатели на голову и хвост приемника инициализированы на начало буфера при * старте таска модема **/ // Прием символа if( state & USART_SR_RXNE ) { // Проверка ошибок if( !( state & ( USART_SR_PE | USART_SR_ORE | USART_SR_NE | USART_SR_FE ) ) ) { GREEN_LED_TOGGLE; // принятый символ пишем в буфер *modem_buffer_tail = modem_port.Instance->DR; // и отдаем его на анализ if(parse_char(MODEM_CHANNEL, *modem_buffer_tail, &message[MODEM_CHANNEL],&status[MODEM_CHANNEL]) ) { // собран пакет,отдадим его длину в месседж packet.len = (uint16_t)message[MODEM_CHANNEL].len + MAVLINK_NUM_NON_PAYLOAD_BYTES; packet.msgid = message[MODEM_CHANNEL].msgid; packet.origin = MODEM_CHANNEL; // запомним указатель на последний символ пакета // и продвинем указатель хвоста на свободное место last_symbol = modem_buffer_tail++; if(modem_buffer_tail == (uint8_t*)&modem_buffer + MODEM_RX_BUFLEN) modem_buffer_tail = (uint8_t*)&modem_buffer; // найдем указатель на голову packet.head = ( (last_symbol > modem_buffer_head) ? (last_symbol - packet.len + 1 ) : (last_symbol + MODEM_RX_BUFLEN - packet.len + 1 ) ); packet.tail = last_symbol; modem_buffer_head = modem_buffer_tail; #ifdef USE_PILOT xQueueSendToBackFromISR(pilotQueue,&packet,&xHigherPriorityTaskWoken); #endif } // пакет еще не собран,подготовим место для следующего символа modem_buffer_tail++; if(modem_buffer_tail == (uint8_t*)&modem_buffer + MODEM_RX_BUFLEN) modem_buffer_tail = (uint8_t*)&modem_buffer; } else { char dummy = (char)modem_port.Instance->DR; } } if(xHigherPriorityTaskWoken) portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } В мейне создаются таски и очереди,затем стартует шедулер. Порт принимает данные,парсит их и отдает гейткиперу другого порта для передачи. Другой порт делает то же самое,но в другом направлении,пакеты мелкие,2К буфера им с головой хватает,равно как и 32 пакета в очереди Забыл добавить: использую Eclipse Kepler + arm-none-eabi_5.4_2016q3 + FreeRTOS 9.0.0
  2. Здравствуйте,All! Прошу помочь в разрешении следующей проблемы: нужно сопрячь 2 устройства, имеющих скорости по компорту отличающуюся в 30 раз (1М5 и 56К) тип информации - пакеты,разной длины,могут рваться на пол-дороги и приходить по 2 и более в пачке. Они имеют известный хидер, я их парсю без проблем на лету в обработчике прерывания,благо скорострельности камня хватает. Все это крутится под FreeRTOS на stm32f415. В обработчике прерывания кладу символ в кольцевой буфер и отдаю его парсеру(инлайн в обработчике). Если парсер собрал пакет - отдаю указатель на начало пакета и его длину через очередь гейткиперу сопряженного порта. Гейт копирует пакет в свой буфер передачи и разрешает передачу по порту. Все прекрасно работает до неопределенного момента - может зависнуть вся система,а может тупо перейти в вызовы задач каждую миллисекунду. Неопределенный момент может возникнуть как и через 10 сек после старта , так и через несколько часов. Ход процесса я смотрю с помощью SEGGER SYSVIEW,очень полезная вещь. Буду рад,если кто либо поможет мне разобраться,где же порылась собака. WBR, Sergey
  3. Сорри,недопонял :-( В этом случае правильнее всего установить фильтр в рабочую схему,подключить ачехометр(у вас есть 48-й) и подбирать сопротивление нагрузки до получения требуемых параметров фильтра.
  4. Наверное,все-же посмотрев в даташит на фильтр:http://www.kds.info/data/pdf/090E.pdf 1300 Ом || 1,5 пФ
  5. Если вы хотите работать с анонимными битовыми полями,попробуйте вот это: // в хидере,например, flags.h,делаем объявление __no_init volatile union { unsigned char flags; struct { unsigned char flag_wait :1; unsigned char flag_ESC :1; unsigned char flag_in :1; }; }@<здесь пропишите адрес ОЗУ,где будет храниться этот юнион,например,начальный адрес свободного ОЗУ,по вкусу>; Далее инклудите этот хидер в модули,где есть обращение к нужным флажкам,и спокойно работаете с ними,например: if(flag_wait) flag_ESC = 0; else flag_in = 1; Компилятор создаст в ОЗУ переменную _A_flags и будет дергать биты командами установки/сброса конкретного бита. Многократное объявление переменной в разных программных модулях(#include flags.h) здесь до лампады, как-бы гуру-супермодераторы не возмущались по этому поводу ;-)
  6. Волновое сопротивление - это параметр линии передачи,а характеристическое сопротивление - параметр колебательной системы,в данном случае,резонатора. Математически они описываются одинаково, sqrt(L/C),только в случае линии - это погонные емкость и индуктивность.
  7. Мы тоже на нее "наткнулись",на Д48-06-01А. Один сдох через полчаса, разлетелся один из резисторов, второй не запустился следующим утром. Вскрытие показало холодную пайку перемычки из медного нелуженого провода.
  8. Вот здесь http://www.audioworld.ru/FAQ/Power/diod_01.html лежит статья о "вреде диодов", правда,для трансформаторного БП
  9. Какой-же все таки сигнал вы гоните по этому кабелю? А то получается какая-то "оптимизация неопределенности"...
  10. Нет,вы не тормозите,в самом начале вы писали: Если у вас цифровой сигнал - то сопротивление провода ему,ИМХО до лампочки,если оно,конечно не возрастет до такой величины,что приемник не распознает сигнал.Если в кабеле есть лишняя четверка - сделайте шлейф на удаленной стороне, запустите в этот канал псевдослучайную последовательность и меряйте к-т ошибок за период времени,который посчитаете нужным.Потом определите себе пороговый уровень к-та ошибок, который зажжет "красную лампочку"... Это всего-лишь MHO :-)
  11. А если использовать генератор ПСП и вырабатывать сигнал аварии при превышении установленного порога за период накопления?
  12. А что,если повыбрасывать все обработчики прерываний и переписать tx_uart0() наподобие примера со стр. 172 из даташита на контроллер?
  13. IAR для Z80 zilog

    Аппаратного нет,есть симулятор Z80 от Avocet под DOS.
  14. NonLinearDistortion, тобишь нелинейные искажения.
×
×
  • Создать...