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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
Minti
сообщение Jun 10 2011, 09:37
Сообщение #1





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



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

Так как я с МК и КЭНом(CANFestival) дело не имел, пытаюсь перепесать фаил timer.c от AVR(./drivers/AVR/timer_AVR.c) для STM32. Застрял на 2 defines(для начало wink.gif):
CODE
// Define the timer registers
#define TimerAlarm OCR3B
#define TimerCounter TCNT3

какие регистры соответствуют на STM32F103?
Go to the top of the page
 
+Quote Post
Minti
сообщение Jul 18 2011, 09:42
Сообщение #2





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



Помучившись с даташит от разных МК я пришёл к такому решению проблемы:
CODE
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_InitStructure;
#define TIM2_IRQChannel ((u8)0x1C) /* TIM2 global Interrupt (alte Bibliothek)*/

#define TimerAlarm TIM2->CCMR1
#define TimerCounter TIM_GetCounter(TIM2)

#define TIMER_INTERRUPT_LEVEL 1

void timer_can_irq_handler(void);


/************************** Modul variables **********************************/
// Store the last timer value to calculate the elapsed time
static TIMEVAL last_time_set = TIMEVAL_MAX;

void initTimer(void)
/******************************************************************************
Initializes the timer, turn on the interrupt and put the interrupt time to zero
INPUT void
OUTPUT void
******************************************************************************/
{
//TODO: check
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //TIM2 mit einem Takt versorgen

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; //Interrupt Kanal auswählen. Hier TIM2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //Interrupt Priorität festlegen
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //Interrupt Unterpriorität festlegen
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Aktivieren des Interrupts
NVIC_Init(&NVIC_InitStructure); //Konfiguration übernehmen

TIM_InitStructure.TIM_Prescaler = 2000; // Clock Teiler 72MHz / 2000 = 36kHz
TIM_InitStructure.TIM_Period = 36000; // Anzahl Durchläufe bis Überlauf Interrupt 36kHz / 36000 = 1s
TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Keine Clock Division
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; //Hochzählender Timer Modus
TIM_TimeBaseInit(TIM2, &TIM_InitStructure); //Konfiguration Übernehmen
TIM_Cmd(TIM2, ENABLE); //Timer Aktivieren

TIM_ClearFlag(TIM2, TIM_FLAG_Update); //Interrupt Flag von TIM2 löschen
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //Interrupt für TIM2 Aktivieren
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //Interrupt Flag für TIM2 Löschen
//End check


}

void setTimer(TIMEVAL value)
/******************************************************************************
Set the timer for the next alarm.
INPUT value TIMEVAL (unsigned long)
OUTPUT void
******************************************************************************/
{
TimerAlarm += value; // Add the desired time to timer interrupt time
}

TIMEVAL getElapsedTime(void)
/******************************************************************************
Return the elapsed time to tell the stack how much time is spent since last call.
INPUT void
OUTPUT value TIMEVAL (unsigned long) the elapsed time
******************************************************************************/
{
unsigned int timer = TimerCounter; // Copy the value of the running timer
// Calculate the time difference
return timer > last_time_set ? timer - last_time_set : last_time_set - timer;
}


//*----------------------------------------------------------------------------
//* Function Name : timer_can_irq_handler
//* Object : C handler interrupt function by the interrupts
//* assembling routine
//* Output Parameters : calls TimeDispatch
//*----------------------------------------------------------------------------
//void timer_can_irq_handler(void)
void TIM2_IRQHandler(void)
{
last_time_set = TimerCounter;
TimeDispatch(); // Call the time handler of the stack to adapt the elapsed time
}


правильно ли выбраны регистры? Какие параметры для TIM_InitStructure, чтобы

Цитата
graph
Scheduler can handle short clock value ranges limitation found on some
µC. As an example, value range for a 16bit clock counter with 4µs tick is
crossed within 0.26 seconds... Long alarms must be segmented.
Chronogram illustrate a long alarm (A) and a short periodic alarm (cool.gif,
with a A value > clock range > B value. Values t0...t8 are successive setTimer
call parameter values. t1 illustrates an intermediate call to TimeDispatch,
caused by a delay longer than clock range. Because of long alarm segmentation,
at the end of t1, TimeDispatch call will not trig any alarm callback.
Go to the top of the page
 
+Quote Post
syoma
сообщение Oct 9 2011, 20:14
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



А какой профиль делаете?
Go to the top of the page
 
+Quote Post
Minti
сообщение Oct 12 2011, 08:33
Сообщение #4





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



CiA 402
пока проблема с прерываниями(interrupts): TIM2 и Heartbeat с 50ms съедают все ресурсы. а может быть собака в другом месте зарыта?
Go to the top of the page
 
+Quote Post
Forger
сообщение Oct 13 2011, 18:03
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Minti @ Oct 12 2011, 12:33) *
CiA 402
пока проблема с прерываниями(interrupts): TIM2 и Heartbeat с 50ms съедают все ресурсы. а может быть собака в другом месте зарыта?

