Портал для радиолюбителей и разработчиков электроники · с 2003 годаРеклама на сайте
Найти компонент, схему или даташит

Даташиты, справочник отечественных приборов, схемы с разбором и живой форум


 
Опции темы

STM32F103, непонятки с DMA

Непрочитано 29.10.2014, 22:37  
dosikus
Гуру портала
 
Аватар для dosikus
 
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
dosikus на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

Проверил одиночный выхлоп по твоему примеру - все в норме .



Код:
void _1wire_init (void)
{
	
	 uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};

	
	RCC-›AHBENR |=RCC_AHBENR_DMA1EN;
	DMA1_Channel7 -›CPAR = (uint32_t)& (TIM2-›CCR4);
	DMA1_Channel7 -›CMAR = (uint32_t)tim2_buff;
	DMA1_Channel7 -›CNDTR =9;
	DMA1_Channel7 -›CCR =
	                 DMA_CCR7_MSIZE_0 |
			 DMA_CCR7_PSIZE_0 |
			 DMA_CCR7_MINC |
			 DMA_CCR7_DIR  |
			 DMA_CCR7_EN ;
                    	
    
	         
	RCC-›APB1ENR |=  RCC_APB1ENR_TIM2EN;
	RCC-›APB2ENR |=  RCC_APB2ENR_IOPAEN;
	GPIOA-›CRL |= GPIO_CRL_MODE3; 
	GPIOA-›CRL &=~GPIO_CRL_CNF3;
	GPIOA-›CRL |=GPIO_CRL_CNF3_1;
	 TIM2-›CR1 |= TIM_CR1_ARPE ;
	 TIM2-›PSC =72-1;
	 TIM2-›ARR= 87-1;
	
	
   TIM2-›CCMR2 |= 
             TIM_CCMR2_OC4M_2 | 
             TIM_CCMR2_OC4M_1 | 
	     TIM_CCMR2_OC4PE |
             TIM_CCMR2_OC4FE  
                            ;   
  TIM2-›CCER |= 
             
             TIM_CCER_CC4E 
                          ;
 
	 
	 TIM2-›DIER = TIM_DIER_CC4DE;                               
   TIM2-›CR1 =  TIM_CR1_CEN;  
	
	
	 
	 
}
Миниатюры:
Нажмите на изображение для увеличения
Название: 2014-10-29_213420.png
Просмотров: 65
Размер:	109.6 Кб
ID:	71159  
Реклама:
__________________
Осторожно , злой кот

Последний раз редактировалось dosikus; 29.10.2014 в 22:52.
dosikus вне форума  
Непрочитано 29.10.2014, 22:55  
STM32F0
Заблокирован
 
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
STM32F0 на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

Сообщение от eddy Посмотреть сообщение
Но аппаратный 1-wire очень хочется сделать.
Попробуй сначала на голом таймере без ДМА. Там одного прерывания достаточно. На СТМ8 потери на прерывания не превышают 5-7%.
STM32F0 вне форума  
Непрочитано 30.10.2014, 10:43  
eddy
Почётный гражданин KAZUS.RUN
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

dosikus, а почему "DMA1_Channel7 -›CNDTR =9;" ?
И почему DMA_CCR7_PSIZE_0?
И полярность инвертированная получилась.

Но таки все равно странно... У меня не работает.
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
eddy вне форума  
Непрочитано 30.10.2014, 11:07  
eddy
Почётный гражданин KAZUS.RUN
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

Чертовщина какая-то! ЗАРАБОТАЛО!!!
Код:
uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};
uint16_t tim2_inbuff[9];

