单片机c语言1ms 2ms 4ms方波,48+汇编语言和C语言.ppt

本文详细介绍了在8051单片机环境下,如何使用C51语言与汇编语言进行混合编程。主要内容包括:不同语言模块的结合方式,C语言调用汇编函数的注意事项,如参数传递、函数声明和内存管理。通过实例展示了如何在C语言主程序中调用汇编子程序来实现特定功能,如产生周期方波,并探讨了高效C语言编程的策略,如变量定位和数据类型的选取。此外,还提供了混合编程的编译连接方法和调试步骤。
摘要由CSDN通过智能技术生成

4 8汇编语言和C语言的混合编程 本节介绍不同的模块 不同的语言相结合的编程方法 通常情况下以高级语言编写主程序 用汇编语言编写与硬件有关的子程序 不同的编译程序高级语言对汇编的调用方法不同 在FranklinC51中 是将不同的模块 包括不同语言的模块 分别汇编或编译 再通过连接生成一个可执行文件 C语言程序调用汇编语言程序要注意以下几点 1 被调函数要在主函数中说明 在汇编程序中 要使用伪指令使CODE选项有效并声明为可再定位段类型 并且根据不同情况对函数名作转换 见表4 6 2 对为其他模块使用的符号进行PUBLIC声明 对外来符号进行EXTRN声明 3 参数的传递 在混合语言编程中 关键是入口参数和出口参数的传递 FranklinC编译器可使用寄存器传递参数 也可以使用固定存贮器或使用堆栈 由于8XX51的堆栈深度有限 因此多用寄存器或存贮器传递 用寄存器传递最多只能传递三个参数 选择固定的寄存器 见表4 7 表4 7 例如func1 inta a 是第一个参数 在R6 R7传递 func2 intb intc int d b 在R6 R7中传递 c 在R4 R5中传递 d 在R1 R2 R3中传递 如果传递参数寄存器不够用 可以使用存贮器传送 通过指针取得参数 汇编语言通过寄存器或存贮器传递参数给C语言程序 汇编语言通过寄存器传递给C语言的返回值见表4 8 下面通过两个实例说明混合编程的方法及参数传递过程 例4 10用P1 0产生周期为4ms的方波 同时用P1 1产生周期为8ms的方波 说明 设计三个模块模块一C语言编主程序 使P1 1产生周期为8ms的方波 模块二用C语言编程 使P1 0产生周期为4ms的方波 模块三用汇编语言编写延时1ms程序 模块一调用模块二获得8ms方波 模块二调模块三 向汇编程序传递字符型参数 x 2 延时2ms 各模块程序如下 模块一 P1 1产生周期为8ms的方波 include defineucharunsignedchar sbitP1 1 P1 1 voiddelay4ms void 定义延时4ms函数 模块二 main uchari for P1 1 0 delay4ms 调模块二延时4ms P1 1 1 delay4ms 调模块二延时4ms 模块二 delay4ms 使P1 0产生周期为4ms的方波 include defineucharunsignedchar sbitP1 0 P1 0 delaylms ucharx 定义延时1ms函数 模块三 voiddelay4ms void P1 0 0 delaylms 2 调汇编函数 模块三 P1 0 1 delaylms 2 调汇编函数 模块三 模块三 PUBLIC DELAY1MS DELAY1MS为其他模块调用 DESEGMENTCODE 定义DE段为再定位程序段RSEGDE 选择DE为当前段 DELAY1MS NOP DELA MOVR1 0F8H 延时 LOP1 NOP NOPDJNZR1 LOP1 DJNZR7 DELA R7为C程序传递过来的参数 x 2 EXIT RET END 上例可见汇编语言程序从R7中获取C程序传递参数 x 2 例2 在汇编程序中比较两数大小 将大数放到指定的存储区 由C程序的主调函数取出 C语言程序 模块一 defineucharunsignedchar voidmax uchara ucharb 定义汇编函数 main uchara 5 b 35 c d c 0 x30 c指针变量指向内部RAM30H单元 max a b 调汇编函数 a b为传递的参数 d c d存放模块二传递过来的参数 模块二 汇编语言程序PUBLIC MAXMAX为其他模块调 DESEGMENTCODE 定义DE段为再定位程序段 RSEGDE 选择DE为当前段 MAX MOVA R7 取模块一的参数a MOV30H R5 取模块一的参数b CJNEA 30H TAG1 比较a b的大小 TAG1 JCEXIT MOV30H R7 大数存于30H单元 EXIT RET END 可见 C语言程序通过R7和R5传递字符型参数a和b到汇编语言程序 汇编语言程序将返回值放在固定存贮单元 主调函数通过指针取出返回值 C语言程序调用汇编程序最多只能传递三个参数 如果多于三个参数 就需要通过存贮qu区传递 这就需要在汇编程序中建立数据段 在下例中C语言程序向汇编传递六个参数 汇编程序 C CALL C pragmacodesmallexternintafunc charv a charv b charv c charv d charv e charv f 外来函数说明voidC call void charv a 0 x11 传递参数赋值 charv b 0 x18 charv c 0 x33 charv d 0 x44 charv e 0 x55 charv f 0 x98 intdata aa 指针变量指向int型data区 intA ret 存汇编返回结果的变量 aa 0 x30 置指针 A ret afunc v a v b v c v d v e v f 调汇编函数 aa A ret 取汇编返回结果 aa int 0 为方便观察改值 强制0为int型 aa A ret 再次观察汇编返回结果 voidmain void 主函数 chara1 a2 a3 为方便观察设a1a2a3 a1 0 a2 2 a3 3 C call a1 1 a2 3 while 1 AFANC ASM PR AFUNCSEGMENTCODE 名为AFUNC段为代码段 PR 在CODE区可再定位 DT AFUNCSEGMENTDATAOVERLAYABLE 名为AFUNC段为数据段 DT 在DATA区 可再定位 可以覆盖PUBLIC afunc BYTE 公共符号定义PUBLIC afuncRSEGDT AFUNC afunc BYTE 数据段保留参数传递区v a DS1v b DS1v c DS1v d DS1 v e DS1v f DS1RSEGPR AFUNC afunc USING0 程序段MOVA R7 取R7中的v aADDA R5 取R5中的v bADDA R3 取R3中的v cADDA v dADDA v eADDA v fMOVR7 A 和存R7 进位存R6MOVA 0 以便返回RLCA MOVR6 ARETEND编译连接方法以上各模块可以先分别汇编 A51 和编译 C51 选择DEBUG编译控制项 生成的 OBJ文件 然后运行L51将各OBJ文件连接 生成一个新的文件 在集成环境下的连接调试可以连续进行 比上面方法更为方便 现使用wave 伟福 的仿真软件ICExplorerW ICEForWindows 的编译连接步骤如下 1 编辑好各个模块 保存 2 点击文件 新建项目 弹出项目窗口 3 点击项目菜单 选加入模块 此时弹出有文件目录的对话框 选中要加入刚才编辑好的文件 模块 并打开 此时在项目窗口中可以看到加入的模块文件 4 点击项目菜单中的全部编辑 并取名保存项目 于是系统对加入各模块进行编译 并进行连5 编译连接完成会弹出信息窗口 如编译连接有错 信息窗口将出现错误信息 6 模块连接成功 生成二进制文件 BIN 和十六进制文件 HEX 7 点击跟踪或单步按钮 就可对程序进行跟踪调试 程序运行到不同模块时 wave就会弹出相应的模块源程序窗口 显示程序运行情况 4 9小结本章介绍了C51的基本数据类型 存贮类型及对C51对单片机内部部件的定义 并介绍了C语言基础知识 最后通过编程实例介绍了各种结构的程序设计 以上是利用C语言编单片机程序的基础 都应该掌握并灵活应用 只有多编程 多上机才能不断提高编程的能力 如何编写高效的C语言程序 通常应注意以下问题 1 定位变量 经常访问的数据对象放入在片内数据RAM中 这可在任一种模式 COMPACT LARGE 下用输入存贮器类型的方法实现 访问片内RAM要比访问片外RAM快得多 在片内RAM由寄存器组 位数据区 栈和其它由用户用 data 类型定义的变量共享 由于片内RAM容量的限制 128 256 字节 由使用的处理器决定 必须权衡利弊以解决访问效率和这些对象的数量之间的矛盾 2 尽可能使用最小数据类型MCS 51系列单片机是8位机 因此对具有 char 类型的对象的操作比 int 或 long 类型 的对象方便得多 建议编程者只要能满足要求 应尽量使用最小数据类型 C51编译器直接支持所有的字节操作 因而如果不是运算符要求 就不作 int 类型的转换 这可用一个乘积运算来说明 两 char 类型对象的乘积与8XX51操作码 MULAB 刚好相符 如果用整型完成同样的运算 则需调用库函数 只要有可能 使用 unsigned 数据类型 8XX51单片机的CPU不直接支持有符号数的运算 因而C51编译必须产生与之相关的更多的代码以解决这个问题 如果使用无符号类型 产生的代码要少得多 只要有可能 使用局部函数变量 编译器总是尝试在寄存器里保持局部变量 这样 将索引变量 如FOR和WHILE循环中计数变量 声明为局部变量是最好的 这个优化步骤只为局部变量执行 使用 unsignedchar int 的对象通常能获得最好的结果

展开阅读全文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值