单片机c语言预编译时间问题

来源:百度知道 编辑:UC知道 时间:2024/05/24 01:41:45
先看完原程序,用的是预编译,之后可再把预编译去了

#include"reg52.h"

#define uint unsigned int
#define uchar unsigned char

#define FOSC 12000000 //系统振荡频率,Hz
#define Time (12*1000000)/FOSC //周期us
#define Time_Per 10000 //所需定时时间10ms
#define Time_Reg_H (65536-Time_Per/Time)/256 //定时器高8位初值
#define Time_Reg_L (65536-Time_Per/Time)%256 //定时器低8位初值*/

bit flag=0;
uchar i=0;
sbit D1=P1^0;

void T0_0()
{
TMOD=0X01;
TH0=Time_Reg_H;
TL0=Time_Reg_L; //强制类型转换
/* TH0=0XD8;
TL0=0XF0; */

TR0=1;
EA=1;
ET0=1;
}

void main(void)
{
D1=0xff;
T0_0();
while(1)
{
if(flag)
{
flag=0;
D1=~D1;
}
}
}

void T0_int(void) interrupt 1
{
TH0=Time_Reg_H;<

楼上的,你好像说的不对吧,你有没有学过编译原理。
宏定义都是在编译时就处理好了(属于预处理,直接在编译时处理好代进去用的),运行时并不占用大量的实型数据运算。

(65536-Time_Per/Time)/256
(65536-Time_Per/Time)%256
#define Time (12*1000000)/FOSC

这里进行了大量的实型数据的乘除运算,您可以看看程序生成的汇编,编译器可能生成了大段的汇编来完成这些计算(您可以人工优化这段汇编试一试)。每次定时器中断里面都去计算,这样耗费的时间太多了,造成了很大的误差。改为直接数值代入,那就是几句MOV就完成了,所以能正常运行。

您可以对比一下单片机产生正弦波,如果去计算Y=SIN X,那么只能产生几Hz的。 单片机没有乘法器,虽然能较快地做加减和位移,但是多字节的乘除对51单片机来说,确实比较困难。多采用查表的方法来回避这种计算。

编译器很可能出错,产生大量的冗余编码,这是在实际应用中遇到过的,全靠人工优化(几句C都搞出了将近1K的汇编,那个汗啊)。所以应该尽量避免这种编程方式。