我正在使用小型UART设备,经常需要切换其运行的波特率 从本质上讲,整个设置归结为
#define FOSC 2000000
#define BAUD 9600
uint8_t rate = (uint8_t) ((FOSC / (16.0 * BAUD)) - 1 + 0.5);
(其中+0.5用于对结果进行舍入。)
我目前正在使用gcc 4.8.1编译-O1
编译器是否优化了整个演员表,还是我留下了一个强制转换后跟一个常量?这会因不同的-O#
值(-O0
除外)而有所不同吗?那么-Os
(我最终可能要编译)呢?
如果重要,我正在开发Atmel AT90USB647(或datasheet [pdf])。
答案 0 :(得分:3)
非常可能任何理智的编译器都会在启用优化的情况下编译时将整个表达式(包括强制转换)转换为常量。
但是,当然,您需要查看编译器的汇编输出。
#include <stdint.h>
#include <stdio.h>
#define FOSC 2000000
#define BAUD 9600
int main() {
uint8_t rate = (uint8_t) (FOSC / (16.0 * BAUD)) - 1 + 0.5;
printf("%u", rate);
}
gcc -O1 red.c
main:
.LFB11:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $12, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
我们可以清楚地看到gcc已为12
预先计算了rate
的值。
答案 1 :(得分:0)
Atmel AVR发布了newlib C库,它是一个简单的ANSI C库,数学库和板级支持包的集合。您可以参考ANSI C规范来查找。特别是转换部分。
答案 2 :(得分:0)
我会确保将速率写入易失性变量或指针。也许速率值计算正常,但是当它写入外设目的地时,它缺少volatile标记,优化器不执行写操作。