IO及IO扩展练习
内容来自B站小蜜蜂老师
外部资料的地址映射关系
0x8000 ------led指示灯
0xa000 ------蜂鸣器与继电器
0xc000 ------数码管位选
0xe000 ------数码管段选
注意:
在该单片机进行IO扩展的时候J13要将1-2引脚短接
引入头文件"absacc.h" 通过关键字XBYTE关键字直接操作扩展资源
IO扩展方式要占用P3^6引脚
下面分别用io和io扩展方式实现上述功能
方式一:IO操作
#include "reg52.h"
/********************************************
Date:2022-1-13
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/
//--------------------------74HC138初始化---------------------------
void Init_74HC138(unsigned char n)
{
switch(n)
{
case 4: P2 = P2 | 0x1f; P2 = 0x80; break;
case 5: P2 = P2 | 0x1f; P2 = 0xa0; break;
case 6: P2 = P2 | 0x1f; P2 = 0xc0; break;
case 7: P2 = P2 | 0x1f; P2 = 0xe0; break;
}
}
void delay(unsigned int t)
{
unsigned int i,j;
for(i = 0; i< t;i++)
{
for(j = 0; j < 12000;j++);
}
}
//--------------------------------------------------------------------
//-----------------------------系统初始化-----------------------------
void InitSystem(void)
{
Init_74HC138(5); //Y5选通
P0 = 0x00; //关闭继电器和蜂鸣器
Init_74HC138(4); //Y4
P0 = 0xff; //关闭LED
}
//----------------------------------------------------------------------
//--------------------------------LED功能函数----------------------------
void LedRunning(void)
{
Init_74HC138(4);
P0 = 0xf0;
delay(50);
P0 = 0x0f;
delay(50);
P0 = 0xff;
delay(50);
}
void SMG_Running(void)
{
unsigned char i;
for(i = 0; i< 8;i++)
{
Init_74HC138(6);
P0 = 0x01 << i;
Init_74HC138(7);
P0 = 0X00;
delay(10);
}
P0 = 0xff;
delay(10);
}
//------------------------------------------------------------------------
void main(void)
{
InitSystem();
while(1)
{
LedRunning();
SMG_Running();
}
}
方式二:IO扩展操作
#include "reg52.h"
#include "absacc.h"
/********************************************
Date:2022-1-13
Author:小殷同学
Learn From:B 站小蜜蜂老师
*********************************************/
void delay(unsigned int t)
{
unsigned int i,j;
for(i = 0; i< t;i++)
{
for(j = 0; j < 12000;j++);
}
}
//-----------------------------系统初始化-----------------------------
void InitSystem(void)
{
XBYTE[0xa000] = 0x00; //关闭蜂鸣器 继电器
XBYTE[0x8000] = 0xff; //关闭LED
}
//----------------------------------------------------------------------
//--------------------------------LED功能函数----------------------------
void LedRunning(void)
{
XBYTE[0x8000] = 0xf0;
delay(50);
XBYTE[0x8000] = 0x0f;
delay(50);
P0 = 0xff;
delay(50);
}
void SMG_Running(void)
{
unsigned char i;
for(i = 0; i< 8;i++)
{
XBYTE[0xc000] = 0x01 << i;
XBYTE[0xe000] = 0x00;
delay(10);
}
XBYTE[0xe000] = 0xff;
delay(10);
}
//------------------------------------------------------------------------
void main(void)
{
InitSystem();
while(1)
{
LedRunning();
SMG_Running();
}
}
通过上面两种方式的比较可以看出io扩展方式确实会比io直接操作的代码简短很多
也会比较简洁,当然两种方式各自有自己的优势 譬如当我们要进行矩阵键盘操作的
时候P3^6引脚就会被IO扩展方式所占用 这时候就只能用普通IO操作 在应用这两种
方式的时候根据功能要求考虑 更适合哪一种。