51单片机嵌入式开发:STC89C52操作GPIO口LED灯

STC89C52操作GPIO口LED灯

  • [1 芯片介绍](#1 芯片介绍)
    • [1.1 芯片类型](#1.1 芯片类型)
    • [1.2 芯片系列说明](#1.2 芯片系列说明)
  • [2 GPIO引脚寄存器说明](#2 GPIO引脚寄存器说明)
  • [3 GPIO操作](#3 GPIO操作)
    • [3.1 GPIO输入](#3.1 GPIO输入)
    • [3.2 GPIO输出](#3.2 GPIO输出)
    • [3.3 GPIO流水灯](#3.3 GPIO流水灯)
    • [3.4 Protues仿真](#3.4 Protues仿真)
  • [4 总结](#4 总结)

1 芯片介绍

1.1 芯片类型

芯片采用宏晶科技品牌下的STC89C52RC单片机

选择STC89C52RC系列STC89C58RD+系列单片机的理由:

★加密性强

★超强抗干扰:

1、高抗静电(ESD保护)

2、轻松过 2KV/4KV 快速脉冲干扰(EFT 测试)

3、宽电压,不怕电源抖动

4、宽温度范围,-40℃℃~85℃℃

★三大降低单片机时钟对外部电磁辐射的措施:--出口欧美的有力保证

1、禁止ALE 输出;

2如选6时钟/机器周期,外部时钟频率可降一半;3、单片机时钟振荡器增益可设为 1/2gain。

★超低功耗:

1 、掉电模式:典型功耗<0.1 μA2、正常工作模式:典型功耗4MA - 7MA3、掉电模式可由外部中断唤醒,适用于电池供电系统,如水表、气表、便携设备等。

★在系统可编程,无需编程器,无需仿真器

★可送STC-ISP下载编程器,1万片/人/天

★可供应内部集成MAX810专用复位电路的单片机只有D 版本才有内部集成专用复位电路,原复位电路可以保留,也可以不用,不用时RESET脚接1K电阻到地

1.2 芯片系列说明

STC89C52RC芯片最高工作时钟频率为80M,flash内存有8K大小,RAM空间512字节,足以满足日常学习课单一功能的实现应用。

STC89C52RC/RD+ 系列单片机是宏晶科技推出的新一代超强抗干扰/高速/低功耗的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可任意选择,最新的D版本内部集成 MAX810 专用复位电路。

特点:

1.增强型6时钟/机器周期,12时钟/机器周期 8051 CPU

2.工作电压:5.5V-3.4V(5V单片机) / 3.8V - 2.0V(3V 单片机)3.工作频率范围:0-40 MHz,相当于普通8051的 0~80MHz.实际工作频率可达 48MHz.4.用户应用程序空间4K/8K/13K/16K/20K/32K/64K 字节

5.片上集成 1280 字节 /512字节 RAM

6.通用1/0口(32/36个),复位后为: P1/P2/P3/P4是准双向口上拉(普通8051传统 1/0 口)P0 口是开漏输出,作为总线扩展用时,不用加上拉电阻,作为1/0口用时,需加上拉电阻。7.ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器/仿真器可通过串口(P3.0/P3.1)直接下载用户程序,8K程序3秒即可完成一片

8.EEPROM 功能

9.看门狗

10.内部集成MAX810 专用复位电路(D 版本才有),外部晶体20M 以下时,可省外部复位电路11.共3个16 位定时器/计数器,其中定时器0还可以当成2个8位定时器使用12.外部中断4路,下降沿中断或低电平触发中断,Power Down模式可由外部中断低电平触发中断方式唤醒13.通用异步串行口(UART),还可用定时器软件实现多个 UART

14.工作温度范围:0-75℃℃/-40-+85℃℃

15.封装: LOFP-44,PDIP-40,PLCC-44,POFP-44,如选择STC89 系列,请优先选择LOFP-44 封装

2 GPIO引脚寄存器说明

手册说明:通用1/0口(32/36个),复位后为: P1/P2/P3/P4是准双向口上拉(普通8051传统1/0口)P0 口是开漏输出,作为总线扩展用时,不用加上拉电阻,作为1/0口用时,需加上拉电阻。

查看芯片的寄存器寻址框图,GPIO寄存器位置在80h、90h、A0h、B0h、E8h.

寄存器分别为P0/P1/P2/P3/P4,没有其他特殊的类似于高级芯片的方向控制上下拉控制寄存器等,操作简单易用。

3 GPIO操作

结合第一章节将工程重新整理

(1)切换使用keil5版本,根据第节说明的,将STC的的芯片包重新安装到KEIL5安装目录下即可,并按照同样的方式创建工程。

(2)工程架构整理,为了使工程看起来具有较高的可读性,我将led控制的gpio程序独立到c51_gpio.c,并建立c51_gpio.h,用于声明c51_gpio.c创建的函数和变量,创建includes.h用于引用所有的头文件和部分系统函数及变量。

C51_gpio.c

c 复制代码
#include "includes.h"


void sys_led(void)
{
	
}


/********************************************************
函数名称:sys_led_test
函数功能:IO口高低电平控制
入口参数:
出口参数:
修    改:
内    容:现在实现D0/D2/D4/D6指示灯亮起,
				D1/D3/D5/D7指示灯灭掉,并演示
********************************************************/
void sys_led_test(void)
{
	P1 = 0xFF;		//P1口全部为高电平,对应的LED灯全灭掉,ff换算成二进制是 1111 1111
	P1 = 0x00;		//P1口全部为低电平,对应的LED灯全亮起,ff换算成二进制是 0000 0000
	
	P1 = 0x55;		//D0/D2/D4/D6指示灯亮起
					//D1/D3/D5/D7指示灯灭掉,AA换算成二进制是 1010 1010 
}

C51_gpio.h

c 复制代码
#ifndef __C51_GPIO_H__
#define __C51_GPIO_H__

extern void sys_led(void);
extern void sys_led_test(void);

#endif

includes.h

#ifndef __INCLUDES_H__
#define __INCLUDES_H__

//#include<reg52.h> 

//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "STC89C5xRC_RDP.h"

//应用层头文件
#include "c51_gpio.h"



#endif

(3)根据串口助手提示更新芯片头文件放置工程的include文件夹中

我创建的名称为STC89C5xRC_RDP.h,并在includes.h中引用,屏蔽//#include<reg52.h>

c 复制代码
#ifndef __STC89C5xRC_RDP_H__
#define __STC89C5xRC_RDP_H__

/

//包含本头文件后,不用另外再包含"REG51.H"

sfr         P0          =           0x80;
    sbit    P00         =           P0^0;
    sbit    P01         =           P0^1;
    sbit    P02         =           P0^2;
    sbit    P03         =           P0^3;
    sbit    P04         =           P0^4;
    sbit    P05         =           P0^5;
    sbit    P06         =           P0^6;
    sbit    P07         =           P0^7;

sfr         SP          =           0x81;
sfr         DPL         =           0x82;
sfr         DPH         =           0x83;
sfr         PCON        =           0x87;

sfr         TCON        =           0x88;
    sbit    TF1         =           TCON^7;
    sbit    TR1         =           TCON^6;
    sbit    TF0         =           TCON^5;
    sbit    TR0         =           TCON^4;
    sbit    IE1         =           TCON^3;
    sbit    IT1         =           TCON^2;
    sbit    IE0         =           TCON^1;
    sbit    IT0         =           TCON^0;

sfr         TMOD        =           0x89;
sfr         TL0         =           0x8A;
sfr         TL1         =           0x8B;
sfr         TH0         =           0x8C;
sfr         TH1         =           0x8D;
sfr         AUXR        =           0x8E;

sfr         P1          =           0x90;
    sbit    P10         =           P1^0;
    sbit    P11         =           P1^1;
    sbit    P12         =           P1^2;
    sbit    P13         =           P1^3;
    sbit    P14         =           P1^4;
    sbit    P15         =           P1^5;
    sbit    P16         =           P1^6;
    sbit    P17         =           P1^7;
    
    sbit    T2EX        =           P1^1;
    sbit    T2          =           P1^0;

sfr         SCON        =           0x98;
    sbit    SM0         =           SCON^7;
    sbit    SM1         =           SCON^6;
    sbit    SM2         =           SCON^5;
    sbit    REN         =           SCON^4;
    sbit    TB8         =           SCON^3;
    sbit    RB8         =           SCON^2;
    sbit    TI          =           SCON^1;
    sbit    RI          =           SCON^0;

sfr         SBUF        =           0x99;

sfr         P2          =           0xA0;
    sbit    P20         =           P2^0;
    sbit    P21         =           P2^1;
    sbit    P22         =           P2^2;
    sbit    P23         =           P2^3;
    sbit    P24         =           P2^4;
    sbit    P25         =           P2^5;
    sbit    P26         =           P2^6;
    sbit    P27         =           P2^7;
    
sfr         AUXR1       =           0xA2;

sfr         IE          =           0xA8;
    sbit    EA          =           IE^7;
    sbit    EC          =           IE^6;
    sbit    ET2         =           IE^5;
    sbit    ES          =           IE^4;
    sbit    ET1         =           IE^3;
    sbit    EX1         =           IE^2;
    sbit    ET0         =           IE^1;
    sbit    EX0         =           IE^0;
    
sfr         SADDR       =           0xA9;

sfr         P3          =           0xB0;
    sbit    P30         =           P3^0;
    sbit    P31         =           P3^1;
    sbit    P32         =           P3^2;
    sbit    P33         =           P3^3;
    sbit    P34         =           P3^4;
    sbit    P35         =           P3^5;
    sbit    P36         =           P3^6;
    sbit    P37         =           P3^7;

    sbit    RD          =           P3^7;
    sbit    WR          =           P3^6;
    sbit    T1          =           P3^5;
    sbit    T0          =           P3^4;
    sbit    INT1        =           P3^3;
    sbit    INT0        =           P3^2;
    sbit    TXD         =           P3^1;
    sbit    RXD         =           P3^0;

sfr         IPH         =           0xB7;
sfr         IP          =           0xB8;
    sbit    PT2         =           IP^5;
    sbit    PS          =           IP^4;
    sbit    PT1         =           IP^3;
    sbit    PX1         =           IP^2;
    sbit    PT0         =           IP^1;
    sbit    PX0         =           IP^0;

sfr         SADEN       =           0xB9;
    
sfr         XICON       =           0xC0;
    sbit    PX3         =           XICON^7;
    sbit    EX3         =           XICON^6;
    sbit    IE3         =           XICON^5;
    sbit    IT3         =           XICON^4;
    sbit    PX2         =           XICON^3;
    sbit    EX2         =           XICON^2;
    sbit    IE2         =           XICON^1;
    sbit    IT2         =           XICON^0;

sfr         T2CON       =           0xC8;
    sbit    TF2         =           T2CON^7;
    sbit    EXF2        =           T2CON^6;
    sbit    RCLK        =           T2CON^5;
    sbit    TCLK        =           T2CON^4;
    sbit    EXEN2       =           T2CON^3;
    sbit    TR2         =           T2CON^2;
    sbit    C_T2        =           T2CON^1;
    sbit    CP_RL2      =           T2CON^0;
    
sfr         T2MOD       =           0xC9;
sfr         RCAP2L      =           0xCA;
sfr         RCAP2H      =           0xCB;
sfr         TL2         =           0xCC;
sfr         TH2         =           0xCD;

sfr         PSW         =           0xD0;
    sbit    CY          =           PSW^7;
    sbit    AC          =           PSW^6;
    sbit    F0          =           PSW^5;
    sbit    RS1         =           PSW^4;
    sbit    RS0         =           PSW^3;
    sbit    OV          =           PSW^2;
    sbit    F1          =           PSW^1;
    sbit    P           =           PSW^0;

sfr         ACC         =           0xE0;

sfr         WDT_CONTR   =           0xE1;
sfr         ISP_DATA    =           0xE2;
sfr         ISP_ADDRH   =           0xE3;
sfr         ISP_ADDRL   =           0xE4;
sfr         ISP_CMD     =           0xE5;
sfr         ISP_TRIG    =           0xE6;
sfr         ISP_CONTR   =           0xE7;

sfr         P4          =           0xE8;
    sbit    P40         =           P4^0;
    sbit    P41         =           P4^1;
    sbit    P42         =           P4^2;
    sbit    P43         =           P4^3;
    sbit    P44         =           P4^4;
    sbit    P45         =           P4^5;
    sbit    P46         =           P4^6;
    sbit    P47         =           P4^7;

sfr         B           =           0xF0;

/

#endif

至此工程整理完毕,接下来进行程序验证。

3.1 GPIO输入

GPIO输入检测即是对PX引脚的检测直接获取寄存器P的值即可。

先控制4个IO口输出为高低不同的电平,再用另外4个IO口获取前面4个端口的电平,并测试获取之后的电平状态是否是先前输出的电平状态。

程序代码如下:

c 复制代码
void sys_led_test(void)
{
	unsigned char tmp = 0;//中间变量用于获取io口状态
	
	//控制4个引脚输出
	P10 = 1;
	P11 = 0;
	P12 = 0;
	P13 = 1;
	
	//用另外四个IO口获取状态并测试(指示灯显示)
	tmp = P10;
	P14 = tmp;
	
	tmp = P11;
	P15 = tmp;
	
	tmp = P12;
	P16 = tmp;
	
	tmp = P13;
	P17 = tmp;
	
	
}

根据测试结果可知,获取IO口状态,直接读出对应寄存器位即可

3.2 GPIO输出

同理,控制GPIO口状态,直接写入寄存器即可,根据STC89C5xRC_RDP.h可知:

Pxy:x指的是端口名称,y指的是这个名称下的端口序号。

c 复制代码
sfr         P1          =           0x90;
    sbit    P10         =           P1^0;
    sbit    P11         =           P1^1;
    sbit    P12         =           P1^2;
    sbit    P13         =           P1^3;
    sbit    P14         =           P1^4;
    sbit    P15         =           P1^5;
    sbit    P16         =           P1^6;
    sbit    P17         =           P1^7;

3.3 GPIO流水灯

流水灯控制肯定要用到延时函数,首先定义一个简单的delay函数,并在includes.h中声明

c 复制代码
/*------------------------------------------------
                    延时子程序
------------------------------------------------*/
void delay(unsigned int cnt) 
{
 while(--cnt);
}

然后再c51_gpio.c中定义一个跑马灯程序,并在主程序的while(1)中使用,在c51_gpio.h中进行声明。

Led流水灯函数如下,其实在以下两句之间有一小段时间P1.0引脚出来的是低电平,在仿真时可以看出来。

P1<<=1; //左移一位 该语句等效于 P1=P1<<1

P1|=0x01; //最后一位补1,该语句等效于 P1=P1|0x01 符号"|"表示"或"

c 复制代码
/********************************************************
函数名称:sys_led_test
函数功能:led流水灯
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_led_test1(void)
{
	delay(30000);//延时程序
	P1<<=1;      //左移一位 该语句等效于 P1=P1<<1
	P1|=0x01;    //最后一位补1,该语句等效于 P1=P1|0x01 符号"|"表示"或"
	if(P1==0x7f) //检测是否移到最左端?"=="表示检测符号2端的值是否相等
	{ 
		delay(30000);
		P1=0xfe; //重新赋值
	}

}

烧录板子验证,流水灯成功。

3.4 Protues仿真

Protues仿真可以摆脱硬件的瓶颈,但是需要对器件特性有一定的了解,此处制作简单演示,后续完结后使用protues演示几个项目

4 总结

做一件事很容易,如何把这件事做好,做到自己满意的程度,需要花费心思和精力,实现功能很容易,实现具有高可靠性的功能需要再接再厉。

欢迎大家交流。

相关推荐
yannan201903138 分钟前
【算法】(C语言):二分查找
c语言·算法
Michael Lee.12 分钟前
Python学习篇:Python基础知识(三)
开发语言·python·学习·pycharm
martian66513 分钟前
学懂C#编程:属性(Property)的概念定义及使用详解
java·开发语言·c#·属性·property
小龙在慢慢变强..17 分钟前
C语言学习笔记--第一个程序
c语言·笔记·学习
逸群不凡23 分钟前
C++11|lambda语法与使用
开发语言·c++
DieSnowK30 分钟前
[C++][CMake][CMake基础]详细讲解
开发语言·c++·makefile·make·cmake·新手向·详细讲解
时间瑾33 分钟前
线程池实践篇
java·开发语言
JY9401 小时前
使用Qt制作一个简单的界面
开发语言·qt
萝卜地里的兔子1 小时前
面向对象编程思想新解 第二章 编程的本质
java·开发语言
weixin_307779131 小时前
C#实现求解函数在某一点的切线与法线函数
开发语言·c#