keil C语言编程 位地址定义,Keil C编写下位机程序的小技巧和注意点
1. 用C直接操作DPTR方式
我们平常用Keil C访问总线一般是定义 unsigned char xdata *fardptr; fardptr=0xbf00; *fardptr=0; 来访问,这就涉及到一个问题:首先增加一个占两个字节的变量,其次是每次系统多了一个赋值给这个变量,不论你是否要用这个用量。用汇编操作总线 MOVX A,@DPTR 和MOVX @DPTR,A,我们可以用混汇编方法是可以插入,但象这种类似操作多了,代码看起来不清晰,还有一种办法:
我们先定义一个宏:#define dptr(n) (*((unsigned char xdata *)n)) 然后我们就可以象写函数一样
dptr(0xbf04)=0;
dptr(0xbf05)=0xff;
dptr(0xbf06)=0x18;
这种方式用Keil C 编译成的实际形式就是:
MOV DPTR,#0BF04H
CLR A
MOVX @DPTR,A
INC DPTR ;这里Keil c自动优化为INC ,而不是 MOV DPTR ,#0BF05H,使执行速度更快
MOV A,#0FFH
MOVX @DPTR,A
INC DPTR
MOV A,#018H
MOVX @DPTR,A
这种写法是和直接汇编的效率是一样高的!但反过来行不行呢?
unsigned char m;
dptr(0xbf04)=0; m=dptr(0xbf05); 编译后得到: MOV DPTR,#0BF04H
CLR A
MOVX @DPTR,A
INC DPTR
MOVX A,@DPTR
MOV m,A
效率看起来好象真不错呢!但这里有一种潜在的BUG,如我们要实现对写出去的总线再验证读的时候就出问题了,如:
do { dptr(0xbf00)=0; ACC=dptr(0xbf00); } while(!ACC0);
这段代码实际是送出总线值后再读回来,保证设置正确,但实际Keil C 编译后成了
?C0018:
MOV DPTR,#0BF00H
CLR A
MOVX @DPTR,A
MOV R7,A 这里不是 MOVX A,@DPTR
JNB ACC0,?C0018
如果真需要验证的情况下,显然没有达到我们的目的! 这种情况我一般是头文件里加 #define checkDPTR _asm MOVX A,@DPTR,在需要的时候(前后DPTR值不更改,ACC也没有再附值的时候)用于取出总线。大部分的时候,是可以这么取出来的。或者在程序过程如有加减运算(非加减1)或位运算后,累加器必参位运算,这时就可以用这种方法。程序的可读性就可大大提高的同时,保证效率。
2 循环的使用
看下面一段代码:
void SendSIOData2(const unsigned char value)
{
unsigned char i;
for(i=0,ACC=value;i<8;i++)
{
MCP2510_SCK2=0;
__asm RLC A
MCP2510_SI2=CY;
MCP2510_SCK2=1;
}
MCP2510_SCK2=0;
} 我相信至少一半的人会如此写这个循环,这种类似的代码在串行总线里是用得最多,也最可能占我们时间的,需要我们写出最经典的代码。但这种循环汇编后的代码是
CLR A
MOV R6,A
MOV A,R7
CLR MCP2510_SCK2 ......循环体省了
INC R6
CJNE R6,#08H,?C0005
如果我们把 for(i=0,ACC=value;i<8;i++) 改成 for(i=8,ACC=value;i!=0;i--) 呢?判断循环体就成了: MOV R6,08H 。。。DJNZ R6 ,?C0005
一个小小的编程习惯让我们在这里至少提高了10%-20%的效率。
keil C语言编程 位地址定义,Keil C编写下位机程序的小技巧和注意点相关推荐
- 单片机c语言too many actual parameter,keil c语言编程常见错误分析.doc
keil c语言编程常见错误分析.doc 1. Warning 280:'i':unreferenced local variable 说明局部变量i 在函数中未作任何的存取操作解决方法消除函数中i ...
- C语言编程>第十周 ⑧ 请编写函数fun,其功能是:将两个两位正整数x、y合并成一个整数放在z中。合并的方式是:将x的十位和个位依次放在z的十位和千位上,y十位和个位依次放在z的百位和个位上。
例题:请编写函数fun,其功能是:将两个两位正整数x.y合并成一个整数放在z中.合并的方式是:将x的十位和个位依次放在z的十位和千位上,y十位和个位依次放在z的百位和个位上. 例如,当x=12,y=3 ...
- C语言编程>第十四周 ⑦ 请编写一个函数fun,它的功能是:计算n门课程的平均分,计算结果作为函数值返回。
例题:请编写一个函数fun,它的功能是:计算n门课程的平均分,计算结果作为函数值返回. 例如,若有5门课程的成绩是88.92.80.61.5.55:则函数的值为75.30. 请勿改动主函数main与其 ...
- C语言编程>第十周 ⑦ 请编写函数fun,该函数的功能是:统计一行字符串中单词的个数,作为函数值返回。一行字符串在主函数中输入,规定所有单词由小写字母组成,单词之间由若干个空格隔开,一行……
例题:请编写函数fun,该函数的功能是:统计一行字符串中单词的个数,作为函数值返回.一行字符串在主函数中输入,规定所有单词由小写字母组成,单词之间由若干个空格隔开,一行的开始和结尾都没有空格. 请勿改 ...
- C语言编程>第二十二周 ③ 下列给定的程序中,函数fun的功能是根据整型形参n,计算如下公式的值:
例题:下列给定的程序中,函数fun的功能是根据整型形参n,计算如下公式的值: 例如,若n=1000,则应输出0.000155. 注意:不要改动main函数,不能增行或删行,也不能更改程序的结构. 代码 ...
- C语言编程>第十一周 ⑤ 请编写一个函数,用来删除字符串中的所有空格。
例题:请编写一个函数,用来删除字符串中的所有空格. 例如,输入we l come,则输出为welcome. 请勿改动主函数main与其它函数中的任何内容,仅在函数fun的花括号中填入所编写的若干语句. ...
- C++ 网络编程下的socket编程(TCP\UDP),连接下位机
正常情况下我们需要对下位机进行通信需要使用Socket进行连接操作,而在网络编程中又分为面向连接(TCP)和面向无连接(UDP)这两种,针对这两种方式,我们不做具体的原理解释,只说各自的特点和各自的应 ...
- 编程技术分享,程序员小技巧,程序员小伙伴们,你们用到了多少
程序员的工作就是日复一日的敲代码,每天走着重复的生活,在这枯燥的码代码生活中会让很多的程序员抓狂,那么怎样才能在这无味的生活中找到一丝的乐趣呢?我感觉还是态度问题,拥有自始至终的态度,并且附加一些编程 ...
- efm8系列单片机c语言编程,EFM8单片机用Keil编程,头文件怎么写?
找到头文件了,如下:(芯片为Silicon Laboratories的EFM8UB10F16G) 需要用到P1口,头文件中这样定义P1口"SI_SFR (P1, 0x90); ...
最新文章
- 网站推广专员浅析网站建设实用技巧助力网站推广优化
- ApplicationEventPublisherAware--待完善
- Java 8 - 收集器Collectors
- MFC 基础知识:主对话框与子对话框(二)
- python矩阵左除_matlab学习笔记
- uva 120——Stacks of Flapjacks
- Java多线程实现异步调用
- 【Python3网络爬虫开发实战】1.5.3-redis-py的安装
- day23 内置函数,匿名函数,递归
- MySQL中 Data truncated for column ‘xxx‘解决方法
- 计算机装系统找不到硬盘分区,u盘装系统找不到硬盘分区的处理方法
- dimm和udimm_RDIMM和UDIMM内存的区别
- 微信小程序数据库操作之更新数据(转载)
- 磁盘阵列RAID卡组建设置
- 农林牧渔行业S2B2C系统网站提升品牌知名度,提升盈利水平
- 歌曲影视随意赏计算机课件,世界影视音乐赏析课件.ppt
- 德州大学达拉斯分校计算机工程,“你的留学故事”| 德克萨斯大学达拉斯分校交换生感悟...
- JAVA求三角形的面积
- 将bios中的boot mode 从uefi改为legacy之后,进不去bios
- IDEA插件系列(18):Translation插件——翻译插件
热门文章
- ESP32-WROOM-32 ESP32 wifi模块基本参数与引脚定义
- 蔚来:汽车行业变革时代的人才招聘与培养战略
- 商业化广告--体系学习-- 10 -- 业务实战篇 -- 效果优化:如何一步步从提升曝光量深入到提升销量?
- QT学习笔记(六)——QT弹出对话框并在主窗口调用对话框的信息
- 获取微信公众号的二维码图片
- 软工网络15个人作业3——案例分析
- HTML 信息隐藏与提取
- sun oracle服务器登管理口,Sun Solaris系统管理命令对照简介
- 【总结-学习-提升】web应用为什么需要tomcat容器
- html 拓扑图 开源,GitHub - pylixm/zJTopo: 开源拓扑图工具类jTopo的扩展,jtopo是一个不错的拓扑图,基于html5 canvas,功能强大...