找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

巢课
电巢直播8月计划
查看: 41|回复: 1
打印 上一主题 下一主题

C51语言应用编程的若干问题

[复制链接]

157

主题

559

帖子

1198

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

积分
1198
跳转到指定楼层
1#
发表于 2016-8-9 15:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您!

您需要 登录 才可以下载或查看,没有帐号?注册

x
在研制单片机应用系统时,汇编语言是一种常用的软件工具。它能直接操作硬件,指令的执行速度快。但其指令系统的固有格式受硬件结构的限制很大,且难于编写与调试,可移植性也差。随着单片机硬件性能的提高,其工作速度越来越快,因此在编写单片机应用系统程序时,更着重于程序本身的编写效率。而Franklin C51交叉编译器是专为80C51系列单片机设计的一种高效的C语言编译器,使用它可以缩短开发周期,降低开发成本,而且开发出的系统易于维护,可靠性高,可移植性好,即使在代码的使用效率上,也完全可以和汇编语言相比,因此目前它已成为开发80C51系列单片机的流行工具。6 ^- g; j1 m$ M4 t/ B6 s

5 c: c& `1 }* p' m  l! A' D1 C51语言程序设计的基本技巧, U( `5 A* m3 Q, v1 G/ B
& k9 p( u: J, r% I
    C语言是一种高级程序设计语言,它提供了十分完备的规范化流程控制结构。因此采用C51语言设计单片机应用系统程序时,首先要尽可能地采用结构化的程序设计方法,这样可使整个应用系统程序结构清晰,易于调试和维护。对于一个较大的程序,可将整个程序按功能分成若干个模块,不同的模块完成不同的功能。对于不同的功能模块,分别指定相应的入口参数和出口参数,而经常使用的一些程序最好编成函数,这样既不会引起整个程序管理的混乱,还可增强可读性,移植性也好。
2 Q3 f8 G% ?7 {
  {, Z" U  w4 }( `1 v    在程序设计过程中,要充分利用C51语言的预处理命令。对于一些常用的常数,如TRUE,FALSE,PI以及各种特殊功能寄存器,或程序中一些重要的依据外界条件可变的常量,可采用宏定义"#define"或集中起来放在一个头文件中进行定义,再采用文件包含命令"#include"将其加入到程序中去。这样当需要修改某个参量时,只须修改相应的包含文件或宏定义,而不必对使用它们的每个程序文件都作修改,从而有利于文件的维护和更新。现举例说明如下:; T/ ?0 }1 o2 y& S/ H5 t$ p5 _) |
) [0 F* q4 E% c1 ]& w
    例1 对于不同的单片机晶振,程序取不同的延时时间,而且可根据外界条件的变化修改延时时间的长短。对于这样的程序,可利用宏定义和条件编译来实现。程序如下:
" d% r5 x) }" l& T6 T6 w. }! D& I( @% H5 B1 c
#define     flag 1/ v$ o0 m/ }+ T" D
#ifdef     flag==1
' K3 f/ j) [1 q/ H; p! {: t1 A   #define  fosc  6M
8 }; ]# B: y# b& k+ S. C9 r  delay=10;
8 O  A8 w. ^3 H#elif     flag = = 01 L' k) H! e# U
#define   fosc    8M  g6 [" b' _) t# V" z( x- K* P% r& R
  delay=12;: z1 q* t$ s# U9 B
