产品概述

单片机 goto 四单片机c语言入门之跳转语句

小编 2024-11-23 产品概述 23 0

四单片机c语言入门之跳转语句

C语言控制语句中,除前述两篇文章中介绍的判断语句结构和循环语句结构之外,最后一种控制语句就是跳转语句结构了。

跳转语句包括break语句、continue语句、return语句以及goto语句四种

break语句结构

break语句作用是跳出当前循环,无论有几重循环,break永远只跳出自己所在的那一层循环,break一般用法是有条件的跳出while循环,以及用来跳出switch的选择判断(参考前述判断语句文章)。

举个例子,单片机中一般采用IO口来读取按键的状态(硬件如上图),需要实现的是按键每按下一次,自定义变量seft_count值自加1,直到按键按下10次为止(前一篇文章循环结构例子一样)。除前一篇采用条件判断的方式完成算法外,也可使用while加break的方式完成需求。

Continue语句结构

循环语句里有此语句时,程序运行到此语句时,不再执行循环体里continue后面的语句而是跳到下一次循环入口处执行下一次循环判断。简单来说,contine语句只是结束一次当前循环体内部执行的语句,不会跳出循环结构。

举个例子,单片机应用需要实现的功能是按键每按下一次,自定义变量seft_count值自加1,直到按键按下10次为止,如果应用需求是按下十次后,保持按键采样状态但是自定义变量值不再增加,那实现程序可以如下

return语句结构

return是表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值(也可不带参数直接返回),由return后面的参数指定。简单来说,return就是跳出当前return所处函数。

举个例子,单片机应用需要实现的功能是按键每按下一次,自定义变量seft_count值自加1,当按键按下10次后,返回主函数执行空跑指令。

goto语句结构

goto语句也称为无条件转移语句,其一般格式如下:

goto 语句标号;

其中语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加半角冒号“:”。语句标号起标识语句的作用,与goto句配合使用。goto语句简单说来就是粗暴的转移,需要注意的就是转移到哪里,用户可以在希望转移到的语句前面加一个语句标识就可以了。

基本结构

loop:

语句;

goto loop;

goto语句使用简单,此处就不举例了,不过需要注意的是,goto指令跳转很容易造成程序机构混乱,并且该指令在单片机应用中实质上涉及到人为强制无条件的干预程序运行地址指针,需要慎之又慎。

后续

到本章节为止,c语言控制语句已经跟大家分享完毕,下一章节将分享c语言运算相关入门知识,请大家关注。

单片机C语言基础入门第三章:变量与数据类型

大家好,上次和大家介绍了单片机的开发流程。也就是大家可以根据单片机的开发流程进行单片机程序的烧写,但这仅限于已经写好的程序(假设对C语言还没有了解),接下来这章我们开始介绍单片机中C语言的编写。

、关键字介绍

既然是编程语言那么就得有自己的规则,其实单片机C语言和标准C语言区别并不是很大,毕竟是利用的标准C语言扩展来的。既然说到规则定义,那我们从单片机C语言的关键字说起。

ANSIC的关键字有32个,其中包括9种控制语句,如下:

auto、const、signed、unsigned、static、extern、

char、long、short、int、float、double、void、volatile、register、union、struct、enum、

sizeof、typedef、

if、while、break、case、continue、defualt、do、else、for、goto、return、switch

单片机中除了上面的关键字还有自己的变量:

bit:定义为变量的关键字;

sbit:定义特殊功能寄存器的位变量;

sfr:定义特殊功能寄存器变量;

sfr16:16位特殊功能寄存器变量定义;

除此之外还有单片机特有的存储器类型:

data:直接访问内部数据数据存储器,访问速度最快;

bdata:可位寻址内部数据存储器,允许位与字节混合访问;

idata:间接访问内部数据存储器,允许访问全部内存地址;

pdata:分页访问外部数据存储器,等效汇编movx @Ri访问;

