-
Постов
10 898 -
Зарегистрирован
-
Посещение
-
Победитель дней
30
Сообщения, опубликованные Сергей Борщ
-
-
11 часов назад, tonyk_av сказал:
И там, и там есть дуга, причём на ~230В она больше
Тут дело не в ее размере, а в том, что на переменном токе она быстро гаснет сама. А на постоянном может держаться бесконечно пока в зону дуги подается электрод (см. "дуговая лампа")
-
12 минут назад, Arlleex сказал:
Аа... понятно. Я сделал свой stm32.h в который поместил все #include "stm32f????.h
Больше ничего полезного в этом вашем stm32f4xx.h нет.
-
8 часов назад, Arlleex сказал:
уже имеется такое имя у энумератора в заголовочном файле stm32f4xx.h
В этом файле такого имени нет. Выкиньте кубовые файлы с подобной чушью, оставив вместо них пустые заглушки (чтобы не менять сам stm32f4xx.h и сохранить возможность его обновления без правок).
-
Модератор: прошу всех желающих отметиться в этой теме еще раз перечитать правила раздела "Предлагаю работу" и потом не обижаться.
-
1
-
-
-
1 час назад, _3m сказал:
Проблема в GBD сервере. Он завершается когда теряет коннект с таргетом что и происходит при снятии питания (RTT - тоже). Процедура автоматического коннекта при появлении питания в сеггеровском ПО почему то не предусмотрена.
Так проблема в этом? OpenOCD такое умеет, но время подключения может быть до 6.5 сек. Я-то думал надо подключиться и перехватить управление буквально с первых команд - такого, наверное, не умеет никто.
-
Остановите отладчиком, прочитайте и сохраните на бумажку или в блокнот на компе значение регистров RCC, TMR, PWR. Запустите, дождитесь сбоя, остановите, сравните.
1 час назад, gerber сказал:Аппаратный ШИМ с выхода канала таймера TIM2.
Несущая частота ШИМа тоже пропорционально меняется? У F103 не особо много возможностей менять тактирование таймеров - в отличие от более новых тут оно прибито гвоздями к APB. То есть причина либо в измененном делителе APB (если UART, который продолжает работать висит на другой APB), либо в предделителе самого таймера (в обоих этих случаях должна меняться несущая частота ШИМ), либо в программной ошибке, из-за которой значения в CCR таймера грузятся в N раз реже (это если несущая частота не меняется). Я делаю ставку на последний вариант.
1 час назад, gerber сказал:Китаиса однако.
Ой, да хватит пугать. Китаиса их делают так долго и в таких количествах, что все ошибки кристалла давно вылизали.
-
Запускать без отладчика. В интересующих местах программы дергать ногами, писать их состояние логическим анализатором. Выводить диагностику в USART, смотреть ее в терминалке на компе.
-
1
-
-
16 часов назад, Arlleex сказал:
А если для обоих случаев посмотреть, что возвращает ISR->DIEROK?
Да, вы правы - в первом случае DIEROK не выставляется.
-
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 после записи пробовал - не помогало.
-
1
-
-
В кубовом проекте прерывание происходит. "Будем искать".
-
49 минут назад, HardEgor сказал:
А в errata есть такой пункт, может быть там где-то собака порылась?:
Это учтено.Флаги в ISR у меня выставляются. Если их сбросить - выставляются снова. Тут все хорошо. Ставлю куб от безысходности... -
1 час назад, Plain сказал:
Table 221
Ой. 13 таблиц. Но да, тут два канала и соответствующий флаг в ISR выставляется. А проблема с любым флагом. Ни одно событие, взводящее флаг в ISR, не вызывает прерывание.
22 минуты назад, Arlleex сказал:P.S. А какая частота шины APB для таймера? Я бы попробовал ее сильно снизить для эксперимента.
На APB включен делитель 2. Попробовал 16 - не помогает.
-
22 минуты назад, Plain сказал:
Про CC2IE есть сноска в таблице.
В руководстве пользователя 12 таблиц в разделе, посвященном LPTIM. Ни под одной из них я упоминания CC2IE не нашел. Какую именно таблицу вы имеете ввиду?
-
1 час назад, Arlleex сказал:
Это условие выполняется. Код в исходном сообщении исправил.
48 минут назад, Arlleex сказал:А я имел в виду возбудить именно этот вектор прерывания через активацию pending в NVIC (регистр ISPR вроде).
А смысл делать это вручную? Таймер должен сам взвести именно этот бит, но не взводит.
-
5 часов назад, jcxz сказал:
Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?
Не взлетело - ни в одном ISPR ни один бит не взводится.
1 час назад, Arlleex сказал:проверить хотя бы заход в прерывание
В другие прерывания заходит...
-
Да, как обычный таймер. Спячки тоже пока нет.
-
Тоже пробовал - то же яйцо, только в профиль.
-
3 часа назад, Arlleex сказал:
Что в этот момент в PRIMASK и BASEPRI?
Забыл упомянуть, что остальные задействованные прерывания (USB, USART, GPDMA, TIM1, TIM3, COMP, EXTI_10) в это время работают. А с LPTIM не доходит до выставления флагов в NVIC. Причем и с LPTIM1 и с LPTIM2.
1 час назад, jcxz сказал:Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?
Интересная мысль. Маловероятно, но сейчас проверю.
-
Инициализация:
Спойлер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 соответствующий бит не взводится и обработчик прерывания, соответственно, не вызывается. Что я делаю не так???
-
Предположу, что высох C1, после чего пробило микросхему и уже это явилось причиной перегорания L1. Проверьте на замыкание выходной ключ в микросхеме.
Мы не знаем, какими знаниями, умениями и навыками вы обладаете. В зависимости от них, возможно, имеет смысл сразу отдать эту плату на ремонт специалисту, чтобы потом не пришлось после вашего "ремонта" платить за ее восстановление гораздо дороже.
-
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); }
-
1
-
-
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"); }
-
1
-
-
3 часа назад, MrYuran сказал:
Сергей, а Windows это тоже касается?
Понятия не имею - давно пересел на линух.
По реле
в В помощь начинающему
Опубликовано · Пожаловаться
Ничего странного:
Оттуда же про постоянный ток:
Ну и подробнее по ссылке.