当前位置:首页 >> 技术频道 >> 嵌入式开发

嵌入式C语言位操作的移植与优化

来源:单片机与嵌入式系统应用 作者:佚名 发布时间:2009-06-24 09:27:38 发表评论

摘要:单片机的应用越来越广泛,种类也越来越多。由于嵌入式C语言可读性强、移植性好,与汇编语言相比大大减轻了软件工程师的劳动强度

关键词:嵌入式

  引言

  单片机的应用越来越广泛,种类也越来越多。由于嵌入式C语言可读性强、移植性好,与汇编语言相比大大减轻了软件工程师的劳动强度,因而越来越多的单片机工程师开始使用C语言编程。但C语言的可移植性仅限于与硬件无关的子程序,而与具体硬件有关的子程序则无法移植。在单片机应用中,位操作(特别是对引脚的位操作)非常普遍,如EEPROM数据和IC卡数据的读写、字段式LCD显示等,很多带串口的集成电路都需要单片机用软件来做I/O口读写程序。如何让这些子程序既有很好的通用性,生成代码的效率又高,是很多软件工程师都在考虑的问题。这里介绍两种C语言位操作的移植方法。

  1 用逻辑运算实现位操作

  请看下面这个子程序:

  INT8U Card102RdByte(void) {

  INT8U Temp8U, n = 8;

  do{ Temp8U <<= 1;

  if( PIN_CARD_SDA_RD() ) Temp8U |= 0x01;

  PIN_CARD_CLK_H();PIN_CARD_CLK_L();

  }while(--n);

  return Temp8U;

  }

  这是通过单片机引脚从88SC102卡中读一个字节的子程序。程序采用μC/OSII中的书写风格,即变量和函数采用“驼峰”写法,由define定义的常量和内联函数采用全部大写加下划线的写法。

  此程序驱动一个引脚输出CARD_CLK高低信号,从另一个引脚一位一位读取CARD_SDA数据。

  1.1 用于MSP430系列单片机

  此程序应用到MSP430单片机上(本文用的是MSP430F413单片机),头文件中要有如下定义:

  typedefunsigned charINT8U;

  #include

  #definePIN_CARD_SDA_RD()(P6IN & 0x01)

  #definePIN_CARD_CLK_H()P6OUT |=0x04

  #definePIN_CARD_CLK_L()P6OUT &= ~0x04

  汇编结果如下:

  In segment CODE, align 2, keepwithnext

  __code unsigned char Card102RdByte(void)

  Card102RdByte:

  0000007E42MOV.B#0x8, R14

  ??Card102RdByte_0:

  0000024C5CRLA.BR12

  000004D2B33400BIT.B#0x1, &0x34

  0000080128JNC??Card102RdByte_1

  00000A5CD3BIS.B#0x1, R12

  ??Card102RdByte_1:

  00000CE2D23500BIS.B#0x4, &0x35

  000010E2C23500BIC.B#0x4, &0x35

  0000147E53ADD.B#0xff, R14

  0000164E93CMP.B#0x0, R14

  000018F423 JNE??Card102RdByte_0

  00001A3041RET

  这与手工汇编编程的结果几乎一样,代码效率很高。

  1.2 用于51系列单片机

  在51系列单片机中应用此程序,头文件要加入以下定义:

  #include"Reg932.h"//Philips LPC932单片机

  sbitCradClk=P0^1;

  sbitCardSDA=P0^0;

  #definePIN_CARD_SDA_RD()CardSDA

  #definePIN_CARD_CLK_H()CradClk=1

  #definePIN_CARD_CLK_L()CradClk=0

  原来的程序不作任何改动,汇编结果如下:

  ; FUNCTION Card102RdByte (BEGIN)

  ;-- Variable 'Temp8U' assigned to Register 'R7' --

  ;-- Variable 'n' assigned to Register 'R6' --

  00007E08MOVR6,#08H

  0002?C0007:

  0002EFMOVA,R7

  000325E0ADDA,ACC

  0005FFMOVR7,A

  0006308003JNBCardSDA,?C0008

  0009430701ORLAR7,#01H

  000C?C0008:

  000CD281SETBCradClk

  000EC281CLRCradClk

  0010DEF0DJNZR6,?C0007

  0012?C0009:

  001222RET

  ; FUNCTION Card102RdByte (END)

  由汇编结果可知,对位的直接清零和置位已达到最简,只是读位值不够理想。

0
顶一下
0
踩一下

发表评论

请自觉遵守互联网相关政策法规,作者管理后台可以删除恶意评论、广告和违禁词语。