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

 
 
> Директива #define, Научить считать препроцессор
andrvisht
сообщение Nov 21 2005, 08:30
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064



Захотелось чтобы препроцессор вычислял значение которое нужно запихнуть в UBRR...
решил сделать вот так:
Код
#define _BAUND 9600
#define Fosc 4000000
#define BAUND (Fosc/(_BAUND*16))-1

В результате получил 176 а не 25

тогда попробовал вот так:

Код
#define _BAUND 9600
#define BAUND ((Fosc/_BAUND)/16)-1

и получил желанные 25


Но ведь записи то одинаковые, а результаты разные... ???

дальше хочу определить ошибку вот таким вариантом
Код
#define _UBRR ((Fosc/(BAUND+1))/16)
#define BAUND_ERROR ((_UBRR - _BAUND)/_BAUND)*1000

результат который хотелось видеть 1 (т.е. 0.1%) а получил 0 sad.gif

И хотелось бы выводить само значение ошибки, нашел директиву

Код
#warning любое текстовое сообщение


но оно не позволяет выводить результат расчета
типа
Код
#warning ошибка установки скорости обмена составляет BAUND_ERROR


Вообщем вопрос - как обрабатывается препроцессор и можно ли выводить на экран результат в численном виде ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KRS
сообщение Nov 21 2005, 09:52
Сообщение #2


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Вообще грамотнее использовать округление!
#define BAUND (unsigned)((Fosc/(_BAUND*16))-0.5)

А вот с выводом посчитанного значения проблема sad.gif
Go to the top of the page
 
+Quote Post
starter48
сообщение Nov 21 2005, 11:23
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 15-10-05
Из: Томск
Пользователь №: 9 680



Цитата(KRS @ Nov 21 2005, 15:52) *
Вообще грамотнее использовать округление!
#define BAUND (unsigned)((Fosc/(_BAUND*16))-0.5)

Не понял... cranky.gif
будет (unsigned)((4000000/(int)(9600*16))-0.5)
или (unsigned)(177-0.5)
или (unsigned)(176.5)
или просто 176 excl.gif
т.е. вычитание 0.5 здесь ничего не даст, т.к. все вычисления до этого целочисленные.

Может ты хотел предложить считать как вещественные числа?
вот так: #define BAUND ((unsigned)(Fosc/(_BAUND*16.0f))-1)
Можно, но осторожно, т.к. иногда при вычислении вещественных чисел иногда возникает погрешность, которая при обрезании дробной части даст ошибку на целую 1. Например вместо числа 10.0 может получится 9.999999999 - после обрезания будет 9, а не 10. Так что лучше именно целочисленную арифметику использовать.
Go to the top of the page
 
+Quote Post
KRS
сообщение Nov 21 2005, 11:57
Сообщение #4


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(starter48 @ Nov 21 2005, 14:23) *
Цитата(KRS @ Nov 21 2005, 15:52) *

Вообще грамотнее использовать округление!
#define BAUND (unsigned)((Fosc/(_BAUND*16))-0.5)

Не понял... cranky.gif
будет (unsigned)((4000000/(int)(9600*16))-0.5)
или (unsigned)(177-0.5)
или (unsigned)(176.5)
или просто 176 excl.gif
т.е. вычитание 0.5 здесь ничего не даст, т.к. все вычисления до этого целочисленные.

Может ты хотел предложить считать как вещественные числа?
вот так: #define BAUND ((unsigned)(Fosc/(_BAUND*16.0f))-1)
Можно, но осторожно, т.к. иногда при вычислении вещественных чисел иногда возникает погрешность, которая при обрезании дробной части даст ошибку на целую 1. Например вместо числа 10.0 может получится 9.999999999 - после обрезания будет 9, а не 10. Так что лучше именно целочисленную арифметику использовать.


нет именно -0.5 бывает надо округлять в другую сторону
например
для 14400 и 8 mhz
(unsigned)((8000000/(14400*16))-0.5) = 34

а если счиать в целых и вычитать 1 будет 33

8000000/(14400*16)-1=33.722222 и надо окурглять вверх


