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

strifonoff

Members
  • Постов

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

  • Посещение

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

  • День рождения 05.03.1984

Информация

  • Пол
    Мужчина
  • Город
    Иваново

Электроника

  • Стаж в электронике
    Не связан с электроникой

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

Блок последних пользователей отключён и не показывается другим пользователям.

Достижения strifonoff

Завсегдатай

Завсегдатай (8/14)

  • 10 постов на форуме
  • Пост-машина Редкий
  • Неделя на форуме
  • Месяц на форуме
  • Год на форуме

Последние значки

165

Репутация

  1. Mea culpa. Спасибо за подсказку. Эта деталь больше похожа на FM116C.
  2. Гирлянда 5 вольтовая. Утверждение оттуда, что гирлянда светодиодная и параллельно включенные светодиоды включаются группами. Переключает полярность на двух проводах. Сначала на одном плюс, а на другом минус. А потом наоборот. Что-то типа н-моста. Ещё вопросы? Или в Гугле только про БМВ написано?
  3. Подскажите, что это? Стоит в гирлянде, переключает полярность. Управляется с МК (что за мк не в курсе, маркировка китайцами стёрта).
  4. strifonoff

    stm32f103c8 ровный ШИМ

    Никак не могу получить ровные края генерации ШИМ по двум каналам. Инициализация таймера: RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST; __NOP();__NOP();__NOP(); RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST; GPIOA->ODR &= ~( GPIO_ODR_ODR6 | GPIO_ODR_ODR7 ); GPIOA->CRL &= ~( GPIO_CRL_CNF6 | GPIO_CRL_CNF7 | GPIO_CRL_MODE6 | GPIO_CRL_MODE7 ); GPIOA->CRL |= ( GPIO_CRL_MODE6 | GPIO_CRL_CNF6_1 | GPIO_CRL_MODE7 | GPIO_CRL_CNF7_1 ); uint32_t arr = 200; uint32_t ccr = arr/2; uint32_t syf = 56000000; TIM3->CR2 |= TIM_CR2_MMS_1; // TRGO trigger TIM3->PSC = syf/arr/40000 - 1; TIM3->ARR = arr - 1; TIM3->CCR1 = ccr; TIM3->CCR2 = ccr; TIM3->CCMR1 |= ( TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 ); // TIM3_CH2 PWM mode 1 TIM3->CCMR1 |= ( TIM_CCMR1_OC1M ); // TIM3_CH1 PWM mode 2 TIM3->DIER |= TIM_DIER_UIE; TIM3->EGR = TIM_EGR_UG; TIM3->CR1 |= TIM_CR1_ARPE; TIM3->CCER |= ( TIM_CCER_CC1E | TIM_CCER_CC2E ); TIM3->CR1 |= TIM_CR1_CEN; прерывание: void TIM3_IRQHandler(void) { static uint8_t count = 0; if (TIM3->SR & TIM_SR_UIF) { if(++count > 4) { count = 0; TIM3->CCER &= ~( TIM_CCER_CC1E | TIM_CCER_CC2E ); TIM3->CR1 &= ~TIM_CR1_CEN; } TIM3->SR &= ~TIM_SR_UIF; } } На старте и финише ситуация на картинках Как сделать ровный старт и убрать всплеск в конце? не пишите пожалуйста про какие-то теневые регистры. пишите код. ровный старт - это равный 12.5 мкс - полуволна 40 кГц
  5. Перенёс выключение ШИМ в другое прерывание (TIM_DIER_CC2IE). Хвост пропал. Но "всплеск" в начале остался... Есть идеи как его убрать?
  6. Поймал какую-то странность. ШИМ делает 20 импульсов в частотой 40 кГц и скважностью 50%. АЦП работает с начала работы таймера ШИМ и до 1000 измерений. Подключил напрямую ногу ШИМ и ногу АЦП, и получил следующую картину: перед первым импульсом и после последнего АЦП ловит короткие (2 мкс) всплески, в массиве поучается что-то типа: 4095,4095,0,0,4095....тут все нормально, импульсы ШИМ идут поочерёдно, с заданной скважностью, после последнего импульса идёт низкий уровень и потом ещё 2 раза 4095 и опять нули до конца измерений. TIM3->CNT = 0; TIM3->CR1 |= TIM_CR1_CEN; ADC1->CR2 |= ADC_CR2_SWSTART; while (_timer_pwm) {} //TIM3->CNT = TIM3->CCR2+1; TIM3->CCR2 = 0; TIM3->CR1 &= ~TIM_CR1_CEN; while(_work.adc) {} ADC1->CR2 &= ~ADC_CR2_ADON; _timer_pwm декрементируется в обработчике прерывания счётчика TIM3 Что за фича такая? Как убрать эти "всплески"? Почему ШИМ не начинает работать сразу? Инициализация ШИМ: RCC->APB1RSTR |= RCC_APB1RSTR_TIM3RST; RCC->APB1RSTR &= ~RCC_APB1RSTR_TIM3RST; GPIOA->CRL |= GPIO_CRL_MODE7; GPIOA->CRL &= ~GPIO_CRL_CNF7; GPIOA->CRL |= GPIO_CRL_CNF7_1; uint32_t freq = 56000000; uint32_t f = 40000; uint32_t arr = 200; uint32_t ccr = arr/2; TIM3->PSC = freq/arr/f-1; TIM3->ARR = arr-1; TIM3->CCR2 = ccr; TIM3->CR1 |= TIM_CR1_ARPE; TIM3->CCER |= TIM_CCER_CC2E; TIM3->CCMR1 |= (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1); TIM3->DIER |= TIM_DIER_UIE; NVIC_EnableIRQ(TIM3_IRQn);
  7. Пришел мне клон st-link v2 на sk32f103. Никаких проблем. В CubeIDE под линуксом обновляется, прошивает, отлаживает вообще без проблем. Хуже когда МК левый, отладка через openocd, а не встроенный gdb.
  8. 115226.337 вместо 115200. Это 0.023%... Совсем сопли. Но вопрос по изменению частоты остаётся открытым: энергопотребление немного снизить можно.
  9. это снова я... Максимального быстродействия АЦП можно достичь при частоте АЦП 14 МГц, а этого можно добиться только при системной частоте 56 МГц (если внешний кварц на 8 МГц). Но возникает проблема со скоростями UART: значение регистра BRR не получится выставить так, что бы скорость была из стандартного ряда. Назрели несколько вопросов: 1) возможно ли менять системную частоту на лету? (чую, что можно, но пока не знаю как) 2) критична ли ошибка в скорости UART по сравнению со стандартной? (что будет на другой стороне заранее не известно, т.к. любой может воткнуть свой девайс работающий на какой-то заранее согласованной стандартной скорости) 3) как поведёт себя железо (состояние ОЗУ, регистров перефирии, состояние ног и т.д.) на изменение частоты? Две части программы () практически независимы, их объединяет только один массив, который наполняется в первой половине, а обрабатывается в другой.
  10. Вроде со всем разобрался. Всё работает. Всем огромное спасибо за помощь!
  11. Но что-то пошло не так. Совсем не могу понять что именно #include "stm32f10x.h" #define BUF_SIZE 1000 void Init_RCC(void); void Init_TIM4(void); void Init_ADC1(void); void Init_ADC2(void); void Init_ADC_DMA(void); void Init_PWM(void); void Init_USART1(void); void _delay_10(void); vu16 _timer_pwm; vu8 WorkSensor; vu8 WorkADC; vu32 _tim4cnt; vu8 _timer; vu32 _timer_hour; vu16 ADC_Buf[BUF_SIZE] = {0}; int main() { SystemInit(); Init_RCC(); Init_TIM4(); // Init_ADC2(); // Init_USART1(); // __enable_irq(); while(1){ _timer_hour = 0; for(u8 i=0; i<5; i++){ Init_ADC1(); Init_PWM(); _timer = 0; TIM4->CNT = 0; WorkADC=1; WorkSensor = 1; _timer_pwm = 0; TIM2->CNT = 0; DMA1_Channel1->CCR |= DMA_CCR1_EN; ADC1->CR2 |= ADC_CR2_SWSTART; TIM2->CR1 |= TIM_CR1_CEN; while (WorkSensor) {} TIM2->CR1 &= ~TIM_CR1_CEN; while(WorkADC) {} ADC1->CR2 &= ~ADC_CR2_SWSTART; while(_timer) {} // wait for next measurement } // math + usart while(_timer_hour) {} // wait 1 hour } } void Init_RCC(void){ RCC->AHBENR |= RCC_AHBENR_DMA1EN; // DMA1 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // TIM2 RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // TIM4 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // GPIOA RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // AF IO RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // ADC1 RCC->APB2ENR |= RCC_APB2ENR_ADC2EN; // ADC2 RCC->CFGR |= RCC_CFGR_ADCPRE_DIV6; // ADC clock prescaler (/6) 12 MHz RCC->APB2ENR |= RCC_APB2ENR_USART1EN; } void Init_TIM4(void){ TIM4->PSC = 3600-1; TIM4->ARR = 10-1; TIM4->DIER |= TIM_DIER_UIE; TIM4->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(TIM4_IRQn); } void TIM2_IRQHandler(void){ if(TIM2->SR & TIM_SR_UIF){ _timer_pwm++; if (_timer_pwm == 20) { WorkSensor = 0; } TIM2->SR &= ~TIM_SR_UIF; } } void TIM4_IRQHandler(void){ if(TIM4->SR & TIM_SR_UIF){ _timer = (250-_timer) ? _timer+1 : 0; _timer_hour = (3600000-_timer_hour) ? _timer_hour+1 : 0; TIM4->SR &= ~TIM_SR_UIF; } } void DMA1_Channel1_IRQHandler(void){ if(DMA1->ISR & DMA_ISR_TCIF1){ DMA1_Channel1->CCR &= ~DMA_CCR1_EN; DMA1->IFCR |= DMA_IFCR_CTCIF1; WorkADC=0; } } void Init_ADC_DMA(void){ DMA1_Channel1->CCR = 0; DMA1_Channel1->CPAR = (uint32_t) &ADC1->DR; DMA1_Channel1->CMAR = (uint32_t) &ADC_Buf[0]; DMA1_Channel1->CNDTR = BUF_SIZE; DMA1_Channel1->CCR |= DMA_CCR1_MINC | DMA_CCR1_MSIZE_1 | DMA_CCR1_PSIZE_1 | DMA_CCR1_TCIE; NVIC_EnableIRQ (DMA1_Channel1_IRQn); } void Init_ADC1(void){ GPIOA->CRL &= ~GPIO_CRL_MODE1; GPIOA->CRL &= ~GPIO_CRL_CNF1; Init_ADC_DMA(); // ADC1->SQR1 = 0; ADC1->SQR3 |= 1; ADC1->CR2 |= ADC_CR2_CONT; ADC1->CR1 &= ~ADC_CR1_SCAN; ADC1->CR2 |= ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG | ADC_CR2_DMA; ADC1->CR2 |= ADC_CR2_ADON; _delay_10(); ADC1->CR2 |= ADC_CR2_CAL; while (!(ADC1->CR2 & ADC_CR2_CAL)){}; } void Init_PWM(void){ GPIOA->CRL &= ~GPIO_CRL_MODE3; GPIOA->CRL |= GPIO_CRL_MODE3_1; GPIOA->CRL &= ~GPIO_CRL_CNF3; GPIOA->CRL |= GPIO_CRL_CNF3_1; TIM2->PSC = 9-1; TIM2->ARR = 500-1; TIM2->CCR4 = 250; TIM2->CR1 |= TIM_CR1_ARPE; TIM2->CCER |= TIM_CCER_CC4E; TIM2->CCMR2 |= (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1); TIM2->DIER |= TIM_DIER_UIE; NVIC_EnableIRQ(TIM2_IRQn); // TIM2->CR1 |= TIM_CR1_CEN; } void Init_ADC2(void){ GPIOA->CRL &= ~GPIO_CRL_MODE2; GPIOA->CRL &= ~GPIO_CRL_CNF2; ADC2->SQR1 = 0; ADC2->SQR3 |= 2; ADC2->CR2 |= ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG; ADC2->CR2 |= ADC_CR2_ADON; _delay_10(); ADC2->CR2 |= ADC_CR2_CAL; while (!(ADC2->CR2 & ADC_CR2_CAL)){}; } void Init_USART1(void) { //A9 - TX //A10 - RX GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_MODE10); GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_CNF10); GPIOA->CRH |= (GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_0); // PA9 output 10 MHz, AFPP GPIOA->CRH |= GPIO_CRH_CNF10_1; // PA10 input GPIOA->BSRR |= GPIO_ODR_ODR10; USART1->CR1 = USART_CR1_UE; USART1->BRR = 7500; USART1->CR1 |= USART_CR1_TE | USART_CR1_RE ; USART1->CR2 = 0; USART1->CR3 = 0; } void _delay_10(void){ for(u8 i=0;i<10;i++) {} } Вот код. Работает не так как я хочу. Мне надо запустить "одновременно" ШИМ и АЦП. ШИМ на 500 мкс, АЦП на 1000 измерений (это 1.17 мс получается). Но по отладке вижу, что ДМА в массив ADC_Buf записывает только 18 значений, причем через одну. (может где-то с размерами напутал?) ЧЯДНТ?
  12. А ещё вопрос. по ШИМ. как настроить ШИМ на определенное время выполнения используя тот же таймер? Сделать прерывание на том же таймере и там считать? С этим разобрался, как думал так и сделал.
  13. Подскажите по режиму StandBy. Пишут, что выход из него аналогичен сбросу. Это значит что он начинает снова с точки входа main или всё-таки с места где его усыпили/разбудили?
  14. С TIM2->CNT сравнивается, как я понял. Его и надо будет обнулить?
  15. вопрос по ШИМ, про старт и останов. как я понял генерация ШИМ определяется работой таймера на котором ШИМ висит, в моём случае это TIM2_CH4 (нога PA3). т.е. TIM2->CR1 |= TIM_CR1_CEN стартует, TIM2->CR1 ?= ~TIM_CR1_CEN останавливает. Но там же есть счётчик, который сверяется с регистром CCR4, этот счётчик нужно обнулить, а какой регистр за это отвечает? Я что-то запутался.
×
×
  • Создать...