22.10.2016, 23:26
|
|
Заблокирован
Регистрация: 16.03.2005
Сообщений: 5,918
Сказал спасибо: 560
Сказали Спасибо 9,145 раз(а) в 2,892 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Сообщение от индюк
|
на рассыпухе которые тоже больше 50 кгц не могут. ну 100кгц максимум
|
Для недорогих, вот это пожалуй максимум:
(Можно найти до 300 кГц)
Последний раз редактировалось verdana; 22.10.2016 в 23:38.
|
|
|
|
22.10.2016, 23:29
|
|
Частый гость
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
У меня свои драйвера на STM32, там аппаратно таймер шаги считает, так что можно и 10 МГц, лишь бы порт столько мог осилить.
|
|
|
|
22.10.2016, 23:43
|
|
Заблокирован
Регистрация: 16.03.2005
Сообщений: 5,918
Сказал спасибо: 560
Сказали Спасибо 9,145 раз(а) в 2,892 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Сообщение от backlan
|
У меня свои драйвера на STM32,
|
А Вы не задумывались почему не выпускают выше 200-300 кГц?
P.S.
Ответ-"Нешмогли"- неверный.
|
|
|
|
23.10.2016, 00:04
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,220 раз(а) в 1,319 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Сообщение от backlan
|
У меня свои драйвера
|
Ну а моторчик то может крутиться на таких скоростях? Как бы 4800 об/мин или 16 тыс.шагов в секунду нужно. А моторчики так то поменьше дозволяют. А если больше - то вот оно и гудение бешеное.
Может вместо ходового винта поставить шестерню и зубчатый ремень? Как на принтерах струйных и матричных.
|
|
|
|
23.10.2016, 00:47
|
|
Частый гость
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Это уже не выход. Если даже взять шаг = 0.01 мм, то надо будет 10 000 шагов/сек для жалких 10 см/сек. В будущем заменю шаговые на сервы и всё равно упрусь в производительность.
|
|
|
|
23.10.2016, 00:47
|
|
Гуру портала
Регистрация: 17.07.2010
Адрес: мурмурляндия
Сообщений: 10,700
Сказал спасибо: 189
Сказали Спасибо 3,191 раз(а) в 2,068 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
если передатчик на проце и драйвер на проце зачем тогда такое тупое управление? по шине дай ему команду 500-1000 микрошагов насчитать и пусть наваливает мотору там сколько приказали....
нда - вобщем очередной кулибин......... обсуждать наверно нечего с ним.
дома пусть делает чо хочет а на техническом уровне таким обычно выносят вердикт -неумение правильно поставить задачу, неумение рационально распоряжаться техническими ресурсами.
__________________
кагмаподэ магмаподэ
Последний раз редактировалось индюк; 23.10.2016 в 00:51.
|
|
|
|
23.10.2016, 01:02
|
|
Частый гость
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Делал уже свой интерфейс, напрямую выдавал ШИМ для движков, так что с меня такого хватит , хочу сделать стандартный. Странно что вы Кулибина с отрицательным акцентом упоминаете, но мне сравнение с ним льстит . Вот именно, делаю дома что хочу, и вопрос я задавал не по станку, а по микроконтроллеру. Как придумаю подходящий вариант, выложу сюда код.
|
|
|
|
23.10.2016, 11:01
|
|
Заблокирован
Регистрация: 16.03.2005
Сообщений: 5,918
Сказал спасибо: 560
Сказали Спасибо 9,145 раз(а) в 2,892 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Сообщение от backlan
|
. Как придумаю подходящий вариант, выложу сюда код.
|
Вы не поверите,
но для того чтобы написать грамотную программу,
ну хотя бы для управления воротами в гараже,
нужно в первую очередь хорошо знать
механику и электротехнику, а не языки программирования
|
|
|
Сказали "Спасибо" verdana
|
|
|
23.10.2016, 17:04
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,220 раз(а) в 1,319 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Сообщение от backlan
|
придумаю подходящий вариант
|
Есть вот такой вариант аппаратного управления стартом, ускорением, замедлением и остановкой. Работает полностью аппаратно, даже при остановленном МК, так что достаточно задать длительность работы одного таймера и запустить его. Частота генерируемых импульсов автоматически начнет увеличиваться, затем постоянная частота, затем уменьшение частоты и прекращение генерации.
Используются три таймера. Собственно, генерация выходного меандра на TIM1, изменение частоты генерации меандра таймером TIM3 (отправляет запросы DMA для загрузки регистра TIM1-›PSC), и главный таймер TIM2, запускающий и останавливающий работу таймеров. Именно этот таймер и определяет количество выдаваемых импульсов
Для визуальных тестов специально задал низкие частоты и вывел контрольки работы на светодиоды:
Нажмите, чтобы открыть спойлер
PHP код:
|
uint16_t Period[12] = {64000, 48000, 36000, 24000, // ускорение
12000, 12000, 12000, 12000, // константа
24000, 36000, 48000, 64000}; // замедление
void Interface_Init(void)
{
/* Настройка выходов */
RCC-›APB2ENR |= RCC_APB2ENR_IOPAEN ; // Тактирование PA
/* TIM1 Ch 1, pulse out PA8 */
GPIOA-›CRH &= ~GPIO_CRH_CNF8; // Очистка бит выбора режима
GPIOA-›CRH |= GPIO_CRH_MODE8; // 50 MHz
GPIOA-›CRH |= GPIO_CRH_CNF8_1; // AF
/* TIM2 Ch 2, Enable out PA1 */
GPIOA-›CRL &= ~GPIO_CRL_CNF1; // Очистка бит выбора режима
GPIOA-›CRL |= GPIO_CRL_MODE1; // 50 MHz
GPIOA-›CRL |= GPIO_CRL_CNF1_1; // AF
/* Контролька TIM1 Ch2 PA9 */
GPIOA-›CRH &= ~GPIO_CRH_CNF9; // Очистка бит выбора режима
GPIOA-›CRH |= GPIO_CRH_MODE9; // 50 MHz
GPIOA-›CRH |= GPIO_CRH_CNF9_1; // AF
/* Контролька TIM3 Ch1 PA6 */
GPIOA-›CRL &= ~GPIO_CRL_CNF6; // Очистка бит выбора режима
GPIOA-›CRL |= GPIO_CRL_MODE6; // 50 MHz
GPIOA-›CRL |= GPIO_CRL_CNF6_1; // AF
/* ......................
* Настройка таймера TIM1 генерации импульсов
* Slave Gated, ITR1 (от TIM2)
* Ch1, PWM mode 2, 50%,
* PSC от DMAR
*
* __/--\__/--\
* | |
*/
RCC-›APB2ENR |= RCC_APB2ENR_TIM1EN;
TIM1-›PSC = 24000-1; //(управляется по DMA) PSC = Fh / (ARR * Fi)
TIM1-›ARR = 100-1; // частота выходных импульсов Fi = Fh /(PSC * ARR)
TIM1-›CCR1 = 50; // PWM 50%
TIM1-›SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_2 | // Gated mode
TIM_SMCR_TS_0; // ITR1 (TIM2)
/* Ch1 */
TIM1-›CCMR1 |= TIM_CCMR1_OC1M | TIM_CCMR1_OC1PE; // PWM mode2
TIM1-›CCER |= TIM_CCER_CC1E ; // PWM out enable
TIM1-›BDTR = TIM_BDTR_MOE; // Master out
//*********************
TIM1-›DCR = 0x0A ; // доступ DMA к PSC
//*********************
TIM1-›CR1 |= TIM_CR1_CEN; // таймер запущен
/* ......................
* Настройка таймера и DMA
* Выдает по UEV сигналы для изменения частоты TIM1
* Запускается от главного TIM2 одновременно с TIM1
* Slave Geted mode, ITR1 от TIM2
*
* DMA1, Ch3, Mem-›Periph, 16/16 bit
*/
RCC-›APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3-›PSC = 24000-1; //
TIM3-›ARR = 1000-1; // Период изменения частоты TIM1
TIM3-›DIER |= TIM_DIER_UDE; // разрешен запрос DMA от UEV
TIM3-›SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_2 | // Gated mode
TIM_SMCR_TS_0; // ITR1 (TIM2)
/* Контролька работы TIM3 Ch 1*/
TIM3-›CCR1 = 100;
TIM3-›CCMR1 = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM mode1
TIM3-›CCER = TIM_CCER_CC1E ; // PWM out enable
/* DMA1, Ch3 */
RCC-›AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel3-›CCR |= DMA_CCR3_DIR | // Mem-›Periph
DMA_CCR3_MINC | // Mem incr
DMA_CCR3_CIRC | //
DMA_CCR3_PSIZE_0 | DMA_CCR3_MSIZE_0 |
DMA_CCR3_PL_0; // Prior. Medium
DMA1_Channel3-›CNDTR = 12; // Число передач
DMA1_Channel3-›CMAR = (uint32_t)&Period;
DMA1_Channel3-›CPAR = (uint32_t)&TIM1-›DMAR;
DMA1_Channel3-›CCR |= DMA_CCR3_EN; // Канал включен
TIM3-›CR1 |= TIM_CR1_CEN; // TIM3 запущен
/* ......................
* Настройка TIM2. Главный запускающий таймер
* TRGO Compare Ch2
* Задает (PSC * ARR) длительность работы TIM1, TIM3
* Количество генерируемых импульсов TIM1 определяется этим таймером.
*
* Start__/TRGO------\Stop
*/
RCC-›APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2-›PSC = 24000-1;
TIM2-›ARR = 12000+5-1; // Длительность работы TIM1, TIM3
TIM2-›CCR2 = 5; // ВременнАя зона остановки таймеров
TIM2-›CR1 |= TIM_CR1_OPM | TIM_CR1_ARPE; // Однократный запуск
TIM2-›CR2 |= TIM_CR2_MMS_0 | TIM_CR2_MMS_2; // TRGO Compare Ch2
/* Контролька работы TMR2 Ch2 */
TIM2-›CCMR1 = TIM_CCMR1_OC2M ; // PWM mode2
TIM2-›CCER = TIM_CCER_CC2E; // PWM out enable
}
/* ..........................
* Запуск работы
*/
void Start(void)
{
while (TIM2-›CR1 & TIM_CR1_CEN) {}
// настроить параметры, затем
TIM1-›CNT = 0; // сброс счетчика TIM1
TIM2-›CR1 |= TIM_CR1_CEN; // запуск
}
|
Последний раз редактировалось NewWriter; 23.10.2016 в 17:10.
|
|
|
|
23.10.2016, 22:45
|
|
Частый гость
Регистрация: 06.10.2008
Адрес: Ростов-на-Дону
Сообщений: 49
Сказал спасибо: 5
Сказали Спасибо 4 раз(а) в 3 сообщении(ях)
|
Re: Аппаратный учет числа импульсов ШИМ
Написал какой-то вариант, посмотрел под отладчиком. Для периодов шага
10, 50, 60, 200
выдаёт количество шагов
25, 9, 8, 3.
Что-то ещё надо с тактированием поковырять, потому что не сходится с задержкой на измерение. А ещё у меня таймеры под отладчиком не останавливаются .
Нажмите, чтобы открыть спойлер
Код:
|
#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"
//================================================== =======================
#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_6;
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_PinSource6, GPIO_AF_1); //TIM3 CH1
}
//================================================== =======================
void init_tim_pair()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //подключаем таймеры к шинам
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseInitTypeDef timerBase;
TIM_TimeBaseStructInit(&timerBase);
timerBase.TIM_Prescaler = 0; //здесь к теневому регистру доступа нет
timerBase.TIM_Period = 65535; //чем больше разрядность, тем лучше
TIM_TimeBaseInit(TIM1, &timerBase);
timerBase.TIM_Prescaler = 0; //длительность шага будет задаваться в процессе
timerBase.TIM_Period = 1; //скважность всегда 50%, для этого хватит 2 тактов на период
TIM_TimeBaseInit(TIM3, &timerBase);
TIM_OCInitTypeDef timerPWM;
TIM_OCStructInit(&timerPWM);
timerPWM.TIM_Pulse = 1; //регулирование скважности не нужно
timerPWM.TIM_OCMode = TIM_OCMode_PWM1;
timerPWM.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1Init(TIM3, &timerPWM);
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); //выдаем тактирование при событии апдейта
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
TIM_SelectInputTrigger(TIM1, TIM_TS_ITR2); //ловим вторым таймером сигналы от первого
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_External1);
}
//================================================== =======================
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_pair();
init_timer();
}
//================================================== =======================
inline int get_timer()
{
return -SysTick-›VAL; //он всегда downcounter, тикает в обратную сторону
}
//================================================== =======================
inline int time_delta(int value) //максимум 16777216/6000000 ~= 2 сек
{
return (get_timer() - value) & 0xFFFFFF;
}
//================================================== =======================
int main(void)
{
init();
int time = get_timer();
const int UPDATE_TIME = 100; //SYSTEM_TIMER_CLOCK/2; //обновление через 0,5 секунд
int period[] = {10, 50, 60, 200};
int index = 0;
TIM3-›PSC = period[index];
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM3, ENABLE);
int last = TIM1-›CNT; //здесь лежит число импульсов * 2
while (1)
{
if (time_delta(time) › UPDATE_TIME)
{
time = get_timer();
index = (index + 1) & 3;
TIM3-›PSC = period[index];
int current = TIM1-›CNT;
int delta = current - last;
static int cc = 0;
if (++cc › 4)
cc = 0;
last = current;
}
}
} |
Последний раз редактировалось backlan; 23.10.2016 в 23:07.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 05:49.
|
|