Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

2VasilyS. Вы недавно интересовались как в плавающей точке(+)

Отправлено Quasy 02 сентября 2008 г. 17:31



сделать вычисление таймерной константы для AVR, да чтобы проверочка была при некорректном задании прескалера и периода. И чтобы переносимость компиляторная была. Я обычно в целом виде считаю и точности хватает, но тоже решил попробовать. Вот на основе Вашего примера у меня получился такой крокодил. Сколько у меня компилеров на всех работает. Но в Линуксе, увы, не проверял... Может, кому пригодится.

// Задание таймерной константы AVR
#define QUARTZ (1000000UL)
//////////////////////////////////////////////
#define fQUARTZ_HZ (float)(QUARTZ)
///////////////////
#define fTIMER_PRESCALER_200US (1.0) // прескалер таймера
#define fTIMER_PERIOD_200US (0.0002) // период таймера в сек
////////////////////////////////////////////////////
// Задание значения для 16-разрядного таймера AVR.
// Задаваемое значение проверяется на выход из 2-х байт.
// В случае выхода за 2 байта компилятор дает предупреждение
// о делении на 0.
#define __TIMER16_LOAD_PERIOD_LONG(presc,sec) ( ( \
65535.0 - ((fQUARTZ_HZ * sec) / presc) + \
1.5 ) >= 0.0) ? (unsigned long)( 65535.0 - \
((fQUARTZ_HZ*sec) / presc ) + 1.5 ) : \
(0UL)
#define _TIMER16_LOAD_PERIOD_LONG(presc,sec) (100UL / \
(__TIMER16_LOAD_PERIOD_LONG(presc,sec)))
#define TIMER16_LOAD_PERIOD_LONG(presc,sec) ( \
_TIMER16_LOAD_PERIOD_LONG(presc,sec)) ? \
(__TIMER16_LOAD_PERIOD_LONG(presc,sec)) : \
(__TIMER16_LOAD_PERIOD_LONG(presc,sec))
/////////
// Разбиение на байты
#define TIMER16_LOAD_INT( presc, sec ) (unsigned int) \
( (TIMER16_LOAD_PERIOD_LONG(presc, sec)) & 0xffff)
#define TIMER16_LOAD_H( presc, sec ) (unsigned char) \
((TIMER16_LOAD_INT(presc, sec)) >> 8)
#define TIMER16_LOAD_L( presc, sec ) (unsigned char) \
((TIMER16_LOAD_INT(presc, sec)) & 0xff)
////////////////////////////////////////////////////
// Задание значения для 8-разрядного таймера AVR.
// Задаваемое значение проверяется на выход из байта.
// В случае выхода за байт компилятор дает предупреждение
// о делении на 0.
#define __TIMER8_LOAD_PERIOD(presc,sec) ( ( \
255.0 - ((fQUARTZ_HZ * sec) / \
presc)+1.5 ) >= 0.0) ? (unsigned int)( 255.0 - \
((fQUARTZ_HZ*sec) / presc ) + 1.5 ) : \
((unsigned int)(0))
#define _TIMER8_LOAD_PERIOD(presc,sec) (100 / \
(__TIMER8_LOAD_PERIOD(presc,sec)))
#define TIMER8_LOAD_PERIOD(presc,sec) ( \
_TIMER8_LOAD_PERIOD(presc,sec) ) ? \
(__TIMER8_LOAD_PERIOD(presc,sec)) : \
(__TIMER8_LOAD_PERIOD(presc,sec))
//////////////////
// Выделение младшего байта
#define TIMER8_LOAD(presc,sec) (unsigned char) \
((TIMER8_LOAD_PERIOD(presc,sec)) & 0xff )
////////////////////////////////////////////////////
void main( void )
{
// Для TCNT-16
printf("0x%02x 0x%02x\n", TIMER16_LOAD_H(
fTIMER_PRESCALER_200US, fTIMER_PERIOD_200US ),
TIMER16_LOAD_L(
fTIMER_PRESCALER_200US, fTIMER_PERIOD_200US) );
// Для TCNT-8
printf("0x%02x \n", TIMER8_LOAD(
fTIMER_PRESCALER_200US, fTIMER_PERIOD_200US));
}


Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
сложите 2 и 3:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru