单片机c语言教程第十五章C51数组的使用Word文档格式.docx

上传人:b****5 文档编号:19059373 上传时间:2023-01-03 格式:DOCX 页数:9 大小:19.17KB
下载 相关 举报
单片机c语言教程第十五章C51数组的使用Word文档格式.docx_第1页
第1页 / 共9页
单片机c语言教程第十五章C51数组的使用Word文档格式.docx_第2页
第2页 / 共9页
单片机c语言教程第十五章C51数组的使用Word文档格式.docx_第3页
第3页 / 共9页
单片机c语言教程第十五章C51数组的使用Word文档格式.docx_第4页
第4页 / 共9页
单片机c语言教程第十五章C51数组的使用Word文档格式.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

单片机c语言教程第十五章C51数组的使用Word文档格式.docx

《单片机c语言教程第十五章C51数组的使用Word文档格式.docx》由会员分享,可在线阅读,更多相关《单片机c语言教程第十五章C51数组的使用Word文档格式.docx(9页珍藏版)》请在冰豆网上搜索。

单片机c语言教程第十五章C51数组的使用Word文档格式.docx

floatoutnum[10],[10];

//定义浮点型数组,有100个数据单元

在C语言中数组的下标是从0开始的而不是从1开始,如一个具有10个数据单元的数

组count,它的下标就是从count[0]到count[9],引用单个元素就是数组名加下标,如count[1]就是引用count数组中的第2个元素,如果错用了count[10]就会有错误出现了。

还有一点要注意的就是在程序中只能逐个引用数组中的元素,不能一次引用整个数组,但是字符型的数组就能一次引用整个数组。

数组也是能赋初值的。

在上面介绍的定义方式只适用于定义在内存DATA存储器使用的内存,有的时候我们需要把一些数据表存放在数组中,通常这些数据是不用在程序中改变数值的,这个时候就要把这些数据在程序编写时就赋给数组变量。

因为51芯片的片内RAM很有限,通常会把RAM分给参与运算的变量或数组,而那些程序中不变数据则应存放在片内的CODE存储区,以节省宝贵的RAM。

赋初值的方式如下:

数据类型[存储器类型]数组名[常量表达式]={常量表达式};

数据类型[存储器类型]数组名[常量表达式1]......[常量表达式N]={{常量表达式}...{常量表达式N}};

在定义并为数组赋初值时,开始学习的朋友一般会搞错初值个数和数组长度的关系,而致使编译出错。

初值个数必须小于或等于数组长度,不指定数组长度则会在编译时由实际的初值个数自动设置。

unsignedcharLEDNUM[2]={12,35};

//一维数组赋初值

intKey[2][3]={{1,2,4},{2,2,1}};

//二维数组赋初值

unsignedcharIOStr[]={3,5,2,5,3};

//没有指定数组长度,编译器自动设置

unsignedcharcodeskydata[]={0x02,0x34,0x22,0x32,0x21,0x12};

//数据保存在code区

下面的一个简单例子是对数组中的数据进行排序,使用的是冒泡法,一来了解数组的使用,二来掌握基本的排序算法。

冒泡排序算法是一种基本的排序算法,它每次顺序取数组中的两个数,并按需要按其大小排列,在下一次循环中则取下一次的一个数和数组中下一个数进行排序,直到数组中的数据全部排序完成。

 

#include

voidtaxisfun(inttaxis2[])

{

unsignedcharTempCycA,TempCycB,Temp;

for(TempCycA=0;

TempCycA<

=8;

TempCycA++)

for(TempCycB=0;

TempCycB<

=8-TempCycA;

TempCycB++)

{//TempCycB<

8-TempCycA比用TempCycB<

=8少用很多循环

if(taxis2[TempCycB+1]>

taxis2[TempCycB])//当后一个数大于前一个数

Temp=taxis2[TempCycB];

//前后2数交换

taxis2[TempCycB]=taxis2[TempCycB+1];

taxis2[TempCycB+1]=Temp;

//因函数参数是数组名调用形

参的变动影响实参

}

voidmain(void)

inttaxis[]={113,5,22,12,32,233,1,21,129,3};

charText1[]={"

sourcedata:

"

};

//"

源数据"

charText2[]={"

sorteddata:

排序后数据"

unsignedcharTempCyc;

SCON=0x50;

//串行口方式1,允许接收

TMOD=0x20;

//定时器1定时方式2

TCON=0x40;

//设定时器1开始计数

TH1=0xE8;

//11.0592MHz1200波特率

TL1=0xE8;

TI=1;

TR1=1;

//启动定时器

printf("

%s\n"

Text1);

//字符数组的整体引用

for(TempCyc=0;

TempCyc<

10;

TempCyc++)

%d"

taxis[TempCyc]);

\n----------\n"

);

taxisfun(taxis);

//以实际参数数组名taxis做参数被函数调用

Text2);

TempCyc++)//调用后taxis会被改变

while

(1);

例子中能看出,数组同样能作为函数的参数进行传递。

数组做参数时是用数组名进

行传递的,一个数组的数组名表示该数组的首地址,在用数组名作为函数的调用参数时,它的传递方式是采用了地址传递,就是将实际参数数组的首地址传递给函数中的形式参数数组,这个时候实际参数数组和形式参数数组实际上是使用了同一段内存单元,当形式参数数组在函数体中改变了元素的值,同时也会影响到实际参数数组,因为它们是存放在同一个地址的。

