八、实例综合

一、强制类型转换

在这里插入图片描述
在进行数据运算的时候,有时候会出现数据溢出现象,为了解决这一问题,可采用数据强制转换的方法。

二、实例

实例一:数字秒表实例

#include <reg52.h>

sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;
sbit KEY3 = P2^6;
sbit KEY4 = P2^7;

unsigned char code LedChar[] = {  //数码管显示字符转换表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = {  //数码管显示缓冲区
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char KeySta[4] = {  //按键当前状态
    1, 1, 1, 1
};
unsigned char T0RH = 0;
unsigned char T0RL = 0;
bit  StopwatchRefresh = 1;
bit  StopwatchRunning = 0;
unsigned char DecimalPart = 0;
unsigned int IntegerPart = 0;

void ConfigTimer0(unsigned int ms);
void StopwatchDisplay();
void KeyDriver();
void main()
{
	EA = 1;
	ENLED = 0;
	ADDR3 = 1;
	P2 = 0xFE;
	ConfigTimer0(2);
  	while(1)
	{
		if(StopwatchRefresh)
		{
			StopwatchRefresh = 0;
			StopwatchDisplay();	
		}
		KeyDriver();	
	}
}

void ConfigTimer0(unsigned int ms)
{
	unsigned long tmp;

	tmp = 11059200/12;
	tmp = (tmp * ms)/1000;
	tmp = 65536 - tmp;
	tmp = tmp + 18;

	T0RH = (unsigned char)(tmp >> 8);
	T0RL = (unsigned char)tmp;
	TMOD &= 0xF0;
	TMOD |= 0x01;
	TH0 = T0RH;
	TL0 = T0RL;
	ET0 =1;
	TR0 = 1;
}
void StopwatchDisplay()
{
	signed char i;
	unsigned char buf[4];
	
	LedBuff[0] = LedChar[DecimalPart%10];
	LedBuff[1] = LedChar[DecimalPart/10];
	buf[0] = IntegerPart%10;
	buf[1] = IntegerPart/10%10;
	buf[2] = IntegerPart/100%10;
	buf[3] = IntegerPart/1000%10;

	for(i=3; i>=1; i--)
	{
		if(buf[i] == 0)
			LedBuff[i+2] = 0xFF;
		else
			break;
	}
	for(; i>=0; i--)
	{
		LedBuff[i+2] = LedChar[buf[i]];
	}
	LedBuff[2] &= 0x7F;
		
}
void StopwatchAction()
{
	if(StopwatchRunning)
		StopwatchRunning = 0;
	else
		StopwatchRunning = 1;
}
void StopwatchReset()
{
	StopwatchRunning = 0;
	DecimalPart = 0;
	IntegerPart = 0;
	StopwatchRefresh = 1;	
}
void KeyDriver()
{
    unsigned char i;
    static unsigned char backup[4] = {1,1,1,1};

    for (i=0; i<4; i++)  //循环检测4个按键
    {
        if (backup[i] != KeySta[i])  //检测按键动作
        {
            if (backup[i] != 0)      //按键按下时执行动作
            {
                if (i == 1)          //Esc键复位秒表
                    StopwatchReset();
                else if (i == 2)     //回车键启停秒表
                    StopwatchAction();
            }
            backup[i] = KeySta[i];   //刷新前一次的备份值
        }
    }
}

void KeyScan()
{
    unsigned char i;
    static unsigned char keybuf[4] = {  //按键扫描缓冲区
        0xFF, 0xFF, 0xFF, 0xFF
    };
    
    //按键值移入缓冲区
    keybuf[0] = (keybuf[0] << 1) | KEY1;
    keybuf[1] = (keybuf[1] << 1) | KEY2;
    keybuf[2] = (keybuf[2] << 1) | KEY3;
    keybuf[3] = (keybuf[3] << 1) | KEY4;
    //消抖后更新按键状态
    for (i=0; i<4; i++)
    {
        if (keybuf[i] == 0x00)
        {   //连续8次扫描值为0,即16ms内都是按下状态时,可认为按键已稳定的按下
            KeySta[i] = 0;
        }
        else if (keybuf[i] == 0xFF)
        {   //连续8次扫描值为1,即16ms内都是弹起状态时,可认为按键已稳定的弹起
            KeySta[i] = 1;
        }
    }
}

void LedScan()
{
    static unsigned char i = 0;  //动态扫描索引
    
    P0 = 0xFF;             //关闭所有段选位,显示消隐
    P1 = (P1 & 0xF8) | i;  //位选索引值赋值到P1口低3位
    P0 = LedBuff[i];       //缓冲区中索引位置的数据送到P0口
    if (i < 5)             //索引递增循环,遍历整个缓冲区
        i++;
    else
        i = 0;
}
void StopwatchCount()
{
	if(StopwatchRunning)
	{
		DecimalPart++;
		if(DecimalPart >= 100)
		{
			DecimalPart = 0;
			IntegerPart++;
			if(IntegerPart >= 10000)
			{
				IntegerPart = 0;
			}
		}
		StopwatchRefresh = 1;
	}
}

/* T0中断服务函数,完成数码管、按键扫描与秒表计数 */
void InterruptTimer0() interrupt 1
{
	static unsigned char tmr10ms = 0;

    TH0 = T0RH;  //重新加载重载值
    TL0 = T0RL;
    LedScan();   //数码管扫描显示
    KeyScan();   //按键扫描

	tmr10ms++;
	if(tmr10ms >= 5)
	{
		tmr10ms = 0;
		StopwatchCount();
	}
  
}

三、RAM区域划分

在这里插入图片描述
idata包括data,data区域访问速度最快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值