реклама на сайте
подробности

 
 
> General Purpose Timer, Input Capture
MarYuriy
сообщение Sep 19 2012, 16:43
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 20-11-10
Пользователь №: 61 036



Здравствуйте!

У меня есть, на мой взгляд, интересная задачка (хотя я новичок в МК, может быть, преувеличиваю), над которой я изрядно поломал мозг, но так и не решил.

Есть устройство (на основе STM32f107), которое синхронизируется от GPS и тактируется от высокостабильного источника частоты.

После того, как прибор засинхронизировался, таймер (TIM4) в режиме Input Capture начинает захватывать 1PPS от GPS в третьем канале и 1PPS от того же GPS в четвёртом канале, дальше из одного значения вычитается другое и получаем... (2103 плюс-минус 3) такта, это, примерно, 29 мкс. Снимая таким образом показания каждую секунду, получаем одно и то же значение.

Вопрос возникает сам собой — откуда берутся эти 2103 тактов?

Если нужно будет, я выложу весь код.

Инициализация таймера:
CODE
void TIM4_Alarm_Config (void)
{
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // подача тактов на TIM4 от шины тактирования APB1

TIM4->PSC = 1 - 1; // Предварительный делитель: значения счетчика будут инкрементироваться с частотой 35 MГц
TIM4->ARR = 65534 - 1; // Максимальное значение, до которого будет считать таймер, равно 65535

// канал 3 (1Гц)
TIM4->CCMR2 |= TIM_CCMR2_CC3S_0; // выбор активного входа, канал 3 TIM4_CH3 (PB8) <<------ подать на этот канал 1Гц
TIM4->CCER &=~ TIM_CCER_CC3P; // срабатывание по переднему фронту
TIM4->CCMR2 &=~ TIM_CCMR2_IC3PSC; // захват каждого импульса
// TIM4->CCER |= TIM_CCER_CC3E; // включить захват из счётчика // в EXTI1
TIM4->DIER |= TIM_DIER_CC3IE; // включение прерывания от захвата

// канал 4 (1PPS)
TIM4->CCMR2 |= TIM_CCMR2_CC4S_0; // выбор активного входа, канал 4 TIM4_CH4 (PB9) <<------ подать на этот канал 1PPS
TIM4->CCER &=~ TIM_CCER_CC4P; // срабатывание по переднему фронту
TIM4->CCMR2 &=~ TIM_CCMR2_IC4PSC; // захват каждого импульса
// TIM4->CCER |= TIM_CCER_CC4E; // включить захват из счётчика // в EXTI1
TIM4->DIER |= TIM_DIER_CC4IE; // включение прерывания от захвата
}


Прерывание от таймера:
CODE
void TIM4_IRQHandler(void)
{

if (TIM4->SR&TIM_SR_CC3IF) // 1Гц
{
TIM4->SR &=~ TIM_SR_CC3IF; // очиcтка флага прерывания
count1 = TIM4->CCR3; // считываем значение счётчика в переменную count1, если выставлен флаг прерывания
}

if (TIM4->SR&TIM_SR_CC4IF) // 1PPS
{
TIM4->SR &=~ TIM_SR_CC4IF; // очиcтка флага прерывания
count2 = TIM4->CCR4; // считываем значение счётчика в переменную count1, если выставлен флаг прерывания
}

if((count1>0)&&(count2>0))
{
if(count1>count2)
{
razn = count1 - count2;
}
if(count2>count1)
{
razn = count2 - count1;
}

count1=0;
count2=0;

if (razn >(bias+1000)){razn = 65534 - razn;}

// if(bias>razn)
// {
rash = razn + 100;// - bias; // добавил биас rash - unsigned int
// }
// if(razn>bias)
// {
// rash = razn - bias;
// }

//while (!(USART2->SR & USART_SR_TXE)) {} // Ждать освобождения буфера.
//USART2->DR=rash;

union {
unsigned int Mylong2;
char buf3[2]; // рассогласование в микросекундах
}MyUnion2;
MyUnion2.Mylong2 = rash;


while (!(USART2->SR & USART_SR_TXE)) {} // Ждать освобождения буфера.
USART2->DR=MyUnion2.buf3[1]; // рассогласование в микросекундах
while (!(USART2->SR & USART_SR_TXE)) {} // Ждать освобождения буфера.
USART2->DR=MyUnion2.buf3[0];

if (rash<90)

{GPIOA->BSRR |= GPIO_BSRR_BS7;} // генерация импульса, который подаётся на GPIOA_PIN6 (PA7), <<----- импульс сигнализации}

if (rash>110)

{GPIOA->BSRR |= GPIO_BSRR_BS7;} // генерация импульса, который подаётся на GPIOA_PIN6 (PA7), <<----- импульс сигнализации}
}
}


Сообщение отредактировал MarYuriy - Sep 19 2012, 16:44
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MarYuriy
сообщение Sep 25 2012, 12:45
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 20-11-10
Пользователь №: 61 036



