Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту


 
Опции темы

Аппаратный учет числа импульсов ШИМ

Непрочитано 26.10.2016, 00:56  
backlan
Частый гость
 
Аватар для backlan
 
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
backlan на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Сообщение от omercury Посмотреть сообщение
1. Какова частота STEP с Вашего "велосипеда"?
2. Какова частота ШИМ драйвера приводов ШД?
3. Сколько шагов пропустит драйвер за один период ШИМ?
Пока гонял на 400 мм/мин, больше не тянет.
400 * 160 шагов/мм * 16 делений / 60 сек = 17 кГц
ШИМ драйвера 30-50кГц
Если драйвер пропустит микрошаги, это не проблема, просто вместо последовательного подключения обмоток будет, например, последовательное подключение пар обмоток. Таким образом на низких частотах обеспечивается плавность, а на высоких нет пропуска шагов.

Сообщение от omercury Посмотреть сообщение
Ну и пожалуй самый главный вопрос: Пацаны, вы по какому принципу себе такие "говорящие" ники выбираете?
Что в голову пришло, то и написал.

Так вот, я же не договорил. Это в обычной памяти переключение битов не работает через пдп, а для GPIO же есть BSRR. Можно настроить таймер на каждом тике запускать пдп, который будет в цикле из буфера на 2 элемента выгребать int и писать в BSRR. Вопрос только в задержке, за сколько запустится этот самый пдп, если их будет много.

PS. кто-то уже провел такой эксперимент.
http://caxapa.ru/395890.html
Реклама:

Последний раз редактировалось backlan; 26.10.2016 в 01:11. Причина: Вспомнил, что хотел сказать.
backlan вне форума  
Непрочитано 26.10.2016, 01:13  
omercury
Почётный гражданин KAZUS.RUN
 
Аватар для omercury
 
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,487
Сказал спасибо: 30
Сказали Спасибо 3,070 раз(а) в 2,011 сообщении(ях)
omercury на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Сообщение от backlan Посмотреть сообщение
больше не тянет
Больше не тянуть вполне может и сам мотор - скорость нарастания тока в обмотках тоже не бесконечно малая. Плюс падение момента с нарастанием оборотов.

Сообщение от backlan Посмотреть сообщение
Вопрос только в задержке, за сколько запустится этот самый пдп, если их будет много.
В любом случае это будет быстрее, чем "переварит" мотор. Самая медленная часть в Вашем случае именно механика.
omercury вне форума  
Непрочитано 26.10.2016, 09:37  
NewWriter
Почётный гражданин KAZUS.RUN
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,481
Сказал спасибо: 396
Сказали Спасибо 2,222 раз(а) в 1,317 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Мне так кажется, топикстартер вообще-то идет не по правильному пути, особенно заморачиваясь с чтением счетного регистра через пдп, и особенно с заморочками с выходными портами. Читать то по пдп можно, но все равно придется все время программно сидеть в цикле ожидания, проверяя то, чего сбросил пдп. Получается, что на время работы ШД все остальные операции с МК будут перекрыты ожиданием.

И кстати, ШГ в режиме микрошага управляется двумя ступенчатыми сигналами, близкими к синусоиде, сдвинутыми на 90° относительно друг друга.
И лично мне кажется вообще чето во всей этой затее есть неправильное. Если уже есть самодельный контроллер ШД на МК, то зачем ставить еще одну коробочку с похожим функционалом? Это у ардуинистов принято наслаивать бутерброды плат на штырьках и клеммниках, плодя кучу промежуточных модулей в силу нехватки ресурсов каждого из них.

По-хорошему бы вот, главный управляющий контроллер должен лишь выдать команды исполнительным контроллерам в формате "куда и насколько и с какой скоростью переместить". А уже исполнительные контроллеры ШД, работающие через силовые драйвера ШД, должны сами посчитать импульсы.
Либо, если хотите одним МК управлять всем, то просто берите более мощный МК с большим числом таймеров. Но и тут могут быть затыки, надо сначала просмотреть связи таймеров и наличие таймеров с нужными номерами. В результате по цене такое решение окажется чуть ли не дороже, чем три раздельных МК, управляющих каждым ШД.

Последний раз редактировалось NewWriter; 26.10.2016 в 09:49.
NewWriter вне форума  
Непрочитано 27.10.2016, 00:37  
backlan
Частый гость
 
Аватар для backlan
 
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
backlan на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Новый вариант, на счётчике байт dma.
Нажмите, чтобы открыть спойлер
Код:
#include "stm32f0xx_syscfg.h"
#include "stm32f0xx_gpio.h"
#include "stm32f0xx_rcc.h"
#include "stm32f0xx_tim.h"
#include "stm32f0xx_exti.h"
#include "stm32f0xx_adc.h"
#include "stm32f0xx_dma.h"
#include "stdbool.h"

char dummyArray[256];

//==================================================  =======================
#define SYSTEM_CLOCK 48000000                           //частота процессора и таймеров
#define SYSTEM_TIMER_CLOCK 6000000                      //стоит кварц на 8 МГц *6 /8

