(玩电子) 电子技术学习与研讨
当时方位:单片机教程网 >> 根底教程 >> 阅览文章

第十二课 C51开关分支句子

作者:佚名   来历:本站原创   点击数:x  更新时刻:2007年07月14日   【字体:

学习了条件句子,用多个条件句子能完结多方向条件分支,可是能发现运用过多的 条件句子完结多方向分支会使条件句子嵌套过多,程序冗长,这样读起来也很不好读。这个时分 运用开关句子相同能到达处理多分支挑选的意图,又能使程序结构明晰。它的语法为下:

switch  (表达式)

{

case  常量表达式 1:  句子 1;  break; case  常量表达式 2:  句子 2;  break; case  常量表达式 3:  句子 3;  break; case  常量表达式 n:  句子 n;  break; default:    句子

}

运转中 switch 后边的表达式的值将会做为条件,与 case 后边的各个常量表达式的值相 比照,假如持平时则履行 case 后边的句子,再履行 break(连续句子)句子,跳出 switch 句子。假如 case 后没有和条件持平的值时就履行 default 后的句子。当要求没有契合的条 件时不做任何处理,则能不写 default 句子。

在上面的章节中咱们一向在用 printf 这个规范的 C 输出函数做字符的输出,运用它当 然会很便利,但它的功用强大,所占用的存储空间天然也很大,要 1K 左右字节空间,假如 再加上 scanf 输入函数就要到达 2K 左右的字节,这样的话假如要求用 2K 存储空间的芯片时 就无法再运用这两个函数,例如 AT89C2051。在这些小项目中,一般咱们仅仅要求简略的字 符输入输出,这儿以笔者宣布在自己网站的一个简略的串行口运用实例为例,一来学习运用开 关句子的运用,二来简略了解 51 芯片串行口根本编程。这个实例是用 PC 串行口经过上位机程序 与由 AT89c51 组成的下位机相通讯,完结用 PC 软件操控 AT89c51 芯片的 IO 口,这样也就可 以再经过相关电路完结对设备的操控。为了便利试验,在此所运用的硬件仍是用回以上课程 中做好的硬件,以串行口和  PC  衔接,用  LED  检查试验的成果。原代码请到在笔者的网站 下载,上面有  单片机c言语  下位机源码、PC 上位机源码、电路图等材料。

代码中有多处运用开关句子的,运用它对不相同的条件做不相同的处理,如在 CSToOut 函数 中依据 CN[1]来挑选输出到那个 IO 口,CN[1]=0 则把 CN[2]的值送到 P0,CN[1]=1 则送到 P1, 这样的写法比重用 if (CN[1]==0)这样的判别句子来的明晰明晰。当然它们的效果没有太大 的不同(在不考虑编译后的代码履行功率的情况下)。

在这段代码首要的效果便是经过串行口和上位机软件进行通讯,跟据上位机的指令字串, 对指定的 IO 端口进行读写。InitCom 函数,原型为 void InitCom(unsigned char BaudRate), 其效果为初始化串行口。它的输入参数为一个字节,程序便是用这个参数做为开关句子的挑选 参数。如调用 InitCom(6),函数就会把波特率设置为 9600。当然这段代码只运用了一种波特 率,能用更高功率的句子去编写,这儿就不多谈论了。

看到这儿,你或许会问函数中的 SCON,TCON,TMOD,SCOM 等是代表什么?它们是特别 功用存放器。

SBUF    数据缓冲存放器    这是一个能直接寻址的串行口专用存放器。有朋友这样问起 过“为安在串行口收发中,都仅仅运用到同一个存放器 SBUF?而不是收发各用一个存放器。” 实践上 SBUF 包含了两个独立的存放器,一个是发送存放,另一个是接纳存放器,但它们都 一起运用同一个寻址地址-99H。CPU 在读 SBUF 时会指到接纳存放器,在写时会指到发送寄

存器,并且接纳存放器是双缓冲存放器,这样能防止接纳中止没有及时的被呼应,数据没


 

casino

有被取走,下一帧数据已到来,而形成的数据堆叠问题。发送器则不需求用到双缓冲,一般 情况下咱们在写发送程序时也不用用到发送中止去外理发送数据。操作 SBUF 存放器的办法 则很简略,只要把这个 99H 地址用关键字 sfr 界说为一个变量就能对其进行读写操作了,

如 sfr  SBUF  =  0x99;当然你也能用其它的称号。一般在规范的 reg51.h 或 at89x51.h 等 头文件中已对其做了界说,只要用#include 引证就能了。

SCON    串行口操控存放器    一般在芯片或设备中为了监督或操控接口状况,都会引证 到接口操控存放器。SCON 便是 51 芯片的串行口操控存放器。它的寻址地址是 98H,是一个 能位寻址的存放器,效果便是监督和操控 51 芯片串行口的作业状况。51 芯片的串行口能 作业在几个不相同的作业形式下,其作业形式的设置便是运用 SCON 存放器。它的各个位的具 体界说如下:

(MSB)                                                                                                (LSB) SM0          SM1          SM2          REN          TB8          RB8           TI            RI

表 8-1    串行口操控存放器 SCON

SM0、SM1  为串行口作业形式设置位,这样两位能对应进行四种形式的设置。看表  8

-2 串行口作业形式设置。

SM0

SM1

模    式

功    能

波特率

0

0

0

同步移位存放器

fosc/12

0

1

1

8 位 UART

可变

1

0

2

9 位 UART

fosc/32 或 fosc/64

1

1

3

9 位 UART

可变

表 8-2    串行口作业形式设置

在这儿只阐明最常用的形式 1,其它的形式也就逐个略过,有爱好的朋友能找相关的 硬件材料检查。表中的  fosc  代表振动器的频率,也便是晶体震动器的频率。UART  为(Universal Asynchronous  Receiver)的英文缩写。

SM2 在形式 2、形式 3 中为多处理机通讯使能位。在形式 0 中要求该位为 0。

REM 为答应接纳位,REM 置 1 时串行口答应接纳,置 0 时制止接纳。REM 是由软件置位或 清零。假如在一个电路中接纳和发送引脚 P3.0,P3.1 都和上位机相连,在软件上有串行口中止 处理程序,当要求在处理某个子程序时不答应串行口被上位机来的操控字符发生中止,那么可 以在这个子程序的开端处参加 REM=0 来制止接纳,在子程序完毕处参加 REM=1 再次翻开串行口 接纳。咱们也能用上面的实践源码参加 REM=0 来进行试验。

TB8 发送数据位 8,在形式 2 和 3 是要发送的第 9 位。该位能用软件依据需求置位或 铲除,一般这位在通讯协议中做奇偶位,在多处理机通讯中这一位则用于标明是地址帧仍是 数据帧。

RB8 接纳数据位 8,在形式 2 和 3 是已接纳数据的第 9 位。该位可能是奇偶位,地址/ 数据标识位。在形式 0 中,RB8 为保存位没有被运用。在形式 1 中,当 SM2=0,RB8 是已接 收数据的中止位。

TI 发送中止标识位。在形式 0,发送完第 8 位数据时,由硬件置位。其它形式中则是在 发送中止位之初,由硬件置位。TI 置位后,请求中止,CPU 呼应中止后,发送下一帧数据。 在任何形式下,TI 都有必要由软件来铲除,也便是说在数据写入到 SBUF 后,硬件发送数据,

中止呼应(如中止翻开),这个时分 TI=1,标明发送已完结,TI 不会由硬件铲除,所以这个时分有必要


 

用软件对其清零。

RI 接纳中止标识位。在形式 0,接纳第 8 位完毕时,由硬件置位。其它形式中则是在接 收中止位的半中心,由硬件置位。RI=1,请求中止,要求 CPU 取走数据。但在形式 1 中,SM2=1 时,当未收到有用的中止位,则不会对 RI 置位。相同 RI 也有必要要靠软件铲除。

常用的串行口形式 1 是传输 10 个位的,1 位开端位为 0,8 位数据位,低位在先,1 位中止 位为 1。它的波特率是可变的,其速率是取决于守时器 1 或守时器 2 的守时值(溢出速率)。 AT89c51 和 AT89C2051 等 51 系列芯片只要两个守时器,守时器 0 和守时器 1,而守时器 2

是 89C52 系列芯片才有的。

波特率    在运用串行口做通讯时,一个很重要的参数便是波特率,只要上下位机的波特率 相同时才干进行正常通讯。波特率是指串行端口每秒内能传输的波特位数。有一些开端学习 的朋友以为波特率是指每秒传输的字节数,如规范  9600  会被误以为每秒种能传送  9600 个字节,而实践上它是指每秒能传送 9600 个二进位,而一个字节要 8 个二进位,如用串 口形式 1 来传输那么加上开端位和中止位,每个数据字节就要占用 10 个二进位,9600 波特 率用形式 1 传输时,每秒传输的字节数是 9600÷10=960 字节。51 芯片的串行口作业形式 0 的波特率是固定的,为 fosc/12,以一个 12M 的晶体震动器来核算,那么它的波特率能到达 1M。 形式 2 的波特率是固定在 fosc/64 或 fosc/32,具体用那一种就取决于 PCON 存放器中的 SMOD 位,如 SMOD 为 0,波特率为 focs/64,SMOD 为 1,波特率为 focs/32。形式 1 和形式 3 的波 特率是可变的,取决于守时器 1 或 2(52 芯片)的溢出速率。那么咱们怎样去核算这两个模 式的波特率设置时相关的存放器的值呢?能用以下的公式去核算。

波特率=(2SMOD÷32)×守时器 1 溢出速率

上式中如设置了 PCON 存放器中的 SMOD 位为 1 时就能把波特率提高 2 倍。一般会运用 守时器 1 作业在守时器作业形式 2 下,这个时分守时值中的 TL1 做为计数,TH1 做为主动重装值    , 这个守时形式下,守时器溢出后,TH1 的值会主动装载到 TL1,再次开端计数,这样能不 用软件去干涉,使得守时更准确。在这个守时形式 2 下守时器 1 溢出速率的核算公式如下:

溢出速率=(计数速率)/(256-TH1) 上式中的“计数速率”与所运用的晶体振动器频率有关,在 51 芯片中守时器发动后会

在每一个机器周期使守时存放器 TH 的值添加一,一个机器周期等于十二个振动周期,所以

能得知 51 芯片的计数速率为晶体振动器频率的 1/12,一个 12M 的晶体震动器用在 51 芯片上, 那么 51 的计数速率就为 1M。一般用 11.0592M 晶体是为了得到规范的无差错的波特率,那 么为何呢?核算一下就知道了。如咱们要得到 9600 的波特率,晶体震动器为 11.0592M 和 12M,定 时器 1 为形式 2,SMOD 设为 1,别离看看那所要求的 TH1 为何值。代入公式:

11.0592M

9600=(2÷32)×((11.0592M/12)/(256-TH1))

TH1=250    //看看是不是和上面实例中的运用的数值相同?

12M

9600=(2÷32)×((12M/12)/(256-TH1)) TH1≈249.49

上面的核算能看出运用 12M 晶体的时分核算出来的 TH1 不为整数,而 TH1 的值只能取


 

整数,这样它就会有必定的差错存在不能发生准确的 9600 波特率。当然必定的差错是能 在运用中被承受的,就算运用 11.0592M 的晶体振动器也会因晶体自身所存在的差错使波特

率发生差错,但晶体自身的差错对波特率的影响是十分之小的,能忽略不计。

宣布谈论】【告知老友】【保藏此文】【封闭窗口

文章谈论

相关文章