程序中一个字节码程序(八位)为什么能表示255个数?

&这两天将STM32的IIC按照原子哥的程序,大致走了一遍,多少对IIC不是那么地陌生了,也多少有了自己的一些感悟,在这里,将这两天的学习的一个大致步骤总结下,一来可以让自己形成一个清晰地思路,二来,希望能给一些新手一点启发。
& 首先IIC是一种通信协议,通信方式相对比较简单,主要有两条线,SDA,SCL。SDA是串行数据线,上面走命令和数据,而SCL只是一条时钟线,其保证数据是按照时钟节拍来进行传输。IIC上面可以外挂很多的IIC芯片,每一个芯片对应着不同的地址,通过地址来将不同的芯片进行分开,保证不同芯片之间的数据传输,由于每一个芯片都是可以独立地收发,故,每一个芯片都是主机/从机。接下来,就是数据的传输过程了,
& 大致的一个数据传输流程是:主机向SDA线上发送一个起始信号,表示有信号进行传输,此时所有连接到IIC总线上的芯片都处于接收状态,接下来,主机发送想要与其进行数据传输的从机地址信号,所有的从机都会接收到该地址信号并和自己固有的地址信号进行匹配,当配对成功时,接下来就在时钟信号的带动下进行数据传输,数据的传输是按照每8位一个单元进行数据的传输。每一位的传输过程中,在SCL高电平期间,一定要保证SDA数值的稳定,否则会出现出错的情况,SDA数值的改变发生在SCL的低电平期间。最终8位全部传输完毕,从机产生一个应答信号给主机,主机在接收到该应答信号后决定接下来是发送一组新的数据还是终止发送。
& 大致按照传输的一个流程和模拟IIC的源码来对数据传输过程进行分析:
分析之前,将一些定义告诉大家,免得有疑问:
//I/O方向设置
#define SDA_OUT() {GPIOB-&CRL &= 0X0FFFFFFF;GPIOB-&CRL |= 3&&28;} //0011 通用推挽输出,50M
#define SDA_IN() {GPIOB-&CRL &= 0X0FFFFFFF;GPIOB-&CRL |= 8&&28;} //1000 上拉/下拉输入
//I/O操作函数
#define IIC_SCL PBout(6)
#define IIC_SDA PBout(7)
#define READ_SDA PBin(7)
其中SDA_IN()、&SDA_OUT()设置了I/O口的方向,也就是SDA是输入那?还是输出那?
IIC_SCL & 是SCL输出管脚
IIC_SDA & 是SDA输出管脚
READ_SDA &读取SDA输入引脚,等待应答信号时要用。
OK!接下来就磨刀霍霍,开始分析数据传输过程
1、起始信号
首先,SDA、SCL线默认是高,表示总线处于空闲状态,接着SDA线被主机拉低,表示主机有信号进行传输,要么是发数据,或者是要进行读数据,当SDA线拉低之后,SCL线也同样被拉低,准备接下来的数据传输。用了原子哥的模拟IIC,此开始信号的产生如下:
声明:此时将CPU当做了主机,而AT24C02当做了从机。
//起始信号
void IIC_Start(void)
SDA_OUT(); //设为主机输出
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(4);
IIC_SDA = 0; //scl为高电平时,SDA出现低电平跳变,表示传输开始
delay_us(5);
IIC_SCL = 0; && //钳位SCL,方便接下来进行数据传输
此程序产生的波形就是上面起始信号所对应的波形。
2、终止信号
终止信号:就是在SCL为高电平时,SDC出现一个上升沿的跳变,即表示终止信号
源程序如下:
//终止信号
void IIC_Stop(void)
SDA_OUT(); && //设为主机输出
IIC_SDA = 0;
IIC_SCL = 1;
delay_us(2); &&//scl为高电平,SDA出现高电平跳变,表示传输结束
IIC_SDA = 1;
3、等待应答信号
& 主机将一组数据发送完毕,接下来就进入等待从机发送応答信号的到来,从机会在第9个时钟信号时,发送该应答信号,此应答信号就是将SDA信号线拉低,而又由于SDA、SCL为开漏输出,故支持线与的形式,当从机那边将SDA线拉低,而主机这边依旧是将SDA线置高,主机通过判断SDA线的高低电平就可以知道是否收到了该应答信号,当然,接收到该应答信号的前提是,使能了从机的应答功能,否则接受不到,之能通过每组发送完毕的一个长延时来保证从机接收数据完毕。
//等待应答信号到来
//返回值:1,接收应答失败
// & & & &0,接收应答成功
u8 IIC_Wait_Ack(void)
u16 Errtime=0;
SDA_IN(); //此时设置为输入
IIC_SCL = 1;
IIC_SDA = 1; //线与的关系
if(READ_SDA)
Errtime++;
if(Errtime & 250)
IIC_Stop();
IIC_SCL = 0; //钳位,方便下次传输
程序中需要注意的地方是,虽然设置了GPIO的方向为输入,但是GPIO的电平还是可以设置的,没有矛盾,GPIO方向由CRL &CRH来决定,输出电平由ODR寄存器来决定
4、产生应答信号
如上所说,从机可以选择产生应答信号,同样也可以选择不产生应答信号。
产生应答辛号就是从机将SDA线拉低,不产生应答辛号就是SDA线一直保持高电平
//产生应答信号
void IIC_Ack(void)
SDA_OUT(); &//此时,相当于主机在接收数据,是被动方
IIC_SCL = 0;
IIC_SDA = 0;
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
需要注意的是,此时,CUP相当于是从机,故I/O方向为输出
5、不产生应答信号
//不产生应答信号
void IIC_NAck(void)
SDA_OUT(); &//此时,相当于主机在接收数据,是被动方
IIC_SCL = 0;
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
6、写一个字节
按照该时序图就可以写数据了,流程如下:
&主机:起始信号-----&第一位------&第二位---------& & ........ & &--------&第八位---------& & 等待应答信号-------&停止信号
SDA数据的有效性,在上面已经分析过,就是在SCL高电平期间,SDA数据不能改变,这样才是一个有效数据,否则无效
& & & SDA只能在SCL低电平期间改变
//发送一个字节数据
void IIC_Send_Byte(u8 txd)
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(i=0;i&8;i++)
if(txd & 0x80)
IIC_SDA = 1;
IIC_SDA = 0;
txd &&= 1;
delay_us(2);
IIC_SCL = 1;
delay_us(2);
IIC_SCL = 0;
delay_us(2);
高位先发,程序中严格保证了SDA的有效性
7、读一个字节
此时CPU相当于是从机,而芯片才是主机,主机在发数据,从机在接受
//读一个字节数据 & ack = 1 时,产生应答 && ack = 0 &,不产生应答
u8 IIC_Read_Byte(unsigned char ack)
unsigned char i,receive=0;
for(i=0;i&8;i++)
IIC_SCL = 0;
delay_us(2);
IIC_SCL = 1; &&//高电平时数据已经稳定,故进行数据的读取
receive &&= 1;
if(READ_SDA)
receive++;
IIC_Ack();
IIC_NAck();
以上就是模拟IIC的函数
接下来就要针对AT24C02来进行程序的编写
1、在AT24C02指定地址读出一个数据
先来看AT24C02的随机读数据的时序图
此时序图上需要注意两个地方,箭头所标记的两次开始信号,以及椭圆圈起来的写信号和读信号,接下来就分析该过程
首先,发送一个开始信号,接下来发送器件的地址,注意最后一位为Write标志位(0),等待应答,然后发送要读的地址,等待应答,又要发送一个起始信号,发送器件的地址,注意此时,最后一位为Read标志位(1),等待应答,接下来数据就可以读回来了。
器件的地址:
地址按照这个来进行设置,AT24CXX,这个XX即表示存储量XX(K),很显然AT24C02为2K,有256Byte,A2,A1,A0定义看芯片,如下
故,AT24C02的写地址为0XA0,读地址为0XA1,到这里,任督二脉已打通,接下来,上源码
//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址 & 0-255
//返回值 &:读到的数据
u8 AT24C02_ReadOneByte(u8 ReadAddr)
IIC_Start();
IIC_Send_Byte(0XA0); //发送器件地址
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr); //发送首地址
IIC_Wait_Ack();
IIC_Start();& && //注意,这个需要一个新的起始信号
IIC_Send_Byte(0XA1);
IIC_Wait_Ack();
temp = IIC_Read_Byte(0); //不产生应答
IIC_Stop();
2、在AT24C02指定地址写入一个数据
有了上面读的分析,这里应该可以看懂,注意箭头那位就好,严格按照这个流程来就好了
//在AT24CXX指定地址写入一个数据
//WriteAddr &:写入数据的目的地址 & &
//DataToWrite:要写入的数据
void AT24C02_WriteOneByte(u8 WriteAddr,u8 DataToWrite)
IIC_Start();
IIC_Send_Byte(0XA0); //发送器件地址
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr); //发送首地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);
&//这个延时是必须的,保证下次发送之前,上次的数据已经被接收
需要注意的地方是这个延时,红色标记,因为后面要用到这个进行连续的写操作,故这里加一个延时,保证下次写之前,上次的数据已经被完全接收,否则有可能会出错
3、在AT24C02里面的指定地址开始写入长度为Len的数据
直接调用上面的在指定位置写数据的函数即可
//在AT24CXX里面的指定地址开始写入长度为Len的数据
//该函数用于写入16bit或者32bit的数据.
//WriteAddr &:开始写入的地址 &
//DataToWrite:数据数组首地址
//Len & & & &:要写入数据的长度2,4
void AT24C02_WriteLenByte(u16 WriteAddr,u32 DataToWtie,u8 Len)
for(i=0;i&Li++)
AT24C02_WriteOneByte(WriteAddr + i,(DataToWtie && (8*i)) & 0XFF);
需要注意的是,此时将数据的高位写到了后面地址处,所以接下来读数据的时候,要从后面开始读,免得出错
4、在AT24C02里面的指定地址开始读取长度为Len的数据
同上,直接调用上面在指定位置读取数据的函数即可
//在AT24CXX里面的指定地址开始读取长度为Len的数据
//该函数用于读取16bit或者32bit的数据.
//WriteAddr &:开始写入的地址 &
//Len & & & &:要写入数据的长度2,4
u32 AT24C02_ReadLenByte(u16 WriteAddr,u8 Len)
u32 temp=0;
for(i=0;i&Li++)
temp &&= 8;&
temp += AT24C02_ReadOneByte(WriteAddr + Len - i - 1);
注意,先读的是后面的数据
5、校验IIC芯片是否在,是否正常
通过IIC芯片的最后一个地址255,写入数据0X55,当能读回这个数据时,说明芯片工作正常,否则不正常
//检查AT24C02是否正常
//这里用了2402的最后一个地址(255)来存储标志字.0x55
//返回1:检测失败
//返回0:检测成功
u8 AT24C02_Check(void)
u8 temp=0;
temp = AT24C02_ReadOneByte(255);
if(temp == 0X55)
AT24C02_WriteOneByte(255,0X55);
temp = AT24C02_ReadOneByte(255);
if(temp == 0X55)
上来直接读,可以免得每次都要写,写一次就好了,其他时间都是读她就行
6、在AT24C02里面的指定地址开始读出指定个数的数据
依旧是调用上面的,不多说了,要饿死了zzzzzzzzz
//在AT24C02里面的指定地址开始读出指定个数的数据
//ReadAddr :开始读出的地址 对24c02为0~255
//pBuffer &:数据数组首地址
//NumToRead:要读出数据的个数
void AT24C02_Read(u8 ReadAddr,u8 *pBuffer,u8 NumToRead)
while(NumToRead)
*pBuffer++ = AT24C02_ReadOneByte(ReadAddr++);
NumToRead--;
7、在AT24C02里面的指定地址开始写指定个数的数据
//在AT24C02里面的指定地址开始写指定个数的数据
//WriteAddr :开始写数据的地址 对24c02为0~255
//pBuffer &:数据数组首地址
//NumToWrite:要写数据的个数
void AT24C02_Write(u8 WriteAddr,u8 *pBuffer,u8 NumToWrite)
while(NumToWrite)
AT24C02_WriteOneByte(WriteAddr++,*pBuffer++);
NumToWrite--;
看好DATASHEET是关键,我所获得的有很多都是来自于网络,所以要记得回馈,羊有跪乳之恩,只是当今时代发展太快,都忘记了感恩,心怀感恩,世界是这么美好,希望也能给你一点帮助吧!
旗下网站:
与非门科技(北京)有限公司 All Rights Reserved.
京ICP证:070212号
北京市公安局备案编号: 京ICP备:号从单片机基础到程序框架(连载) - 第4页 - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
10:33:25  
第十二节:变量的定义和赋值。
(105.69 KB, 下载次数: 29)
10:31 上传
点击文件名下载附件
下载积分: 积分 -1 分
【12.1& &学习C语言的建议和方法。】
& && & 先提一些学C语言的建议和方法,帮大家删繁就简,去掉一些初学者常见的思想包袱。现阶段我们的学习是使用单片机,把单片机当做一个成品,把单片机当做一个忠诚的士兵,学习C语言就是学习如何使用单片机,如何命令单片机,如何让单片机听懂我们的话并且听我们指挥。单片机内部太细节的构造原理暂时不用过多去关注,只要知道跟我们使用相关的几个特征就可以,这样初学者的学习包袱就没有那么重,就可以把重点放在使用上的,而不是好奇于根本原理的死磕到底。学C语言跟学习英语的性质是一样的,都是在学习一门外语,只是C语言比英语的语法要简单很多,非常容易上手,词汇量也没有英语那么多,C语言常用单词才几十个而已。学习任何一门语言的秘诀在于练习,学习C语言的秘诀是多在单片机上练习编程。本教程后面几乎每个章节都有例程,这个例程很重要,初学者即使看懂了,我也强烈建议要把“C语言学习区域”的那部分代码亲自上机敲键盘练习一遍,并且看看实验现象是否如你所愿。
【12.2& &变量定义和赋值的感性认识。】
& && & 这些年我用过很多单片机,比如51,PIC,LPC17系列,STM8,STM32等单片机。尽管各类单片机有一些差异,但是在选单片机时有3个参数我们一定会关注的,它们分别是:工作频率,数据存储器RAM,程序存储器ROM。工作频率跟晶振和倍频有关,决定了每条指令所要损耗的时间,从而决定了运算速度。RAM跟代码里所定义变量的数量有关。ROM跟程序代码量的大小有关。程序是什么?程序就是由对象和行为两者构成的。对象就是变量,就是变量的定义,就是RAM,RAM的大小决定了一个程序允许的对象数量。行为就是赋值,判断,跳转,运算等语法,就是ROM,ROM的大小决定了一个程序允许的行为程度。本节的标题是“变量的定义和赋值”,其中“定义”就是对象,“赋值”就是行为。
【12.3& &变量的定义。】
& && & 变量的定义。一个程序最大允许有多少个对象,是由RAM的字节数决定的(字节是一种单位,后面章节会讲到)。本教程的编译环境是以AT89C52芯片为准,AT89C52这个单片机有256个字节的RAM,但是并不意味着程序就一定要全部占用这些RAM。程序需要占用多少RAM,完全是根据程序的实际情况来决定,需要多少就申请多少。这里的“对象”就是变量,这里的“申请”就是变量的定义。& && & 定义变量的关键字。常用有3种容量的变量,每种变量的取值范围不一样。第一种是”unsigned char”变量,取值范围从0到255,占用RAM一个字节,比喻成一房一厅。第二种是”unsigned int”变量,取值范围从0到65535,占用RAM两个字节,比喻成两房一厅。第三种是“unsigned long”变量,取值范围从0到,占用RAM四个字节,比喻成四房一厅。unsigned char,unsigned int和unsigned long都是定义变量的关键字,所谓关键字也可以看成是某门外语的单词,需要大家记忆的,当然不用死记硬背,只要多上机练习就自然熟记于心,出口成章。多说一句,上述的变量范围是针对本教程所用的单片机,当针对不同的单片机时上述变量的范围可能会有一些小差异,比如在stm32单片机中,unsigned int的字节数就不是两个字节,而是四个字节,这些都是由所选的编译器决定的,大家暂时有个初步了解就可以。& && & 定义变量的语法格式。定义变量的语法格式由3部分组成:关键字,变量名,分号。比如:& && &复制代码
& && & 其中unsigned char就是关键字,a就是变量名,分号”;”就是一条语句的结束符号。& && & 变量名的命名规则。变量名的第一个字符不能是数字,必须是字母或者下划线,字母或者下划线后面可以带数字,一个变量名之间的字符不能带空格,两个独立变量名之间也不能用空格隔开(但是两个独立变量名之间可以用逗号隔开)。变量名不能跟编译器已征用的关键字重名,不能跟函数名重名,这个现象跟古代要求臣民避讳皇帝的名字有点像。哪些名字是合法的,哪些名字是不合法的?现在举一些例子说明:& && &&&unsigned char 3a; //不合法,第一个字符不能是数字。
& && &&& //不合法,char是编译器已征用的关键字。
& && &&& //不合法,ab是一个变量名,a与b的中间不能有空格。
& && &&&unsigned char a,b; //合法,a和b分别是一个独立的变量名,a与b的中间可以用逗号隔开。
& && &&& //合法。
& && &&& //合法。
& && &&&unsigned char _ //合法。
& && &&&unsigned char _3 //合法。
& && &&&unsigned char a123; //合法。
& && &&&unsigned char a12 //合法。复制代码
& && &&&定义变量与RAM的内在关系。当我们定义一个变量时,相当于向单片机申请了一个RAM空间。C编译器会自动为这个变量名分配一个RAM空间,每个字节的RAM空间都有一个固定唯一的地址。把每个字节的RAM空间比喻成房间,这个地址就是房号。地址是纯数字编号,不利于我们记忆,C语言编译器为了降低我们的工作难度,不用我们记每个变量的地址,只需要记住这个变量的名称就可以了。操作某个变量名,就相当于操作某个对应地址的RAM空间。变量名与对应地址RAM空间的映射关系是C编译器暗中悄悄帮我们分配好的。比如:& && &&&&&//a占用一个字节的RAM空间,这个空间的地址由C编译自动分配。
& && &&&&&//b占用一个字节的RAM空间,这个空间的地址由C编译自动分配。
& && &&&&&//c占用一个字节的RAM空间,这个空间的地址由C编译自动分配。&&复制代码
& && &&&上述a,b,c三个变量各自占用一个字节的RAM空间,同时被C编译器分配了3个不同的RAM空间地址。& && &&&变量定义的初始化。变量定义之后,等于被C编译器分配了一个RAM空间,那么这个空间里面存储的数据是什么?如果没有刻意给它初始化,RAM空间里面存储的数据是不太确定的,是默认的。有些场合,需要在给变量分配RAM空间时就给它一个固定的初始值,这就是变量定义的初始化。变量初始化的语法格式由3部分组成:关键字,变量名赋值,分号。比如:& && &&&unsigned char a=9;复制代码
& && &&&其中unsigned char就是关键字。& && &&&其中a=9就是变量名赋值。a从被C编译器分配RAM空间那一刻起,就默认是预存了一个9的数据。& && &&&分号“;”就是一条语句的结束符号。
【12.4& &变量的赋值。】
& && & 赋值语句的含义。把右边对象的内容复制一份给左边对象。赋值语句有一个很重要的特性,就是覆盖性,左边对象原来的内容会被右边对象复制过来的新内容所覆盖。比如,左边对象是变量a,假设原来a里面存的数据是3,右边对象是数据6,执行赋值语句后,会把右边的6赋值给了对象a,那么a原来的数据3就被覆盖丢失了,变成了6。& && & 赋值语句的格式。赋值语句的语法格式由4部分组成:左边对象,关键字,右边对象,分号。比如:& && & a=b;复制代码
& && & 其中a就是左边对象。& && & 其中“=”就是关键字。写法跟我们平时用的等于号是一样,但是在C语言里不是等于的意思,而是代表赋值的意思,它是代表中文含义的“给”,而不是用于判断的“等于”,跟等于号是两码事(C语言的等于号是“==”,这个后面章节会讲到)。& && & 其中b就是右边对象。& && & 其中分号“;”代表一条语句的结束符。& && & 赋值语句与ROM的关系。赋值语句是行为的一种,所以编译会把赋值这个行为翻译成对应的指令,这些指令在下载程序时最终也是以数据的形式存储在ROM里,指令也是以字节为单位(字节是一种单位,后面章节会讲到)。本教程的编译环境是以AT89C52芯片为准,AT89C52这个单片机有8K的ROM容量,也就是有8192个字节的ROM(8乘以1024等于8192),但是并不意味着程序就一定要全部占用这些ROM。程序需要占用多少ROM,完全是根据程序的行为程度决定,也就是通常所说的你的程序容量有多大,有多少行代码。多说一句,在单片机或者我们常说的计算机领域里,存储容量是以字节为单位,而每K之间的进制不是我们日常所用的1000,而是1024,所以刚才所说的8K不是8000,而是8192,这个是初学者很容易迷惑的地方。刚才提到,赋值语句是行为,凡是程序的行为指令都存储在单片机的ROM区。C编译器会把一条赋值语句翻译成对应的一条或者几条机器码,机器码指令也是以字节为单位的。下载程序的时候,这些机器码就会被下载进单片机的ROM区。比如以下这行赋值语句:& && &
& && & unsigned char b=3;
& && & a=b;复制代码
& && & 经过C编译器编译后会生成以字节为单位的机器码。这些机器码记录着这些信息:变量a的RAM地址,变量b的RAM地址和初始化时的预存数据3,以及把b变量的内容赋值给a变量的这个行为。所有这些信息,不管是“数据”还是“行为”,本质都是以“数据”(或称数字,数码都可以)的形式存储记录的,单位是字节。
【12.5& &例程的分析和练习。】
& && & 接下来练习一个程序实例。直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。本章节在“C语言学习区域”练习的代码如下:
/*---C语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
& && &&&//定义的变量a被分配了一个字节的RAM空间,保存的数据是不确定的默认值。
& && && &//定义的变量b被分配了一个字节的RAM空间,保存的数据是不确定的默认值。
& && && &//定义的变量c被分配了一个字节的RAM空间,保存的数据是不确定的默认值。
& && & unsigned char d=9; //定义的变量d被分配了一个字节的RAM空间,保存的数据被初始化成9.
& && & b=3;&&//把3赋值给变量b,b由原来不确定的默认数据变成了3。
& && & c=b;&&//把变量b的内容复制一份赋值给左边的变量c,c从不确定的默认值变成了3。
& &View(a);& &//把第1个数a发送到电脑端的串口助手软件上观察。
& &View(b);& &//把第2个数b发送到电脑端的串口助手软件上观察。
& &View(c);& &//把第3个数c发送到电脑端的串口助手软件上观察。
& &View(d);& &//把第4个数d发送到电脑端的串口助手软件上观察。
& &while(1)&&
& &{
& &}
}
/*---C语言学习区域的结束。-----------------------------------------------*/复制代码
& && & 在电脑串口助手软件上观察到的程序执行现象如下:
第1个数
十进制:255
十六进制:FF
二进制:
第2个数
十进制:3
十六进制:3
二进制:11
第3个数
十进制:3
十六进制:3
二进制:11
第4个数
十进制:9
十六进制:9
二进制:1001复制代码
分析:& && &&&第1个数a居然是255,这个255从哪来?因为a我们一直没有给它初始值,也没有给它赋值,所以它是不确定的默认值,这个255就是所谓的不确定的默认值,是编译器在定义变量a时分配的,带有不确定的随机性,不同的编译器可能分配的默认值都会存在差异。根据我的经验,unsigned char类型定义的默认值往往是0或者255(255是十六进制的0xff,十六进制的内容后续章节会讲到)。
助理工程师
22:03:07  
跟着鸿哥学单片机
22:54:06  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
非常期待,学习中
10:38:39  
第十三节:赋值语句的覆盖性。
(69.44 KB, 下载次数: 22)
10:36 上传
点击文件名下载附件
下载积分: 积分 -1 分
【13.1& &什么是赋值语句的覆盖性?】
& && &&&a=b;复制代码
& && & 上述代码,执行完这条赋值语句后,会把右边变量b的数值复制一份给左边变量a,a获得了跟b一样的数值,但是a原来自己的数值却丢失了,为什么会丢失?就是因为被b复制过来的新数据给覆盖了,这就是赋值语句的覆盖性。
【13.2& &例程的分析和练习。】
& && & 既然赋值语句有覆盖性的特点,那么如何让两个变量相互交换数值?假设a原来的数据是1,b原来的数据是5,交换数据后,a的数据应该变为5,b的数据应该变为1,怎么做?很多初学者刚看到这么简单的题目,会马上根据日常生活的思路,你把你的东西给我,我把我的东西给你,就两个步骤而已,看似很简单,现在按这个思路编写一段程序看看会出什么问题,代码如下:
/*---C语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
& && & unsigned char a=1;& &//定义的变量a被分配了1个字节的RAM空间,保存的数据被初始化成1。
& && & unsigned char b=5;& &//定义的变量b被分配了1个字节的RAM空间,保存的数据被初始化成5。
& && & b=a; //第一步:为了交换,先把a的数赋值给b。
& && & a=b; //第二步:为了交换,再把b的数赋值给a。
& && & View(a);& &//把第1个数a发送到电脑端的串口助手软件上观察。
& &View(b);& &//把第2个数b发送到电脑端的串口助手软件上观察。
& &while(1)&&
& &{
/*---C语言学习区域的结束。-----------------------------------------------*/复制代码
& && &&&在电脑串口助手软件上观察到的程序执行现象如下:
第1个数
十进制:1
十六进制:1
二进制:1
第2个数
十进制:1
十六进制:1
二进制:1
复制代码
分析:& && &&&
& && && &第1个数a和第2个数b居然都是1!这不是我们想要的结果。我们要的交换结果是:交换后,a变为5,b变为1。在哪个环节出了问题?把镜头切换到上述代码的“第一步”和“第二步”,由于b的数据在执行完“第一步”后,b自己原来的数据5被覆盖丢失了变成新的数据1,接着执行“第二步”后,此时相当于把 b的新数据1赋值给a,并没有5!所以a和b的数据都是1,不能达到交换后“a为5,b为1”的目的。其实就是赋值语句的覆盖性在作祟。
& && & 上述交换数据的程序宣告失败!怎么办?既然赋值语句具有覆盖性,那么两变量想交换数据,就必须借助第三方变量来寄存,此时只需要多定义一个第三方变量t。正确的代码如下:
/*---C语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
& && & unsigned char a=1;& &//定义的变量a被分配了1个字节的RAM空间,保存的数据被初始化成1。
& && & unsigned char b=5;& &//定义的变量b被分配了1个字节的RAM空间,保存的数据被初始化成5。
& && && &&&//定义一个第三方变量t,用来临时寄存数值。
& && & t=b; //第一步:为了避免b的数据在赋值后被覆盖丢失,先寄存一份在第三方变量t那里。
& && & b=a; //第二步:把a的数赋值给b,b原来的数据虽然丢失,但是b在t变量那里有备份。
& && & a=t; //第三步:再把b在t变量里的备份赋值给a。注意,这里不能用b,因b原数据已被覆盖。
& && & View(a);& &//把第1个数a发送到电脑端的串口助手软件上观察。
& &View(b);& &//把第2个数b发送到电脑端的串口助手软件上观察。
& &while(1)&&
& &{
/*---C语言学习区域的结束。-----------------------------------------------*/
复制代码
& && &&&在电脑串口助手软件上观察到的程序执行现象如下:
第1个数
十进制:5
十六进制:5
二进制:101
第2个数
十进制:1
十六进制:1
二进制:1复制代码
分析:& && &&&
& && &&&实验结果显示,两变量的数值交换成功。
【13.3& &如何在单片机上练习本章节C语言程序?】
& && &&&直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。
11:18:34  
进来看看,学习学习
09:37:03  
第十四节:二进制与字节单位,以及常用三种变量的取值范围。
(81.21 KB, 下载次数: 22)
09:35 上传
点击文件名下载附件
下载积分: 积分 -1 分
【14.1& &为什么要二进制?】
& && & 为什么要二进制?我们日常生活明明是十进制的,为何数字电子领域偏要选择二进制?这是由数字硬件电路决定的。人有十个手指头,人可以直接发出十种不同声音来命名0,1,2,3...9这些数字,人可以直接用眼睛识别出十种不同状态的信息,但是数字底层基础硬件电路要直接处理和识别十种状态却很难,相对来说,处理和识别两种状态就轻松多了,所以选择二进制。比如,一颗LED灯的亮或灭,一个IO口的输出高电平或低电平,识别某一个点的电压是高电平或低电平,只需要三极管等基础元器件就可把硬件处理电路搭建起来,二进制广泛应用在数字电路的存储,通讯和运算等领域,想学好单片机就必须掌握它。
【14.2& &二进制如何表示成千上万的大数值?】
& && & 二进制如何表示成千上万的数值?现在用LED灯的亮和灭来跟大家讲解。
& &&&(1)1个LED灯:
& && &灭& &第0种状态
& && &亮& &第1种状态复制代码
& && &合计:共2种状态。
& & (2)2个LED灯挨着:
& && &灭灭& &第0种状态
& && &灭亮& &第1种状态
& && &亮灭& &第2种状态
& && &亮亮& &第3种状态复制代码
& && &合计:共4种状态。
& &(3)3个LED灯挨着:
& && &灭灭灭& &第0种状态
& && &灭灭亮& &第1种状态
& && &灭亮灭& &第2种状态
& && &灭亮亮& &第3种状态
& && &亮灭灭& &第4种状态
& && &亮灭亮& &第5种状态
& && &亮亮灭& &第6种状态
& && &亮亮亮& &第7种状态复制代码
& && &合计:共8种状态。
& &(4)8个LED灯挨着:
& && &灭灭灭灭灭灭灭灭& &第0种状态
& && &灭灭灭灭灭灭灭亮& &第1种状态
& && &......& && && && && && && && & 第N种状态
& && &亮亮亮亮亮亮亮灭& &第254种状态
& && &亮亮亮亮亮亮亮亮& &第255种状态复制代码
& && &合计:共256种状态。
& & (5)16个LED灯挨着:
& && &灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭& &第0种状态
& && &灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭亮& &第1种状态
& && &......& && && && && && && && && && && && && && && && && &&&第N种状态
& && &亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮灭& &第65534种状态
& && &亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮& &第65535种状态复制代码
& && &合计:共65536种状态。
& & (6)32个LED灯挨着:
& && &灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭& &第0种状态
& && &灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭灭亮& &第1种状态
& && &......& && && && && && && && && && && && && && && && && && && && && &第N种状态
& && &亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮灭& &第种状态
& && &亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮亮& &第种状态复制代码
& && &合计:共种状态。
& && & 连续挨着的LED灯越多,能表达的数值范围就越大。
【14.3& &什么是位?】
& && & 什么是位?以上一个LED灯就代表1位,8个LED灯就代表8位。位的英文名是用bit来表示。一个变量的位数越大就意味着这个变量的取值范围越大。一个单片机的位数越大,就说明这个单片机一次处理的数据范围就越大,意味着运算和处理速度就越快。我们日常所说的8位单片机,32位单片机,就是这个位的概念。为什么32位的单片机比8位单片机的处理和运算能力强,就是这个原因。
【14.4& &什么是字节?】
& && & 什么是字节?字节是计算机很重要的一个基本单位,一个字节有8位。8个LED灯挨着能代表多少种状态,就意味着一个字节的数据范围有多大。从上面举的例子中,我们知道8个LED灯挨着,能表示从0到255种状态,所以一个字节的取值范围就是从0到255。
【14.5& &三种常用变量的取值范围是什么?】
& && & 前面章节曾提到三种常用的变量:unsigned char,unsigned int ,unsigned long。现在有了二进制和字节的基础知识,就可以跟大家讲讲这三种变量的取值范围,而且很重要,这是我们写单片机程序必备的概念。
& && & unsigned char的变量占用1个字节RAM,共8位,根据前面LED灯的例子,取值范围是从0到255。
& && & unsigned int的变量占用2个字节RAM,共16位,根据前面LED灯的例子,取值范围是从0到65535。多说一句,对于51内核的单片机,unsigned int的变量是占用2个字节。如果是在32位的stm32单片机,unsigned int的变量是占用4个字节的,所以不同的单片机不同的编译器是会有一些差异的。
& && & unsigned long的变量占用4个字节RAM,共32位,根据前面LED灯的例子,取值范围是从0到。
【14.6& &例程练习和分析。】
& && & 现在我们编写一个程序来验证unsigned char,unsigned int,unsigned long的取值范围。
& && & 定义两个unsigned char变量a和b,a赋值255,b赋值256,255和256恰好处于unsigned char的取值边界。
& && & 再定义两个unsigned int变量c和d,c赋值65535,d赋值6和65536恰好处于unsigned int的取值边界。
& && & 最后定义两个unsigned long变量e和f,e赋值,f赋值,和恰好处于unsigned long的取值边界。
& && & 程序代码如下:
/*---C语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
& && &&&& &//定义一个变量a,并且分配了1个字节的RAM空间。
& && &&&& &//定义一个变量b,并且分配了1个字节的RAM空间。
& && &&&& & //定义一个变量c,并且分配了2个字节的RAM空间。
& && &&&& & //定义一个变量d,并且分配了2个字节的RAM空间。
& && &&&& &//定义一个变量e,并且分配了4个字节的RAM空间。
& && &&&& &//定义一个变量f,并且分配了4个字节的RAM空间。
& && &&&a=255;& && && &//把255赋值给变量a,a此时会是什么数?会超范围溢出吗?
& && &&&b=256;& && && &//把256赋值给变量b,b此时会是什么数?会超范围溢出吗?
& && &&&c=65535;& && & //把65535赋值给变量c,c此时会是什么数?会超范围溢出吗?
& && &&&d=65536;& && & //把65536赋值给变量d,d此时会是什么数?会超范围溢出吗?
& && &&&e=;&&//把赋值给变量e,e此时会是什么数?会超范围溢出吗?
& && &&&f=;&&//把赋值给变量f,f此时会是什么数?会超范围溢出吗?
& && &&&View(a);& &//把第1个数a发送到电脑端的串口助手软件上观察。
& & View(b);& &//把第2个数b发送到电脑端的串口助手软件上观察。
& && &&&View(c);& &//把第3个数c发送到电脑端的串口助手软件上观察。
& & View(d);& &//把第4个数d发送到电脑端的串口助手软件上观察。
& && &&&View(e);& &//把第5个数e发送到电脑端的串口助手软件上观察。
& & View(f);& &//把第6个数f发送到电脑端的串口助手软件上观察。
& & while(1)&&
& & {
/*---C语言学习区域的结束。-----------------------------------------------*/复制代码
在电脑串口助手软件上观察到的程序执行现象如下:
第1个数
十进制:255
十六进制:FF
二进制:
第2个数
十进制:0
十六进制:0
二进制:0
第3个数
十进制:65535
十六进制:FFFF
二进制:1111
第4个数
十进制:0
十六进制:0
二进制:0
第5个数
十进制:
十六进制:FFFFFFFF
二进制:
第6个数
十进制:0
十六进制:0
二进制:0复制代码
分析:& && &&&
& && &&&通过实验结果,我们知道unsigned char变量最大能取值到255,如果非要赋值256就会超出范围溢出后变成了0。unsigned int变量最大能取值到65535,如果非要赋值65536就会超出范围溢出后变成了0。unsigned long变量最大能取值到,如果非要赋值就会超出范围溢出后变成了0。
【14.7& &如何在单片机上练习本章节C语言程序?】
& && &&&直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。
09:44:30  
11:56:06  
新手过来看看
21:36:08  
赞&&!& &加油& &
07:37:14  
虽然看那种纯理论的书也能看懂,但是看楼主用比喻写的如此形象,更容易吸收
14:38:36  
时隔两年,再次看到鸿哥的帖子,不免有点小小的感慨,记得第一次看鸿哥的帖子还是在大二刚接触51,那个时候就迷上了鸿哥的多任务处理模式,然后疯狂的学习鸿哥帖子里的精华部分,但是现在出来工作了接触到的东西慢慢的多了起来,现在再回过头来看鸿哥的帖子,仿佛有看到了当年那个沉迷在实验室的自己。现在对鸿哥的技术帖也有自己的看法和观点了,总之还是那句话,谢谢鸿哥的无私奉献,希望鸿哥能够在技术方面更上一层楼,谢谢鸿哥带给我那些年美好的回忆。
16:59:56  
最近才接触单片机,一直在找学习资料,坚鸿大叔的帖子让我受益匪浅。看到这帖子之前也在学校图书馆找了一本单片机原理及应用和STC系列单片机原理及应用,但是两本书一开始就讲那些专有名词,虽然有解释,我也能看懂,但是坚鸿叔用比喻说明这些深奥的名词,一下子就明白了。期待后续章节!
17:21:53  
顶顶顶!!!!!!支持鸿哥!!!!!!!!!!!
10:51:41  
第十五节:二进制与十六进制。
(75.46 KB, 下载次数: 17)
10:50 上传
点击文件名下载附件
下载积分: 积分 -1 分
【15.1& &十六进制是二进制的缩写。】
& && & 在我的印象中,C51编译器好像并不支持二进制的书写格式,即使它能支持二进制的书写格式,二进制的书写还是有个弊端,就是数字太多太长了,写起来非常费劲不方便,怎么办?解决办法就是用十六进制。十六进制是二进制的缩写,之所以称它为二进制的缩写,是因为它们的转换关系非常简单直观,不需要借助计算器即可相互转换。
【15.2& &何谓十六进制?】
& && & 何谓十六进制?欲搞清楚这个问题,还得先从十进制说起。所谓十进制,就是用一位字符可以表示从0到9这十个数字。所谓二进制,就是用一位字符可以表示从0到1这二个数字。所谓十六进制,当然也就是用一位字符可以表示从0到15这十六个数字。但是十六进制马上就会面临一个问题,十六进制的10到15这6个数其实是有两位字符组成的,并不是一位呀?于是C语言用这些字符A,B,C,D,E,F分别替代10,11,12,13,14,15这6个数,10前面的0到9还是跟十进制的字符一致。A,B,C,D,E,F也可以用小写a,b,c,d,e,f来替代,在数值上不区分大小写,比如十六进制的a与A都是表示十进制的10。
【15.3& &二进制与十六进制是如何转换的?】
& && & 前面提到了十六进制是二进制的缩写,它们的转换关系非常简单直观,每1位十六进制的字符,对应4位二进制的字符。关系如下:
& & 十进制& && & 二进制& && &十六进制
& & 0& && && && &0000& && &&&0
& & 1& && && && &0001& && &&&1
& & 2& && && && &0010& && &&&2
& & 3& && && && &0011& && &&&3
& & 4& && && && &0100& && &&&4
& & 5& && && && &0101& && &&&5
& & 6& && && && &0110& && &&&6
& & 7& && && && &0111& && &&&7
& & 8& && && && &1000& && &&&8
& & 9& && && && &1001& && &&&9
& & 10& && && &&&1010& && &&&A
& & 11& && && &&&1011& && &&&B
& & 12& && && &&&1100& && &&&C
& & 13& && && &&&1101& && &&&D
& & 14& && && &&&1110& && &&&E
& & 15& && && &&&1111& && &&&F
& && & 二进制转换成十六进制的时候,如果不是4位的倍数,则最左边高位默认补上0凑合成4位的倍数。比如一个二进制的数101001,可以在左边补上2个0变成,然后把每4位字符转成1个十六进制的字符。左边高4位0010对应十六进制的2,右边低4位1001对应十六进制的9,所以二进制的101001合起来最终转换成十六进制的数是29(实际上正确的写法是0x29,为什么?请继续往下看。)。
【15.4& &十六进制数的标准书写格式是什么样子的?】
& && & 十六进制的标准书写格式是什么样子的?实际上,十六进制29并不能直接写成29,否则就跟十进制的写法混淆了。为了把十六进制和十进制的书写格式进行区分,C语言规定凡是十六进制必须加一个数字0和一个字母x作为前缀,也就是十六进制必须以0x作为前缀,所以刚才的十六进制29就应该写成0x29,否则,如果直接写29编译器会认为是十进制的29,而十进制的29转换成十六进制是0x1D(十进制与十六进制之间如何转换在后面章节会讲到),0x29与0x1D可见差别很大的,凡是不加前缀的都会被默认为十进制。 多说一句,在C语言程序里,对于同样一个数值,既可以用十六进制,也可以用十进制,比如:d=0x2C与d=44的含义是一样的,因为十六进制的0x2C和十进制的44最终都会被C51编译器翻译成二进制,是表示同样大小的数值。
【15.5& &例程练习和分析。】
& && & 现在我们编写一个程序来观察十六进制和二进制的关系。
& && & 程序代码如下:
/*---C语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
& && &&&& & //定义一个变量a,并且分配了1个字节的RAM空间。
& && &&&& & //定义一个变量b,并且分配了1个字节的RAM空间。
& && &&&& & //定义一个变量c,并且分配了1个字节的RAM空间。
& && &&&& & //定义一个变量d,并且分配了1个字节的RAM空间。
& && &&&a=0x06;& &//十六进制前记得加0x前缀,超过9部分的字母不分大小写。
& && &&&b=0x0A;& &//十六进制前记得加0x前缀,超过9部分的字母不分大小写。
& && &&&c=0x0e;& &//十六进制前记得加0x前缀,超过9部分的字母不分大小写。
& && &&&d=0x2C;& &//十六进制前记得加0x前缀,超过9部分的字母不分大小写。
& && &&&View(a);& &//把第1个数a发送到电脑端的串口助手软件上观察。
& & View(b);& &//把第2个数b发送到电脑端的串口助手软件上观察。
& && &&&View(c);& &//把第3个数c发送到电脑端的串口助手软件上观察。
& & View(d);& &//把第4个数d发送到电脑端的串口助手软件上观察。
& & while(1)&&
& & {
/*---C语言学习区域的结束。-----------------------------------------------*/复制代码
& && & 在电脑串口助手软件上观察到的程序执行现象如下:
第1个数
十进制:6
十六进制:6
二进制:110
第2个数
十进制:10
十六进制:A
二进制:1010
第3个数
十进制:14
十六进制:E
二进制:1110
第4个数
十进制:44
十六进制:2C
二进制:101100复制代码
分析:& && &&&
& && & 通过实验结果,我们知道二进制与十六进制的转换关系确实非常清晰简单,所以十六进制也可以看作是二进制的缩写。
【15.6& &如何在单片机上练习本章节C语言程序?】
& && & 直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。
11:32:50  
谢谢分享,楼主赞!!!
11:54:34  
好内容!值得一看,不是一大抄性的。
08:53:21  
6666666厉害!
16:12:54  
多谢!好多比喻很贴实,容易理解!
15:01:51  
继续!感恩鸿哥!!!
10:47:54  
第十六节:十进制与十六进制。
(329 KB, 下载次数: 19)
10:45 上传
点击文件名下载附件
下载积分: 积分 -1 分
【16.1& &十进制与十六进制各自的应用场合。】
& && & C语言程序里只用了十进制和十六进制这两种书写格式,有的初学者会问,为什么没有用二进制?我的回答是:不是没有用二进制,而是十六进制已经代表了二进制,因为十六进制就是二进制的缩写形式,所以可以把十六进制和二进制看作是同一个东西。
& && &十进制和十六进制各自有什么应用场合?十六进制方便人们理解机器,通常应用在配置寄存器,底层通讯驱动,底层IO口驱动,以及数据的移位、转换、合并等场合,在底层驱动程序方面经常要用到。而十进制则方便人们直观理解数值的大小,在程序应用层要经常用到。总之,进制只是数据的表现形式而已,不管是什么进制的数,最终经过编译后都可以看做是二进制的数据。
【16.2& &十进制与十六进制相互转换的方法。】
& && & 十进制与十六进制如何相互转换?其实很多教科书上都有介绍它们之间如何通过手工计算进行转换的方法,这种方法当然是有助于我们深入理解数据的含义和转换关系,有兴趣的朋友可以自己找相关书籍来看看,但是在实际应用中,我本人是从来没有用过这种手工计算方法,而我用的方法是最简单直接的,就是借助电脑自带的计算器进行数制转换即可。现在把这种方法介绍给大家,以WIND7系统的电脑为例来讲解详细的操作步骤。
& && && && && &
16.2.1.1.png (61.91 KB, 下载次数: 0)
10:45 上传
& && && && && && & 图16.2.1.1&&点击“所有程序”选项切换到系统自带程序的窗口& && &
& && && && && &
16.2.1.2.png (43.84 KB, 下载次数: 0)
10:45 上传
& && && && && && & 图16.2.1.2&&在“附件”子菜单下点击“计算器”启动此软件
& && && && && &
16.2.1.3.png (24.56 KB, 下载次数: 0)
10:45 上传
& && && && && && & 图16.2.1.3&&已启动的“计算器”软件界面
& && & 第一步:打开电脑自带的计算器。
& && & 点击电脑左下角“开始” 菜单,在菜单中点击“所有程序”选项切换到自带程序的窗口,在此窗口下,再点击“附件”的文件夹图标,在“附件”子菜单下点击“计算器”启动此软件。
----------------------------------步骤之间的分割线----------------------------------------
& && && && && &&&
16.2.2.1.png (34.46 KB, 下载次数: 0)
10:45 上传
& && && && && && &&&图16.2.2.1&&把“计算器”的主界面切换到“程序员”界面& && &
& && && && && &
16.2.2.2.png (45.24 KB, 下载次数: 0)
10:45 上传
& && && && && && &&&图16.2.2.2&&已打开的“程序员”界面& &
& && & 第二步:把“计算器”的主界面切换到“程序员”界面。
点击打开左上角“查看”的下拉菜单,在下拉菜单中选择“程序员”选项。
----------------------------------步骤之间的分割线----------------------------------------
& && && && && &&&
16.2.3.1.png (43.57 KB, 下载次数: 0)
10:45 上传
& && && && && && && &图16.2.3.1&&在十进制的选项下输入十进制的数据& &&&
& && && && && && &
16.2.3.2.png (43.53 KB, 下载次数: 0)
10:45 上传
& && && && && && && &图16.2.3.2&&把十进制的数据转换成十六进制的数据
& && & 第三步:十进制转换成十六进制的方法。
& && & 点击勾选中“十进制”选项,在此选项下输入十进制的数据,输入数据后,再切换点击勾选“十六进制”,即可完成从十进制到十六进制的数据转换。比如输入十进制的“230”,切换到十六进制后就变成了“E6”。
----------------------------------步骤之间的分割线----------------------------------------
& && && && && && &
16.2.4.1.png (68.84 KB, 下载次数: 0)
10:45 上传
& && && && && && && & 图16.2.4.1&&在十六进制的选项下输入十六进制的数据& &&&
& && && && && && &
16.2.4.2.png (44.44 KB, 下载次数: 0)
10:45 上传
& && && && && && && & 图16.2.4.2&&把十六进制的数据转换成十进制的数据
& && & 第四步:十六进制转换成十进制的方法。
& && & 点击勾选中“十六进制”选项,在此选项下输入十六进制的数据,输入数据后,再切换点击勾选“十进制”,即可完成从十六进制到十进制的数据转换。比如输入十六进制的“AC”,切换到十进制后就变成了“172”。
----------------------------------步骤之间的分割线----------------------------------------
& && & 第五步:十六进制,十进制,八进制,二进制它们四者之间相互转换的方法。
& && & 我们看到“计算器”软件里已经包含了十六进制,十进制,八进制,二进制这四个选项,所以它们之间相互转换的方法跟上面介绍的步骤是一样的。
----------------------------------步骤之间的分割线----------------------------------------
【16.3& &例程练习和分析。】
& && &现在我们编写一个程序来验证上面讲到的两个例子:
& &&&(1)输入十进制的230,看看它的十六进制是什么样的。
& &&&(2)输入十六进制的AC,看看它的十进制是什么样的。
& && & 程序代码如下:
/*---C语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
& && && & //定义一个变量a,并且分配了1个字节的RAM空间。
& && && & //定义一个变量b,并且分配了1个字节的RAM空间。
& && & a=230;& & //把十进制的230赋值给变量a,在串口助手上观察一下它的十六进制是不是E6。
& && & b=0xAC;& &//把十六进制的AC赋值给变量b,在串口助手上观察一下它的十进制是不是172。
& && &&&View(a);& &//把第1个数a发送到电脑端的串口助手软件上观察。
& & View(b);& &//把第2个数b发送到电脑端的串口助手软件上观察。
& & while(1)&&
& & {
/*---C语言学习区域的结束。-----------------------------------------------*/复制代码
& && & 在电脑串口助手软件上观察到的程序执行现象如下:
第1个数
十进制:230
十六进制:E6
二进制:
第2个数
十进制:172
十六进制:AC
二进制:复制代码
分析:& && &&&
& && & 通过实验结果,发现在单片机上转换的结果和在电脑自带“计算器”上转换的结果是一样的。
【16.4& &如何在单片机上练习本章节C语言程序?】
& && & 直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C语言学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的51学习板,通过电脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。
Powered by
供应链服务
商务及广告合作
Jeffery Guo
关注我们的微信
供应链服务 PCB/IC/PCBA
版权所有 (C) 深圳华强聚丰电子科技有限公司

我要回帖

更多关于 一个字节多少位 的文章

 

随机推荐