//==================================================  =======================
void init_pins()
{
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

	GPIO_InitTypeDef GPIO_InitStruct;

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
}

//==================================================  =======================
void connect_pins()
{
	//stm32f031 datasheet, 31
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); //TIM1 CH1
}

//==================================================  =======================
void init_tim()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

	TIM_TimeBaseInitTypeDef timerBase;
	TIM_TimeBaseStructInit(&timerBase);

	timerBase.TIM_Prescaler = 0; //длительность шага будет задаваться в процессе
	timerBase.TIM_Period = 1; //скважность всегда 50%, для этого хватит 2 тактов на период
	TIM_TimeBaseInit(TIM1, &timerBase);

	TIM_OCInitTypeDef timerPWM;
	TIM_OCStructInit(&timerPWM);
	timerPWM.TIM_Pulse = 0; //регулирование скважности не нужно
	timerPWM.TIM_OCMode = TIM_OCMode_Toggle;
	timerPWM.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OC1Init(TIM1, &timerPWM);

	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
}

//==================================================  =======================
void init_dma()
{
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

	DMA_InitTypeDef dmaInit;
	dmaInit.DMA_BufferSize = 256;
	dmaInit.DMA_DIR = DMA_DIR_PeripheralSRC;
	dmaInit.DMA_M2M = DMA_M2M_Disable;
	dmaInit.DMA_MemoryBaseAddr = dummyArray;
	dmaInit.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	dmaInit.DMA_MemoryInc = DMA_MemoryInc_Enable;
	dmaInit.DMA_Mode = DMA_Mode_Circular;
	dmaInit.DMA_PeripheralBaseAddr = &TIM1-›PSC;
	dmaInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	dmaInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	dmaInit.DMA_Priority = DMA_Priority_High;

	DMA_Init(DMA1_Channel5, &dmaInit);

	//TIM_DMAConfig(TIM1, TIM_DMABase_CNT, TIM_DMABurstLength_1Transfer);
	TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);

	DMA_Cmd(DMA1_Channel5, ENABLE);
}

//==================================================  =======================
void init_timer()
{
	SysTick-›LOAD = SysTick_LOAD_RELOAD_Msk;
	SysTick-›CTRL = SysTick_CTRL_ENABLE_Msk;//SysTick_CTRL_CLKSOURCE_Msk |
}

//==================================================  =======================
void init()
{
	init_pins();
	connect_pins();
	init_tim();
	init_dma();
	init_timer();
}

//==================================================  =======================
inline int get_timer()
{
	return -SysTick-›VAL;       //он всегда downcounter, тикает в обратную сторону
}

//==================================================  =======================
inline int time_delta(int value) //максимум 16777216/6000000 ~= 2 сек
{
	return (get_timer() - value) & 0xFFFFFF;
}

inline int get_count()
{
	DMA1_Channel5-›CNDTR;
}

//==================================================  =======================
int main(void)
{
	init();
	int time = get_timer();
	const int UPDATE_TIME = 100;

	int period[] = {10, 50, 60, 200};
	int index = 0;
	TIM1-›PSC = period[index];
	TIM_Cmd(TIM1, ENABLE);
	int last = get_count(); //здесь лежит число импульсов

	while (1)
	{
		if (time_delta(time) › UPDATE_TIME)
		{
			time = get_timer();
			index = (index + 1) & 3;
			TIM1-›PSC = period[index];
			int current = get_count();
			int delta = current - last;
			static int cc = 0;
			if (++cc › 4)
				cc = 0;
			last = current;
		}
	}
}


Осталось выяснить, можно ли задать ему произвольный адрес, чтобы не выделять здоровый массив dummyArray лишь для того, чтобы под рукой был счетчик.
backlan вне форума  
Непрочитано 27.10.2016, 01:01  
NewWriter
Почётный гражданин KAZUS.RUN
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,481
Сказал спасибо: 396
Сказали Спасибо 2,222 раз(а) в 1,317 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

счетчик числа транзакций DMA будет выполнять ту же работу, что счетчик числа событий UEV (обновления) таймера. Только в процесс вовлекают еще и канал DMA, и уж совсем для полного счастья - массив размером до 64 килобайт - по количеству возможных транзакций DMA. И счетчик транзакций считает число оставшихся от начального значения, а не число проведенных транзакций.
Нужно убрать инкремент адресов памяти (DMA_MemoryInc), тогда будет писать в один и тот же адрес памяти. А отслеживать программно число оставшихся транзакций - это тупиковый путь.

Если задать начальное значение для счетчика DMA, то DMA после передачи последнего элемента выключится и, если разрешено, вызовет прерывание TCIF. В этом прерывании можно будет остановить таймер. Максимальное число отсчитываемых таким способом импульсов - 65536.
Сообщение от backlan Посмотреть сообщение
можно ли задать ему произвольный адрес
"ему" - это чему? Произвольный адрес массива уже и так задан - второй конец DMA-пути.
Так же можно задать любой адрес на первом конце DMA. Вообще любой.

