C语言,单片机主要运用到那些?

在单片机的开发应用中,已逐渐开始引入高级语言,

C语言就是其中的一种。对用惯了汇编的人来说,总觉得高级语言’可控性’不好,不如汇编那样随心所欲。

但是只要我们掌握了一定的C语言知识,有些东西还是容易做出来的,以下是笔者实际工作中遇到的几个问题,希望对初学C51者有所帮助。

一、C51热启动代码的编制

对于工业控制计算机,往往设有有看门狗电路,当看门狗动作,使计算机复位,这就是热启动。

热启动时,一般不允许从头开始,这将导致现有的已测量到或计算到的值复位,导致系统工作异常。

因而在程序必须判断是热启动还是冷启动,常用的方法是:确定某内存单位为标志位(如0x7f位和0x7e位),

启动时首先读该内存单元的内容,如果它等于一个特定的值(例如两个内存单元的都是0xaa),就认为是热启动,

否则就是冷启动,程序执行初始化部份,并将0xaa赋与这两个内存单元。

根据以上的设计思路,编程时,设置一个指针,让其指向特定的内存单元如0x7f,然后在程序中判断,程序如下:

voidmain()

{chardata*HotPoint=(char*)0x7f;

if((*HotPoint==0xaa)&&(*(--HotPoint)==0xaa))

{/*热启动的处理*/

}

else

{HotPoint=0x7e;/*冷启动的处进

*HotPoint=0xaa;

*(++HotPoint)=0xaa;

}

/*正常工作代码*/

}

然而实际调试中发现,无论是热启动还是冷启动,开机后所有内存单元的值都被复位为0,当然也实现不了热启动的要求。这是为什么呢?原来,用C语言编程时,开机时执行的代码并非是从main()函数的第一句语句开始的,在main()函数的第一句语句执行前要先执行一段’起始代码’。正是这段代码执行了清零的工作。C编译程序提供了这段起始代码的源程序,名为CSTARTUP.A51,打开这个文件,可以看到如下代码:

.

IDATALENEQU80H;thelengthofIDATAmemoryinbytes.

.

STARTUP1:

IFIDATALEN<>0

MOVR0,#IDATALEN-1

CLRA

IDATALOOP:MOV@R0,A

DJNZR0,IDATALOOP

ENDIF

.

可见,在执行到判断是否热启动的代码之前,起始代码已将所有内存单元清零。如何解决这个问题呢?好在启动代码是可以更改的,方法是:修改startup.a51源文件,然后用编译程序所附带的a51.exe程序对startup.a51编译,得到startup.obj文件,然后用这段代码代替原来的起始代码。具体步骤是(设C源程序名为HOTSTART.C):

修改startup.a51源文件(这个文件在C51LIB目录下)。

执行如下命令:

A51startup.a51得到startup.obj文件。将此文件拷入HOTSTART.C所在目录。

将编好的C源程序用C51.EXE编译好,得到目标文件HOTS

TART.OBJ。

用L51HOTSTART,STARTUP.OBJ命令连接,得到绝对目标文件HOTSTART。

用OHS51HOTSTART得到HOTSTART.HEX文件,即可。

对于startup.a51的修改,根据自已的需要进行,如将IDATALENEQU80H中的80H改为70H,就可以使6F到7F的16字节内存不被清零。

二、直接调用EPROM中已固化的程序

笔者用的仿真机,由6位数码管显示,在内存DE00H处放显示子程序,只要将要显示的数放入显示缓冲区,然后调用这个子程序就可以使用了,汇编指令为:

LCALL0DEOOH

在用C语言编程时,如何实现这一功能呢?C语言中有指向函数的指针这一概念,可以利用这种指针来实现用函数指针调用函数。指向函数的指针变量的定义格式为:

类型标识符(*指针变量名)();

在定义好指针后就可以给指针变量赋值,使其指向某个函数的开始存地址,然后用

(*指针变量名)()即可调用这个函数。如下例:

voidmain(void)

{

void(*DispBuffer)();/*定义指向函数指针*/

DispBuffer=0xde00;/*赋值*/

for(;;)

{Key();

DispBuffer();

}

}

三、将浮点数转化为字符数组

笔者在编制应用程序时有这样的要求:将运算的结果(浮点数)存入EEPROM中。我们知道,浮点数在C语言中是以IEEE格式存储的,一个浮点数占用四个字节,例如浮点数34.526存为(160,26,10,66)这四个数。要将一个浮点数存入EEPROM,实际上就是要存这四个数。那么如何在程序中得到一个浮点数的组成数呢?

浮点数在存储时,是存储连续的字节中的,只要设法找到存储位置,就可以得到这些数了。可以定义一个void的指针,将此指针指向需要存储的浮点数,然后将此指针强制转化为char型,这样,利用指针就可以得到组成该浮点数的各个字节的值了。具体程序如下:

#defineucharunsignedchar#defineuintunsignedintvoidFtoC(void)

{floata;

uchari,*px

ucharx[4];/*定义字符数组,准备存储浮点数的四个字节*、

void*pf;

px=x;/*px指针指向数组x*/

pf=&a;/*void型指针指向浮点数首地址*/

a=34.526;

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

{*(px+i)=*((char*)pf+i);/*强制void型指针转成char型,因为*/

}/*void型指针不能运算*/

}

如果已将数存入EEPROM,要将其取出合并,方法也是一样,可参考下面的程序。

#defineucharunsignedchar#defineuintunsignedint

voidCtoF(void)

{floata;

uchari,*px

ucharx[4]={56,180,150,73};

void*pf;

px=x;

pf=&a;

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

{*((char*)pf+i)=*(px+i);

}

}

以上所用C语言为FRANKLINC51VER3.2。




  • C璇█,鍗曠墖鏈轰富瑕佽繍鐢ㄥ埌閭d簺?
    绛旓細鍘熸潵锛鐢–璇█缂栫▼鏃讹紝寮鏈烘椂鎵ц鐨勪唬鐮佸苟闈炴槸浠巑ain()鍑芥暟鐨勭涓鍙ヨ鍙ュ紑濮鐨锛鍦main()鍑芥暟鐨勭涓鍙ヨ鍙ユ墽琛屽墠瑕佸厛鎵ц涓娈碘欒捣濮嬩唬鐮佲欍傛鏄繖娈典唬鐮佹墽琛屼簡娓呴浂鐨勫伐浣溿侰缂栬瘧绋嬪簭鎻愪緵浜嗚繖娈佃捣濮嬩唬鐮佺殑婧绋嬪簭锛鍚嶄负CSTARTUP.A51锛屾墦寮杩欎釜鏂囦欢锛屽彲浠ョ湅鍒板涓嬩唬鐮侊細.IDATALENEQU80H;thelengthofIDATA...
  • 鍗曠墖鏈銆佸井鏈恒C璇█鍒嗗埆鏈変粈涔堜笉鍚,鍚勮嚜搴旂敤鍦浠涔堝満鍚?
    绛旓細鍗曠墖鏈猴細涓昏杩愮敤姹囩紪璇█锛岀敤鍦ㄧ畝鍗曠殑鐢靛瓙CPU涓紝鍙互鐑у綍鎵ц浠g爜锛屼緥濡備互鍓嶇數瑙嗘満涓殑CPU鑺墖锛屽畬鎴愮畝鍗曠殑璁剧疆鍙婃崲鍙扮瓑鎸囦护 寰満锛氬井鍨嬭绠楁満锛屽疄闄呬笂鍗曠墖鏈哄彲浠ョ湅鍋氭槸绠鍗曠殑寰満锛屾墽琛屼唬鐮佽緝灏 C璇█锛氱▼搴忓紑鍙戣瑷锛屾棭鏈熺殑JAVA锛岀幇鍦ㄧ殑瀹夊崜搴曞眰閮芥槸鐢–璇█鍐欑殑銆傛湜閲囩撼锛岃阿璋 ...
  • 鍗曠墖鏈篊璇█绋嬪簭璁捐鍝簺宀椾綅鐢ㄥ埌?
    绛旓細涓昏鏄祵鍏ュ紡寮鍙戝惂锛岃璁LC鏃朵篃瑕佺敤鍒帮紝浣嗚瀛︽繁浜嗘墠鏈夌敤銆傛垜涓句釜宓屽叆寮忕殑渚嬪瓙锛屽皬绫虫櫤鑳藉浠躲
  • C璇█鍦ㄥ崟鐗囨満涓鐨勫簲鐢
    绛旓細鍗曠墖鏈哄氨鍍忔槸涓涓函浣擄紝鑰岀▼搴忓氨鏄畠鐨勭伒榄傘侰璇█灏辨槸鍒堕狅紙缂栧啓锛夊畠鐨勭伒榄傜殑宸ュ叿銆傚崟鐗囨満涓殑C璇█涓庢爣鍑咰璇█鏈変竴浜涗笉鍚岋紝鏈夊緢澶氬浣嶇殑瀹氫箟鍜屾搷浣溿傚湪鍗曠墖鏈哄簲鐢ㄤ腑鏈甯哥敤鐨勭紪璇戣蒋浠舵槸KEIL C51锛屽姛鑳藉己澶с侰璇█鏄竴绉嶉珮绾ц瑷锛屽湪鍗曠墖鏈哄簲鐢ㄤ腑鍏朵紭鐐逛篃鏄潪甯哥獊鍑猴細缂栫▼鐏垫椿銆佸彲璇绘с佸彲绉绘鎬ч兘寰堝己銆
  • 瀛︿簡鍗曠墖鏈篶璇█,鑳藉共浠涔? 璇烽棶鏈夎繖鏂归潰鐨勬棩浼佸悧?
    绛旓細瀛︿範鍗曠墖鏈篊璇█涓昏骞朵笉鏄涔犺瑷鏈韩锛岃屾槸C璇█鍦鍗曠墖鏈轰笂鐨勫簲鐢紝杩欓噷鏇撮噸瑕佺殑鏄鍗曠墖鏈虹殑鍐呴儴缁撴瀯鍙婂伐浣滄満鐞嗙殑鐞嗚В锛屾瘮濡傛庢牱璁惧畾鍙婃帶鍒禝O鍙c佹庢牱閫氳繃鐗规畩鍔熻兘瀵勫瓨鍣ㄦ搷浣滃畾鏃跺櫒銆佸鐞嗕腑鏂瓑绛夌瓑绛夈傚涔犲崟鐗囨満C璇█鏇村鐨勬槸瀵圭‖浠剁殑鐞嗚В銆傛悶鎳備簡鍗曠墖鏈哄氨鏄宓屽叆寮忕郴缁熷涔犵殑涓涓熀纭锛屾湁浜嗚繖涓熀纭鍙互...
  • 鏈汉鏄娴嬫帶涓撲笟鐨,甯屾湜鍓嶈緢鍛婅瘔鎴鍗曠墖鏈鍜C璇█閲嶈鍚?鎴戜互鍚庢瘯涓...
    绛旓細C璇█锛屽彧鏄浜庡崟鐗囨満寮鍙戠殑鍏朵腑涓绉嶈蒋浠躲傝瘹鐒讹紝鐩稿浜庢眹缂栬瑷鏉ヨ锛孋璇█寮鍙戞瘮杈冮氫織銆備絾瑕佸涔犲崟鐗囨満锛屽氨蹇呴』瑕佷簡瑙e畠鐨勬寚浠わ紙灏辨槸姹囩紪锛夛紝鍥犱负C璇█杩樻槸闇瑕佺紪璇戞垚姹囩紪鐨勩傛湁浜涘崟鐗囨満鍦ㄦ煇浜涚壒娈婂姛鑳戒笂锛岃繕蹇呴』宓屽叆姹囩紪璇█鎵嶈兘寮鍙戯紝姣斿PIC鍗曠墖鏈虹殑鏍″噯瀛椼傛祴鎺т笓涓氳窡鑷姩鍖栦笓涓氱浉杩戯紝浣嗗畠鏇翠晶閲嶄簬鍦...
  • 浣犲ソ,璇烽棶浣犻偅涓熀浜51鍗曠墖鏈虹殑浜ら氱伅鐨C璇█绋嬪簭璁捐鍜岀數璺浘涓 鐢...
    绛旓細鍗曠墖鏈鏈灏忕郴缁燂紙鍗曠墖鏈恒佹櫠鎸佺數瀹广佺數闃伙級锛屾暟鐮佺锛孡ED锛岀數闃+涓浜涙彃浠跺拰IC搴с
  • 鎴戞槸鍗曠墖鏈哄垵瀛﹁,瀛鍗曠墖鏈虹殑璇濇槸瀛C璇█杩樻槸瀛++鍛?
    绛旓細鍗曠墖鏈涓嶆敮鎸乧++锛屽c灏卞彲浠ヤ簡
  • 鍗曠墖鏈,C璇█,宓屽叆寮忔妧鏈湁浠涔堝叧绯
    绛旓細C璇█锛灏辨槸涓闂ㄦ棭鍓嶇殑楂樼骇缂栫▼璇█锛屽彲浠ョ敤鏉ョ紪鍐欑數鑴戣蒋浠讹紝涔熷彲浠ョ敤鏉ョ紪鍐鍗曠墖鏈鎺у埗绋嬪簭锛岃繕鍙互鐢ㄦ潵缂栧啓宓屽叆寮忕殑绋嬪簭銆傚祵鍏ュ紡锛岃繖涓笉濂借В閲婏紝姣斿鐜板湪鐨勬櫤鑳芥墜鏈猴紝灏辨槸涓涓祵鍏ュ紡璁惧銆傚祵鍏ュ紡锛屽湪杞欢涓涓昏鎸囧彲浠ヨ繍琛屼簬鍗曠墖鏈烘垨ARM绛夋洿楂樼骇鑺墖鐨勭郴缁燂紝鍦ㄧ‖浠朵笂涓昏鎸囧寘鍚簡鍗曠墖鏈烘垨ARM绛夐珮绾ф帶鍒惰姱鐗...
  • 鍗曠墖鏈涓轰粈涔堣繕鍦鐢–璇█缂栫▼?
    绛旓細C璇█鏄竴涓姌涓夋嫨 鍏跺疄鐢–璇█寮鍙戝崟鐗囨満涔熸槸涓涓姌涓柟妗堬紝鍥犱负鏈閫傚悎鍗曠墖鏈哄紑鍙戠殑缂栫▼璇█瀹炲湪澶繃鏅︽订闅炬噦锛屽苟涓旀瘡涓绉鍗曠墖鏈虹殑姹囩紪鎸囦护鏈夊緢澶у尯鍒紝鎵浠ユ兂鎶婁竴涓▼搴忎粠杩欑鍗曠墖鏈虹Щ妞嶅埌鍙︿竴绉嶅崟鐗囨満绠鐩存槸鐥村績濡勬兂锛岃繕涓嶅閲嶆柊鍐欎竴閬嶇▼搴忋傝孋璇█浠g爜鎵ц鏁堢巼楂橈紝涔熸瘮杈冪簿绠锛屾洿渚夸簬绉绘...鎵浠ュ湪鐜...
  • 扩展阅读:扫一扫题目出答案 ... 三类人不适合学编程 ... 单片机c语言入门自学 ... 单片机必须会c语言吗 ... c++编程 ... 单片机必备基础知识 ... 单片机最简单编程软件 ... 苹果手机plc编程仿真软件 ... 单片机三大编程语言 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网