Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Странно поведение на функция GNU-C
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=13466
Страница 1 от 2

Автор:  showMANiak [ Чет Яну 01, 2015 10:37 pm ]
Заглавие:  Странно поведение на функция GNU-C

За много години на всички :).Много здраве и щастие :)

Къде бъркам,че тая функция
Код:
void UART_config(unsigned long FCPU,unsigned int BAUDR)
{
   unsigned int UBRR;
   UBRR=(FCPU/(16*BAUDR))-1;
   UDR=UBRR;
   
}


извикана със следните параметри

Код:
UART_config(16000000,9600);


да връща 0xC5 , вместо 0x67 (толкова е UBRR за 16MHz и 9600bps)?

Автор:  3aek [ Чет Яну 01, 2015 11:29 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

я пак, функция void какво да връща?

Автор:  showMANiak [ Чет Яну 01, 2015 11:37 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

Не се изказах правилно.Правилният въпрос е,защо присвоява на нещо си (в случая регистъра на серийния порт) грешна стойност?.Ясно е,че void няма как да връща нещо :)

Автор:  Cino [ Чет Яну 01, 2015 11:39 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

така е защото (16*BAUDR) е 16 битов резултат
кастни то uint32 във скобите

Автор:  showMANiak [ Чет Яну 01, 2015 11:57 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

Точно в 10-ката :).Не се бях сетил за това.
Благодаря :)

Автор:  CALL-151 [ Вто Фев 03, 2015 7:41 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

защо не напишеш:

UBRR=FCPU/16/BAUDR-1;

така избягваш големия междинен резултат от умножението.

Отделно за къкъв процесор е това gcc че int-а му е 16bit?

Автор:  Gogo [ Сря Фев 04, 2015 9:13 am ]
Заглавие:  Re: Странно поведение на функция GNU-C

Код:
UBRR=(((FCPU/BAUDR)/8)-1)/2)

Аз ползвам това. Няма голям междинен резултат и е по-точно.

Автор:  marcuka68 [ Пет Фев 06, 2015 9:52 am ]
Заглавие:  Re: Странно поведение на функция GNU-C

Аз ползвам код, който закръгля към по-голям резултат, ако той преминава с 0.5 цялата част на числото (25.8 => 26). Разбира се, изразходва доста повече памет.

#define ROUND(a) ( ((uint32_t) (a) < (uint32_t) ((a) + 0.5))? (uint32_t) (a + 1) : (uint32_t) (a))
#define F_OSC (64) // in MHz
#define UINT16_BYTE_MSB(WORD) ((WORD) >> 8 )
#define UINT16_BYTE_LSB(WORD) ((uint8_t) (WORD))

#define BAUD_RATE1 (38400UL)
#define SPBRG1_VALUE ((uint16_t) ROUND(((float) F_OSC) * 1000000UL / (BAUD_RATE1 * 4) - 1)) // Used with BRG16=1, BRGH=1.

...

SPBRGH1 = UINT16_BYTE_MSB(SPBRG1_VALUE); // Baud Rate Generator High Byte.
SPBRG1 = UINT16_BYTE_LSB(SPBRG1_VALUE); // Baud Rate Generator Low Byte.

Автор:  ike [ Пет Фев 06, 2015 3:33 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

marcuka68 написа:
Разбира се, изразходва доста повече памет.

Обикновенно при микроконтролерите се ползва една скорост или 9600 или 115200. Като набиеш изчислението в макрос, компилатора го изчислява по време на компилирането и не заема никаква памет или процесорно време.

Автор:  marcuka68 [ Пет Фев 06, 2015 3:43 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

Гледах сутринта изразходваната програмна памет и беше с около 40 байта повече, ако ползвам макрос. Ползвам свободната версия на xc8. Струва ми се, че не изчислява предварително, а само замества в кода макроса, с неговото съответствие. Най-вероятно не ми е известно нещо.

Автор:  Цецо [ Пет Фев 06, 2015 6:13 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

Е това ще е наистина гениално творение (тоя компилатор) ако верно са направили тая простотия. Елементарно е да се провери де, просто отвори lst файла :)

Автор:  syscop [ Пет Фев 06, 2015 7:50 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

Нищо му няма, компилаторът генерира код за окръглянето - препроцесорът не може(не трябва) да го смята.

Автор:  Цецо [ Пет Фев 06, 2015 7:52 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

Да аз не съм дочел, при така написаните макроси е нормално да генерира код.

Автор:  marcuka68 [ Пет Фев 06, 2015 11:11 pm ]
Заглавие:  Re: Странно поведение на функция GNU-C

syscop написа:
Нищо му няма, компилаторът генерира код за окръглянето - препроцесорът не може(не трябва) да го смята.


За кои операции се генерира код и за кой не? Къде е описано това нещо?

Автор:  syscop [ Съб Фев 07, 2015 9:56 am ]
Заглавие:  Re: Странно поведение на функция GNU-C

#define ROUND(a) ( ((uint32_t) (a) < (uint32_t) ((a) + 0.5))? (uint32_t) (a + 1) : (uint32_t) (a)) - прегледай изхода от препроцесора.

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/