单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx

上传人:b****5 文档编号:18964775 上传时间:2023-01-02 格式:DOCX 页数:21 大小:22.10KB
下载 相关 举报
单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx_第1页
第1页 / 共21页
单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx_第2页
第2页 / 共21页
单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx_第3页
第3页 / 共21页
单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx_第4页
第4页 / 共21页
单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx

《单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx》由会员分享,可在线阅读,更多相关《单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx(21页珍藏版)》请在冰豆网上搜索。

单片机的C语言程序设计与应用基于Proteus仿真第2版Word格式.docx

//访问定时器0,设置时间常数

TH0=ox3c;

TR0=1;

//启动定时器0

3-3sbit型变量的定义示例

程序如下:

sfrPSW=0xD0;

sbitOV=PSW^2;

sbitOV=0xd0^2;

sbitOV=0xD2;

unsignedcharbdataflag;

sbitflag0=flag^0;

sfrp1=0x90;

sbitp1_0=p1^0;

sbitp1_1=p1^1;

sbitp1_2=p1^2;

sbitp1_3=p1^3;

sbitp1_4=p1^4;

sbitp1_5=p1^5;

sbitp1_6=p1^6;

sbitp1_7=p1^7;

3-4片内I/O口及其位的定义示例。

sfrP1=0x90;

//P1口的SFR定义

sfrP3=0xB0;

//P3口的SFR定义

sbitDIPswitch=P1^4;

//P3口的4位DIP开关输入

sbitgreenLED=P1^5;

//P1口的5位的绿LED输出

