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

Auratos

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

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

  • Посещение

Весь контент Auratos


  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? А не могли бы вы, пожалуйста, привести пример своих функций для работы со временем?
  16. Можно, пожалуйста, поподробнее? Просто я пользуюсь библиотечной функцией при установке времени и даты void Set_Time(struct tm *t) { uint32_t CounterValue = (uint32_t)mktime(t); save_Time(CounterValue; } void save_Time(uint32_t tmr) { RTC_WaitForLastTask(); RTC_SetCounter(tmr); RTC_WaitForLastTask(); } Так вот, функция mktime не воспринимает дату позже февраля 2036 года (найдено опытным путем вплоть до минуты и секунды), т.к. при инкрементации новой секунды происходит переполнение 32-битного CounterValue. Или я неправильно Вас понял? Как выставить дату больше указанной?
  17. Принцип работы RTC в STM32F107

    Добрый день. Имеется на руках контроллер серии STM32F107xx. Пользуюсь активно таймером реального времени. И вот, собственно, возник вопрос: а какой у этого таймера диапазон измерения времени? Т.к. там 32-битный секундный счетчик, то максимум он сможет отсчитать ~136 лет. Отсчет начинается, как я понял, с 1900 года, т.е. до 2036 года. А что будет после его переполнения, т.е. после 2036 года? Можно ли самому подвинуть точку отсчета? Или там совсем все устроено по-другому? Объясните, пожалуйста
  18. Добрый день. Не нашел отдельной ветки для STM-контроллеров, поэтому пишу сюда. Имеется контроллер STM32F107RCT6. Задействовал у него модуль USB и взял с сайта ST последнюю версию библиотеки и драйвера USB (STM32_USB_OTG_Driver v2.2.0). На плате также имеется GSM-модуль фирмы SIMCOM. Спаяли две платы с данными контроллерами. Одна работает, вторая "болеет". Проблема в том, что если не вставлена SIM-карта, то USB модуль работает отлично. Но со вставленной SIM-картой и после прохождения этапа регистрации в сети перестает работать обмен данными через USB: принимать данные - принимает, но обратно не передает. Попробовали сначала перепаять контроллер и просмотреть линии, ведущие к USB - не помогло. Стал теперь копаться в драйвере. В рабочей версии платы при попытке передать данные в USB порт в функции USBD_OTG_ISR_Handler дважды генерируется некое прерывание, которое драйвер относит к группе inepint uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintr_status; uint32_t retval = 0; if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */ { gintr_status.d32 = USB_OTG_ReadCoreItr(pdev); ... if (gintr_status.b.inepint) { retval |= DCD_HandleInEP_ISR(pdev); } ... } return retval; } При обнаружении данного прерывания вызывается функция DCD_HandleInEP_ISR static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_DIEPINTn_TypeDef diepint; uint32_t ep_intr; uint32_t epnum = 0; uint32_t fifoemptymsk; diepint.d32 = 0; ep_intr = USB_OTG_ReadDevAllInEPItr(pdev); while ( ep_intr ) { if ((ep_intr & 0x1) == 0x01) /* In ITR */ { diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */ if ( diepint.b.xfercompl ) { fifoemptymsk = 0x1 << epnum; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); CLEAR_IN_EP_INTR(epnum, xfercompl); /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(pdev , epnum); if (pdev->cfg.dma_enable == 1) { if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN)) { /* prepare to rx more setup packets */ USB_OTG_EP0_OutStart(pdev); } } } if ( diepint.b.timeout ) { CLEAR_IN_EP_INTR(epnum, timeout); } if (diepint.b.intktxfemp) { CLEAR_IN_EP_INTR(epnum, intktxfemp); } if (diepint.b.inepnakeff) { CLEAR_IN_EP_INTR(epnum, inepnakeff); } if ( diepint.b.epdisabled ) { CLEAR_IN_EP_INTR(epnum, epdisabled); } if (diepint.b.emptyintr) { DCD_WriteEmptyTxFifo(pdev , epnum); } } epnum++; ep_intr >>= 1; } return 1; } За эти два прерывания, про которые я упомянул, поочередно взводятся два флага: diepint.b.emptyintr и diepint.b.xfercompl. Возведение diepint.b.xfercompl как раз и сигнализирует о том, что данные пошли на отправку. Но в нерабочей плате взводится только diepint.b.emptyintr, и статус USB так и остается как "занят", но при этом данные не передались. Стал копаться глубже и зашел в тупик. Подскажите, пожалуйста, что можно посмотреть еще? Линии, регистры? Любая подсказка
  19. Добрый день. В данный момент у меня на руках плата с контроллером PIC18F25K22 и проект от предыдущего сотрудника. Если очень рассказать очень сжато суть проекта, то есть первичный преобразователь расхода, который состоит из магнито-механического клапана, поршня и катушки индуктивности, обеспечивающей индикацию перемещения поршня в клапане и частичное управление поршнем. При открытии клапана на катушке формируется положительный потенциал, что может быть установлено с помощью компаратора, настроенного на верхний предел (ножка RA4, она же C1OUT). При закрытии клапана на катушке формируется отрицательный потенциал, что приводит к срабатыванию компаратора, если он настроен на нижний предел. Так вот, весь механизм фиксации открытия/закрытия клапана построен на 7 ключевых точках, в которых мониторятся определенные состояния и производятся определенныедействия. Компаратор настроен так: TRISAbits.RA4 = 0; // установить порт RА4 на выход (выход компаратора) PORTAbits.RA4 = 0; CM1CON0bits.C1POL = 0; // логика на C1OUT не инвертирована CM1CON0bits.C1SP = 0; // компаратор работает в режиме малой мощности и низкой скорости CM1CON0bits.C1R = 0; CM1CON0bits.C1CH = 1; // выставить канал компаратора на верхний предел IPR2bits.C1IP = 1; // приоритет прерываний от компаратора C1 высокий И обработчик его прерывания: void high_isr() { if (PIR2bits.C1IF) // прерывание от компаратора { if ((PIE2bits.C1IE) && (T3CONbits.TMR3ON == 0)) // если прерывания от компаратора разрешены и таймер TMR3 свободен FFComparator1Interrupt(); // войти в обработчик прерываний компаратора CM1CON0bits.C1OUT = 0; // выставить 0 на выходе компаратора PIR2bits.C1IF = 0; // сбросить флаг прерывания } } Все начинается с состояния PPR_CLOSE: void FFComparator1Interrupt() { switch(PPR.State) { case PPR_CLOSE: DelayInterrupt = 0; //исключаем пересечения if (CM1CON0bits.C1CH == 1) // если компаратор переключен на верхний порог (т.е. фиксируем движение клапана) { PPR.State = PPR_START_OPEN; // изменить состояния клапана на "Начал открываться" PIE2bits.C1IE = 0; // отключить прерывания от компаратора PORTAbits.RA4 = 1; // поднять уровень сигнала на линии TAU CM1CON0bits.C1OE = 0; // отключить выход компаратора (не реагировать на изменения на выходе) timer3Delay(2); // установить задержку в 2мс DelayInterrupt = 1; // выставить флаг для обработчика прерываний таймера TMR3 } else { CM1CON0bits.C1CH = 1; // переключить компаратор на верхний порог } break; } return; } В следующем же состоянии PPR_START_OPEN: void FFTimerEvent() { switch(PPR.State) { case PPR_START_OPEN: if (CM1CON0bits.C1CH == 1) // если компаратор переключен на верхний порог { if (CM1CON0bits.C1OUT == 1) // если клапан действительно открывается { timer3Delay(40); // установить задержку в 40мс для исключения дребезга DelayInterrupt = 1; // выставить флаг для обработчика прерываний таймера TMR3 PPR.State = PPR_PRE_OPEN;// изменить состояния клапана на "Почти открылся" StateChanged = 1; // выставить флаг о смене состояния клапана } else // иначе это был дребезг { PPR.State = PPR_CLOSE; CM1CON0bits.C1OE = 1; // подключить выход компаратора PIR2bits.C1IF = 0; // сбросить флаг прерывания компаратора PIE2bits.C1IE = 1; // включить прерывания от компаратора } } else { CM1CON0bits.C1CH = 1; // переключить компаратор на верхний порог timer3Delay(1); // установить задержку в 1мс DelayInterrupt = 1; // выставить флаг для обработчика прерываний таймера TMR3 } break; } } При попытке разобраться возникли спорные моменты: подскажите, пожалуйста 1. зачем по окончании обработки прерывания компаратора выставляется CM1CON0bits.C1OUT = 0 ? 2. зачем в след. за первым состоянием мониторится CM1CON0bits.C1OUT == 1, когда только что был CM1CON0bits.C1OUT = 0 ? Что мы просто мониторим в данном случае, и что сейчас на выходе компаратора реально? 3. действие PORTAbits.RA4 = 1 в первом состоянии не идентично CM1CON0bits.C1OUT = 1? Просто по даташиту Pin #6 = RA4 (C1OUT, SRQ, CCP5, T0CKI) Связаны ли эти два действия вообще друг с другом и как? И если кому то интересно, то вот изображение самого сигнала (измеряемый промежуток находится между вертикальными пунктирными линиями):
  20. megajohn, большое спасибо за помощь. До этого пробовал %u, %ul, но не работало
  21. C18 Ограничения sprintf

    Добрый день. У меня есть число типа float. Необходимо его записать в массив, дополнив целую и дробную части до определенного размера нулями. С целой частью проблем нет, дробную пока не получилось дополнить нулями. Но проблема в другом: sprintf отказывается принимать числа больше int. Подскажите, пожалуйста, как можно ли как-то обойти это ограничение? Может быть в настройках компилятора что-то включить? Среда разработки - MPLab X IDE. Вот пример кода, где я использую sprintf void main(void) { float minSet1 = 0.5; unsigned char Setting[11] = " "; NumbConverter(Setting, minSet1, 36); } void NumbConverter (void* destination, float numb, unsigned char numbDecimal) { unsigned char* array = (unsigned char*)destination; unsigned int whole; unsigned long decimal; whole = numb; // целая часть switch (numbDecimal) { case 36: decimal = (numb - whole) * 1000000; // дробная часть sprintf((char*)array, (const far rom char*)"%03d.%06u", whole, decimal); break; case 43: decimal = (numb - whole) * 1000; // дробная часть sprintf((char*)array, (const far rom char*)"%04d.%03u", whole, decimal); break; case 46: decimal = (numb - whole) * 1000000; // дробная часть sprintf((char*)array, (const far rom char*)"%04d.%06u", whole, decimal); break; } } На выходе я получаю массив Setting с содержимым "000.000007" вместо "000.500000". Не знаю, как быть
  22. C18 Функция strtok

    Byte у меня unsigned char typedef unsigned char byte; Вот результат на выходе цикла
  23. C18 Функция strtok

    Все верно. Я допустил эту ошибку вчера под конец рабочего дня. Сегодня утром я ее исправил, но результат не изменился. Проблема именно в том, что в цикле while совершается ровно одна итерация, после которой происходит выход из цикла. А, судя по логике, должны пройти 3 итерации. Вот моя функция void ParseDateTime(void) { char date[] = "30.10.15"; byte bytes[3] = " "; int i = 0; char* buff; buff = strtok(date,(const char*)"."); while (buff != NULL) { bytes[i] = (byte)atoi(buff); buff = strtok(NULL,(const char*)"."); i++; } }
  24. C18 Функция strtok

    Способ 1: в C18 нет такой функции strtol Способ 2: это совсем не то, что мне нужно. У меня стоит задача разбить 2 строки дд.мм.гг и чч.мм.сс (дату и время соответственно) на 6 переменных, хранящих отдельно каждое значение. Т.е. я предполагал при помощи функции strtok разбить на подстроки, а дальше при помощи функции atoi переконвертировать эти строки в число. Не хотелось бы изобретать некрасивый велосипед, когда есть готовая функция. Вот только разобраться с ней не удается.
  25. C18 Функция strtok

    Добрый день. У меня возникла необходимость парсить большое количество строк и вычленять числа из строки, разделенные между собой точкой (например, "15.23.10"). Стал копать в эту сторону и набрел на функцию strtok, которая призвана разделять строку на подстроки, разделенные маркером, передаваемым в функцию в виде параметра. Нашел готовый пример #include <string.h> int main() { char str[] = "192.168.0.1"; unsigned char bytes[4]; int i = 0; char* buff = malloc(10); buff = strtok(str,"."); while (buff != NULL) { //if you want to print its value printf("%s\n",buff); //and also if you want to save each byte bytes[i] = (unsigned char)atoi(buff); buff = strtok(NULL,"."); i++; } free(buff); return 0; } Чуть-чуть переделал его под себя char sc[] = "150.156.16"; byte bytes[3] = " "; int i = 0; char* buff; buff = strtok(sc,(const char*)'.'); while (buff != NULL) { bytes[i] = (byte)atoi(buff); buff = strtok(NULL,(const char*)'.'); i++; } Но считывается только первое число (150), а дальше происходит выход из цикла, и я не пойму, почему. Подскажите, пожалуйста, какие условия из описания я не выполнил (P.S. ниже я привел описание функции, взятое из самого компилятора)?
×
×
  • Создать...