Конечно в другом!
Для сравнения в моей реализации CANopen на STM32F1xx (тактовая 24МГц) загрузка не превышает 20% (внутри стоит RTOS).
В среднем же загрузка около 2..3% в типовых задачах (профиль 401), если по уму настроить PDOсы самого узла.




--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Minti
сообщение Oct 13 2011, 20:10
Сообщение #6





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



такое ощущение, что таймер перебевает "инфинити луп" и второе при этом теряет данные.
Forger, какой тик у вашего таймера?
Go to the top of the page
 
+Quote Post
Forger
сообщение Oct 13 2011, 21:45
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Minti @ Oct 14 2011, 00:10) *
Forger, какой тик у вашего таймера?

У RTOS 1 мс, для CANopen тоже (потом будет 0,1 мс).
Таймер CANopen пока используется лишь для Hearbeat Consumer/Producer и светодиодов (по стандарту).
Все остальное - по событию.
0,1 мс нужен для правильной отработки Inhibit timer (PDO) и EMCY объектов.
Поэтому пока что для RTOS и CANopen используется один и тот же таймер.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
syoma
сообщение Oct 14 2011, 06:52
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Цитата
Heartbeat с 50ms

Чего-то очень часто. Вам действительно необходимо определение потери узла так быстро? Обычно это время от 0,5с и выше.
У меня на STM32F TIM2 крутится с шагом 8µS, а как системный таймер я настроил SysTick на 1мс. У вас помоему TIM2 неправильно настроен. CANFestival считает, что он должен увеличиваться каждые 8µS, и прерывание должно по сравнению генерироваться, а у вас немного другое получается.
Я уже выкладывал свои исходники на порт - посмотрите, как там таймер настроен.
http://permalink.gmane.org/gmane.comp.embe...canfestival/507

ПС. Хммм, только дров таймера там как-раз и нету. Вечером тогда выложу.

Цитата
0,1 мс нужен для правильной отработки Inhibit timer (PDO) и EMCY объектов.

Кстати, в CanFestival мне нравится как это дело реализовано. Благодаря 8µS шагу - все эти дела обрабатываются очень четко.
Go to the top of the page
 
+Quote Post
Forger
сообщение Oct 14 2011, 07:22
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(syoma @ Oct 14 2011, 10:52) *
Кстати, в CanFestival мне нравится как это дело реализовано. Благодаря 8µS шагу - все эти дела обрабатываются очень четко.

А почему не 1мкс, не 100мкс, а именно 8? Зачем там такая точность?



--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Minti
сообщение Oct 14 2011, 11:20
Сообщение #10





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



Цитата(syoma @ Oct 14 2011, 08:52) *
Чего-то очень часто. Вам действительно необходимо определение потери узла так быстро? Обычно это время от 0,5с и выше. У меня на STM32F TIM2 крутится с шагом 8µS

настроил Heartbeat на 0,5с. ТIM2 настроеть с шагом меньше чем 1ms не получается, interrupt USART2 теряется.

Цитата(syoma @ Oct 14 2011, 08:52) *
, а как системный таймер я настроил SysTick на 1мс. У вас помоему TIM2 неправильно настроен. CANFestival считает, что он должен увеличиваться каждые 8µS, и прерывание должно по сравнению генерироваться, а у вас немного другое получается.

А вот тут пожалуйста поподробнее. Зачем SysTick настраевать(если что извените за нубский вопрос)? Что неправельно в настроиках TIM2?

Цитата(syoma @ Oct 14 2011, 08:52) *
ПС. Хммм, только дров таймера там как-раз и нету. Вечером тогда выложу.

Буден очень благодарен!

RTOS нету.
Go to the top of the page
 
+Quote Post
syoma
сообщение Oct 15 2011, 17:01
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Вот мои текущие реализации драйверов таймера и CAN- контроллера для CANfestival и STM32F105. F103 должен быть вроде такой же.
В качестве библиотеки использовалась STM32F10x Standard Peripherals Library версия 3.5.0 с сайта ST.
Цитата
Зачем SysTick настраевать(если что извените за нубский вопрос)?

Systick я настроил на прерывание каждые 1мс чисто для своих нужд - например каждую мс входы опрашивать и т.д. в Canfestival он не учавствует.