#else5 A* B% z. i7 N2 e; T
#define    fosc   12M3 A* e3 L* q+ A. E0 {
  delay=20;2 Y4 |) w1 W/ [% v8 L
#endif
3 T& R( a+ L3 M* S: H+ |$ o4 t: wmain(). G, R% z9 a5 e) j: y) L; B2 S  I& R8 Z
{+ E* V0 E5 K- ~8 Z
for(I=0;I<delay;I++);
1 y% K) X" z+ s0 \2 W' D}
2 b6 j; w* f% T- T& a% @/ \    这样源程序不作任何修改就可适用于不同时钟频率的单片机系统,并可根据情况的不同取不同的delay值,完成不同的目的。
5 t. e+ ], z9 h% C
! u( J+ K5 A, _! a2 C51语言与汇编语言程序的混合编程
* G4 t8 {, E( Y& ^$ i
! }8 d  B3 P* ?. m, A0 [3 `4 Y    C51编译器能对C语言源程序进行高效率的编译,生成高效简洁的代码,在绝大多数场合采用C语言编程即可完成预期的目的。但有时为了编程直观或某些特殊地址的处理,还须采用一定的汇编语言编程。而在另一些场合,出于某种目的,汇编语言也可调用C语言。在这种混合编程中,关键是参数的传递和函数的返回值。它们必须有完整的约定,否则数据的交换就可能出错。下面就以力源公司的10位串行A/D转换器TLC1549 为例说明C语言程序与汇编语言程序的调用。                tjk_1.gif (1043 字节)
2 e% k7 h9 @# H# U7 g图1 TLC1549管脚图
' i- y1 [! B% Y2 }2 h+ G- y& t- N6 X4 o+ g" x' A
    1549的管脚图和时序图分别如图1和图2所示,假定DATA OUT接P1.0,CS   接P1.1,CLOCK接P1.2。1 ^# ^; z( t' h, W( L. T/ Q! F2 v
1549的具体特性请查阅有关资料。( K# d8 K$ {3 \* O! w! h- a
1 g& _8 ?7 ~$ E
 tjk_2.gif (3208 字节)% K8 [! y: J6 e  G& `

; \* G- G7 L& V5 ^图2 TLC1549时序图
' F* ?% k6 O) t$ b) N+ |& }% Y
0 p/ t- d! d/ M! v; R# i0 P    例2 C语言程序与汇编语言程序的调用,其子程序如下:- O: V; ]+ q2 s
' N4 \% @) U: k# a) Z- `
PUBLIC AD     ;入口地址
+ F4 d' P: g9 JSEG_AD SEGMENT CODE ;程序段 5 ]" [4 `! n3 A# Z) D
RSEG SEG_AD* T3 B$ H* \+ G, ^) m3 p: k
USING 0
' p/ `; V4 Y6 w$ F   AD:         MOV R6,#00
2 \5 e8 U" K( P# K5 R" d% d" ZMOV R7,#000 a6 h5 U- P0 @$ q& }
SETB P1.1
3 g* F) q0 {* r7 H1 DACALL DELAY% U( m7 m% G9 u1 i
CLR P1.1
3 O3 S, |6 k9 I8 g$ kACALL DELAY/ c$ O$ j& K( X) Q
MOV R0,#10: i) [) A6 o0 r% Y; j. j- {! D
   RR0:        SETB P1.2
3 |& C, X6 u3 `NOP4 D7 r* j6 m( z- ~6 w  x! n5 V- ]
CLR P1.2* s, q0 B" u$ m* O, u
DJNZ R0,RR0
; M, e( @/ P( |9 r& l( U7 FACALL DELAY2 a) i/ u" b( D% A7 }: `, t
MOV 30H,R6     ;A/D转换的高
3 w! L. L2 X# m6 ?              ;两位保存在R6中9 a. c5 k: ^7 R  P6 S) E5 b& z9 k
ACALL CIR$ S1 |6 y+ a  z( z/ w+ w* _
MOV R6,30H
' c* H& P7 i* b* N( F, Z$ j4 tSETB P1.2
5 J' S7 S% J& UNOP
8 P& M1 q  a2 x8 w2 cCLR P1.2
  s/ U  Z9 q3 a, BMOV 30H,R6
1 i  g3 _* X0 k' W9 [% W2 ^- SACALL CIR* `1 ~$ }& C% W
MOV R6,30H
" w, @# a9 A( l( D) S8 {+ r3 ~MOV R0,#8     ;A/D转换的低
+ E9 p4 A, ^  u- V' e" i1 ^             ;8位保存在R7中7 ^% ^; O4 t" W$ A3 g
   RR2:        SETB P1.2
$ o4 n& b1 e( |5 z$ i! S' UNOP' W9 a( E7 z& ?
CLR P1.2# }) Z1 N, c1 W% a
MOV 30H,R7
2 w. w: f. i/ f3 \ACALL CIR3 q" E5 C( F( ~, a9 z; V+ M8 v
MOV R7,30H
8 C/ o: U2 A7 T* A4 T, v+ ADJNZ R0,RR2
  ?) r$ {5 _# P5 d- E+ \8 C9 iRET0 N1 E6 x/ A5 ]0 ^1 x! {. I
   CIR:        CLR C
0 x' [. A( h' y0 h6 o4 @MOV C,P1.0
2 {6 W! n5 k0 l1 t+ t  F# s( ?MOV A,30H
, k& p- h0 g# e- r$ {RLC A5 I  _6 N# N7 g% ~+ O
MOV 30H,A
' V9 [  L* t  I0 b4 Q: ~RET& x: R/ w( s4 n$ ?# s! p$ [
END# |, `. B& D' f) r0 c8 E
    在以上程序中,函数的返回值为一无符号整型数,根据调用规则,返回值的高位必须在R6中,低位在R7中,这样才可保证数据的传递不出错。另外,在调用过程中,必须注意寄存器的入栈。这样在以后用到A/D转换时,在C语言中调用汇编语言子程序AD()即可。 
0 S3 A; r; C6 f0 q9 o$ f4 L4 D* T; q2 A0 O+ M* a
3 C51中断处理过程
6 ?; [6 m4 S, B. [  a; U. J
- N; L' {$ U) s. u    C51编译器支持在C源程序中直接开发中断过程,因此减轻了使用汇编语言的繁琐工作,提高了开发效率。中断服务函数的完整语法如下:7 J, u4 s) C& c0 g; W2 g3 f

5 S" p+ @/ o: g! ]- I' h) v    void 函数名(void)[模式]( ~  L1 D; l8 ^5 ?* v# g
    [再入]interrupt n [using r]
' I7 Q+ n% U) c8 Z* X* u5 U8 O( c/ L6 u( w8 P4 _
    其中n(0~31)代表中断号。C51编译器允许32个中断,具体使用哪个中断由80C51系列的芯片决定。r(0~3)代表第r组寄存器。在调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同。"再入"用于说明中断处理函数有无"再入"能力。C51编译器及其对C语言的扩充允许编程者对中断所有方面的控制和寄存器组的使用。这种支持能使编程者创建高效的中断服务程序,用户只须在C语言下关心中断和必要的寄存器组切换操作。
$ m6 D! Z* S' z' x3 X  a( P" j; N% j2 _- q7 Q, ~
    例3 设单片机的fosc=12MHz,要求用T0的方式1编程,在P1.0脚输出周期为2ms的方波。5 O2 ?5 E# C/ {' U; ]% R% |: e- p
% q3 V; U( x, j$ }8 b5 x/ _
    用C语言编写的中断服务程序如下:
! P  A* @2 H& F4 q. p, N  `6 X5 B
; ~% H& O0 K: s/ w' `' X! u3 y+ T#include <reg51.h>
  r" J& _/ l' U/ M* esbit P1_0=P1^0;
1 ]9 h; W' ^" O7 C, bvoid timer0(void)interrupt 1 using 1 {2 \/ }# _, ?$ L1 G
     /*T0中断服务程序入口*/
' o: d: x9 R: _5 j# p5 IP1_0=!P1_0;5 s$ M" r: {: M& s* e% r) n1 n/ ~
TH0=-(1000/256);      /*计数初值重装*/+ {& E1 z* y9 W2 N4 J
TL0=-(1000%256);5 ~9 y# G+ s& T2 r6 q' s! b
}. G; Q1 W( ~6 W# R; h  ]9 m4 D
void main(void)
" ~8 f0 x3 {! u2 R  g5 y" j' I) j{
, F2 x% q& @# e& W/ ^$ JTMOD=0x01;     /*T0工作在定时器方式1*/0 a+ L4 B; \; |& _. K/ ^; {
P1_0=0;
$ u* q$ z4 P9 @  T( R4 vTH0=-(1000/256);     /*预置计数初值*/
# C7 t. ^, R7 w6 {, x, x+ iTL0=-(1000%256);& T9 b: W- I4 i8 d! k1 h
EA=1;            /*CPU开中断*/" D" c, z8 t* K% W
ET0=1;           /*T0开中断*/7 F$ U5 O( v* Y0 h+ O
TR0=1;           /*启动T0*/
( v) t2 b+ c6 n1 }do{}while(1);
3 O& {8 V* D! y! I8 c! }3 [}' }1 }. ~/ m9 \/ R- g  j
  在编写中断服务程序时必须注意不能进行参数传递,不能有返回值。' \$ ~8 y9 I6 A1 |
" @% N+ N: o9 Z" Q2 Z. Z4 w$ _
4 结论
# e. M  A& B/ B. x, M7 T6 g( t+ z: Q/ W. [2 T/ G+ w+ ]8 h% t7 p* w
    C51编译器不但可以缩短单片机控制系统的开发周期,而且易于调试和维护。此外,C51语言还有许多强大的功能,如提供丰富的库函数供用户直接调用,完整的编译控制指令为程序调试提供必要的符号信息等等。总之,C51语言是广大单片机开发人员的强有力的工具。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 支持!支持! 反对!反对!

183

主题

642

帖子

1350

积分

四级会员(40)

Rank: 4Rank: 4Rank: 4Rank: 4

积分
1350
2#
发表于 2016-8-10 09:21 | 只看该作者
支持楼主!谢谢分享!- Y* U9 S* X5 v& f0 |+ P# |
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

巢课

技术风云榜

关于我们|手机版|EDA365 ( 粤ICP备18020198号 )

GMT+8, 2024-11-15 14:42 , Processed in 0.057580 second(s), 32 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表