{unsignedchardatainval;

inval=0;

//inval的初始化值

while

(1)

{P1=0XFF;

{inval=p1&

0x0f;

//从P1读位0~3

}

}

3-5片内RAM、片外RAM及I/O的定义示例

absacc.h>

#definePAXBYTE[0xffec]//将PA定义为外部I/O口,地址为0xffec

#defineNRAMDBYTE[0x40]/*将NRAM定义为片内RAM,地址为40H,长度为8位*/

{PA=0x3A;

//将数据3AH写入地址0xffec的外部I/O端口

NRAM=0x01;

//将数据01H写入片内RAM40H单元

3-6通过_at_实现绝对地址的访问示例。

dataunsignedcharx1_at_0x40;

/*在data区定义字节变量x1,它的地址为40H*/

xdataunsignedintx2_at_0x2000;

/*在xdata区定义字符变量x2,它的地址为2000H*/

{x1=0xff;

x2=0x1234;

while

(1);

3-7将片外RAM6000H开始的连续的10个字节单元内容清0.

xdataunsignedcharBuffer[10]_at_0x6000;

voidmain(void)

{unsignedcharindex;

for(index=0;

index<

10;

index++)

{Buffer[index=0]

如果是片内RAM60H单元开始的10个单元内容清0,可以这样编程:

dataunsignedcharBuffer[10]_at_0x60;

3-8自增和自减运算符的程序示例

voidmain()

{intx,y,z1,z2;

x=10;

y=21;

z1=(x++)+(x++);

printf("

x=%d,z1=%d\n"

x,z1);

z2=(++y)+(++y);

y=%d,z2=%d\n"

y,z2);

执行结果如下:

x=12,z1=21

y=23,z2=45

3-9关系运算符运算的程序示例

{inta,b,c,d;

a=-2.3>

0;

b=71==32;

c=7!

=0;

d=-12<

a=%d,b=%d,c=%d,d=%d\n"

a,b,c,d);

a=0,b=0,c=1,d=1

3-10逻辑运算的程序示例

{inta,b,c,d,e;

a=!

0;

b=15&

&

22;

c=35&

d=17.3||0;

e=17.3||2.6;

a=%d,b=%d,c=%d,d=%d,e=%d\n"

a,b,c,d,e);

a=1,b=1,c=0,d=1,e=1

3-11利用位移运算符进行循环移位的示例。

若a=11000011B,将a值右循环位移2位。

a右循环n位,即将a中原来左面(8-n)位右移n位,而将原来右端的n位移到最左面的n位。

上述问题可以由下列步骤来实现。

1.将a的右端n位先放到b中的高n位中:

b=a<

<

(8-n)

2.将a右移n位,其左面高n位被补0:

c=a>

>

n

3.将b、c进行或运算:

a=c|b

对a进行循环右移两位的程序如下:

main()

{unsignedchara=0xc3,b,c;

intn=2;

b=a<

(8-n);

n;

a=c|b;

结果如下:

循环右移前a=11000011B

循环右移后a=11110000B

3-12位运算程序示例

{inta,b,c;

a=23;

b217;

c=a&

b;

a&

b=%d\n"

c);

c=a|b;

a|b=%d\n"

c=a^b;

a^b=%d\n"

c=~a;

~a=%d\n"

c=a<

3;

a<

3=%d\n"

c=b>

2;

b>

b=17

a|b=223

a^b=206

~a=-24

3=184

2=54

3-13分支编程示例

有一个函数如下:

1x>

y=0x=0

-1x<

编写一个程序,输入一个x值,输出y值。

使用嵌套的if语句判断函数y的取值。

#include<

main()

{intx,y;

scanf()

if(x<

0)y=-1;

else

{if(x==0)y=0;

elsey=1;

x=%d,y=%d\n"

x,y);

3-14选择语句程序示例

{inta,b;

a=200;

b=321;

if(a==b)

{a++;

b++;

a=%d,b=%d\n"

a,b);

a=200,b=321

3-15选择语句程序示例

a=12;

b=21;

{a--;

b--;

a=11,b=20

3-16选择语句程序示例

{intscore;

chargrade;

score=45;

if(score>

=90)

grade='

A'

;

elseif(score>

=80)

B'

=70)

C'

=60)

D'

elsegrade='

E'

score=%d,grade=%c\n"

score,grade);

score=45,grade=E

3-17Proteus仿真电路如图所示。

AT89C51单片机的P1.0和P1.1引脚接有两只按键,其4种逻辑组合分别点亮由P2.0~P2.3控制的4只LED(低电平点亮),试编程实现此功能。

参考程序如下:

{chara;

do

{P1=0xff;

a=p1;

a=a&

0x03;

switch(a)

{case0:

P2=0x0e;

break;

case1:

P2=0x0d;

case2:

P2=0x0b;

case3:

P2=0x07;

}while

(1);

3-18实型数组sample存有10个采样值,编写一个函数返回其平均值(即平均值滤波程序)

floatavg(float*sample)

{floatsum=0;

charno=0;

{sum+=sample[no];

no++;

}while(no<

10);

return(sum/10)

3-19时间延迟程序举例

循环的基本用途之一是用嵌套产生时间延迟,执行的指令消磨一定已知的时间。

这种延时方法是依靠一定数量的时钟周期来计时的,

所以延时依赖于晶振频率。

8051单片机的数据手册中列出了每一条机器指令所需要的时钟周期数,使用2MHzDE晶振,12个震荡指令花费1μs

下面是一个延时1ms的延时程序。

如果给这个程序传递一个50的数值,则可产生约50ms的延时。

voidmsec(unsignesintx)

{unsignedcharj;

while(x--)

{for(j=0;

j<

125;

j++)

{;

根据汇编代码进行的分析表明,用j进行的内部循环大约延时8μs

3-20[break语句]无符号char型数据sdata内存放一个随机数,这个数据每秒产生一次,要求计算这些数据的和,当和超过4000时不再计算,并且计算花费的时间。

{unsignedcharsdata;

inttime;

//存放和花费的秒数

doublesum;

//和

sum=0;

time=0;

sdata=0;

for(;

{time++;

//计算秒数

sum=sum+sdata;

//计算和

if(sum>

4000)

{break;

//退出整个循环

}由于不知道什么时候能够超过4000,所以使用一个‘无限循环’,每次计算和之后判断当前sum的值,当sum超过4000时使用break退出整个循环,不再执行。

3-21[continue语句]退出当前循环,不再执行本轮循环,从下一轮循环开始执行。

无符号char型数据sdata内存放一个随机数,这个数据每秒产生一次,如果这个数据不等于0x45,则计算这些数据的和,当和超过4000时停止计算,

保存出现的0x45的个数并且计算整个过程花费的时间。

intcounter;

counter=0;

//计算秒和

if(sdata==0x45)//如果等于0x45

{counter++;

//统计出现的个数

continue;

//退出本次循环,不计算sum

else//如果不等于0x45

{sum=sum+sdata;

}当sdata等于0x45时,利用continue语句退出本次循环;

当sum和大于4000时,使用break语句退出整个循环。

3-22[goto语句]无条件转移语句

计算1~100的和,存放到sum中

{unsignedcharcounter;

intsum;

sumadd:

sum=sum+counter;

counter++;

if(counter<

101)

{gotosumadd;

3-23一维数组程序示例

如图所示为一由MCS-51单片机控制指示灯的proteus仿真电路,此电路从P0口相连的8个开关读入空置量信息,将最近读入的10次信息存储在10字节数组

chararray[10]中,并把读入的信息显示在与P2口相连接的8位LED指示灯上。

每次读入显示信息间隔100ms,由延时程序msec(100)完成。

相应的C语言程序流程图如下

voidmsec(unsignedint);

{unsignedchararray[10];

unsignedchari;

{for(i=0;

i<

=9;

i++)

{array[i]=p2=p0;

msec(100);

voidmsec(unsignedintx);

while((x--)!

=0)

{for(j=0;

{;

3-24将摄氏温度转换成华氏温度

#defineucharunsignedchar

ucharcodetempt[]={32,34,36,37,39,41};

/*数组,设置在EPROM中,长度为实际输入的数值数*/

ucharftoc(uchardegc)

{returntempt[degc]/*返回华氏温度值*/

{ucharx;

x=ftoc(5);

/*得到与5℃相应的华氏温度值*/

3-25利用指针变量完成A/D接口的启动和读取结果值。

unsignedcharxdata*ADC;

/*定义ADC0809的端口指针*/

unsignedcharxdata*ADCdata;

/*定义ADC0809数据缓冲器指针*/

unsignedchari;

{ADC=0x00f0;

ADCdata=0x1000;

/*定义地址端口和数据缓冲器地址*/

i=8;

/*ADC0809有8个模拟输入通道*/

EA=1;

EX1=1;

IT1=1;

/*开中断*/

*ADC=i;

/*启动ADC0809*/

while(i);

/*等待8个通道转换结束*/

voidint1()interrupt2

{unsignedchartmp;

tmp=*ADC;

*ADCdata=tmp;

/*读出A/D转换结果*/

ADCdata++;

/*数据存到数据缓冲器*/

i--;

/*启动下一个模拟输入通道A/D转换*/

3-26无参函数举例。

程序如下

func()

(printf("

FunctionInfuncrespondthecallofMain\n"

);

{printf("

FunctionInMainCallsAFunctioninfunc\n"

func();

上面的程序中,实际上定义了两个函数main()和func()。

它们都是无参函数,因此它们的返回值类型标识符可以省略,默认值是int类型。

3-27求两个数的最大公约数程序如下

intgcd(u,v)

intu,v;

{inttemp;

while(v!

{temp=u%v;

u=v;

v=temp;

return(u);

{intresult,a=150,b=35;

SCON=0x50;

TM0D=0x20;

TH1=0xf3;

TR1=1;

T1=1;

result=gcd(a,b);

Thegcdof%dand%dis%d\n"

a,b,result);

程序运行结果为a=150b=35

Thegcdof150and35is5

3-28中断函数举例程序如下

unsignedintinterruprcnt;

unsignedcharsecond;

voidtimer0(void)interrupt1using2

{if(++interruprcnt=4000)

{second++;

interruptcnt=0;

{

定义中断函数要注意:

1interrupt和using不能用于外部中断;

2使用using定义寄存器组时,要保证寄存器组切换在所控制的区域内,否则出错。

I/O函数

函数功能

_getkey从串行口读入一个字符

_getchar从串行口读入一个字符并输出该字符

gets从串行口读入一个字符串

ungetchar将读入的字符回送到输入缓冲区

putchar通过8051的串行口输出字符

printf按照一定的格式输出数据或字符串

sprintf按照一定的格式将数据或字符串输出到内存缓冲区

puts将字符串和换行符写入串行口

scanf将字符串和数据按照一定的格式从串行口读入

sscanf将格式化的字符串和数据送入数据缓冲区

vprintf将格式化字符串输出到内存数据缓冲区

vsprintf将格式化字符串和数字输出到由指针所指向的内存数据缓冲区

内部函数库

_crol_将char型变量循环向左移动指定位数后返回

_irol_将int型变量型循环向左移动指定位数后返回

_lrol_将long型变量循环向左移动指定位数后返回

_cror_将char型变量循环向右移动指定位数后返回

_iror_将int型变量循环向右移动指定位数后返回

_lror_将long型变量循环向右移动指定位数后返回

_nop_使单片机产生延时(相当于插入汇编指令NOP)

_testbit_对字节中的一位进行测试(相当于JBCbit)指令

绝对地址访问函数

CBYTE对8051单片机的存储空间进行字节寻址CODE区

DBYTE对8051单片机的存储空间进行字节寻址DATA区

PBYTE对8051单片机的存储空间进行字节寻址PDATA区

XBYTE对8051单片机的存储空间进行字节寻址XDATA区

CWORD对8051单片机的存储空间进行字寻址CODE区

DWORD对8051单片机的存储空间进行字寻址DATA区

PWORD对8051单片机的存储空间进行字寻址PDATA区

XWORD对8051单片机的存储空间进行字寻址XDATA区

3-29字节型空间访问示例

//头文件

{charch;

DBYTE[0x0040]=0x41;

//赋值

PBYTE[0x0002]=0x42;

XBYTE[0x0003]=0x43;

ch=CBYTE[0x0002];

//读取并输出

ch=%bx\n"

ch);

ch=DBYTE[0x0040];

ch=PBYTE[0x0002];

ch=XBYTE[0x0002];

}运行结果如下ch=6ach=41ch=42ch=43

3-30字型空间访问示例

{intch1;

DWORD[0x0040]=0x41;

PWORD[0x0002]=0x42;

XWORD[0X0002]=0X43;

ch1=CWORD[0x0002];

/

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

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

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

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