Фазовый сдвиг ШИМ сигнала STM32F107
Добавлено: Ср дек 05, 2012 10:48:40
Доброго дня уважаемые инженеры.
Столкнулся с проблемой связанной с появлением фазового сдвига на ШИМ сигналах.
Задача: Получить два синхронных сигнала прямоугольной формы частотой 8КГц и 1024КГц соответственно на PD.15 и PC.9 контроллера STM32F107.
Реализация: Синхронизируем таймеры TIM3 и TIM4 от таймера TIM1 (TIM1 - master, TIM3,TIM4 - slave). С таймеров TIM3 и TIM4 выводим 50% ШИМ сигнал на нужные ноги
Проблема: На выходных сигналах появляется сдвиг фазы на 500нС
Сигналы называются CLK и SYNK
Для чистоты эксперимента пытаюсь вывести два одинаковых сигнала частотой 8КГц и наблюдаю сдвиг.
.h файл:
.с файл:
Собственно что я вижу на осциллографе:
В общем виде

Фронты

Буду очень признателен за помощь по данной проблемы. Советы, ссылки, буду рад всему, уже 3 дня бьюсь, перелопатил кучу документации и форумов и не могу устранить этот косяк.
Столкнулся с проблемой связанной с появлением фазового сдвига на ШИМ сигналах.
Задача: Получить два синхронных сигнала прямоугольной формы частотой 8КГц и 1024КГц соответственно на PD.15 и PC.9 контроллера STM32F107.
Реализация: Синхронизируем таймеры TIM3 и TIM4 от таймера TIM1 (TIM1 - master, TIM3,TIM4 - slave). С таймеров TIM3 и TIM4 выводим 50% ШИМ сигнал на нужные ноги
Проблема: На выходных сигналах появляется сдвиг фазы на 500нС
Сигналы называются CLK и SYNK
Для чистоты эксперимента пытаюсь вывести два одинаковых сигнала частотой 8КГц и наблюдаю сдвиг.
.h файл:
Код: Выделить всё
#define Si3210_SYNC_PIN GPIO_Pin_15 /* PD.15 */
#define Si3210_SYNC_GPIO_PORT GPIOD /* GPIOD */
#define Si3210_SYNC_GPIO_CLK RCC_APB2Periph_GPIOD
#define Si3210_CLK_PIN GPIO_Pin_9 /* PC.9 */
#define Si3210_CLK_GPIO_PORT GPIOC /* GPIOC */
#define Si3210_CLK_GPIO_CLK RCC_APB2Periph_GPIOC
#define Si3210_TIM3 TIM3
#define Si3210_TIM_CLK RCC_APB1Periph_TIM3
#define Si3210_TIM4 TIM4
#define Si3210_TIM_SYNC RCC_APB1Periph_TIM4
Код: Выделить всё
void PWM_Sync_CLK_Init(void)
{
// подаем тактовую частоту на таймер порта С
RCC_APB1PeriphClockCmd(Si3210_TIM_CLK, ENABLE);
RCC_APB2PeriphClockCmd(Si3210_CLK_GPIO_CLK, ENABLE);
// подаем тактовую частоту на таймер порта D
RCC_APB1PeriphClockCmd(Si3210_TIM_SYNC, ENABLE);
RCC_APB2PeriphClockCmd(Si3210_SYNC_GPIO_CLK, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //под вопросом
//************************ внастраеваем выводы таймеров ************************
GPIO_InitStructure.GPIO_Pin = Si3210_SYNC_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Si3210_SYNC_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Si3210_CLK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Si3210_CLK_GPIO_PORT, &GPIO_InitStructure);
//************** закончили внастраивать выводы таймеров ************************
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //включение альтернативной функции
GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); //включение альтернативной функции
// Конфигурация таймера
TIM_TimeBaseInitTypeDef TIM_BaseConfig;
// Конфигурация выхода таймера
TIM_OCInitTypeDef TIM_OCConfig;
// конфигурируем что то там для TIM1
//TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
//************************ведущий таймер Т1*************************************
TIM_BaseConfig.TIM_Prescaler = 0;
TIM_BaseConfig.TIM_Period = 4;
TIM_BaseConfig.TIM_ClockDivision = 0;
// Отсчет от нуля до TIM_Period
TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up;
// Инициализирум таймер №3 (его выходы как раз на порту С)
TIM_TimeBaseInit(TIM1, &TIM_BaseConfig);
//******************************************************************************
// Automatic Output enable, Break, dead time and lock configuration
//TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
//TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
//TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
//TIM_BDTRInitStructure.TIM_DeadTime = 200;//5;
//TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
//TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
//TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
//******************************************************************************
//Select the Master Slave Mode
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
//TIM1->SMCR |= 0x0080; //ручная установка бита MSM в регистр SMCR
//Master Mode selection
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
//*********************** закончили с Т1****************************************
//*************************** CLK на TIM3 *************************************
TIM_BaseConfig.TIM_Prescaler = 9;
TIM_BaseConfig.TIM_Period = 179;
TIM_BaseConfig.TIM_ClockDivision = 0;
//TIM_BaseConfig.TIM_RepetitionCounter = 4;
// Отсчет от нуля до TIM_Period
TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up;
// Инициализирум таймер №3 (его выходы как раз на порту С)
TIM_TimeBaseInit(Si3210_TIM3, &TIM_BaseConfig);
//******************************************************************************
// Конфигурируем выход таймера, режим - PWM1
TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1;
// Собственно - выход включен
TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
// Пульс длинной 250 тактов => 7/14 = 50%
TIM_OCConfig.TIM_Pulse = 90;
// Полярность => пульс - это единица (+3.3V)
TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High;
// инициализируем третий выход таймера №3
TIM_OC4Init(Si3210_TIM3, &TIM_OCConfig);
//Slave Mode selection: TIM3
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);
//TIM3->SMCR |= 0x0080;
//******************************************************************************
//TIM_OC3PreloadConfig(Si3210_TIM3, TIM_OCPreload_Enable);
//TIM_OC4PreloadConfig(Si3210_TIM3, TIM_OCPreload_Enable);
//TIM_ARRPreloadConfig(Si3210_TIM3, ENABLE);
//****************** закончили с CLK на TIM3 ***********************************
//****************************** SYNC на TIM4 ********************************
TIM_BaseConfig.TIM_Prescaler = 9;
TIM_BaseConfig.TIM_Period = 179; //499;
TIM_BaseConfig.TIM_ClockDivision = 0;
//TIM_BaseConfig.TIM_RepetitionCounter = 4;
// Отсчет от нуля до TIM_Period
TIM_BaseConfig.TIM_CounterMode = TIM_CounterMode_Up;
// Инициализирум таймер №3 (его выходы как раз на порту D)
TIM_TimeBaseInit(Si3210_TIM4, &TIM_BaseConfig);
//******************************************************************************
// Конфигурируем выход таймера, режим - PWM1
TIM_OCConfig.TIM_OCMode = TIM_OCMode_PWM1;
// Собственно - выход включен
TIM_OCConfig.TIM_OutputState = TIM_OutputState_Enable;
// Пульс длинной 250 тактов => 250/500 = 50%
TIM_OCConfig.TIM_Pulse = 90;
// Полярность => пульс - это единица (+3.3V)
TIM_OCConfig.TIM_OCPolarity = TIM_OCPolarity_High; //TIM_OCPolarity_High;
// инициализируем третий выход таймера №3
TIM_OC4Init(Si3210_TIM4, &TIM_OCConfig);
//Slave Mode selection: TIM3
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0);
//TIM4->SMCR |= 0x0080;
// Как я понял - автоматическая перезарядка таймера, если не прав -поправте.
//TIM_OC3PreloadConfig(Si3210_TIM4, TIM_OCPreload_Enable);
//TIM_OC4PreloadConfig(Si3210_TIM4, TIM_OCPreload_Enable);
//TIM_ARRPreloadConfig(Si3210_TIM4, ENABLE);
//******************* закончили с SYNC на TIM4 ********************************
// Обнуляем таймерыв, неуверен что надо, но пусть будет на всякий случай
//TIM_SetCounter(TIM1, 0);
//TIM_SetCounter(TIM3, 0);
//TIM_SetCounter(TIM4, 0);
//******************* запускаем TIM1 TIM3 TIM4 ********************************
TIM_Cmd(TIM1, ENABLE); // Включаем таймер №3.
TIM_Cmd(TIM3, ENABLE); // Включаем таймер №3.
TIM_Cmd(TIM4, ENABLE); // Включаем таймер №4.
// Main Output Enable
//TIM_CtrlPWMOutputs(TIM1, ENABLE); // вроде это включает перефирию TIM1 но в данном случае она не нужна
}
В общем виде
Фронты
Буду очень признателен за помощь по данной проблемы. Советы, ссылки, буду рад всему, уже 3 дня бьюсь, перелопатил кучу документации и форумов и не могу устранить этот косяк.