《51单片机C语言程序设计教程》涉及的细节问题笔记

前言

上一次写博客仿佛是在一万年前。
不论你想从这篇博客中了解到什么,如果你是一个新手,请自己审查自己手里拿着的板子。我的单片机型号为STC89C52RC,如果你不是这个型号,那么本文所述可能将不适合你的开发。
另外,本文编写的目的是以STC89C52RC为参考,来纠正**《51单片机C语言程序设计教程》(作者王云·异步图书·人民邮电出版社)**中的一些表述和代码。
并不是说这本书说错了,而是这本书实在过于古老(自己看看那示例图片的浓浓XP风),已经不适合我这块生产于2021的开发板了
另外,这本书也不是专门为这块普中开发板所编写,因此难免会有出入。我并不想单纯地将这篇文章变成一个“纠偏”文章,而是希望通过这种“纠偏”能够使感兴趣的读者进一步深入了解单片机,也可以为笔者未来的复习提供很大的参考。
本文将持续更新

单片机上电

没想到吧,这本书说了一大堆,但是没告诉你怎么启动单片机[手动滑稽]
首先你需要找到你的单片机的USB口,普中开发板单片机使用MicroUSB而非TypeA,就是以前安卓手机用的接口。
在这里插入图片描述
这是一块STC89C52RD+开发板,不用担心,他们长得几乎一样。在本图左下角我们可以发现一个写着USB1的东西,这就是我说的microUSB接口了。而它的上方就是开关。
接入电脑后将会显示其驱动已经安装,此时你按动开关,单片机就会亮起。

STC-ISP冷启动

由于书本当中使用的STC-ISP冷启动和我们的普中单片机所配套的STC-ISP软件不同,本文在此说明一下我们的下载软件该怎么使用。当然,STC-ISP软件必须冷启动给我们带来了很大的不便,因此在本目末尾,将给出普中芯片的下载软件——PZ-ISP
在这里插入图片描述
当你打开STC-ISP的时候基本上都会弹出来这个提示,并且之后你所进入的界面也和书本所述不同。
在这里插入图片描述
事实上你也找不到STC89C52RC,你只能找到上图的东西。
但是没关系,基本操作是一样的。
你的串口号可以通过扫描来确定
在这里插入图片描述
如果你已经选好了单片机型号以及确定了端口号,你只需要点击下方的的打开文件,你就可以打开你烧录的HEX文件。
在这里插入图片描述
点击下载编程即可
注意,冷启动要求我们先设置好并点击下载后再打开单片机的power开关,否则程序下载将会失败!!!
经常点按单片机开关,一方面影响开关寿命,一方面频繁断电也容易影响单片机寿命。普中开发板另外配套了一款更加神级的软件,它允许我们进行“热启动”
普中自带的下载软件PZ-ISPlogo如下
在这里插入图片描述
在这里插入图片描述
普中PZ-ISP的软件的界面更加清爽,芯片类型也不会多到离谱
在这里插入图片描述
它具备STC-ISP的常用功能,当你插入单片机时,它将也会自动检测所有的可用串口。使用方法和STC-ISP相近,本文不再赘述。
PZ-ISP不需要冷启动,反之,你如果冷启动,反而会失败。请在开机状态下用PZ-ISP下载程序

点亮第一个LED实验代码修正

如果你认真的阅读了书本,那么点亮第一个LED的代码将会是这样:

#include<reg52.h>
sbit LED=P1^0;

void main(){
	LED=0;
	while(1);
}

当你认认真真搞完了代码,编译,烧录后,你发现单片机根本不理你。试了很多次,然而一点办法也没有。你可能觉得使单片机坏了,而事实并不是这样。
书本在前文已经讲了发光二极管的原理,单片机通过改变引脚电平来控制发光二极管两端的电位,因此我们可以首先考虑是否是引脚的问题。
拿到开发板,首先查看技术文档是一个好习惯,技术文档描述了手中开发板的性能和特点。而网络上的意见未必适用与你的情况
在这里插入图片描述
如图所示,这是8个共阳极发光二极管。这里可能会有同学被单片机的标识误导。如下方图片所示,在区域5中同时标有LED模块和88点阵,而实际上88点阵是区域4。
在这里插入图片描述
另外 ,在LED模块示意图中,我们知道LED模块阴极实际上连接着单片机P2引脚群而不是P1引脚群。(假设忽略锁存器RP9和RP10,因为锁存器在使用时都是可以看作导通的)
锁存器可以看成是一种大型的RS触发器(基本触发器),它也具有保持态。书本P27举例了关于锁存器74HC573的例子,这里不再赘述。
为了解决LED无法点亮的问题,我们只需要将所控制的引脚代码修改一下即可。