xdata:外部数据存储器访问,等同汇编的movx @DPTR;

code:程序存储器访问,等同汇编的movc @A+DPTR;

、命名规则介绍

所谓的变量就是对存储空间的区域进行命名,其内存区域存储的值可以改变。变量定义必须放在变量使用之前,一般放在函数体的开头部分。要区分变量名和变量值是两个不同的概念,其对应关系如下:

以下未命名的规则:

1. 标识符由字母(A-Z,a-z)、数字(0-9)、下划线“_”组成,并且首字符不能是数字,但可以是字母或者下划线。例如,正确的标识符:abc,a1,prog_to。

2. 不能把C语言关键字作为用户标识符,例如if ,for, while等.

3. 标识符长度是由机器上的编译系统决定的,一般的限制为8字符(注:8字符长度限制是C89标准,C99标准已经扩充长度,其实大部分工业标准都更长)。

4. 标识符对大小写敏感,即严格区分大小写。一般对变量名用小写,符号常量命名用大写。

5. 标识符命名应做到 见名知意 ,例如,长度(length)圆周率(pi)等等。

、变量定义

有了关键字和标识符的规则就可以定义变量了,一般定义变量的表达式如下:

[存储种类] 数据类型 [存储器类型] 变量名表

可以看到在定义格式中除了数据类型和变量名表是必要的,其它都是可选项。

存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。

数据类型就对应前边介绍的unsigned/signed char、int 、bit、double等数据类型;

而存储器类型就是前面介绍的data、idata、pdata、code等存储器类型,值得注意的是在keil软件中如果忽略存储器类型编译器会根据选择的编译模式SMALL,COMPACT和LARGE去指定变量的存储区域;这三种模式选择可以在右键targetàoption选项中去选择,如下图:

SMALL存储模式把所有函数变量和局部数据段放在8051系统的内部数据存储区这使访问数据非常快,但SMALL存储模式的地址空间受限。在写小型的应用程序时,变量和数据放在data内部数据存储器中是很好的因为访问速度快,但在较大的应用程序中data区最好只存放小的变量、数据或常用的变量(如循环计数、数据索引),而大的数据则放置在别的存储区域。

COMPACT存储模式中所有的函数和程序变量和局部数据段定位在8051系统的外部数据存储区。外部数据存储区可有最多256字节(一页),在本模式中外部数据存储区的短地址用@R0/R1。

LARGE存储模式所有函数和过程的变量和局部数据段都定位在8051系统的外部数据区外部数据区最多可有64KB,这要求用DPTR数据指针访问数据。

四、 几种常用变量的定义方法示例

Ø 常量的定义

常量可以作为一种特殊的变量存在于内存中,只是在程序执行过程中其数值不发生变化,因此通常将称量定义在程序存储器中(有时候有很多常量定义成表格,固化到程序存储器)。

常量的定义有直接定义常量和用预编译的命令来代替的符号常量:

直接定义的常量有直接出现在程序中的数据,比如“2”“a”等。另一种是定义常量比如:const char code a =10;在程序存储器空间定义一个常量a,其值为10,在以后的程序中a的值不能发生变化。

还有一种是利用宏定义的方法来实现,比如:#define Pi 3.14 定义Pi的值为3.14,这样后边程序引用Pi的时候都会被3.14取代,这样的好处是可以方便调试。

Ø 变量的定义

变量根据作用域可以分为局域变量和全局变量,根据其有无static修饰可以分为静态变量和动态变量,因此这两种组合可以分成四个变量:动态全局变量,静态全局变量,动态局部变量,静态局部变量,其作用域以及生命周期的对比如下表格所示:

动态全局 变量 作用域为整个项目,即最终编译成可执行文件的所有文件中均可以使用动态全局变量。生命周期为从程序运行到程序退出,即贯穿整个运行时间。无显式初始化时默认初始化值为0。静态全局变量作用域为当前文件,从定义/声明位置到文件结尾。生命周期为从程序运行到程序退出,即贯穿整个运行时间。无显式初始化时默认初始化值为0动态局部变量作用域为当前函数,从定义位置,到其所在的{}的结束位置。生命周期为从函数调用到函数退出。无显式初始化时默认初始化值为随机值。静态局部变量作用域为当前函数,从定义位置,到其所在的{}的结束位置。生命周期为从程序运行到程序退出,即贯穿整个运行时间,当下次函数调用时,静态局部变量不会被再次初始化,而是沿用上次函数退出时的值。无显式初始化时默认初始化值为0。

对于初学者来说开始可能对这些变量的作用域和生命周期很难理解,是在理解不了就先记着,在我们介绍完函数后再回头看这些东西就有一个比较深刻的认识。

下面就主要举例介绍各个不同的变量以及应用,首先是对于单片机中常用的变量进行定义:

1. Bit定义位变量

bit位变量有点类似于高级语言中的boolean变量,其值只能取0和1。在单片机中经常用作标志位,比如:bit flag;定义一个flag标志位

2. sbit 定义可寻址变量

sbit是定义可寻址对象,定义特殊寄存器的某位。在实际中经常来定义端口的位的。其定义数据的方法:(1) sbit 位变量名=地址;(2) sbit 位变量名=特殊寄存器^位位置;(3) sbit 寄存器字节地址^位位置;比如:

sbit LED=P1^1//表示P1端口的第一位定义为LED;其中P1是特殊寄存器的名称(实际使用sfr关键字定义的)。sbit LED=0x91//0x91的位地址就是P1^1;sbit LED=0x90^1//0x90是P1寄存器的字节地址,0x90^1表示P1的第一位,上面的三个定义是一样的,只是表达方式不同,如果用地址来直接定义那么首先对单片机非常了解,而直接用寄存器的名称去定义的话就得包含单片机的头文件。

3. sfr定义特殊寄存器变量

sfr来定义8位寄存器变量,一般在头文件中经常看到这种定义方式,比如我们打开reg51.h的头文件,我看可以看到如下的定义方式:

sfr P0 = 0x80;

sfr P1 = 0x90;

sfr P2 = 0xA0;

sfr P3 = 0xB0;

其中P0、P1、P1、P3是寄存器变量的名称,而后面的一串数字是这个寄存器的地址,因此我们在编写程序的时候直接写P1、P2等,但是如果在编写程序的时候没有包含头文件直接写P1、P2等就会出现报错的信息,当然如果要将报错的信息解除的话要么包含头文件,要么自己去重新定义这些变量。当然有些时候也会看到sfr16,这个是用来定义长度为16位的寄存器变量的。

4. volatile修饰变量

volatile修饰的变量表示是随时可以发生变化的,因此当编译器用到这个值的时候会重新去调用其数值,而不是使用保存在寄存器的备份。Volatile一般来修饰寄存器变量,因为寄存器里面存数的数据会经常发生变化。Volatile只是一个修饰关键字因此可以用数据类型放在前边修饰比如:const volatile a;表示a是一个volatile类型的常量,说是常量是因为在程序运行中程序不能更改这个数值,但是它可能会意想不到的发生改变。在头文件中常来定义寄存器变量,比如:

#define PWMC (*(unsigned int volatile xdata *)0xfff0)

#define PWMCH (*(unsigned char volatile xdata *)0xfff0)

#define PWMCL (*(unsigned char volatile xdata *)0xfff1)

#define PWMCKS (*(unsigned char volatile xdata *)0xfff2)

通过指针来定义寄存器变量。

5. union定义变量

union定义联合体变量,他和后面要讲述的struct不一样的地方在于,union变量在内存的长度是由联合体内成员变量中长度最长的变量来决定的,他们共同占用一块内存。然而struct变量是struct中变量长度的总和。比如:union ADC{unsigned intADC_VAL;unsigned char AD[2]}其中DAC_VAL是两个自字节长度的变量,而AD[2]是单字节变量的数组,他们的排列如下图所示:

ADC_VALMSBLSBADAD[0]AD[1]

可以看到ADC_VAL的长度和AD[]数组的长度一样,因此可以认为ADC_VAL是用两个8位的数据合成的一个无符号的int数据,因此可以直接调用这个数据即可。

6. struct 定义的变量

Struct定义变量可以有很多的成员,而这些成员的地址是连续的,因此这在一些定义库函数的时候有个很大的方便只要得到结构体的首地址就可以得到一系列的寄存器的地址,这样方便管理。具体的示例在以后可以讲解(在STM32库函数中可以找到)。

在这主要介绍一些常用的变量,对于int,char,等变量的定义和初始化和标准的C语言都相同,最容易出错的是定义变量的类型和采集的数据之间存在不一致,这样调试的时候编译器不会报错,这就需要我们在编程的时候认真。

总结一下:

本次课程的主要内容是,介绍了C语言的关键字以及变量标识符的规则,同时着重介绍了单片机中C语言的变量和定义的问题,最后通过举例说明了具有典型意义的变量的定义。

相关问答

51 单片机 C语言编程,简易计算器,复位键如何编程会简单些?要求...

给我邮箱gotomain4条回答:【推荐答案】提供个思路void(*RecallBp)(void);main(){保存堆栈指针clear:RecallBp=(void*)&clear;恢...

51 单片机 定时闹铃(c语言) - R6OWXQ1Id 的回答 - 懂得

我来发一个C语言51单片机2113时钟程序,希望5261能帮到你/*程序功能:带定时闹4102铃时钟*//*----------------------------------------------...

如何把蓝牙模块HC-05与51 单片机 连接起来?

单片机是可以和蓝牙连接的,通过UART串口连接。HC-05是市面上比较常见的蓝牙模组,主从是一体的,跟单片机通过UART串口连接,连接完成后,即把蓝牙当作串口来使...单...

求一个51 单片机 定时闹钟程序。要C语言。能够调时间 - 小红薯...

我来发一个C语言211351单片机时钟程序,希望5261能帮到你/*程序功能:4102带定时闹铃时钟*//*-------...

求一个51 单片机 定时闹钟程序。要C语言。能够调时间 - 198***...

我来发一个C语言211351单片机时钟程序,希望5261能帮到你/*程序功能:4102带定时闹铃时钟*//*-------...

深圳哪个公司 单片机 专业供应商专业?选英锐恩

[回答]单片机专业供应商以及相关的产品都可以找英锐恩科技公司咨询下,他们公司专业做这方面的,所以产品和质量都是比较放心的。国人比较倾向于品牌效应,...

什么是通用型 单片机 什么是总线型 单片机 ?

[回答]MSP430单片机是16位单片机,51单片机是8位单片机。这应当是HD6433694B是一个16位的单片机,具体情况不可考。总线型单片机指的是单片机构建了总线,...

C语言中,怎么定义 单片机 的寄存器-ZOL问答

例如52单片机的寄存器有4组,分别为00H-07H,08H-0FH,10H-17H,18H-1FH,各组均8字...go0080movXXXX#definereg_name0x0080...

【一周】Linux 28周年 | 方舟编译器开源 | Goodbye Python 2...

允许开发人员在单片机上创建流畅的用户界面,基于Qt的应用程序现在可以部署在传统操作系统以及基于ARMCortexM7的单片机上。Python2.x即将终止支持,是时...

单片机 显示数字2011 的程序 - sky小美12345 的回答 - 懂得

数码管共阴共阳不知道,假定共阴;;74HC573接Vcc,锁存无效,相当于直通,P2口控制数码管笔型C1BITP1.5C3BITP1.6C3BITP1.7C4BITP3.6ORG00HAJMPGOOR...

猜你喜欢