上面的例子同时还使用到字符数组。

字符数组中每一个数据都是一个字符,这样一个一维的字符数组就组成了一个字符串,在C语言中字符串是以字符数组来表达处理的。

为了能测定字符串的长度,C语言中规定以‘\o’来做为字符串的结束标识,编译时会自动在字符串的最后加入一个‘\o’,那么要注意的是如果用一个数组要保存一个长度为10字节的字符串则要求这个数组至少能保存11个元素。

‘\o’是转义字符,它的含义是空字符,它的ASCII码为00H,也就是说当每一个字符串都是以数据00H结束的,在程序中操作字符数据组时要注意这一点。

字符数组除了能对数组中单个元素进行访问,还能访问整个数组,其实整个访问字符数组就是把数组名传到函数中,数组名是一个指向数据存放空间的地址指针,函数根据这个指针和‘/o’就能完整的操作这个字符数组。

对于这一段所说的,能参看下面一例1602LCD显示模块的驱动演示例子进行理解。

这里要注意就是能用单个字

符数组元素来进行运算,但不能用整个数组来做运算,因为数组名是指针而不是数据。

/*============================================================

使用1602液晶显示的实验例子明浩2004/2/27

==============================================================

SMC1602A(16*2)模拟口线接线方式连接线图:

---------------------------------------------------

|LCM-----51|LCM-----51|LCM------51|

---------------------------------------------|

|DB0-----P1.0|DB4-----P1.4|RW-------P2.0|

|DB1-----P1.1|DB5-----P1.5|RS-------P2.1|

|DB2-----P1.2|DB6-----P1.6|E--------P2.2|

|DB3-----P1.3|DB7-----P1.7|VLCD接1K电阻到GND|

[注:

AT89S51使用12M晶体震荡器]

=============================================================*/

#defineLCM_RWP2_0//定义引脚

#defineLCM_RSP2_1

#defineLCM_EP2_2

#defineLCM_DataP1

#defineBusy0x80//用于检测LCM状态字中的Busy标识

voidWriteDataLCM(unsignedcharWDLCM);

voidWriteCommandLCM(unsignedcharWCLCM,BuysC);

unsignedcharReadDataLCM(void);

unsignedcharReadStatusLCM(void);

voidLCMInit(void);

voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);

voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData);

voidDelay5Ms(void);

voidDelay400Ms(void);

unsignedcharcodecdle_net[]={"

unsignedcharcodeemail[]={"

pnzwzw@"

Delay400Ms();

//启动等待,等LCM讲入工作状态

LCMInit();

//LCM初始化

Delay5Ms();

//延时片刻(可不要)

DisplayListChar(0,0,cdle_net);

DisplayListChar(0,1,email);

ReadDataLCM();

//测试用句无意义while

(1);

//写数据

voidWriteDataLCM(unsignedcharWDLCM)

ReadStatusLCM();

//检测忙LCM_Data=WDLCM;

LCM_RS=1;

LCM_RW=0;

LCM_E=0;

//若晶体震荡器速度太高能在这后加小的延时

//延时

LCM_E=1;

//写指令

voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测

if(BuysC)ReadStatusLCM();

//根据需要检测忙

LCM_Data=WCLCM;

LCM_RS=0;

LCM_RW=0;

LCM_E=1;

//读数据

unsignedcharReadDataLCM(void)

LCM_RS=1;

LCM_RW=1;

LCM_E=0;

return(LCM_Data);

//读状态

unsignedcharReadStatusLCM(void)

LCM_Data=0xFF;

while(LCM_Data&

Busy);

//检测忙信号

return(LCM_Data);

voidLCMInit(void)//LCM初始化

LCM_Data=0;

WriteCommandLCM(0x38,0);

//三次显示模式设置,不检测忙信号

WriteCommandLCM(0x38,0);

Delay5Ms();

WriteCommandLCM(0x38,1);

//显示模式设置,开始要求每次检测忙信号

WriteCommandLCM(0x08,1);

//关闭显示WriteCommandLCM(0x01,1);

//显示清屏WriteCommandLCM(0x06,1);

//显示光标移动设置WriteCommandLCM(0x0C,1);

//显示开及光标设置

//按指定位置显示一个字符

voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)

Y&

=0x1;

X&

=0xF;

//限制X不能大于15,Y不能大于1

if(Y)X|=0x40;

//当要显示第二行时地址码+0x40;

X|=0x80;

//算出指令码

WriteCommandLCM(X,0);

//这里不检测忙信号,发送地址码

WriteDataLCM(DData);

//按指定位置显示一串字符

voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)

unsignedcharListLength;

ListLength=0;

Y&

while(DData[ListLength]>

0x20)//若到达字串尾则退出

if(X<

=0xF)//X坐标应小于0xF

DisplayOneChar(X,Y,DData[ListLength]);

//显示单个字符

ListLength++;

X++;

//5ms延时

voidDelay5Ms(void)

unsignedintTempCyc=5552;

while(TempCyc--);

//400ms延时

voidDelay400Ms(void)

unsignedcharTempCycA=5;

unsignedintTempCycB;

while(TempCycA--)

TempCycB=7269;

while(TempCycB--);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1