#include<reg52.h>
sbit LED=P2^0;

void main(){
	LED=0;
	while(1);
}

P2^0就是指P2引脚群的第一个引脚,我们只需更改一个引脚名称,就可以是程序正确起来。

理解GPIO引脚的新方式

我们的单片机有三组GPIO引脚,P0,P1,P2,P3.
通过查看<reg52.h>头文件,我们可以知道这四组引脚的寄存器地址

sfr P0    = 0x80;
sfr P1    = 0x90;
sfr P2    = 0xA0;
sfr P3    = 0xB0;

每一个引脚组间均留出了10个空余地址,再让我们反过来思考在C51中一个让初学者都感到不解的奇怪写法——P2^1
如果不去做深入思考,我们只能知道,它想表达的是在P2引脚群中的第2个引脚的意思(注意P2^0才是第一个引脚)
可是我们根据C语言的常识,我们知道 ^符号是按位异或的意思,而在<reg52.h>头文件中,我们并没有发现这个符号以何种方式进行了运算符重载,也就是说,这里的按位异或符号还真的是按位异或的意思!!
根据我们在**<reg52.h>头文件中所看到的每一组GPIO引脚所在的首地址**,我们对代码LED=P2^0做按位异或运算。所以我们知道LED=0xA0这刚好就是P2引脚群的首地址!
那么,P2^1呢?
如我们所见,恰是0xA1!!
也就是首地址的下一个地址。
若地址都是连续的,我们不妨使用十六进制的地址信息直接对P2引脚群进行统一赋值,如

0x7F 对应 0111 1111 点亮D8灯
0xBF 对应 1011 1111 点亮D7灯

**为什么引脚信号为0才会点亮呢?**因为我们使用的是共阳极发光二极管!所以GPIO引脚低电平点亮,高电平熄灭。
如果你已经理解了,那么不妨看看如下代码:

#include<reg52.h>
unsigned int i=0;

void main(){
	while(1){
		P2=0xF0;
	}
}

它简单地实现了让四个灯保持全亮,而免去了挨个打P2^X的麻烦
运用这样的原理,我们可以使用延时函数结合巧妙的移位操作写出流水灯程序

#include "reg52.h"
#include "intrins.h"
typedef unsigned int u16;	//对系统默认数据类型进行重定义
//相当于将int写成u16
typedef unsigned char u8;

#define LED_PORT	P2	//使用宏定义P2端口

void delay_10us(u16 ten_us){  //这是一个简单的延时函数
	while(ten_us--);	
}

void main(){	
   	u8 i=0;  //可以去查看上面的typedef
	LED_PORT=~0x01;
	delay_10us(50000);
	while(1)
	{
		
		for(i=0;i<8;i++){
			LED_PORT=~(0x01<<i);	//将1右移i位,然后取反将结果赋值到LED_PORT
			delay_10us(50000);
		}
	}		
}

版权声明:本文为CSDN博主「RealMartinX」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Martisum/article/details/122552395

生成海报
点赞 0

RealMartinX

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

单片机按键扫描编程

实验四  单片机按键扫描编程 一、实验目的 1、掌握单片机按键扫描的工作方式; 2、掌握单片机按键扫描的编程方法。 二、实验内容 1、学习单片机按键扫描的工作方式; 2、扫描按键,控制LED

51单片机c语言开发工具keil安装

单片机分好几种,常见的51单片机开发需要安装keil对应c51版本,不能安装成了mdk版本。这个需要注意。目前,比较好的工具,windows下自然是keil了。但是它是收费的&#xff0c

【51单片机】数码管的静态显示

数码管的静态显示 锁存引脚高电平表示直通状态,为低电平表示锁存状态段锁存定位显示数字,位锁存定位用哪段数码管12M的晶振接两个30pf的电容,6M的晶振接20pf的电容三态:高电平,低电