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

 
 
> 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
Ответов
toweroff
сообщение Sep 22 2012, 08:16
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



а вот еще момент с вычислением разницы. Есть потенциальная возможность глюков. Я бы как-то так написал:
Код
if (count1>count2)
{
    razn = count1 - count2;
}
else
{
    razn = count2 - count1;
}



Цитата(MarYuriy @ Sep 22 2012, 11:38) *
Да, но это для отладки.

а уверены, что именно это не приводит к непонятным глюкам?
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
|- - MarYuriy   Цитата(toweroff @ Sep 22 2012, 11:16) а в...   Sep 23 2012, 10:27
- - MarYuriy   Опять всё напутал. Извиняюсь! В общем теперь з...   Sep 25 2012, 12:45
- - AHTOXA   Цитата(MarYuriy @ Sep 25 2012, 18:45) Воп...   Sep 25 2012, 17:30
- - MarYuriy   Цитата(AHTOXA @ Sep 25 2012, 20:30) 2103/...   Sep 26 2012, 09:50
- - AHTOXA   Цитата(MarYuriy @ Sep 26 2012, 15:50) Есл...   Sep 26 2012, 10:39
- - 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 Текстовая версия Сейчас: 22nd July 2025 - 21:10
Рейтинг@Mail.ru


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