27.12.2020, 19:41
|
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,637
Сказал спасибо: 117
Сказали Спасибо 814 раз(а) в 591 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от sat_art
|
(uint32_t)(&dmabuff);
|
Не, dmabuff - это адрес массива, брать его адрес не нужно...
Теперь разбираюсь, как правильно таймер остановить, чтобы последний импульс был нужной длины, а после него был 0.
__________________
Союз Советских Социалистических Округов Северной Америки
|
|
|
|
27.12.2020, 19:47
|
|
Вид на жительство
Регистрация: 27.11.2007
Сообщений: 429
Сказал спасибо: 19
Сказали Спасибо 39 раз(а) в 30 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
eddy, ну много вариантов. Впрерывании ДМА включай прерывание ТИМУпдейт и там выключай таймер.
Второй - включить прелоадер для CCR таймера и писать 0 в CCR в прерывании ДМА (если у 103-го есть прелоадер для него - не помню).
И
dmabuff - это массив, а &dmabuff - указатель - т.е. адрес.
|
|
|
|
27.12.2020, 19:57
|
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,637
Сказал спасибо: 117
Сказали Спасибо 814 раз(а) в 591 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Сообщение от sat_art
|
Впрерывании ДМА включай прерывание ТИМУпдейт и там выключай таймер.
|
Не получается: последний импульс обрезается при этом:
Код:
|
void tim1_up_isr(){
TIM1-›SR = 0;
TIM1-›CCR1 = 0;
TIM1-›CR1 = 0;
}
void dma1_channel5_isr(){
if(DMA1-›ISR & DMA_ISR_TCIF5){ // transfer complete - stop
TIM1-›DIER = TIM_DIER_UIE;
}
DMA1-›IFCR = DMA_IFCR_CGIF5;
} |
Сообщение от sat_art
|
включить прелоадер для CCR таймера и писать 0 в CCR в прерывании ДМА
|
Тоже фигня какая-то получается...
Сообщение от sat_art
|
dmabuff - это массив, а &dmabuff - указатель - т.е. адрес.
|
dmabuff - это и есть адрес. А &dmabuff - адрес размещения этого адреса.
__________________
Союз Советских Социалистических Округов Северной Америки
|
|
|
|
27.12.2020, 20:00
|
|
Вид на жительство
Регистрация: 27.11.2007
Сообщений: 429
Сказал спасибо: 19
Сказали Спасибо 39 раз(а) в 30 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Да поступи проще - сделай 10 значений в буфере - последнее 0.
|
|
|
|
27.12.2020, 20:23
|
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,637
Сказал спасибо: 117
Сказали Спасибо 814 раз(а) в 591 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
sat_art, не, это не кошерно. Решил этот трэш так:
Код:
|
void tim1_up_isr(){
TIM1-›SR = 0;
TIM1-›CCR1 = 0;
}
void tim1_cc_isr(){
TIM1-›SR = 0;
TIM1-›CR1 |= TIM_CR1_OPM;
TIM1-›DIER = TIM_DIER_UIE;
}
void dma1_channel5_isr(){
if(DMA1-›ISR & DMA_ISR_TCIF5){ // transfer complete - stop
DMA1_Channel5-›CCR &= ~DMA_CCR_EN;
TIM1-›DIER = TIM_DIER_CC1IE;
}
DMA1-›IFCR = DMA_IFCR_CGIF5;
}
static void sendone(){
TIM1-›CR1 = 0; // stop
TIM1-›DIER = TIM_DIER_UDE; // enable DMA requests
DMA1-›IFCR = DMA_IFCR_CGIF5;
DMA1_Channel5-›CNDTR = 6;
DMA1_Channel5-›CMAR = (uint32_t)dmabuff;
DMA1_Channel5-›CCR |= DMA_CCR_EN; // start DMA
TIM1-›CR1 = TIM_CR1_CEN | TIM_CR1_URS;
} |
Дело в том, что я для светодиодной ленты на WS2815 код выдумываю. И там буфер ограничен 48 записями. В прерывании по половине передачи DMA заполняю первые 24 байта, в прерывании по окончании передачи заполняю вторые 24. А как количество светодиодов кончилось, отключаю передачу…
__________________
Союз Советских Социалистических Округов Северной Америки
|
|
|
|
27.12.2020, 20:25
|
|
Вид на жительство
Регистрация: 27.11.2007
Сообщений: 429
Сказал спасибо: 19
Сказали Спасибо 39 раз(а) в 30 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
А это кошерно?
|
|
|
|
27.12.2020, 20:33
|
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,637
Сказал спасибо: 117
Сказали Спасибо 814 раз(а) в 591 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Тоже фигня получается: пока на низких частотах работал, нормально было. Как только установил нужную — получаю в конце 2 лишних импульса. И даже добавление в конец массива нуля не дает ничего: получаю лишний короткий импульс длительностью около 120нс... И он не пропадает, даже если я таймер в прерывании DMA отключаю!
Сейчас проверил: если в середину массива 0 добавить, то все равно не получается нуля (на 1 такт таймера вылезает единица). В принципе, это и в RM написано: чтобы вообще 0 на ШИМ получить, нужно выбирать второй режим, а не первый. А мне второй режим не подходит.
__________________
Союз Советских Социалистических Округов Северной Америки
Последний раз редактировалось eddy; 27.12.2020 в 20:37.
|
|
|
|
27.12.2020, 20:40
|
|
Вид на жительство
Регистрация: 27.11.2007
Сообщений: 429
Сказал спасибо: 19
Сказали Спасибо 39 раз(а) в 30 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
Попробуй
void dma1_channel5_isr(){
.
.
TIM1-›CR|=TIM_CR1_OPM;
}
|
|
|
|
27.12.2020, 20:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,637
Сказал спасибо: 117
Сказали Спасибо 814 раз(а) в 591 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
В итоге внезапно нужное количество импульсов без урезания длительности последнего получилось так:
Код:
|
void dma1_channel5_isr(){
if(DMA1-›ISR & DMA_ISR_TCIF5){ // transfer complete - stop
TIM1-›CR1 = 0;
TIM1-›DIER = 0;
}
DMA1-›IFCR = DMA_IFCR_CGIF5;
}
uint8_t dmabuff[] = {3,6,3,3,6,6,3,6};
static void sendone(){
TIM1-›CR1 = 0; // stop
DMA1_Channel5-›CCR &= ~DMA_CCR_EN; // disable DMA to reconfigure
TIM1-›DIER = TIM_DIER_UDE; // enable DMA requests
DMA1-›IFCR = DMA_IFCR_CGIF5;
DMA1_Channel5-›CNDTR = 8;
DMA1_Channel5-›CMAR = (uint32_t)dmabuff;
DMA1_Channel5-›CCR |= DMA_CCR_EN; // start DMA
TIM1-›CR1 = TIM_CR1_CEN | TIM_CR1_URS;
} |
Но если PSC увеличить, получается полная лажа!
OPM не спасает.
__________________
Союз Советских Социалистических Округов Северной Америки
Последний раз редактировалось eddy; 27.12.2020 в 20:51.
|
|
|
|
27.12.2020, 21:02
|
|
Почётный гражданин KAZUS.RU
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,637
Сказал спасибо: 117
Сказали Спасибо 814 раз(а) в 591 сообщении(ях)
|
Re: Изучаем STM32 Cortex M3
В общем, эксперименты показали, что на большой скорости нельзя выставлять линию в нуль в отложенном прерывании по CC или UE. Нужно это делать сразу в прерывании DMA. И безразлично, выключаем мы таймер сразу, или же ставим OPM: все равно работает и так, и так.
А вот в случае с малыми частотами нужно активировать прерывания таймера...
Очень хреново, что даже в режиме OPM на событии UE выход устанавливается в нуль!
__________________
Союз Советских Социалистических Округов Северной Америки
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 12:17.
|
|