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

Сергей Борщ

Модератор
  • Постов

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

  • Посещение

  • Победитель дней

    30

Сообщения, опубликованные Сергей Борщ


  1. 30 минут назад, jcxz сказал:

    Хм, странно...

    Ничего странного:

    Цитата

    Принципиальной разницы между дугой постоянного и переменного тока нет. Однако род тока накладывает свои особенности в отношении гашения дуги. Основной особенностью дуги переменного тока является то, что ток ее 2/ раз (где / частота тока) в секунду проходит через 0, точки а, b (рис. 4.10).
    apparat-avtomat-19.png
    Рис. 4.10                                                           Рис. 4.1 i
    Это обстоятельство решающим образом облегчает гашение дуги переменного тока. Когда ток дуги проходит через нуль, энергия дуги становится равной 0, происходит деионизация дугового промежутка, и если извне усилить этот процесс деионизации, что и делают дугогасительные устройства выключателей, то дуга после прохождения тока через 0 вновь не загорится, погаснет. С точки зрения гашения различают дуги переменного тока: открытую, короткую и длинную.
    Открытая дуга переменного тока гасится без участия специальных дугогасительных устройств. Ее вольт-амперная характеристика приведена на рис.· 4.11. Из этой характеристики следует, что в открытой дуге после прохождения тока дуги через 0 дуговой промежуток мало деионизирован, и с ростом напряжения почти пропорционально (вначале) растет ток дуги. Это свидетельствует о том, что открытая дуга переменного тока по трудности гашения близка к дуге постоянного тока и, чтобы ее погасить, необходимо растянуть до критической длины. Маломощные открытые дуги, например на контактах бытовых выключателей, рубильников и т. д., гасятся простым разрывом дуги на воздухе. Мощные открытые дуги, например на линиях высокого напряжения, можно погасить только путем снятия напряжения. После снятия напряжения дуга гаснет, дуговой промежуток деионизируется. Если вновь подать напряжение на линию, то дуга, как правило, не загорается, и линия продолжает работать.

    Оттуда же про постоянный ток:

    Цитата

    Дуга постоянного тока гашению поддается очень трудно. При малых токах и небольших напряжениях дуга постоянного тока может быть погашена простым разрывом на воздухе без значительных разрушений контактов. Однако даже в аппаратах напряжением до 1000 в необходимо принимать специальные меры для гашения дуги с целью сохранения контактов.
    Основной характеристикой дуги постоянного тока является ее вольт-амперная характеристика, представляющая собой зависимость тока от напряжения дуги, т. е. i=cp((/) при постоянной длине дуги. На рис. 4.2 представлена вольт-амперная характеристика дуги постоянного тока. Из нее следует, что дуга постоянного тока как вид нагрузки представляет собой активное нелинейное сопротивление. С ростом тока напряжение на дуге уменьшается и наоборот.

    Ну и подробнее по ссылке.

    • Like 1
  2. 11 часов назад, tonyk_av сказал:

    И там, и там есть дуга, причём на ~230В она больше

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

  3. 12 минут назад, Arlleex сказал:

    Аа... понятно. Я сделал свой stm32.h в который поместил все #include "stm32f????.h

    Больше ничего полезного в этом вашем stm32f4xx.h нет.

  4. 8 часов назад, Arlleex сказал:

    уже имеется такое имя у энумератора в заголовочном файле stm32f4xx.h

    В этом файле такого имени нет. Выкиньте кубовые файлы с подобной чушью, оставив вместо них пустые заглушки (чтобы не менять сам stm32f4xx.h и сохранить возможность его обновления без правок).

  5. 1 час назад, _3m сказал:

    Проблема в GBD сервере. Он завершается когда теряет коннект с таргетом что и происходит при снятии питания (RTT - тоже). Процедура автоматического коннекта при появлении питания в сеггеровском ПО почему то не предусмотрена.

    Так проблема в этом? OpenOCD такое умеет, но время подключения может быть до 6.5 сек. Я-то думал надо подключиться и перехватить управление буквально с первых команд - такого, наверное, не умеет никто.

  6. Остановите отладчиком, прочитайте и сохраните на бумажку или в блокнот на компе значение регистров RCC, TMR, PWR. Запустите, дождитесь сбоя, остановите, сравните.

    1 час назад, gerber сказал:

    Аппаратный ШИМ с выхода канала таймера TIM2.

    Несущая частота ШИМа тоже пропорционально меняется? У F103 не особо много возможностей менять тактирование таймеров - в отличие от более новых тут оно прибито гвоздями к APB. То есть причина либо в измененном делителе APB (если UART, который продолжает работать висит на другой APB), либо в предделителе самого таймера (в обоих этих случаях должна меняться несущая частота ШИМ), либо в программной ошибке, из-за которой значения в CCR таймера грузятся в N раз реже (это если несущая частота не меняется). Я делаю ставку на последний вариант.

     

    1 час назад, gerber сказал:

    Китаиса однако.

    Ой, да хватит пугать. Китаиса их делают так долго и в таких количествах, что все ошибки кристалла давно вылизали. 

  7. Запускать без отладчика. В интересующих местах программы дергать ногами, писать их состояние логическим анализатором. Выводить диагностику в USART, смотреть ее в терминалке на компе.

    • Thanks 1
  8. 2 часа назад, Сергей Борщ сказал:

    В кубовом проекте прерывание происходит. "Будем искать".

    Следите за руками. Вот так не работает:

    
      LPTIM1->DIER = 0
          | 0 * LPTIM_DIER_UEIE                                   // Update event DMA request enable
          | 0 * LPTIM_DIER_CMP2OKIE                               // CCR2 update complete interrupt enable
          | 1 * LPTIM_DIER_CC2IE                                  // Capture/Compare 2 interrupt enable
          | 0 * LPTIM_DIER_REPOKIE                                // RCR update interrupt enable
          | 0 * LPTIM_DIER_UEIE                                   // Update event interrupt enable
          | 0 * LPTIM_DIER_DOWNIE                                 // Direction change to down interrupt enable
          | 0 * LPTIM_DIER_UPIE                                   // Direction change to up interrupt enable
          | 0 * LPTIM_DIER_ARROKIE                                // ARR update complete interrupt enable
          | 0 * LPTIM_DIER_CMP1OKIE                               // CCR1 update complete interrupt enable
          | 0 * LPTIM_DIER_EXTTRIGIE                              // External trigger valid edge interrupt enable
          | 0 * LPTIM_DIER_ARRMIE                                 // Autoreload match interrupt enable
          | 0 * LPTIM_DIER_CC1IE                                  // Capture/Compare 1 interrupt enable
          ;
      // enable timer
      LPTIM1->CR = 0
          | 0 * LPTIM_CR_RSTARE                                   // Reset after read enable, can be set when LPTIM is enabled
          | 0 * LPTIM_CR_COUNTRST                                 // Reset counter, can be set when LPTIM is enabled
          | 0 * LPTIM_CR_CNTSTRT                                  // Start in continuous mode, can be set when LPTIM is enabled
          | 0 * LPTIM_CR_SNGSTRT                                  // Start in single pulse mode, can be set when LPTIM is enabled
          | 1 * LPTIM_CR_ENABLE                                   // Enable
          ;

    А вот так работает:

      // enable timer
      LPTIM1->CR = 0
          | 0 * LPTIM_CR_RSTARE                                   // Reset after read enable, can be set when LPTIM is enabled
          | 0 * LPTIM_CR_COUNTRST                                 // Reset counter, can be set when LPTIM is enabled
          | 0 * LPTIM_CR_CNTSTRT                                  // Start in continuous mode, can be set when LPTIM is enabled
          | 0 * LPTIM_CR_SNGSTRT                                  // Start in single pulse mode, can be set when LPTIM is enabled
          | 1 * LPTIM_CR_ENABLE                                   // Enable
          ;
    
      LPTIM1->DIER = 0
          | 0 * LPTIM_DIER_UEIE                                   // Update event DMA request enable
          | 0 * LPTIM_DIER_CMP2OKIE                               // CCR2 update complete interrupt enable
          | 1 * LPTIM_DIER_CC2IE                                  // Capture/Compare 2 interrupt enable
          | 0 * LPTIM_DIER_REPOKIE                                // RCR update interrupt enable
          | 0 * LPTIM_DIER_UEIE                                   // Update event interrupt enable
          | 0 * LPTIM_DIER_DOWNIE                                 // Direction change to down interrupt enable
          | 0 * LPTIM_DIER_UPIE                                   // Direction change to up interrupt enable
          | 0 * LPTIM_DIER_ARROKIE                                // ARR update complete interrupt enable
          | 0 * LPTIM_DIER_CMP1OKIE                               // CCR1 update complete interrupt enable
          | 0 * LPTIM_DIER_EXTTRIGIE                              // External trigger valid edge interrupt enable
          | 0 * LPTIM_DIER_ARRMIE                                 // Autoreload match interrupt enable
          | 0 * LPTIM_DIER_CC1IE                                  // Capture/Compare 1 interrupt enable
          ;

    Хотя в в обоих случаях отладчик показывает, что нужные биты в DIER устанавливаются.

    Для регистров CCRx, ARR, RCR в документации явно указано, что писать их можно только при активированном (enabled) таймере, для CFGR - наоборот, при неактивном. На запись в DIER никаких ограничений в документации нет.

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

    Вычитывать DIER после записи пробовал - не помогало.

    • Upvote 1
  9. 49 минут назад, HardEgor сказал:

    А в errata есть такой пункт, может быть там где-то собака порылась?:

     

    Это учтено.  Флаги в ISR у меня выставляются. Если их сбросить - выставляются снова. Тут все хорошо. Ставлю куб от безысходности...

  10. 1 час назад, Plain сказал:

    Table 221

    Ой. 13 таблиц. Но да, тут два канала и соответствующий флаг в ISR выставляется. А проблема с любым флагом. Ни одно событие, взводящее флаг в ISR, не вызывает прерывание. 

    22 минуты назад, Arlleex сказал:

    P.S. А какая частота шины APB для таймера? Я бы попробовал ее сильно снизить для эксперимента.

    На APB включен делитель 2. Попробовал 16 - не помогает.

  11. 22 минуты назад, Plain сказал:

    Про CC2IE есть сноска в таблице.

    В руководстве пользователя 12 таблиц в разделе, посвященном LPTIM. Ни под одной из них я упоминания CC2IE не нашел. Какую именно таблицу вы имеете ввиду?

  12. 1 час назад, Arlleex сказал:

    image.thumb.png.fefa1b31404a7b9bca92c709e6f441f6.png

    Это условие выполняется. Код в исходном сообщении исправил.

    48 минут назад, Arlleex сказал:

    А я имел в виду возбудить именно этот вектор прерывания через активацию pending в NVIC (регистр ISPR вроде).

    А смысл делать это вручную? Таймер должен сам взвести именно этот бит, но не взводит. 

  13. 5 часов назад, jcxz сказал:

    Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?

    Не взлетело - ни в одном ISPR ни один бит не взводится.

    1 час назад, Arlleex сказал:

    проверить хотя бы заход в прерывание

    В другие прерывания заходит...

  14. 3 часа назад, Arlleex сказал:

    Что в этот момент в PRIMASK и BASEPRI?

    Забыл упомянуть, что остальные задействованные прерывания (USB, USART, GPDMA, TIM1, TIM3, COMP, EXTI_10) в это время работают. А с LPTIM  не доходит до выставления флагов в NVIC. Причем и с LPTIM1 и с LPTIM2.

    1 час назад, jcxz сказал:

    Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?

    Интересная мысль. Маловероятно, но сейчас проверю.

  15. Инициализация:

    Спойлер
        LPTIM1->CFGR = 0                                            // must be modified when LPTIM is disabled
            | 0 * LPTIM_CFGR_ENC                                    // Encoder mode enable
            | 0 * LPTIM_CFGR_COUNTMODE                              // Increment source if CKSEL = 0, 0: internal, 1: LPTIM_IN1
            | 0 * LPTIM_CFGR_PRELOAD                                // ARR and CMP update, 0: after each APB access, 1: at the end of LPTIM period
            | 0 * LPTIM_CFGR_WAVE                                   // Waveform shape, 0: normal node, 1: set-once mode
            | 0 * LPTIM_CFGR_TIMOUT                                 // Trigger event when timer is started, 0: ignored, 1: reset and restart timer
            | 0 * (LPTIM_CFGR_TRIGEN & -LPTIM_CFGR_TRIGEN)          // Trigger edge selection, 0: software, 1: rising edge, 2: falling edge, 3: both edges
            | 0 * (LPTIM_CFGR_TRIGSEL & -LPTIM_CFGR_TRIGSEL)        // Trigger selection,
                                                                    // h5xx LPTIM1: 0: LPTIM_ETR, 1: RTC alarm A, 2: RTC alarm B, 3...4: TAMP1..2, 5: GPDMA_CH1, 6: COMP1_OUT, 7: EVENTOUT
            | 0 * (LPTIM_CFGR_PRESC & -LPTIM_CFGR_PRESC)            // Clock prescaler, 0..7: div 2^N
            | 0 * (LPTIM_CFGR_TRGFLT & -LPTIM_CFGR_TRGFLT)          // Trigger filter, 0: off, 1: 2 clk cycles, 2: 4 clk cycles, 3: 8 clk cycles
            | 0 * (LPTIM_CFGR_CKFLT & -LPTIM_CFGR_CKFLT)            // Clock filter, 0: off, 1: 2 int. clk cycles, 2: 4 int. clock cycles, 3: 8 int. clk cycles
            | 0 * (LPTIM_CFGR_CKPOL & -LPTIM_CFGR_CKPOL)            // Clock active edge, 0: rising, 1: falling, 2: both (if CKSEL=0 only), 3: forbidden
            | 0 * LPTIM_CFGR_CKSEL                                  // Clock selection, 0: internal, 1: LPTIM_IN1
            ;
    
        // clear flags. Interrupt not asserted if flag set before enabling in DIER
        LPTIM1->ICR = uint32_t(-1);
    
        LPTIM1->DIER = 0
            | 0 * LPTIM_DIER_UEIE                                   // Update event DMA request enable
            | 0 * LPTIM_DIER_CMP2OKIE                               // CCR2 update complete interrupt enable
            | 1 * LPTIM_DIER_CC2IE                                  // Capture/Compare 2 interrupt enable
            | 0 * LPTIM_DIER_REPOKIE                                // RCR update interrupt enable
            | 0 * LPTIM_DIER_UEIE                                   // Update event interrupt enable
            | 0 * LPTIM_DIER_DOWNIE                                 // Direction change to down interrupt enable
            | 0 * LPTIM_DIER_UPIE                                   // Direction change to up interrupt enable
            | 0 * LPTIM_DIER_ARROKIE                                // ARR update complete interrupt enable
            | 0 * LPTIM_DIER_CMP1OKIE                               // CCR1 update complete interrupt enable
            | 0 * LPTIM_DIER_EXTTRIGIE                              // External trigger valid edge interrupt enable
            | 0 * LPTIM_DIER_ARRMIE                                 // Autoreload match interrupt enable
            | 0 * LPTIM_DIER_CC1IE                                  // Capture/Compare 1 interrupt enable
            ;
    
        LPTIM1->CCMR1 = 0
            | 0 * (LPTIM_CCMR1_IC2F & -LPTIM_CCMR1_IC2F)            // IC2 filter, 0: no filter, 1: 2 cycles, 2: 4 cycles, 3: 8 cycles
            | 0 * (LPTIM_CCMR1_IC2PSC & -LPTIM_CCMR1_IC2PSC)        // IC2 prescaler, 0: disabled, 1: /2, 2: /4, 3: /8
            | 1 * (LPTIM_CCMR1_CC2P & -LPTIM_CCMR1_CC2P)            // CC2 polarity, compare mode: 0, 2: active high, 1,3: active low
                                                                    // capture mode: 0: rising, 1: falling, 3: both edges
            | 0 * LPTIM_CCMR1_CC2E                                  // CC2 enable
            | 0 * LPTIM_CCMR1_CC2SEL                                // CC2 selection, 0: output PWM, 1: capture
            | 0 * (LPTIM_CCMR1_IC1F & -LPTIM_CCMR1_IC1F)            // IC1 filter, 0: no filter, 1: 2 cycles, 2: 4 cycles, 3: 8 cycles
            | 0 * (LPTIM_CCMR1_IC1PSC & -LPTIM_CCMR1_IC1PSC)        // IC1 prescaler, 0: disabled, 1: /2, 2: /4, 3: /8
            | 0 * (LPTIM_CCMR1_CC1P & -LPTIM_CCMR1_CC1P)            // CC1 polarity, compare mode: 0, 2: active high, 1,3: active low
                                                                    // capture mode: 0: rising, 1: falling, 3: both edges
            | 0 * LPTIM_CCMR1_CC1E                                  // CC1 enable
            | 0 * LPTIM_CCMR1_CC1SEL                                // CC1 selection, 0: output PWM, 1: capture
            ;
    
        // enable timer
        LPTIM1->CR = 0
            | 0 * LPTIM_CR_RSTARE                                   // Reset after read enable, can be set when LPTIM is enabled
            | 0 * LPTIM_CR_COUNTRST                                 // Reset counter, can be set when LPTIM is enabled
            | 0 * LPTIM_CR_CNTSTRT                                  // Start in continuous mode, can be set when LPTIM is enabled
            | 0 * LPTIM_CR_SNGSTRT                                  // Start in single pulse mode, can be set when LPTIM is enabled
            | 1 * LPTIM_CR_ENABLE                                   // Enable
            ;
    	// CCRx must only be modified when LPTIM is enabled
        LPTIM1->CCR2 = (LPTIM1_CLK + 1000000 - 1) / 1000000;        // 1 us minimal driver pulse width
    	// CCRx must only be modified when LPTIM is enabled
        LPTIM1->ARR = LPTIM1_CLK / 1000;                            // просто для примера
    	
    	// Enable NVIC interrupt
        NVIC->ISER[2] = 0
            | (1 << (-64 + LPTIM1_IRQn))                // M4_STEP
            | (1 << (-64 + LPTIM2_IRQn))                // M3_STEP
            | (1 << (-64 + USB_DRD_FS_IRQn))
            | (0 << (-64 + CRS_IRQn))
            | (0 << (-64 + GPDMA2_Channel0_IRQn))
            | (0 << (-64 + GPDMA2_Channel1_IRQn))
            | (0 << (-64 + GPDMA2_Channel2_IRQn))
            | (0 << (-64 + GPDMA2_Channel3_IRQn))
            | (0 << (-64 + GPDMA2_Channel4_IRQn))
            | (0 << (-64 + GPDMA2_Channel5_IRQn))
            ;
    
        // start timer
        LPTIM1->CR = 0
            | 0 * LPTIM_CR_RSTARE                                   // Reset after read enable, can be set when LPTIM is enabled
            | 0 * LPTIM_CR_COUNTRST                                 // Reset counter, can be set when LPTIM is enabled
            | 1 * LPTIM_CR_CNTSTRT                                  // Start in continuous mode, can be set when LPTIM is enabled
            | 0 * LPTIM_CR_SNGSTRT                                  // Start in single pulse mode, can be set when LPTIM is enabled
            | 1 * LPTIM_CR_ENABLE                                   // Enable
            ;

     

    Таймер стартует, импульсы на выходе вижу, в регистре LPTIMx->ISR нужные флаги появляются, а в NVIC->ISPR2 соответствующий бит не взводится и обработчик прерывания, соответственно, не вызывается. Что я делаю не так???

     

     

     

  16. Предположу, что высох C1, после чего пробило микросхему и уже это явилось причиной перегорания L1. Проверьте на замыкание выходной ключ в микросхеме.

    Мы не знаем, какими знаниями, умениями и навыками вы обладаете. В зависимости от них, возможно, имеет смысл сразу отдать эту плату на ремонт специалисту, чтобы потом не пришлось после вашего "ремонта" платить за ее восстановление гораздо дороже.

  17. 1 час назад, Arlleex сказал:

    Только у Вас "хитрость" - по сути все send_command имеют тип аргументов "массив" или "что-то, что можно упаковать в массив".

    Так и для дисплея же любая команда - поток байтов. Наша задача - объяснить компилятору, что любую команду надо трактовать как набор N байтов с некоего начального адреса.

    1 час назад, Arlleex сказал:

    Но send_command(1, 2), например, - уже ошибка.

    Увы, это два int. Старшие байты будут нулями. Придумал их только как массив шестнадцатиричных кодов символов (вроде исправил в сообщении, но почему-то не сохранилось):

    send_command({'\x01', '\x02'});

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

    template<typename T>
    void send_command(T const & what)    { send_command(&what, sizeof(T)); }

    примерно так:

    Спойлер
    namespace tdf8599
    {
        namespace core
        {
            union instruction
            {
                struct
                {
    
                    uint8_t Mode                        : 1;    // 0 = standby, 1 = mute/operating
                    uint8_t Ch1_disable                 : 1;
                    uint8_t                             : 1;
                    uint8_t OSC_increase                : 1;    // 0 = Rosc - 10%, 1 = Rosc + 10%
                    uint8_t Freq_hopping_enable         : 1;
                    uint8_t Ch1_clip_detect_disable     : 1;    // clip detection on CLIP pin
                    uint8_t Ch1_offset_monitor_disable  : 1;
                    uint8_t Offset_out_disable          : 1;    // offset detection on DIAG pin
    
                    uint8_t Mute                        : 1;    // 0 = operating, 1 = mute
                    uint8_t Ch2_disable                 : 1;
                    uint8_t DC_load_detection           : 1;
                    uint8_t Temp_pre_warning            : 1;    // 0 = 140 deg.C, 1 = 120 deg.C
                    uint8_t Thermal_pre_warning_disable : 1;    // thermal pre-warning on CLIP pin
                    uint8_t Ch2_clip_detect_disable     : 1;    // clip detection on CLIP pin
                    uint8_t Ch2_offset_monitor_disable  : 1;
                    uint8_t Offset_protection_disable   : 1;
    
                    uint8_t Modulation                  : 1;    // 0 = AD, 1 = BD
                    uint8_t OSC_phase_shift             : 3;    // 0 = 0, 1 = 1/4pi, 2 = 1/3 pi, 3 = 1/2pi, 4 = 2/3pi, 5 = 3/4pi
                    uint8_t AC_load_detection           : 1;
                    uint8_t                             : 2;
                    uint8_t ADS_MOD_latch               : 1;    // 0 = latch on switching start, 1 = latch immediately
                };
                uint8_t     Raw[3];
            };
    ....
    };
    
    bool out_amp::load(config::amplifier const volatile & settings)
    {
        Control = tdf8599::core::instruction(
        {
            settings.Mode != config::amplifier::mode::STANDBY,
            false,      // Ch1_disable
            !!settings.OSC_increase,
            !!settings.Freq_hopping,
            !settings.Clip_detect_enable,
            !settings.Offset_monitor_enable,
            false,      // Offset detection on DIAG pin disable
    
            settings.Mode == config::amplifier::mode::MUTE,
            false,      // Ch2_disable
            !!settings.DC_load_detect,
            !!settings.Temp_pre_warning,
            !settings.Temp_pre_warn_enable,
            !settings.Clip_detect_enable,
            !settings.Offset_monitor_enable,
            !settings.Offset_protection_enable,
    
            !!settings.Modulation,
            0,          // OSC_phase_shift
            !!settings.AC_load_detect,
            true,       // ADS_MOD_latch
        });
    
        return Chip.setup(Control);
    }

     

     

    • Upvote 1
  18. 6 часов назад, Arlleex сказал:

    В конечном итоге хочу получить возможность вот такой записи

    Так?

    void send(uint8_t id, void const * from, size_t size);
    
    void send_command(void const * from, size_t size)       { send(0, from, size); }
    
    template <typename T>
    void send_command(T const & what)                       { send_command(&what, sizeof(T)); }
    
    template <typename T, size_t items>
    void send_command(T const (&what)[items])               { send_command(&what, sizeof(T) * items); }
    
    template<size_t length>
    void send_command(char (&string)[length])               { send_command(&what, size - 1); }
    
    
    void test()
    {
      send_command(0x12);
      send_command({0x12, 0x34, 0x56});
      send_command("Hello");
    }

     

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