Jump to content

strifonoff

Members
  • Content Count

    1195
  • Joined

  • Last visited

Community Reputation

161 Хороший

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