Опять всё напутал. Извиняюсь! В общем теперь задача точно описывается так (всё проверил несколько раз!):
1. Если на оба выхода таймера в режиме Input Capture подаётся один и тот же сигнал, то разница между регистрами сравнения каналов = 00 либо 01 (т.е 1 такт при частоте шины тактирования таймера 35 Мгц).
2. Если на выходы таймера в режиме Input Capture подаются сигналы (1PPS) с разных GPS-ов, то разница между регистрами сравнения каналов варьируется и ползает в разные стороны в пределах от 00 до 10.
3. Если же я из 35МГц (которые получаюся из 10МГц) генерирую 1Гц и в режиме Capture/Campare сравниваю с любым из PPS-ов (т. е. от любого из GPS-ов ), то разница между регистрами сравнения = 2103 (плюс-минус 3).

Вопрос всё тот же: откуда берутся эти постоянные 2103 тактов?

Инициализация и прерывание для таймера, генерирующего 1Гц:
CODE

//********************************************************************************
*
// Функция TIM2_Divider_Config: Делитель на таймере
//********************************************************************************
*
void TIM2_Divider_Config (void)
{
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // подача тактов на TIM2 от шины тактирования APB1

TIM2->PSC = 35000 - 1; // предделитель до частоты 2000 Гц
TIM2->ARR = 2000 - 1; // выход в прерывание каждую секунду
TIM2->DIER |= TIM_DIER_UIE; // После того как таймер достигнет своего максимального значения генерируется прерываие
TIM2->CR1 |= TIM_CR1_ARPE; // сброс по достижении максимального значения
// TIM2->CR1 |= TIM_CR1_CEN; // Разрешить работу таймера
}
//********************************************************************************
*
// Функция TIM2_IRQHandler: Обработчик прерываний для TIM2
//********************************************************************************
*
void TIM2_IRQHandler(void)
{
if (TIM2->SR&TIM_SR_UIF)
{
GPIOE->BSRR |= GPIO_BSRR_BS0; // генерация импульса, который подаётся на (PE0), его надо принять на TIM4_CH3 (PB8)
GPIOE->BSRR |= GPIO_BSRR_BR0;
TIM2->SR &=~ TIM_SR_UIF; // очиcтка флага прерывания
}
}
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 25 2012, 17:30
Сообщение #3


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MarYuriy @ Sep 25 2012, 18:45) *
Вопрос всё тот же: откуда берутся эти постоянные 2103 тактов?

2103/35000000 = 0,000060086. Видимо, это погрешность вашего кварца, помноженная на PLL.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
MarYuriy
сообщение Sep 26 2012, 09:50
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 59
Регистрация: 20-11-10
Пользователь №: 61 036



Цитата(AHTOXA @ Sep 25 2012, 20:30) *
2103/35000000 = 0,000060086. Видимо, это погрешность вашего кварца, помноженная на PLL.


Если бы это была погрешность, то она распространилась и на пункты 1 и 2 моего предыдущего сообщения. Плюс 10Мгц у меня от рубидиевого стандарта. Поэтому я грешу на код...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 26 2012, 10:39
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(MarYuriy @ Sep 26 2012, 15:50) *
Если бы это была погрешность, то она распространилась и на пункты 1 и 2 моего предыдущего сообщения.

Почему? В первом и втором случае вы засекаете секунду, которую формирует GPS. А в третьем - секунду, которая формируется из вашего кварца.
Сформируйте не секунду, а полсекунды, и разница между ней и GPS будет ещё более заметнойsm.gif
Что касаемо кода, то после записи в TIM2->PSC нужно делать
Код
TIM2->EGR = TIM_EGR_UG;

чтобы новое значение PSC вступило в действие.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- MarYuriy   General Purpose Timer   Sep 19 2012, 16:43
- - MarYuriy   Сформулировал вопрос конкретно по таймеру. Подаю ...   Sep 21 2012, 18:58
- - toweroff   А Вы в прерывании таймера еще что-то отправлять в ...   Sep 21 2012, 20:21
|- - MarYuriy   Цитата(toweroff @ Sep 21 2012, 23:21) А В...   Sep 22 2012, 07:38
- - toweroff   а вот еще момент с вычислением разницы. Есть потен...   Sep 22 2012, 08:16
|- - MarYuriy   Цитата(toweroff @ Sep 22 2012, 11:16) а в...   Sep 23 2012, 10:27
- - MarYuriy   Цитата(AHTOXA @ Sep 26 2012, 13:39) Почем...   Sep 27 2012, 10:02
- - AHTOXA   В формировании секундного импульса участвует не то...   Sep 27 2012, 10:41
- - MarYuriy   Цитата(AHTOXA @ Sep 27 2012, 13:41) В фор...   Sep 27 2012, 13:52
- - AHTOXA   Цитата(MarYuriy @ Sep 27 2012, 19:52) По ...   Sep 27 2012, 15:25
- - MarYuriy   ЦитатаКак минимум ещё PLL и таймер. Нуи время вход...   Sep 28 2012, 18:25
- - AHTOXA   Цитата(MarYuriy @ Sep 29 2012, 00:25) Да ...   Sep 28 2012, 20:45
- - MarYuriy   Цитата(AHTOXA @ Sep 28 2012, 23:45) Не то...   Sep 29 2012, 10:14


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th June 2025 - 10:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01447 секунд с 7
ELECTRONIX ©2004-2016