Jump to content

strifonoff

Members
  • Content Count

    1196
  • Joined

  • Last visited

Community Reputation

162 Хороший

About strifonoff

  • Rank
    Живу я тут
  • Birthday 03/05/1984

Информация

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

Электроника

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

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Никак не могу получить ровные края генерации ШИМ по двум каналам. Инициализация таймера: 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 кГц
  2. Перенёс выключение ШИМ в другое прерывание (TIM_DIER_CC2IE). Хвост пропал. Но "всплеск" в начале остался... Есть идеи как его убрать?
  3. Поймал какую-то странность. ШИМ делает 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);
  4. Пришел мне клон st-link v2 на sk32f103. Никаких проблем. В CubeIDE под линуксом обновляется, прошивает, отлаживает вообще без проблем. Хуже когда МК левый, отладка через openocd, а не встроенный gdb.
  5. 115226.337 вместо 115200. Это 0.023%... Совсем сопли. Но вопрос по изменению частоты остаётся открытым: энергопотребление немного снизить можно.
  6. это снова я... Максимального быстродействия АЦП можно достичь при частоте АЦП 14 МГц, а этого можно добиться только при системной частоте 56 МГц (если внешний кварц на 8 МГц). Но возникает проблема со скоростями UART: значение регистра BRR не получится выставить так, что бы скорость была из стандартного ряда. Назрели несколько вопросов: 1) возможно ли менять системную частоту на лету? (чую, что можно, но пока не знаю как) 2) критична ли ошибка в скорости UART по сравнению со стандартной? (что будет на другой стороне заранее не известно, т.к. любой может воткнуть свой девайс работающий на какой-то заранее согласованной стандартной скорости) 3) как поведёт себя железо (состояние ОЗУ, регистров перефирии, состояние ног и т.д.) на изменение частоты? Две части программы () практически независимы, их объединяет только один массив, который наполняется в первой половине, а обрабатывается в другой.
  7. Вроде со всем разобрался. Всё работает. Всем огромное спасибо за помощь!
  8. Но что-то пошло не так. Совсем не могу понять что именно #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 значений, причем через одну. (может где-то с размерами напутал?) ЧЯДНТ?
  9. А ещё вопрос. по ШИМ. как настроить ШИМ на определенное время выполнения используя тот же таймер? Сделать прерывание на том же таймере и там считать? С этим разобрался, как думал так и сделал.
  10. Подскажите по режиму StandBy. Пишут, что выход из него аналогичен сбросу. Это значит что он начинает снова с точки входа main или всё-таки с места где его усыпили/разбудили?
  11. С TIM2->CNT сравнивается, как я понял. Его и надо будет обнулить?
  12. вопрос по ШИМ, про старт и останов. как я понял генерация ШИМ определяется работой таймера на котором ШИМ висит, в моём случае это TIM2_CH4 (нога PA3). т.е. TIM2->CR1 |= TIM_CR1_CEN стартует, TIM2->CR1 ?= ~TIM_CR1_CEN останавливает. Но там же есть счётчик, который сверяется с регистром CCR4, этот счётчик нужно обнулить, а какой регистр за это отвечает? Я что-то запутался.
  13. А зачем мне 50MHz, или я не о том думаю. BDTR в мануале для таймеров кроме 1-го не нашел в принципе...
  14. GPIOA->CRL &= ~GPIO_CRL_CNF3; GPIOA->CRL |= GPIO_CRL_CNF3_1; вот это надо было добавить
  15. Вопрос по ШИМ. Если у PA3 альтернативная функция TIM2_CH4, то для ШИМ его ремапить не надо? GPIOA->CRL &= ~GPIO_CRL_MODE3; GPIOA->CRL |= GPIO_CRL_MODE3_1; TIM2->PSC = 0; TIM2->ARR = 1800-1; TIM2->CCR4 = 900; TIM2->BDTR |= TIM_BDTR_MOE; TIM2->CCMR2 = TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1; TIM2->CCER |= TIM_CCER_CC4E; TIM2->CR1 |= TIM_CR1_CEN; Этот код верный? Тактирование включено так: RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
×
×
  • Create New...