void init_dmatimer(){ // tim2_ch4 - PA3, no remap
	gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
			GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
	rcc_periph_clock_enable(RCC_TIM2);
	//nvic_enable_irq(NVIC_TIM2_IRQ);
	timer_reset(TIM2);
	// timers have frequency of 1MHz -- 1us for one step
	// 36MHz of APB1
	timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
	// 72MHz div 72 = 1MHz
	timer_set_prescaler(TIM2, 71); // prescaler is (div - 1)
	timer_continuous_mode(TIM2); // automatically reload
	timer_enable_preload(TIM2); // force changing period
	timer_set_period(TIM2, 86); // period is 87us
	timer_enable_update_event(TIM2);
	timer_set_oc_mode(TIM2, TIM_OC4, TIM_OCM_PWM1); // edge-aligned mode
	timer_enable_oc_preload(TIM2, TIM_OC4);
	timer_enable_oc_output(TIM2, TIM_OC4);
	timer_enable_irq(TIM2, TIM_DIER_UDE | TIM_DIER_CC4DE | TIM_DIER_CC3DE);

	// TIM2_CH4 - DMA1, channel 7
	rcc_periph_clock_enable(RCC_DMA1);
	dma_channel_reset(DMA1, DMA_CHANNEL7);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
	dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
	dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
	dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
	dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
	dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);

	nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr

	// capture: TIM2_CH3
	timer_ic_set_input(TIM2, TIM_IC3, TIM_IC_IN_TI4);
	timer_set_oc_polarity_high(TIM2, TIM_OC3);
	timer_ic_enable(TIM2, TIM_IC3);
	timer_enable_oc_output(TIM2, TIM_OC3);

	// configure DMA1 Channel1 (ADC1)
	dma_channel_reset(DMA1, DMA_CHANNEL1);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
	dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
	dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
	dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
	dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
	nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
	dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);
	dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
}

void run_dmatimer(){
	int i;
	DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_  GIF7 |
		DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_  GIF1; // clear flags

	dma_set_number_of_data(DMA1, DMA_CHANNEL7, 8);
	timer_set_dma_on_compare_event(TIM2);
	timer_set_oc_polarity_low(TIM2, TIM_OC4);
	timer_enable_oc_output(TIM2, TIM_OC4);

	dma_enable_channel(DMA1, DMA_CHANNEL7);
	timer_enable_counter(TIM2);

	for(i = 0; i ‹ 9; i++) tim2_inbuff[i] = 0;
	dma_set_number_of_data(DMA1, DMA_CHANNEL1, 9);
	dma_enable_channel(DMA1, DMA_CHANNEL1);
}

void dma1_channel7_isr(){
	if(DMA1_ISR & DMA_ISR_TCIF7) {
		DMA1_IFCR = DMA_IFCR_CTCIF7;
		dma_disable_channel(DMA1, DMA_CHANNEL7);
	}else if(DMA1_ISR & DMA_ISR_TEIF7){
		DMA1_IFCR = DMA_IFCR_CTEIF7;
		MSG("out transfer error\n");
	}
}

void dma1_channel1_isr(){
	int i;
	if(DMA1_ISR & DMA_ISR_TCIF1) {
		DMA1_IFCR = DMA_IFCR_CTCIF1;
		dma_disable_channel(DMA1, DMA_CHANNEL1);
		timer_disable_oc_output(TIM2, TIM_OC4);
		timer_set_oc_polarity_high(TIM2, TIM_OC4);
		timer_disable_counter(TIM2);
		for(i = 1; i ‹ 9; i++){
			print_int(tim2_inbuff[i], lastsendfun);
			MSG(" ");
		}
		MSG("\n");
	}else if(DMA1_ISR & DMA_ISR_TEIF1){
		DMA1_IFCR = DMA_IFCR_CTEIF1;
		MSG("in transfer error\n");
	}
}
Осталось только понять, какого хрена выход не устанавливается в единицу (timer_set_oc_polarity_high(TIM2, TIM_OC4) не отрабатывает почему-то)
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
eddy вне форума  
Непрочитано 30.10.2014, 11:12  
dosikus
Гуру портала
 
Аватар для dosikus
 
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
dosikus на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

eddy, А ХЗ )))))))) Поздно уже было .
Правильно конечно 8. А с 9 грузилось нечто в CCR4 большее ARR и ШИМ затыкался
А DMA_CCR7_PSIZE_0, у меня массив uint16_t .

