51单片机的控制语句

发布时间:2023-07-11  

Cx51流程控制共有3种基本结构:顺序结构、选择结构以及循环结构。


一、顺序结构

顺序结构是最基本、最简单的编程结构,程序按先后顺序执行指令代码。


下图是8051单片机的P0口和P1口上分别连接了8个LED,请分别用P0和P1口显示加法125+34和减法176-98的运算结果

图片

#include

int main(void)  

 unsigned char a=125,b=34,c=176,d=98;

 P1=a+b; //加法运算结果送P1端口,P1=159=1001 1111B

 P0=c-d;  //减法运算结果送P0端口,P0=78=0100 1110B

 while(1); //循环等待,防止主程序退出后单片机跑飞

 }


二、选择结构

2.选择结构


(1)if语句


if语句用于根据条件判定结果决定执行的语句。if语句有三种基本形式:


if(表达式)

    {语句组}

说明:如果“表达式”为真,则执行花括号中的语句组,否则跳过花括号执行下面的语句。


if(表达式)

     {语句组1}

    else

     {语句组2}

说明:如果“表达式”真,则执行语句组1,否则执行语句组2。


if(表达式1)

      {语句1}

     else if(表达式2)

      {语句组2 }

     else if(表达式3)

      {语句组3}

     else if(表达式m)

      {语句组m}

     else

      {语句组n}

说明:如果“表达式1”为真,则执行“语句组1”,否则如果“表达式2”为真,则执行“语句组2”…,如果所有的表达式都不满足,则执行语句组n。


同图4-2,用if语句根据54/18的计算结果选择P0口8位LED的状态。


图片

#include  //包含单片机寄存器的头文件

int main(void)

   unsigned char a=54,b=18;

   if (a/b==1)P0=0xfe; //第一个LED亮

   else if (a/b==2) P0=0xfd;  //第二个LED亮

   else if (a/b==3) P0=0xfb; //第三个LED亮

   else if (a/b==4) P0=0xf7; //第四个LED亮

   else if (a/b==5) P0=0xef;  //第五个LED亮 

   else if (a/b==6) P0=0xdf;  //第八个LED亮      

   else if (a/b==7) P0=0xbf;  //第七个LED亮          

   else if (a/b==8) P0=0x7f;  //第八个LED亮       

   else P0=0xff;  //缺省值,关闭所有LED 

   while(1); 

 }

(2)switch/case语句


根据表达式的值决定要执行的语句组,用于实现多中选一,形式如下:


switch(表达式)

 {

case常量表达式1://如果1满足,则执行语句组1

  语句组1;

  break;          //跳出switch结构

case常量表达式2://如果2满足,则执行语句组2

 语句组2;

  break;          //跳出switch结构

default:          //条件都不满足时,执行语句组n

 语句组n;

  }

同图4-2,用swtich语句根据54/18的计算结果选择P0口8位LED的状态


图片

#include  //包含单片机寄存器的头文件

int main(void)

  unsigned char a=56,b=18;

  switch(a/b)   //使用多分支选择语句

 {

     case 1: P0=0xfe; break;   //第一个LED亮

   case 2: P0=0xfd; break;   //第二个LED亮

   case 3: P0=0xfb; break;   //第三个LED亮

   case 4: P0=0xf7; break;   //第四个LED亮

   case 5: P0=0xef; break;   //第五个LED亮      

   case 6:P0=0xdf; break;    //第六个LED亮       

   case 7:P0=0xbf; break;    //第七个LED亮          

   case 8:P0=0x7f; break;    //第八个LED亮       

   default: P0=0xff;  //缺省值,关闭所有LED 

 }   

 while(1);

}

1、for循环


for 循环结构用于按指定的次数循环执行一组语句,格式如下:


for(表达式1;表达式2;表达式3)

{语句;}

for循环语句执行过程如下:


(1)先执行表达式1,一般是对循环变量赋初值;


(2)执行表达式2,若表达式2结果为真,则执行循环体语句,并求解表达式


3(一般是改变循环变量的值);然后再次执行表达式2;并判断结果真假


(3)若表达式2结果为假,则退出for循环。


三、循环结构

while循环


while循环语句先判断条件真假,若表达式为真,则执行花括号内的语句组,否则终止循环,格式如下:


while(表达式)

      {语句组}

同图4-3,用while循环计算7的阶乘并送P1和P0口显示结果。

图片

#include  //包含单片机寄存器的头文件

int main(void)

  unsigned char i=1;

  unsigned int s=1;  

  while(i<=7)

  {

     s=s*i;//计算阶乘

     i++;  //i自增运算

  }

  P1=s/256;   //高8位送P1显示

  P0=s%256;   //低8位送P0显示

  while(1);

}

do while 循环


先执行花括号内的语句组,然后执行表达式,若结果为真,则重复执行花括号内的语句组,否则终止循环,格式如下:


do

  {语句组}

while(表达式);

根据下图用do while循环计算7的阶乘并送P1和P0口显示结果。


图片

#include  //包含单片机寄存器的头文件

int main(void)

  unsigned char i=1;

  unsigned int s=1;  

 do

  {

     s=s*i;//计算阶乘

     i++;  //i自增运算

    } while(i<=7);

  P1=s/256; //高8位送P1显示

  P0=s%256; //低8位送P0显示

  while(1);

}

四、数组

1.一维数组


(1)一维数组的定义方式为:


数据类型 数组名 [常量表达式];


例如定义有3个元素字符型数组m:


charm[3];


m的3个元素分别是m[0], m[1], m[2]。数组的类型指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。


(2)一维数组的初始化


