一、相关概念理解:
- 映射:
如果学过数学的应该从函数中了解过这个概念,映射就是将两个对象联系起来的一种过程
- 存储器映射:
我们知道单片机内部有很多不同类型存储单元,为了方便CPU操作这些存储单元,我们就将这些存储单元用数值连续、数目与其存储单元数相等、以16进制表示的自然数集合来表示,也就是我们平时说的地址。
- 存储器映射扩展:
除了操作内部单元外,我们也会使用单片机许多不同外设,如果外设数量过多就会出现IO口不够用的情况,我们就可以按照操作内部存储器思路去操作外设。
IAP15F2K61S2将P2定义为地址的高八位,将P0复用为地址的低八位和数据的八位,P42为WR位(当做”写入外部存储器“操作时就置”0“)
二、XBYTE的用法:
- 字面意义理解:
XBYTE,extern byte即外部字节的意思,我们可以理解为向外部某个存储单元写入一个字节的意思。
- 用法:
XBYTE[16位地址] = 8位数据
三、硬件电路:
- 各器件的详细解析可以看回之前LED的文章
蓝桥杯模块学习2——LED灯(深夜学习——单片机)_佛科院深夜学习的博客-CSDN博客
2.573锁存器

由这个电路我们可以知道,不同573锁存器是否作用主要由片选LE决定,高电平时起作用
3.或非门的作用

·我们可以看到每一个或非门的一个口都与WR即P42相连,当我们让单片机做XBYTE操作时,单片机会自动置位WR为0,这时选择哪个锁存器都由另一个口决定。
4.138译码器作用

而另一个口又是由138译码器控制
5.由硬件电路我们可以知道选择哪个外设由地址码的八位的前三位决定,如:LED灯地址码为:0x8000
四、存储器映射扩展实验:

- 代码思路:
首先记得将J13的1-2短接,引用"absacc.h"头文件,然后完成LED灯程序编写,最后完成数码管程序编写
- 参考代码:
(1)公共函数:
#ifndef _PUBLIC_H
#define _PUBLIC_H
#include "STC15F2K60S2.H"
#define u8 unsigned char
#define u16 unsigned int
void Delay_1ms(u16 num);
void Close_All(void);
void Delay_10us(u16 num);
#endif
#include "Public.h"
// 延时函数(最小约1ms@12MHz)
void Delay_1ms(u16 num)
{
unsigned int i;
while(num--)
for(i=0; i<628; i++);
}
/*
输入变量:无
输出变量:无
功能:关闭蜂鸣器和继电器
*/
void Close_All(void)
{
//关闭蜂鸣器和继电器
P0 = 0x00;
P2 = (P2 & 0x1f) | 0xA0;
P2 &= 0x1f;
//关闭LED灯
P0 = 0xff;
P2 = (P2 & 0x1F) | 0x80;
P2 &= 0x1f;
}
void Delay_10us(u16 num)
{
u16 i;
while(num--)
for(i=0; i<3; i++);
}
(2)主函数:
// 使用程序前,将J13调整为MM模式(1-2脚短接)
#include "Public.h"
#include "absacc.h"
void LED_ON(u8 L_X);
void LED_Proc();
void SEG_Show(u8 num,u16 PIS);
void SEG_Proc();
// 主函数
void main(void)
{
Close_All();
while(1)
{
LED_Proc();
SEG_Proc();
}
}
/************LED*********************/
/*
输入变量:P0口的对应的16进制数
输出变量:无
功能:选择相应的锁存器后,通过P0口控制LED灯亮
*/
void LED_ON(u8 L_X)
{
XBYTE[0x8000] = L_X;
}
void LED_Proc()
{
LED_ON(0xF0);
Delay_1ms(300);
LED_ON(0x0F);
Delay_1ms(300);
LED_ON(0xff);
}
/*****************数码管********************?
/*
输入变量:num,要显示数据;PIS,显示位置,从左到右分别为0-7
输出变量:无
功能:操作138译码器,4-7分别对应Y4-Y7,其余都会使译码器不起作用
注意:需要把存放从1-f对应的16进制数数组也移植
*/
void SEG_Show(u8 num,u16 PIS)
{
//消影
XBYTE[0xe000] = 0xff;
//改变显示位置
XBYTE[0xc000] = 0x01<<PIS;
//改变数据
XBYTE[0xe000] = num;
}
void SEG_Proc()
{
u8 i=0;
for(i=0;i<=8;i++)
{
SEG_Show(0x00,i);
Delay_1ms(300);
}
}