Полярность - лень было пуллапы лепить - у меня пашпул, отсюда иверсия.
Но это все не суть ...
__________________
Осторожно , злой кот
dosikus вне форума  
Непрочитано 30.10.2014, 12:16  
eddy
Почётный гражданин KAZUS.RUN
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

Все, заработало! Всем спасибо.
Желающие посмотреть результат могут заглядывать периодически сюда или сюда.
Пока что 1-wire не завел, но как только, так сразу сделаю коммит.
Код:
uint16_t tim2_buff[8] = {10,20,30,40,50,60,70,80};
uint16_t tim2_inbuff[8];

void init_dmatimer(){ // tim2_ch4 - PA3, no remap
	gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
			GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO3);
	rcc_periph_clock_enable(RCC_TIM2);
	timer_reset(TIM2);
	// timers have frequency of 1MHz -- 1us for one step
	// 36MHz of APB1
	timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
	// 72MHz div 72 = 1MHz
	timer_set_prescaler(TIM2, 71); // prescaler is (div - 1)
	timer_continuous_mode(TIM2); // automatically reload
	timer_enable_preload(TIM2); // force changing period
	timer_set_period(TIM2, 86); // period is 87us
	timer_enable_update_event(TIM2);
	timer_set_oc_mode(TIM2, TIM_OC4, TIM_OCM_PWM1); // edge-aligned mode
	timer_enable_oc_preload(TIM2, TIM_OC4);
	timer_enable_oc_output(TIM2, TIM_OC4);
	timer_enable_irq(TIM2, TIM_DIER_UDE | TIM_DIER_CC4DE | TIM_DIER_CC3DE);
	timer_set_oc_polarity_low(TIM2, TIM_OC4);

	// TIM2_CH4 - DMA1, channel 7
	rcc_periph_clock_enable(RCC_DMA1);
	dma_channel_reset(DMA1, DMA_CHANNEL7);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t) &(TIM_CCR4(TIM2)));
	dma_set_read_from_memory(DMA1, DMA_CHANNEL7);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_16BIT);
	dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_16BIT);
	dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL7);
	dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL7);
	dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t)tim2_buff);

	nvic_enable_irq(NVIC_DMA1_CHANNEL7_IRQ); // enable dma1_channel7_isr

	// capture: TIM2_CH3
	timer_ic_set_input(TIM2, TIM_IC3, TIM_IC_IN_TI4);
	timer_set_oc_polarity_high(TIM2, TIM_OC3);
	timer_ic_enable(TIM2, TIM_IC3);
	timer_enable_oc_output(TIM2, TIM_OC3);

	// configure DMA1 Channel1 (ADC1)
	dma_channel_reset(DMA1, DMA_CHANNEL1);
	dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t) &(TIM_CCR3(TIM2)));
	dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t) tim2_inbuff);
	dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
	dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
	dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
	dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL1);
	dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
	dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
	nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
	dma_enable_transfer_error_interrupt(DMA1, DMA_CHANNEL1);
	dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
}

void run_dmatimer(){
	int i;
	DMA1_IFCR = DMA_ISR_TEIF7|DMA_ISR_HTIF7|DMA_ISR_TCIF7|DMA_ISR_  GIF7 |
		DMA_ISR_TEIF1|DMA_ISR_HTIF1|DMA_ISR_TCIF1|DMA_ISR_  GIF1; // clear flags

	dma_set_number_of_data(DMA1, DMA_CHANNEL7, 8);
	timer_set_dma_on_compare_event(TIM2);
	timer_enable_oc_output(TIM2, TIM_OC4);
	dma_enable_channel(DMA1, DMA_CHANNEL7);
	timer_enable_counter(TIM2);

	for(i = 0; i ‹ 8; i++) tim2_inbuff[i] = 0;
	dma_set_number_of_data(DMA1, DMA_CHANNEL1, 8);
	dma_enable_channel(DMA1, DMA_CHANNEL1);
}

