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

asdus

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

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

  • Посещение

Сообщения, опубликованные asdus


  1. Обязательно перепишу на DMA, как только, так сразу :)

    Для истории пишу свой код целиком, на неэффективных прерываниях и очередях :)

    Как-нибудь при случае замеряю загрузку ЦП. Работает на STM32F100RB (STM32VLDISCOVERY)

    И не забываем запустить шулдер до использования) хотя у меня работало и до включения, но не протестировано на стабильность.

    #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 );
    }

  2. Смущает вот что:

    бит TXE выставляется когда

    TXE: Transmit data register empty
    This bit is set by hardware when the content of the TDR register has been transferred into the shift register.

    Таким образом при первой записи в очередь прерывание возникнет ДВАЖДЫ, но при втором входе очередь будет пустой. Может быть не это вызывает ваш глюк, однако обратите внимание на это.

    Это нормально, обрабатывается ;)

     

    Возможно проблемы с настройкой прерываний. Неплохо было бы посмотреть как freertos сконфигурирована.
    Проблема была решена.

    Действительно, она была в настройке прерываний. Конкретно: порт FreeRTOS под STM32 требует следующей настройки:

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    Почему он не делает это сам - непонятно. После выполнения этой команды все стало работать как должно.

  3. Во первых, вы начинаете использовать queue до старта шедулера, это грубая ошибка.
    Спасибо за подсказку. В оригинальной программе такого небыло, прибил в тестовой.

     

    И на сколько мне помнится надо сбрасывать соответствующий pending bit при обработке ISR
    GetITStatus уже давно сбрасывает соответствующий ITPendingBit. На всякий случай добавил в тестовую прогу.

     

    Запустил тесты, ждем-с...

    Долго ждать не пришлось, ошибка сохранилась. К слову, с передачей, реализованной на тех-же прерываниях и очередях проблем нет, как и с передачей без использования очередей...

  4. Есть проектик, STM32F10*, FreeRTOS 7.1.0

    USART реализован на прерываниях и очередях, по примеру из FreeRTOS

    С приемом все хорошо, а вот при передаче через некоторое время работы "портятся" данные. Свиду - сдвигаются указатели на голову и хвост в очереди.

    В данный момент пройтись отладчиком возможности нет.

    Выписал код в минипрогу, ошибка повторяется. Через некоторое, рандомное время, вместо "Hello World!\n" становится, например "rlWorld!\no Wo", потом еще что-нибудь и т.д.

    #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(;;)
    {
    }
    }

  5. Если не секрет, кто производитель сего "чуда техники"?
    Фирма в Санкт-Петербурге, производство, ессно, Китай.

    Фирма крупная, имеет филиалы в разных странах, устройства тоже достаточно известные :)

     

    Извините, пропустил. К чему тогда конденсаторы?
    Не знаю.

     

    Чтобы оно просто работало, для 9600 и 100 нФ подтяжку TxD придётся сделать ~ 300 Ом. Проще, имхо, добавить неинвертирующий буфер с паш-пулл.

    Чтобы оно работало на 50 м, даже и не знаю... Линия в экране?

    У меня оно работает на 30 метров по стандартной витой паре, линии RX и TX в парах с землей.

    Производителем описаны только максимальные длины линий (30м при 0.5мм^2, 50м при 0.8мм^2).

     

    Все это неплохо у них работает. Читаю их устройства без проблем, писать в них не получается :(

  6. Ммм...

    Устройства №1 и №2 фабричные, приведены кусочки схем. Это их штатное соединение. Подключиться могу только к желтым линиям (ну и земле, питанию).

    Хочу работать с ними своим прибором. протокол отреверсил. Скорость 7800 8n1 (да да, именно такая), заявленная производителем длина линии до 50м (у этой пары устройств).

    Питание у них общее, с одного БП.

  7. собственно хочу помигать светодиодиком на stm32f100rb

    #include "stm32f10x.h"
    #include "stm32f10x_gpio.h"
    // ..........

    что делать?

    Дефайны STM32F10X_MD_VL и USE_STDPERIPH_DRIVER заданы?

    И почему-бы не "помигать" используя GPIO_SetBits(GPIOC, GPIO_Pin_8) и GPIO_ResetBits(GPIOC, GPIO_Pin_8)?

  8. Есть два устройства на PICах, общаются друг с другом по длинной линии, вот так:

    210601m.png

    В принципе все понятно. на линии держится уровень ~5V, RXD - TriState, TXD - OpenDrain с внутренней подтяжкой (читал что на PIC-ах есть такой).

    Блок питания у устройств общий (->общая земля), 5.6V для подтяжки на каждом с регулятора на стабилитроне.

     

    Пытаюсь работать с Устройством №2 вместо Устройства №1. ARM, питание 3.3V, так-же стоит регулятор на 5V для всяких нужд.

    Подключаюсь как на схеме №1, но добавив подтяжку на своем TXD (настроен на OpenDrain, но внутреннюю подтяжки нет). Ножки TXD и RXD - толерантные к 5V.

     

    Читаю приходящие данные без проблем, уровни на линии нормальные.

    Пишу данные. Уровни на линии - бардак. Пробовал разные подтяжки, от 4.7К до 270К - видно что данные в линию пишу, но с уровнями плохо (высокий уровень <5V), фронты заряда конденсатора появляются (при больших сопротивлениях подтяжки), Устройство №2 меня не понимает.

     

    Что делаю не так?

  9. Выходной ток в 3 ампера вовсе не означает, что ток через ключ будет таким же. Он при ШИМ будет всегда намного больше.

    Похоже, Вы также хотите управлять ШИМ от микроконтроллера, раз о драйвере разговор идет?

    Вы пребываете в надежде распаять какой-нибудь заветный кристалл от TI о 10 ногах и получить источник. Так не получится. "Готовая схема" - тоже ничем не поможет.

    Придется его разработать с применением многих компонентов, уметь их рассчитать, понимать хотя бы общие принципы работы импульного стабилизатора.

    Это просто не Ваша профессия, тут ничего не должно вызывать обиду. Ищите схемотехника в помощь.

    Ищу, но как-то печально...

    Есть желающие заработать? :)

  10. Вы раньше что-нибудь, кроме курсовых, разрабатывали?

    Нет таких источников, чтобы работали и от одной батарейки и от двух, а если что - и 20 вольт держали по входу. И особостабильных и протчая и протчая.... И обязательно сбоку еще МК.

    Разрабатывал, но к аналоговой технике никак отношения не имевших :)

    А по поводу пожеланий - знаете, это как в вакансиях, пишут что хочется, а берут что получится, выбирая лучшее.

    Если что - 20В по входу - такого в задачах нет, имелась ввиду какая-либо защита, если воткнут больше, если возможно :) И не обязательно на том-же драйвере, хотя у irf например видел такие... А по поводу сопряжения с МК... дык вариантов много, просто городить огород сильных не хотелось бы.

    Топология тут может быть примеряна SEPIC, допускающая выходное напряжение как выше, так и ниже входного, но лучше бакбуст. Немного сложнее по ОС, но легче для ключей и моточных.

    Драйвер который контроллер ШИМ можно взять любой, их достаточно много. А далее - считайте, рисуйте, паяйте.

    Все в одном SOIC8 c 8-битной шиной управления нет и не будет. Это аналоговая техника.

    25 ватт при 3 вольтах входного это 15-20 ампер на ключе минимум. Приготовьтесь тепло отводить..

    15-20 Ампер не интересно, я же даже про "защиту" от "выше 3А" писал...

    Buck-Boost-ы и SEPIC-и смотрел, как-то не нашел подходящих мне. Если взять ту же TI http://focus.ti.com.cn/cn/lit/sg/slvt160/slvt160.pdf то у Buck-Boost-ов выхода всего до 5.5V, а у SEPIC-ов от Vin - на понижение не работают...

    Правда это все в силу моего разумения, никогда не работавшего с аналоговой техникой :)

  11. Привет

    Возникла необходимость в хитропопом DC-DC преобразователе:

    Вход: 3.0-8.4V (1 или 2 li-ion/pol на выбор, или стационарный БП 7.5V)

    Выход: 3.3-7.4V (достаточно точный, высокостабильный, регулируемый с МК)

    Ток: 3A постоянной нагрузки

    Защита на входе: от переполюсовки легко, от малого напряжения не нужна (li-ion/pol с защитой), от большого напряжения нужна (например больше 12-21V)

    Защита на выходе: от КЗ и превышения тока, достаточно ограничением тока в 3А

    Основная проблема: требуется регулирование напряжения в "обе стороны". То есть может быть регулировка 8.4V->3.3V а может 3.0V->7.4V.

    Задача - подобрать драйвер для всего этого, максимально маленький по размеру (с учетом обвязки) и хорошим КПД, которым не шибко сложно управлять с МК. Пересмотрел уже кучу драйверов разных производителей - подходящего не нашел. Хотя наверняка пропустил.

    Подскажите, кто знает, что воткнуть. Пасибки ;)

  12. 33 нФ привел как минмально допустимое значение для случая с переключением каналов и Rлев = 10кОм. Ничто не мешает поставить и большее значение. Вопрос только в том, повлияет ли он на сигналы JTAGa (если собрать по 3-й схеме). А это зависит от выхода программатора (для SCK и TDI). Если там не окрытый коллектор (а наколько я помню, там обычный выход), то 99,99% что программатору эта емкость не помешает. Вопрос только в том, как поведет себя контроллер при запуске, когда конденсатор полностью разряжен.

    P.S. Может, для программирования в серии легче использовать SPI? А для отладочной платы использовать джампера.

    Пожалуй так и есть. Просто у меня STK500 подгорел, в плане ISP-а, остался только JTAG. А в серию, думаю, пойдет SPI + бутлоадер для клиентов :)

    fb997aa0019a.png

  13. Работоспособность 3-й схемы зависит от номиналов компонентов. Думаю, что при левом сопротивлении ~10к и конденсаторе ~33нФ она будет волне работоспособна. В крайнем случае, можно будет уменьшить частоту JTAG'a или увеличить сопротивление левого резистора. Но в последнем случае для сохранения точности нужно будет откидывать первые пару измерений после переключения канала.

    А фильтрацию помехи сети можно сделать програмным способом - усреднять значения выборок за период, кратный 20 мс. Если я не прав, пусть поправят

    При конденсаторе ~33нФ для фильтра правый резистор получается уж шибко космический... Для частоты среза в 1гц почти 5МОм...

    Заниматься постоянным мониторингом АЦП нету желания, хотя это и возможно, ибо значения АЦП нужны только по запросу клиента (сетевой девайс)...

  14. Как уже писали, JTAG - непосредственно к ногам контроллера, питание при программировании подавать на конденсатор. При этом левый по схеме резистор работает как подтяжка к питанию пина JTAG'а, а правый - как потдтяжка к питанию источника аналогового сигнала. Поэтому их сопротивления должны быть соответствующие.

    Резисторы 10кОм увеличат выходное сопротивление источника аналогового сигнала (которое по даташиту рекомендуют не более 10к). Это может повлиять на результаты измерений АЦП при single-ended mode. Особенно, если при измерении используется переключение каналов.

    Блин подтяжка совсем не в тему, делать ее специально ой как не хочется :( При том что посмотрел пару девайсов, где есть jtag и используется adc - там везде сделано по 3 схеме...

    Сигнал вялотекущий, измеряется не чаще, чем 1 раз в 30 сек, поэтому до этого планировал ставить RC фильтр на 1гц (основная помеха - 50гц).

    Но что-то шибко большие кондеры надо для этого...

    Чтоб такого сотворить...

  15. Возникла необходимость использовать встроенный АЦП, и конкретно те входы, на которых так-же подключен JTAG.

    В документике "AVR042: AVR Hardware Design Considerations" на 6 страничке есть абзац, и картинка с примерами. Не в курю как сделать. Конкретно, в какую точку подключается сам JTAG, и как, если необходимо, делать подтяжку к VCC при программировании, на каких конкретно пинах, и тд. Да и какого номинала использовать резистор, тот который после RC фильтра...

    6a18b07b1c0c.gif

  16. Это действительно сделано или только нарисовано пока?

    А что самый нижний по схеме диод тут по замыслу делает? Он же вроде коротит источник?

    И каков ток и характер нагрузки? Гальваническая развязка не нужна?

    Вообще, что желаем получить? Если минимум потерь на расчеты, то как нарисовано - погасить 96% энергии в балласте и стабилитрон. Стабилизатор тут даже слишком раскошно.

    Если минимум потерь энергии, то стандартный сетевой адаптер с ~220 на DC5 вольт. Или его схемотехнику взять за отправную точку.

    Это именно сделано, и работает. Про потери понятно, но когда-то давно было сделано на скорую руку, а сейчас вот решил доделать/переделать.

    Он одну полуволну тока отсекает (коротит на землю) - это кусок продолжения схемы, затесался...

    Нагрузка МК, питание желательно достаточно высокостабилизированное, токи мелкие. Гальваническая развязка - хорошо, но размеры очень решают.

    Исходное питание - не чистая синусоида, может быть уже выпрямленной, и импульс тока может занимать не весь период, а скажем треть...

×
×
  • Создать...