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

Auratos

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

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

  • Посещение

Репутация

0 Обычный

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

  • Звание
    Участник
    Участник

Посетители профиля

1 261 просмотр профиля
  1. Спасибо большое вам за помощь. Все работает :)
  2. Попробовал ваш вариант. Контроллер отвечает шустро, только ответ неверный на запрос. Вместо правильного ответа [01][03][0C][00][00][00][00][00][00][00][00][00][05][00][00][83][71] приходит [03][01][00][00][00][00][00][00][00][00][00][05][00][00][83][FD] Не подскажите, в чем может быть загвоздка?
  3. Добрый день. Есть контроллер серии PIC18. Возникла сейчас необходимость производить передачу по USART в прерывании. Раньше для этого я использовал функцию, и работало все без прерываний: void usart_Tx(void* buf,BYTE size) { BYTE i,j; UINT16 k; char* ptr = (char*)buf; TRAN; // установить признак передачи для переключения переходника TTL-RS485 PIE1bits.RCIE = 0; // запретить прерывание от приемника USART for(i = 0; i < size; i++) { TXREG1 = ptr[i]; // запись байта в буфер передатчика USART while(!PIR1bits.TXIF); // ожидание опустошения буфера for(j = 0; j < 255; j++) // временная выдержка для достижения скорости передачи k++; } REC; // установить признак приема для переключения переходника TTL-RS485 PIE1bits.RCIE = 1; // разрешить прерывание от приемника USART } Нужно именно использовать прерывания, чтобы контроллер не отвлекался надолго на передачу. Но что-то не могу найти хотя бы одного примера, как это организовывается.Все, что придумал, это char* ptr = (char*)usart_rx_buf; // количество данных для передачи void tx_str(BYTE cnt) { PIE1bits.TXIE = 1; TRAN; // установить признак передачи для переключения переходника TTL-RS485 PIE1bits.RCIE = 0; // запретить прерывание от приемника USART totalElementstoSend = cnt; sendPointer = 0; REC; // установить признак приема для переключения переходника TTL-RS485 PIE1bits.RCIE = 1; // разрешить прерывание от приемника USART } void usart_Tx_Int(void) { BYTE i,j; UINT16 k; TXREG = ptr[sendPointer]; while(!PIR1bits.TXIF); // ожидание опустошения буфера for(j = 0; j < 255; j++) // временная выдержка для достижения скорости передачи k++; sendPointer++; if (sendPointer >= totalElementstoSend) PIE1bits.TXIE = 0; PIR1bits.TXIF = 0; } Вроде все передается, но все равно как будто не то. Подскажите, пожалуйста, как это сделать лучше? Или может у кого небольшой фрагментик готового кода завалялся :))
  4. Спасибо за помощь. Завтра на работе проверю этот вариант. А по поводу тактирования от внутреннего генератора не подскажите? Как его выбрать источником и выбрать частоту, на котором он работает?
  5. Честно говоря, я и не знал, что это играет роль. Надо именно порядок поменять? TMR0H = 0xEC; TMR0L = 0xСС; Или значение предзагрузки поменять местами? TMR0H = 0xCC; TMR0L = 0xEС;
  6. Добрый день. У меня контроллер PIC18F25K22. Пытался завести таймер TMR0 с частотой прерываний 1мс. Но на деле получаю 1,31мс. И не пойму, почему так. Настройки таймера рассчитал вручную, а затем с помощью программы PIC Timer Calculator. Данные сошлись, но по факту частота не та. У меня внешний тактовый генератор 4,9152МГц с включенной PLL. От этого и отталкивался. Считал, что на CLKOUT имею 4915200Гц. Значит в 16-битном режиме для 1мс мне понадобится 4916 приращений таймера. Сделал предзагрузку 0xECCC. И получил не то, что хотел. Вот такие у меня настройки источника тактирования: #pragma config WDTEN = SWON // сторожевой таймер #pragma config WDTPS = 512 // скорость работы сторожевого таймера #pragma config FOSC = HSMP // частота тактового генератора #pragma config PLLCFG = ON #pragma config PRICLKEN = ON #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRTEN = ON //#pragma config BORV = 285 #pragma config BOREN = OFF #pragma config PBADEN = OFF #pragma config XINST = OFF И вот настройки таймера: // обработка прерывания таймера TMR0 void tmr0_int(void) { INTCONbits.TMR0IF = 0; // сброс переполнения таймера T0CONbits.TMR0ON = 0; TMR0L = 0xСС; TMR0H = 0xEC; T0CONbits.TMR0ON = 1; LED_SW; } // инициализация таймера TMR0 void tmr0_init(void) { T0CONbits.T08BIT = 0; // 16-ти разрядный таймер T0CONbits.T0CS = 0; // тактирование от осцилятора 4*Fosc/4 T0CONbits.T0SE = 0; // приращение по переднему фронту импульса T0CONbits.PSA = 1; // предделитель не используется T0CONbits.T0PS = 0; // коэф. предделителя не используется TMR0L = 0xСС; // регистр таймера в ноль TMR0H = 0xEC; INTCON2bits.TMR0IP = 1; // приоритет прерывания TMR0 - высокий INTCONbits.TMR0IE = 1; // разрешить прерывание по переполнению TMR0 T0CONbits.TMR0ON = 1; } Частоту смотрю на осциллографе по светодиоду, состояние которого меняю каждое прерывание. Схема подключения внешнего тактового генератора на фотографии. Подскажите, пожалуйста, в чем может быть загвоздка? В Fosc выбрал не тот режим? Завел еще таймер TMR1. В регистре T1CONbits в бите TMR1CS ставил и 00 и 01. После соответствующего пересчета получал все то же значение частоты. TMRxCS<1:0>: Timer1/3/5 Clock Source Select bits 11 =Reserved. Do not use. 10 =Timer1/3/5 clock source is pin or oscillator: If TxSOSCEN = 0: External clock from TxCKI pin (on the rising edge) If TxSOSCEN = 1: Crystal oscillator on SOSCI/SOSCO pins 01 =Timer1/3/5 clock source is system clock (FOSC) 00 =Timer1/3/5 clock source is instruction clock (FOSC/4) Еще подскажите, пожалуйста, как начать тактироваться от внутреннего тактового генератора. Где это настраивается? В регистре OSCCON?
  7. Добрый день. Попала ко мне в руки платка с контроллером PIC18F25K22 и проект для нее. Стоит внешний генератор на 4,9152МГц и включен PLL: #pragma config FOSC = HSMP // частота тактового генератора #pragma config PLLCFG = ON #pragma config PRICLKEN = ON #pragma config FCMEN = OFF ... Стоит задача оценить, с какой максимальной частотой можно с помощью этого контроллера передавать через RS-485 на компьютер данные (число float, 4 байта), если не брать в расчет задержки на выполнение сторонних алгоритмов (чистый проект), а сконцентрироваться только на обмене по сети. В данный момент проект сконфигурирован на скорость 9600 бод: void usart_init(void) { UINT_32 tmp; TRISCbits.TRISC6 = 0; // установить 0 вывод порта А как выход ANSELCbits.ANSC6 = 1; tmp = 4915200; // вычисление частоты USART по формуле SPBRG = Fosc/16 - 1 tmp /= 4; tmp /= 9600; tmp--; //не Fosc, а 4xFosc SPBRG1 = (BYTE)tmp; // устанавливаем частоту USART1 TXSTA1bits.SYNC = 0;// установка асинхронного режима TXSTA1bits.BRGH = 1; RCSTA1bits.SPEN = 1;// включить модуль USART1 PIR1bits.RCIF = 0; // очистить буфер приемника PIE1bits.RCIE = 1; // прерывание от приемника USART разрешено PIE1bits.TXIE = 0; // прерывание от передатчика USART запрещено IPR1bits.RCIP = 0; // приоритет прерывания от приемника USART - низкий IPR1bits.TXIP = 0; // приоритет прерывания от передатчика USART - низкий TXSTA1bits.TX9 = 0; // 8 разрядная передача RCSTA1bits.RX9 = 0; // 8 бит принятых данных RCSTA1bits.CREN = 1; // разрешить прием TXSTA1bits.TXEN = 1; // разрешить передачу } Нашел в даташите табличку со скоростями, настройками USART. Если вкратце, то на скорость влияют только 3 регистра: SYNC, BRGH и BRG16. В данном проект они сконфигурированы так: SYNC = 0, BRGH = 1, BRG16 = 0. Формально можно выставить максимальную скорость 115200 бод. Исходя из формулы V_bit = V_uart * d / (d + 1 + s + p) где: V_uart — скорость UART (например: 9600, 115200), бод; d — количество бит данных; s — количество стоповых бит; p — количество бит четности, p = 1 если бит четности присутствует, или p = 0 если бит четности отсутствует; единица в знаменателе отражает наличие стартового бита. Т.е. 1 бит на скорости 115200 бод будет передаваться в идеале со скоростью: 115200 * 8 / (8 + 1 +1 + 0) = 92160 бит/с = 11520 байт/с = 2880 float/c = 2,88 кГц. Подскажите, пожалуйста, способен ли данный контроллер работать на 115200? На сколько упадет частота с учетом задержек при передаче между байтами/внутри байта? Каким-нибудь ПО можно оценить скорость передачи?
  8. STM32F107RCT6 Настройки таймера

    Добрый день. У меня контроллер STM32F107RCT6. Настраиваю таймеры TIM1 и TIM2 для генерации частоты на выводах. TIM_TimeBaseInitTypeDef timer; TIM_OCInitTypeDef TIM_OCConfig; void TIM1_Init(uint16_t presc, uint16_t period, uint16_t repCnt) { TIM_TimeBaseInitTypeDef timer; TIM_OCInitTypeDef TIM_OCConfig; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // тактирование таймера // выход TIM1_CH1 (F1) GPIO_mInit(GPIO_Speed_50MHz, GPIO_Mode_AF_PP, GPIOA, GPIO_Pin_8); TIM_TimeBaseStructInit(&timer); // заполнение поля структуры дефолтными значениями timer.TIM_Prescaler = presc; // предделитель timer.TIM_Period = period; // период timer.TIM_RepetitionCounter = repCnt; // счетчик повторений TIM_TimeBaseInit(TIM1, &timer); // инициализация TIM1 TIM_ARRPreloadConfig(TIM1, ENABLE); TIM1->BDTR |= TIM_BDTR_MOE; // включение выхода таймера TIM1 TIM_OCStructInit(&TIM_OCConfig); TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable; TIM_OC1Init(TIM1, &TIM_OCConfig); // включение канал1 таймера TIM1 TIM_Cmd(TIM1, ENABLE); // включение таймера TIM1_CH1(F1) } TIM1_Init(7, 17999, 1); TIM2_Init(7, 17999); Шина APB1 работает на частоте 36МГц, а APB2 - на 72МГц. Причем частоту фиксирую непосредственно перед инициализацией таймеров. Из даташита на таймеры на STM32 я вижу формулу, по ней произвожу расчет выходной частоты Взять, например, таймер TIM1: 72000000 / ((7 + 1) * (17999 + 1) * (0 + 1)) = 500Гц. Но фактически на осциллографе вижу частоту 249,9Гц, то есть делиться ровно в 2 раза. Пробовал на разных частотах - результат тот же. Подскажите, пожалуйста, в чем может быть косяк? И еще одна непонятная ситуация - изменения значения RepetitionCounter не влияет на выходную частоту. Пробовал и 1, и 2, и 170 - результат один. Как работает этот RepetitionCounter?
  9. Спасибо большое. Помогло :biggrin:
  10. STM32F107RCT6 Time base generator

    Добрый день. У меня контроллер STM32F107RCT6. Хочу сделать тактовый генератор на таймере TIM1 (на 1-й канал выдавать частоту). Вроде все инициализировал (таймер, ножку PA8 для Ch1), а на ножке все равно глухо. Частота кварца 72MГц. Т.е. при текущей настройке на выходе должна быть частота 100Гц. Подскажите, пожалуйста, в чем может быть загвоздка? С контроллером серии STM32L100 у меня получалось, там просто некоторые структуры библиотечные выглядят немного иначе. А вот с этим контроллером никак int main( void) { TIM_TimeBaseInitTypeDef timer; TIM_OCInitTypeDef TIM_OCConfig; SystemCoreClockUpdate (); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2ENR_AFIOEN, ENABLE); GPIO_mInit(GPIO_Speed_10MHz, GPIO_Mode_AF_PP, GPIOA, GPIO_Pin_8); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseStructInit(&timer); timer.TIM_Prescaler = 11000; timer.TIM_Period = 65; TIM_TimeBaseInit(TIM1, &timer); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_OCStructInit(&TIM_OCConfig); TIM_OCConfig.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable; TIM_OC1Init(TIM1, &TIM_OCConfig); TIM_Cmd(TIM1, ENABLE); // Включение таймера TIM1_CH1(F1) while(1) { wdt_reset(); // сброс WDT } }
  11. Мне уже на другом форуме рассказали, что "в одном флаконе" такого нет, нужно будет делать самому. Защиту по току еще можно найти в драйверах, а вот контроля положения - нет :rolleyes: Поэтому сейчас мне интересно узнать хотя бы названия российских производителей/поставщиков с более-менее крупной линейкой контроллеров/драйверов под разные нужды
  12. Подскажите, пожалуйста, хотя бы названия нескольких производителей, желательно, российских, кто занимается производством или поставками драйверов Скажите, пожалуйста, а чем примечателен именно этот контроллер?
  13. Добрый день. Товарищи, подскажите, пожалуйста, недорогие модели (до 300-400 рублей) контроллеров шаговых двигателей или даже готовые драйвера шаговых двигателей (цена до 1000 рублей), кто уже интересовался, сталкивался или знает, где можно поискать. Параметры: вых. напряжение 5В, вых. ток до 2.5А. Желательно наличие функций считывание текущего положения двигателя, т.е. некий аналог датчика положения, чтобы после подачи питания можно было определить количество уже сделанных шагов. И защита от перегрузок в крайних положениях, когда поступает команда "Сделай шаг", а двигатель уже в крайнем положении. Желательно контроллеры более-менее популярных, проверенных и доступных производителей с большой линейкой аналогичной продукции
  14. Все верно. Создаем вычислительное устройство, настал момент его сертифицировать, где мы гарантируем 15 лет бесперебойной работы, поэтому уже через 4 года мы не сможем гарантировать указанный срок службы, т.к. 2022 + 15 = 2037 год :)
  15. И вы также используете библиотечные функции localtime и mktime? А не могли бы вы, пожалуйста, привести пример своих функций для работы со временем?
×
×
  • Создать...