void dma1_channel7_isr(){
	if(DMA1_ISR & DMA_ISR_TCIF7) {
		DMA1_IFCR = DMA_IFCR_CTCIF7;
		dma_disable_channel(DMA1, DMA_CHANNEL7);
	}else if(DMA1_ISR & DMA_ISR_TEIF7){
		DMA1_IFCR = DMA_IFCR_CTEIF7;
		MSG("out transfer error\n");
	}
}

void dma1_channel1_isr(){
	int i;
	if(DMA1_ISR & DMA_ISR_TCIF1) {
		DMA1_IFCR = DMA_IFCR_CTCIF1;
		dma_disable_channel(DMA1, DMA_CHANNEL1);
		timer_disable_counter(TIM2);
		gpio_set(GPIOA, GPIO3);
		for(i = 0; i ‹ 8; i++){
			print_int(tim2_inbuff[i], lastsendfun);
			MSG(" ");
		}
		MSG("\n");
	}else if(DMA1_ISR & DMA_ISR_TEIF1){
		DMA1_IFCR = DMA_IFCR_CTEIF1;
		MSG("in transfer error\n");
	}
}
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
eddy вне форума  
Непрочитано 30.10.2014, 22:07  
eddy
Почётный гражданин KAZUS.RUN
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

Ох и нелегкая же задача — с таймерами через DMA работать!
Переделал функции для работы с разным количеством данных (они помещаются в один и тот же буфер, предельное количество бит за одну посылку == 12. Опять хрень какая-то! Такое впечатление, что DMA у меня где-то неправильно срабатывает: первая посылка вроде отрабатывает, а потом хрень какая-то; да и постоянно у таймера меняется уровень в выключенном состоянии (вообще беда с ним: счетчик отключаю, но таймер не позволяет явно ногу установить в 1; добавляю до выключения таймера установку пассивного уровня в 1, но срабатывает через раз).
Но добить надо будет обязательно.
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
eddy вне форума  
Непрочитано 31.10.2014, 07:32  
niXto
Почётный гражданин KAZUS.RUN
 
Аватар для niXto
 
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,026
Сказал спасибо: 60
Сказали Спасибо 3,941 раз(а) в 2,302 сообщении(ях)
niXto на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

А не проще глянуть отладчиком?
Тем более если он поддерживается
Это только в первый раз сложно, а в дальнейшем такие проблемы будут решаться за десятки минут
niXto вне форума  
Непрочитано 31.10.2014, 09:16  
dosikus
Гуру портала
 
Аватар для dosikus
 
Регистрация: 20.11.2004
Сообщений: 9,979
Сказал спасибо: 928
Сказали Спасибо 2,261 раз(а) в 1,557 сообщении(ях)
dosikus на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

niXto, А у него только хардкор -дебуггер в консоли , надо наизусть помнить все адреса и регистры ...
__________________
Осторожно , злой кот
dosikus вне форума  
Непрочитано 31.10.2014, 09:26  
eddy
Почётный гражданин KAZUS.RUN
 
Аватар для eddy
 
Регистрация: 27.01.2005
Адрес: Россия, КЧР, Нижний Архыз
Сообщений: 3,684
Сказал спасибо: 116
Сказали Спасибо 823 раз(а) в 597 сообщении(ях)
eddy на пути к лучшему
По умолчанию Re: STM32F103, непонятки с DMA

Сообщение от niXto Посмотреть сообщение
А не проще глянуть отладчиком?
Нет отладчика кроме printf ☺
__________________
Если ты пользуешься Windows, то ты финансируешь мировой терроризм!
eddy вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
STM32 - Tips 'N Tricks nahimovv ARM 28 14.10.2024 06:42
STM32F103 ADC+DMA Nik_UFO Микроконтроллеры, АЦП, память и т.д 11 24.08.2016 11:57
Tim19 -> DMA -> значение ADC в memory kvark85 ARM 6 03.06.2014 15:00
STM32 Повторный запуск DMA Nik_UFO Микроконтроллеры, АЦП, память и т.д 2 07.03.2012 17:38
DMA в ATxmega vav618 Микроконтроллеры, АЦП, память и т.д 1 03.04.2010 10:57


Часовой пояс GMT +4, время: 02:36.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.