单片机c语言与汇编语言转换,浅谈单片机中C语言与汇编语言的转换
做了一单片机设计,要用C语言与汇编语言同时实现,现将这次设计的感受和收获,还有遇到的问题写下,欢迎感兴趣的朋友交流想法,提出建议。
单片机设计:基于51单片机的99码表设计
软件环境:Proteus8.0 + Keil4
要求:1,开关按一下,数码管开始计时。2,按两下,数码管显示静止。3,按三下,数码管数值清零。
C语言程序如下:
#include
#define uint unsigned int
#define uchar unsigned char
uchar shi,ge,aa,keycount=0,temp;
sbit anjian=P1^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void display(shi,ge);
void key ();
void init();
void delay(uint z);
/*-----主程序-----*/
void main()
{
init(); //初始化
while(1)
{
key ();
if(keycount==1)
TR0=1; //开中断
if(keycount==2)
TR0=0;
if(keycount==3)
{
temp=0;
keycount=0;
}
if(aa==10){aa=0;
if(temp<=99)
{
temp++;display(shi,ge);
}
else
temp=0;}
}
}
/*------初始化程序-------*/
void init()
{
keycount=0;
temp=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
//TR0=0;
}
/*-----定时器中断-----*/
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
/*-----显示子程序-----*/
void display(shi,ge)
{
shi=temp/10;
ge=temp%10;
P0=table[shi];;delay(70);
P2=table[ge]; ;delay(70);
}
/*-----按键检测子程序-----*/
void key ()
{
if(anjian==0)
{
delay(5); //消抖
if(anjian==0)
keycount++;
}
//while(anjian==0);
//display(shi,ge); //等待按键弹起
}
/*-----延时子程序-----*/
void delay(uint z) //延时约1ms
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
电路仿真结果如下:
好了,那么接下来我们就开始C语言——>汇编语言之旅^_^
(1)C语言1-10行改为
ORG 0000H //汇编起始伪指令,功能是规定程序存储器中源程序或数据块存放的起始地址
ajmp STAR //ajmp无条件跳转指令
ORG 000bh
ajmp timer0
anjian equ P1.7 //位定义
keycount equ 40h
shi equ 41h
gewei equ 42h
aa equ 43h
temp equ 44h
tab: db 3fh,6h,5bh,4fh,66h //建表
db 6dh,7dh,7h,7fh,6fh
(2)C语言中的初始化函数 12-14行和39-49行改为
1 STAR: 2 acall init //子程序近程调用指令,功能是主程序调用子程序,调用子程序的范围为2kb
init:
mov keycount,#0 //keycount=0
mov temp,#0 //temp=1
mov tmod,#01h //TMOD=0x01
mov TH0,#60
mov TL0,#176
setb EA //位置位指令,对操作数所指出的位进行置1操作
setb ET0
setb TR0
ret
acall为子程序近程调用指令,返回用ret。
(3)C语言中15-35行是个while循环,逻辑比较繁琐,注意了!
START:
acall display
inc temp //加1指令,将操作数所指定的单元或寄存器中的内容加1
acall delay70 //近程调用delay70
x8: mov r0,keycount
cjne r0,#2,F1 //cjne比较跳转指令,若r0=2则跳转到x8,否则跳转到F1。
ajmp x8
F1: mov r0,temp
cjne r0,#99,START //若r0<99时,重复循环,否则temp=0
mov temp,#0
ajmp START
F9:
acall key
mov r0,keycount
cjne r0,#0,F2 //keycount=0顺序执行,否则跳转到F1
CLR P1.3 //清0
SETB TR0
F2: mov r0,keycount //第二次按键
cjne r0,#2,F2
clr TR0
reti
mov r0,keycount //第三次按键
cjne r0,#3,F3
mov temp,#0
mov keycount,#0
inc增量指令,功能是将操作数所指定的单元或寄存器中的内容加1,其结果返还回原操作数单元中。
clr位复位,功能是对操作数所指出的位进行清“0”操作。
或者在中断函数中
timer0:
w1:
acall key
mov TH0,#60
mov TL0,#176
cpl p1.0
JB keycount,x2
ajmp x3
x2:
ajmp START
clr p1.0
ajmp w1
ajmp w1
x3: mov r0,keycount
cjne r0,#3,w1 //若r0=3则顺序执行,否则跳转到w1
mov temp,#0
mov keycount,#0
ret
(4)C语言58-64行display函数改为
display:
mov a,temp
mov b,#10
div ab //除法指令,实现两个八位无符号数的除法操作。
mov r2,A
mov r3,B
mov dptr,#tab //16位数据传送使用方式
mov a,r2
movc a,@a+dptr //查表,先将累加器A的内容与数据指针寄存器DPTR的内容相加,再以其结果为地址,将该地址的结果送入A中
mov P0,a
acall delay70
nop //空指令
mov a,r3
movc a,@a+dptr
mov P2,a
nop
acall delay70
ret
div为除法指令,功能是实现两个8位无符号数的除法操作,一般被除数放在累加器A中,除数放在寄存器B中。指令执行后,商放在A中,余数放在B中。
movc为查表指令,先将累加器A的内容与数据指针寄存器DPTR的内容相加,再以其结果为地址,将该地址的内容送入A中。
nop为空操作指令,它不作任何操作,但要占用一个机器周期(即12个振荡周期)的时间,常用于延时或等待。(有些程序执行的效果由于延时时间太短,在人眼视觉暂时作用下无法辨认清楚)
此段程序的作用在于将一个两位数分别分在一个十位上的数码管和一个个位上的数码管显示。
(5)C语言66-76行key函数改为
1 key:2 jb anjian,F6 //若anjian=0则顺序执行,否则跳转到F63 ACALL delay54 inc keycount //keycount++5 F6: 6 ret
jb为位条件转移指令,功能是若直接寻址的位bit=1,则程序转移到指定的目标地址去执行,若bit=0,则程序顺序执行。
(6)C语言78-83行delay函数改为
delay70:
mov r6,#70
D2: mov R7,#248
d1: djnz R7,d1 //248*70次
djnz R6,D2
ret
delay5:
mov r6,#5 //消抖。
F7: mov R7,#248
F8: djnz r7,F8 //248*5次
djnz r6,F7
ret
注意:248=2 8 ,约等于1ms。delay为延时程序。
温馨提示:在汇编中程序代码的大小写不受影响,但在C语言中就有影响了。
思考1:ret和 reti都是程序返回指令,有什么区别?
我的回答:ret是子程序返回指令,reti是中断子程序返回指令。区别在于如果是acall、lcall指令调用的子程序,返回指令就用ret;如果地址是0003,0013,000B,001B,0023调用的子程序,返回指令就用reti。
思考2:mov 20h,#0h和 setb 20h都是加1,用什么区别?
我的回答:mov指令中的20h指字节,setb中的20h是位。
旅途结束!
还记得前段时间我一直纠结于汇编语言中的各种指令的语法和功能,直到一个阳光明媚的中午,我一手拿着已经写好的两页半的C语言代码,一手拿着一本单片机的汇编指令查询手册,开始一行一行的翻译,可能汇编代码会在调试中有所错误,但基本逻辑是对的。而且这次C——>汇编,使我更加深入地理解了数据在计算机中的存储与调用。在此期间班主任和同学也给我答疑解惑,相信在以后的道路上,我会更加更深入地理解计算机。越努力,越幸运!
end
单片机c语言与汇编语言转换,浅谈单片机中C语言与汇编语言的转换相关推荐
- 考研考c语言程序设计的军校,浅谈军校学员C语言程序设计的教学现状及教法改进...
塞熬宣 浅 谈 军 校 学 员 语 言 程 序设 计 的教 学 现 状 及 教 法 改进 邓静 寰 (成 都 市 华 阳镇 武 警 指挥 学 院 四川 成 都 ) 摘 要:本 文从 当前军校学 员 语 ...
- c语言游戏人物结构buff,浅谈游戏中BUFF的设计要点
from http://www.gameres.com/msg_225241.html 其实这类帖子并没有多少的设计理论,对于策划的提升和帮助也并不大,原因其实在于其适用性太窄,当我要设计XX象棋的时 ...
- 浅谈单片机程序设计中的“分层思想”!
浅谈单片机程序设计中的"分层思想",并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用.看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种 ...
- c语言在数学方面的应用编程,浅谈数学在C语言编程中的应用.doc
浅谈数学在C语言编程中的应用 浅谈数学在C语言编程中的应用 [][]C语言对学习者的数学基础要求较高对一部分学生来说学好C语言有一定的困难.本文就本专业知识和自身对C语言的学习经验对数学在C语言编程中 ...
- 对计算机辅助英语的看法,浅谈利用计算机辅助英语语言测试
摘要:随着计算机技术不断深入发展,给我们的生活和学习带来了翻天覆地的变化,越来越多的学校利用计算机辅助各学科进行教学,对计算机教学设施的配备与老师掌握计算机技术方法的要求越来越高.尤其是利用计算机进行 ...
- 浅谈单片机低功耗处理
浅谈单片机低功耗处理 一.什么是低功耗处理 我们在研发电子产品的时候,经常会涉及到功耗的问题.因为电子产品肯定是要供电的,供电的方式最常用的几种是:220V交流直插供电.用直流适配器供电和电池供电.无 ...
- python中 是什么类型_浅谈python中的变量默认是什么类型
浅谈python中的变量默认是什么类型 1.type(变量名),输出的结果就是变量的类型: 例如 >>> type(6) 2.在Python里面变量在声明时,不需要指定变量的类型,变 ...
- 浅谈CTF中各种花式绕过的小trick
文章目录 浅谈CTF中各种花式绕过的小trick 前言 md5加密bypass 弱比较绕过 方法一:0e绕过 方法二:数组绕过 强比较绕过 方法:数组绕过 md5碰撞绕过 方法:使用Fastcoll生 ...
- php css定位到图片上,CSS_浅谈css中图片定位之所有图标放在一张图上,如今做网页为了使网站丰富多 - phpStudy...
浅谈css中图片定位之所有图标放在一张图上 如今做网页为了使网站丰富多彩,富于表现力,往往需要应用大量的图片/图标.如何处理这些图片,使其尽量不影响网页载入,解析等速度,是一个不大不小的问题.如果你的 ...
- java 中的单元测试_浅谈Java 中的单元测试
单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...
最新文章
- 使用异步 I/O 大大提高应用程序的性能
- 1995 年乔布斯访谈:什么对产品最重要
- pytorch教程龙曲良11-15
- 读《系统虚拟化-原理与实现》-第三章
- 前端学习(568):元素定高 容器定高 为什么不能居中
- 【JS 逆向百例】当乐网登录接口参数逆向
- jquery 鼠标事件汇总
- Tensorflow2.0(2):中文分词(jieba)
- TdxAlertWindowManager右下角HINT显示控件
- vue设置页面滚动高度_vue中获取滚动高度或指定滚动到某位置
- 类的加载顺序(例题)
- Tomcat8+redis实现session共享
- js 实现单击、双击事件
- SSH连接树莓派+设置开机自启动程序
- Straight lines have to be straight
- iphonex 测试电池软件,iPhoneX电池容量多大 iPhoneX电池性能评测【详解】
- 2020第四届全球程序员节观后感
- 刷脸支付无人便利店的使用体验也更好了
- python做的游戏放到微信_【1、 创建一个python的文件,运行后,文字版方式模拟微信游戏“跳一跳?】...
- html页面中加skype,分享个刚学会的电子邮件中加Skype即时联络标签的方法~有用请顶...