天天看点

关于STC单片机Keil编译器写C代码的部分小技巧2

1、 通常情况下我们的代码量不大的话,没必要去关注RAM的空间,一旦全局变量多,以及代码量大,这种情况下我们就需要关注了。

我们的51系列单片机,使用keil编译器编译时,会发现下方会有三个参数大小,分别是Data,Xdata,Code。

以个人的理解,整体来说,单片机内部空间,可分为变量存储器和代码存储区,即SDRAM和Flash程序存储区。

关于STC单片机Keil编译器写C代码的部分小技巧2
关于STC单片机Keil编译器写C代码的部分小技巧2
关于STC单片机Keil编译器写C代码的部分小技巧2

即:SDRAM=idata+xdata

data为固定的最大128字节

idata=data+128=256(字节)

xdata则等于单片机规格所拥有的SDRAM-256(字节)

code=Flash程序存储区

所以,需要注意自己的全局变量存储位置,data 和xdata的存放是有不同定义的,个人理解是如果你的变量是需要高速动作的,你就存放于data空间,而某些不是经常使用的变量,你就可以放到xdata空间,例如我个人的一个案例:

我的一个PWM输出函数,是使用定时器生成的,而这个PWM是100Hz的频率,相当于我要给一个100us的定时器来做,那么这个定时器变量就要100us进行一次赋值,这个动作是非常快的,那么我就将这个变量放在了data空间,这样我的PWM的频率是比较准确的,如果我放在了xdata空间,两种情况:要么PWM无法生成,要么频率达不到100HZ左右。

#include "STC8.H"
#define uchar unsigned char
#define uint unsigned int
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned char uint8_t;
typedef unsigned int  uint16_t;

data u8 PWM_C=0;	//PWM用
xdata u8 LED_C=0;	//不常用可放在xdata
data u8 Time0_100usCnt=0;	//定时器0的100us计数
data u8 Time0_1msCnt=0;	//定时器0的1ms计数
data u8 Time0_10msCnt=0;	//定时器0的10ms计数
data u8 Time0_100msCnt=0;	//定时器0的100ms计数

/*函数名称:Timer0Init(void)
 *功能描述:初始化定时器0
 *输入参数:无
 *输出参数:无
 *调用	  :主函数
 */
void Timer0Init(void)		//100微秒@22.1184MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x5C;		//设置定时初值
	TH0 = 0xF7;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	ET0=1;		//开定时器0中断
	EA=1;		//开总中断
}

/*函数名称:timer0(void)
 *功能描述:定时器0中断服务函数
 *输入参数:无
 *输出参数:无
 *调用	  :
 */
void timer0() interrupt 1	//100us
{	
	Time0_100usCnt++;	
	if(Time0_100usCnt>=10)//1ms
	{
		Time0_100usCnt=0;
		Time0_1msCnt++;
		
	}
	if(Time0_1msCnt>=10)//10ms
	{
		Time0_1msCnt=0;
		Time0_10msCnt++;
	}
	if(Time0_10msCnt>=10)//100ms
	{
		Time0_10msCnt=0;
		Time0_100msCnt++;
	}
	if(Time0_100msCnt>10)//1s
	{
		Time0_100msCnt=0;
	}
/***************************************/	
	
	MIC_PWM();
	

}
//****************************************************
/*								PWM								*/
//****************************************************
void MIC_PWM(void)
{

  PWM_C++;
	if(PWM_C==100)		 //100HZ
	{	
		PWM_C=0;		
		if(LED_C==0)	LED_PWM=1;
		else		LED_PWM=0;
	} 
  else
	{

		if(LED_C==WD_C)	LED_PWM=1;
	}

}
void main()
{
	Timer0Init();
	while(1)
	{
		...
	}
}
           

当然了,你需要看下你的配置的内存模式优先级,如果你选的是DATA,编译器就是默认你定义的变量优先为存储到data空间,当你的代码量大的时候,你需要选择xdata。

关于STC单片机Keil编译器写C代码的部分小技巧2
关于STC单片机Keil编译器写C代码的部分小技巧2

意思是说,当你的代码量足够大,然后你的内存空间满了,可以选择该模式,将你的代码自动优化,不至于写了128个字节变量,就挤爆了。

还要你自己去选哪个变量放那个区。

code区是不可变的,不可改动,一般我们定义一些不可变的数组时,可以在数组前添加code定义到程序存储区,减小ram的压力。

继续阅读