Цитата
А почему не 1мкс, не 100мкс, а именно 8? Зачем там такая точность?

Я это дело не разрабатывал, а использовал как есть. Поэтому не знаю. Оно так работает, а мне больше и не надо.
Прикрепленные файлы
Прикрепленный файл  CANfestival_STM.zip ( 5.16 килобайт ) Кол-во скачиваний: 171
 
Go to the top of the page
 
+Quote Post
Minti
сообщение Oct 18 2011, 12:30
Сообщение #12





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



syoma, большое спасибо за исходный текст! Есть ещё парочку вопросов

Ваша текущая реализация драйверов таймера:
CODE
...
/* Compute the prescaler value APB1 divided by two, but this is fixed by timer itself */
PrescalerValue = (uint16_t) ((SystemCoreClock) / 125000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* Prescaler configuration */
TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate);
...

Какое значение у SystemCoreClock? 72MHz?
формула вычисления шага:
Tick := SystemCoreClock / (TIM_Prescaler+1) / TIM_Period
Как я понял TIM_Period у вас в формулу не берется. Это из-за "Output Compare Timing Mode configuration"?
Цитата
Systick я настроил на прерывание каждые 1мс чисто для своих нужд - например каждую мс входы опрашивать и т.д. в Canfestival он не учавствует.

Тогда где у вас в программе этот блок стоит:

if (canReceive(&m)) canDispatch(Obj_Data, &m);

в "инфинити луп"?


Запустил МК с вашими реализациами. USART2 interrupt работает стабильно, а вот функция ConfigureSlaveNode(тут находится CanFestival-3\examples\DS401_Master\TestMasterMicroMod.c) теряется. Обнаружил вот такой феномен: ставлю ТIМ2 на большой шаг ~2с, выполняю ConfigureSlaveNode(доходит до конца), ставлю ТIМ2 шаг обратно и колёсики начинают крутится. Можно ли решить эту проблему по другому?
Go to the top of the page
 
+Quote Post
syoma
сообщение Oct 18 2011, 15:13
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



SystemCoreClock - 72MHz.
Мне нужно было задать делитель так, чтобы таймер увеличивался каждые 8µs. Это получается если Prescaler=575. TIM_Period в этом случае нафиг не нужен. TIM_Period нужен только чтобы таймер проходил полный круг перед сбросом в 0.
Вы возможно путаете - каждые 8µS таймер должен увеличиваться, а не переполняться.
Короче правильность работы этого таймера проверяется легко - запускаете heartbeat generation например на 2с - и наблюдаете в любом CANанализаторе по таймстампингу насколько точно приходят сообщения. Если таймер настроен правильно, то должно быть 2+-0,001с

canDispatch стоит в основном инфинити луп, но не в функции, которая раз в 1мс вызывается. Это изза того, что за 1мс может много сообщений прийти и все их нужно успеть обработать. Если бы canDispatch только раз в мс вызывался, то сообщения терялись бы.
ConfigureSlaveNode я только сегодня тестить буду. Не ожидаю никаких проблем. Что у Вас теряется?
Go to the top of the page
 
+Quote Post
Minti
сообщение Oct 18 2011, 19:06
Сообщение #14





Группа: Участник
Сообщений: 13
Регистрация: 5-04-11
Пользователь №: 64 157



Цитата(syoma @ Oct 18 2011, 17:13) *
canDispatch стоит в основном инфинити луп, но не в функции, которая раз в 1мс вызывается.

Идею с SysTick'ом я теперь понял, спасибо. Вкручу для USART'а.
Цитата(syoma @ Oct 18 2011, 17:13) *
ConfigureSlaveNode я только сегодня тестить буду. Не ожидаю никаких проблем. Что у Вас теряется?

Программирую в Atollic TrueSTUDIO®/STM32 Lite, ставил в ConfigureSlaveNode breakpoints в case 1 и case 3, последний не достигался.
Потом увеличил ТIM2 Prescaler, примерно до case 16 дошёл. И так я Prescaler увеличивал пока полностью функтию не пробежал.

На днях вкручу SysTick, может этот феномен пропадёт.

PS: есть ещё один вопросик. Есть ли разниза между ними:
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate);
Go to the top of the page
 
+Quote Post
syoma
сообщение Oct 19 2011, 07:46
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 817
Регистрация: 14-02-07
Из: наших, которые работают за бугром
Пользователь №: 25 368



Посмотрел я ConfigureSlaveNode - в принципе мне эта функция совсем не нужна - я не собираюсь в словари слейвов с мастера залазить, для этого есть конфигурационные проги.
Но вроде у нее все ОК, так что ищите.
Go to the top of the page
 
+Quote Post

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

 


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


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