Последний раз редактировалось NewWriter; 27.10.2016 в 01:41.
NewWriter вне форума  
Непрочитано 27.10.2016, 15:52  
backlan
Частый гость
 
Аватар для backlan
 
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
backlan на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Сообщение от NewWriter Посмотреть сообщение
1. счетчик числа транзакций DMA будет выполнять ту же работу, что счетчик числа событий UEV (обновления) таймера.

2. Нужно убрать инкремент адресов памяти (DMA_MemoryInc), тогда будет писать в один и тот же адрес памяти.
1. Всё верно, для того и делалось, зато не приходится ещё один таймер занимать. Теперь мне на все 4-5 осей таймеров хватит.

2. Точно! Я думал, что напрямую счётчик оставшихся операций будет недоступен, и надо будет через указатель на память вытаскивать значения. Тогда почти всё готово. Ещё бы как-то объяснить DMA, чтобы он в память не лез
backlan вне форума  
Непрочитано 27.10.2016, 16:59  
NewWriter
Почётный гражданин KAZUS.RUN
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,481
Сказал спасибо: 396
Сказали Спасибо 2,222 раз(а) в 1,317 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

1. Не спешите радоваться. Посмотрите табличку распределения запросов по каналам. Каналов всего 5 в F0чч, и может не получиться распределить все запросы.

2а. Регистр CNDTR имеет режим доступа read/write. Но не обязательно его читать. Когда он будет =0, канал остановится и отправит (если разрешено) запрос прерывания по передаче полного буфера.

2б. DMA - ... доступ к памяти. Так что полюбому второй конец маршрута будет подключен к какой-либо памяти.
NewWriter вне форума  
Непрочитано 27.10.2016, 17:53  
backlan
Частый гость
 
Аватар для backlan
 
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
backlan на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Уже посмотрел для STM32F100 и распихал, 5 осей влезло, ещё и 4 выхода для ШИМ осталось. Думал сделать режим с длиной периода = 2 такта и заполнением 50%, но запросы TIM_DMA_Update и TIM_DMA_CC1 идут к разным каналам, так что не прокатило. Сделал toggle mode для выхода таймера, и здесь небольшая засада - минимальная длительность периода = 2 тактам, половина возможной частоты на этом теряется. А хочется сделать, чтобы на каждом срабатывании CNT выход GPIO переключался. Ну в общем и так сойдёт .
По тактированию тоже всё сошлось, как раз из-за этого деления частоты получалось в 2 раза меньше.

Последний раз редактировалось backlan; 27.10.2016 в 18:03.
backlan вне форума  
Непрочитано 29.10.2016, 15:45  
backlan
Частый гость
 
Аватар для backlan
 
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
backlan на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Для большого периода шага понадобилось вручную переключать выход таймера. Поскольку он сделан toggle, сразу не разберёшь, в каком состоянии находится выход, и хотелось бы сделать переключение так же, как он сам делает. Если CCRx = 0, тогда подходит такой код:
Код:
TIM2-›CNT = TIM2-›ARR;
TIM2-›EGR = TIM_EGR_UG;
Если CCRx != 0, тогда такой
Код:
TIM2-›EGR = TIM_EGR_UG;
TIM2-›CNT = TIM2-›CCR1;

Последний раз редактировалось backlan; 12.11.2016 в 17:00. Причина: баг в коде
backlan вне форума  
Непрочитано 07.01.2017, 16:24  
backlan
Частый гость
 
Аватар для backlan
 
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
backlan на пути к лучшему
По умолчанию Re: Аппаратный учет числа импульсов ШИМ

Нашел один интересный баг, с которым пришлось повозиться пол дня. Если в процессе работы таймера записать ARR = 0, то таймер зависнет, переключение бита CEN не поможет. Под отладчиком это выглядело так, как будто таймер сломался, потому что в ARR уже записалось новое значение, которое выглядело нормальным, бит CEN стоял. А если щёлкнуть UG, таймер продолжал дальше нормально работатьб потому что ARR перезаписывался на нормальный.

И ещё одно "открытие". Если не установлен бит ARPE, тогда лучше не трогать ARR, когда таймер включен, иначе он может проскочить максимальное значение. Например:
ARR = 1000, CNT = 800.
Записываем ARR = 500, а CNT продолжает считать до максимального значения 2^16. Эти грабли пару дней искал, выглядело как ошибка алгоритма коррекции траектории. После исправления стало попадать практически пиксель в пиксель.
backlan вне форума  
 
Опции темы

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
stm32 как шим контроллер Reystlin Микроконтроллеры, АЦП, память и т.д 35 22.03.2016 11:34
Режимы сна Атмега-8 putmannn AVR 123 08.03.2013 15:30
Управление Сервой Mg995 Через Аппаратный Шим Vyazikov Микроконтроллеры, АЦП, память и т.д 16 06.04.2012 21:06
Проблема с аппаратным ШИМ в мега169 Archer07 Микроконтроллеры, АЦП, память и т.д 3 09.07.2010 15:40
Заменить ШИМ на генератор импульсов ? Zemlyanov Микроконтроллеры, АЦП, память и т.д 1 15.05.2007 21:31


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


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