数组初始化是指在数组定义时给数组元素赋予初值。

例如:


int m[3]={ 0,1,2};

相当于a[0]=0,a[1]=1,a[2]=2。


当{ }中值的个数少于元素个数时,只给前面部分元素赋值,其他元素自动赋0值。


例如:


int m[3]={0,1}

(3)一维数组元素的引用


数组必须预先定义才能使用。数组只能逐个地使用各元素,而不能一次引用整个数组。例如,输出有10个元素的数组必须使用循环语句逐个输出各下标变量:


for(i=0;i<3; i++)

   printf("%d",m[i]);

而不能用一个语句输出整个数组。因此,下面的写法是错误的:


printf("%d",m);

用一维数组实现流水点亮P0口的8位LED

图片

int main(void) //主函数

  unsigned char i;

  unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义无符号字符型数组 

  while(1)

  {

   for(i=0;i<8;i++)

      {

        P0=Tab[i];//依次引用数组元素,并将其送P0口显示

        delay();//调用延时函数

     }

  }

}

2.二维数组


二维数组是以行列矩阵的形式存储数据。


** (1)二维数组定义**


数据类型 数组名[下标1][下标2];


第一个下标代表行,第二个下标代表列。例如语句 int a[2][3] 定义了二维整形数组,共有2行3列6个元素。


(2)二维数组的初始化


可以采用以下两种方式初始化:


按先行后列的存储顺序整体赋值,例如:


int a[2][3]={0,1,2,3,4,5}

按每行分别赋值,例如:


int a[2][3]={{0,1,2},{3,4,5}};

用二维数组实现流水点亮P0口的8位LED。

图片

int main(void)

  unsigned char i,j;

  unsigned char codeTab[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}; //定义无符  //号字符型数组 

  while(1)

  {

   for(i=0;i<2;i++)

   for(j=0;j<4;j++)

      {

        P0=Tab[i][j];//依次引用数组元素,并将其送P0口显示

        delay();//调用延时函数

     }

  }

}

变量的指针就是变量的地址。在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。


指针变量是一种特殊的变量,它也和一般变量一样,具有变量名、类型和值,但它的值就是变量所存放的地址。


通过指针对变量进行操作是间接操作,比直接操作变量更费时间,且不够直观,但可以通过灵活运用指针使程序代码更为简洁、有效。


四、指针

1、指针变量的定义


指针变量同普通变量一样,使用之前要进行定义。指针变量定义的一般形式为:


数据类型 *变量名;


其中,数据类型表示本指针变量所指向变量的数据类型,*表示这是一个指针变量。


例如:定义:int*point,表示point指向一个整型变量,但point具体指向哪一个整型变量,取决于point中所存储的地址。一个指针变量只能指向同类型的变量,如上述point 只能指向整形变量,不能指向一个字符变量。


2、指针变量的引用


指针变量在使用之前必须赋予具体的地址,使用未经赋值的指针变量会引起严重后果。指针变量的引用有两个重要运算符:


&:取地址运算符;


*:指针运算符(或称“间接访问” 运算符)。


在指针变量定义中所出现的“ ”是类型说明符,表示其后的变量是指针类型,而指针运算符“ ”则出现在表达式中,用以表示指针指向的变量值。


地址运算符&用来取出变量的地址。其形式为:


&变量名;

Ø指针运算符*用来取出指针指向变量的值,其形式为:


*指针变量名;

inti,j;

int *point;

point= &i;

j=*point;

表示取出变量i的值赋予变量j,与语句j=i的效果相同。对*point的任何操作与直接对变量i的操作效果相同。


3、数组指针


一个变量有一个地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。


一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的。每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。


定义一个指向数组元素的指针变量,与定义普通变量的指针相同。例如:


intm[]={1,2,3};4int*p;4p=&m[0];

经上述定义后,p就是数组m的指针。因为数组名代表数组的首地址,也就是第一个元素的地址,因此下面两个语句等价:


p=&m[0];

p=m;

p指向数组m的首地址后,p+i就是数组的元素m[i]。


例题:用一维数组实现流水点亮P0口的8位LED。

图片

int main(void)

 unsigned char i;

 unsigned char code Tab[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; /*定义无符号字符型数组*/ 

 unsigned char *p;

  p=&Tab[0];/*定义指针变量并指向Tab数组,也可写为unsigned char   *p=Tab */

 while(1)

 {

   for(i=0;i<8;i++)

   {

        P0=*(p+i);//通过指针变量依次引用数组元素,并将其送P0口显示

        delay();//调用延时函数

   }

 }

}

指向二维数组的指针变量的说明形式为


类型说明符 (*指针变量名)[长度];


“长度”是二维数组的列数。二维数组的每一行都代表一个一维数组,该一维数组的长度就是二维数组的列数。若该指针变量指向二组数组A[m][n]的首地址,则 (指针变量名+i)就是A[i],而A[i]是一维数组A[i][n]的首地址, (*(指针变量名+i)+j)就是A[i][j]的值。


例题:用二维数组实现流水点亮P0口的8位LED。

图片

int main(void)

 unsigned char i,j;

 unsigned char codeTab[2][4]={{0xfe,0xfd,0xfb,0xf7},{0xef,0xdf,0xbf,0x7f}}; //定

                                           //义无符号字符型数组

 unsigned char (*p)[4]; //定义二维数组指针

 p=Tab;//指向二维数组首地址

 while(1)

 {

   for(i=0;i<2;i++)

    for(j=0;j<4;j++)

   {

        P0=*(*(p+i)+j);//依次引用数组元素,并将其送P0口显示

        delay();//调用延时函数 

   }

 }

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>