а 9.99999 получится если надо примерно 9.5 и в общем все равно куда округлять вверх или вниз.
Go to the top of the page
 
+Quote Post
starter48
сообщение Nov 21 2005, 12:34
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 112
Регистрация: 15-10-05
Из: Томск
Пользователь №: 9 680



Цитата(KRS @ Nov 21 2005, 17:57) *
нет именно -0.5 бывает надо округлять в другую сторону
например
для 14400 и 8 mhz
(unsigned)((8000000/(14400*16))-0.5) = 34

а если счиать в целых и вычитать 1 будет 33

Согласен, но тогда допиши .0f после 16, иначе -253 будет wink.gif
Вот так: (unsigned)((8000000/(14400*16.0f))-0.5) = 34
Но как раз в таких случаях встаёт проблема с округлением о которой я говорил.
Например может вместо 10.5 в выражении (Fosc/(_BAUD*16.0f)) получиться 10.4999999 и, отняв 0.5, мы получим 9.9999999, что обрежется до 9

Цитата(KRS @ Nov 21 2005, 17:57) *
8000000/(14400*16)-1=33.722222 и надо окурглять вверх

Неа, будет -253
Чтобы получить 33.72, как в математике, надо в вещественных числах всё считать:
#define BAUD ((unsigned)(8000000/(14400*16.0f)-1))
и тогда дествительно можно отнимать 0.5 вместо 1, чтобы повысить точность при округлении.

Цитата(KRS @ Nov 21 2005, 17:57) *
а 9.99999 получится если надо примерно 9.5 и в общем все равно куда округлять вверх или вниз.

Это справедливо, если ты считаешь через long, но тогда 0.5 вычитать не имеет смысла, т.к. вычитаешь ты его от уже целого числа и вычитание 0.5 равносильно вычитанию 1.
Ведь выражение 8000000/(14400*16) - целочисленное.

Вот идея для округления в целочисленной записи:
#define BAUD ((Fosc-(_BAUD*8L))/(_BAUD*16L))

И завязывайте писать слово BAUD через N wink.gif

Сообщение отредактировал starter48 - Nov 21 2005, 12:35
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- &-rey   Директива #define   Nov 21 2005, 08:30
- - vet   Препроцессор не умеет считать, его функция - разве...   Nov 21 2005, 08:41
- - starter48   Цитата(&-rey @ Nov 21 2005, 14:3...   Nov 21 2005, 08:53
- - &-rey   Спасибо, помогло. #define _BAUND 9600 #define Fosc...   Nov 21 2005, 09:37
|- - starter48   Цитата(&-rey @ Nov 21 2005, 15:3...   Nov 21 2005, 11:03
- - &-rey   Ясно. Спасибо всем откликнувшимся... ))   Nov 21 2005, 10:01
- - &-rey   Код#define _BAUD 38400 #define _U2X 2 // Doble Spe...   Nov 24 2005, 07:25
|- - starter48   Цитата(&-rey @ Nov 24 2005, 13:2...   Nov 24 2005, 09:32
|- - &-rey   Цитата(starter48 @ Nov 24 2005, 13:32) У ...   Nov 24 2005, 10:13
|- - starter48   Цитата(&-rey @ Nov 24 2005, 16:1...   Nov 24 2005, 10:36
|- - &-rey   Цитата(starter48 @ Nov 24 2005, 14:36) По...   Nov 24 2005, 11:23
|- - starter48   Цитата(&-rey @ Nov 24 2005, 17:2...   Nov 24 2005, 11:56
|- - &-rey   AVR_Bit7=AVR_Bit2=1 пробовал, но оно разделяет код...   Nov 24 2005, 12:09
|- - starter48   Цитата(&-rey @ Nov 24 2005, 18:0...   Nov 24 2005, 12:21
|- - &-rey   Цитата(starter48 @ Nov 24 2005, 16:21) Ес...   Nov 24 2005, 12:37
- - Rash   ЦитатаВозможно ли обратиться к структуре чтобы раз...   Nov 24 2005, 10:21


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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 15:30
Рейтинг@Mail.ru


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