C51 汇编和C语言编写从1加到100
编写第一个程序
创建项目的方式:
创建一个项目:Project - New μVision Project... 以新建项目
创建项目文件夹:在目录下创建一个文件夹,它将容纳将来所有的项目
(注意:所有路径均不能包含中文字符,下同)
创建项目文件夹:为你的项目取一个名字,打开文件夹
创建项目解决方案:该文件名可以和外面的一样,然后点击保存。
为你的项目选择设备:如果你选择STM32F10x系列,就在software里找,如果是单片机,需要下拉列表找到Legacy Device Database[no RTE],然后搜索51,找到AT89C51芯片,点击ok。
然后会弹出选项框:问我们是否拷贝51单片机的启动文件到当前项目目录中并把它添加到项目里。这个文件是c语言的启动文件,帮助程序找到main函数并执行的。简而言之如下:
如果用汇编编写51程序,就不需要拷贝,点【否】
如果用C语言编写51程序,就需要拷贝,点【是】
【启动文件详解传送门】C51启动文件详解_wang0901的专栏-CSDN博客
点【是】则会发现多一个启动文件,打开是这个样子的:
创建代码文件:之后打开目录层次,我们右键source group 添加一个项,选择C文件或者asm文件(取决于你想用什么语言,因为刚才选了否,我们选择asm文件),然后起一个名字,点击Add。
然后就可以愉快地编写程序了!
编写1加到100的汇编程序
首先分析,1+2+···+100结果是5050,大于255,因此8位不够,16位才够,需要进行16位加法add16子程序的编写:低位和低位半加,高位和高位全加。子程序需要确定传参方式,这里选择比较简单的寄存器传参;无论如何子程序调用和释放至少需要压入PC的值,是需要堆栈的设置SP为60H。
由于是第一个程序,我们对代码进行详细分析:
(1)声明变量(也有说法说这不是变量,这里就当作起个名字)
HB EQU 30H;代表和的高8位
LB EQU 31H;代表和的低8位
LP EQU 32H;代表加数,因为一直加到100,即64H,因此8位够表示
Q1:为什么从30H开始,30H有什么讲究吗?
A1:因为30H以下不属于用户RAM区。C51片内数据存储器的组成如下:
30H~7FH 用户RAM区(堆栈、数据缓冲区)
20H~2FH 可位寻址区
00H~1FH 平均分配有4组工作寄存器区
Q2:为什么EQU没有运行?
A2:EQU是汇编伪指令,不生成机器码。
(2)初始化操作
ORG 0;标记下一条指令在0000H
JMP MAIN;由于上电复位后的程序入口地址0000H,因此执行指令,并跳转到Main
ORG 30H;标记下一条指令在0030H,为了跳过中断向量表区域.MAIN: ....................
Q1:ORG是不是执行不到?JMP MAIN都跳走了,还怎么执行?
A1:ORG本来就是伪指令,是标记下一指令存在ROM中什么位置的,根本就不生成机器码,也不会被执行到。
Q2:为何在之前要标记为00H?
A2:00H是上电复位后的程序入口地址,标记下一条为执行的第一条指令。(不写也不会报错,因为系统自动从0开始,属于是规范。)
Q3:为何又标记为30H?这个30H和上面的30H是一个意思吗?
A3:赋值30H是因为ROM中00H~30H有如下中断向量表,不应覆盖(不同于之前的RAM):
外部中断0 | 0003H |
定时器/计数器T0 | 000BH |
外部中断1 | 0013H |
定时器/计数器T1 | 001BH |
串行口 | 0023H |
(3)子程序的书写
ORG 0060H
ADD16:
CLR C;先清除进位标志
MOV A,R4
ADD A,R6
MOV R6,A;低位加法,加完存在R6中
MOV A,R5
ADDC A,R7
MOV R7,A;高位加法,加完存在R7中
RET
END
首先标记为60H的程序地址(这个应该是估测,实际主函数只写到了0x52)。先做低位加法,再做高位带进位加法。
(4)主程序的书写:
ORG 30H;跳过中断向量表区域
MAIN:
MOV A,#60H
MOV SP,A;入栈操作后sp-2,出栈操作后sp+2。mov sp,#60H 的意思是设置堆栈的长度为60H byte
CLR A
MOV HB,A;给HB赋个0
INC A
MOV LB,A;给LB赋个1
MOV LP,#2;给LP赋个2
LOOP:
MOV R7,HB;加数高八位
MOV R6,LB;加数低八位
MOV R5,#0;由于16位加法,加和上限为100,故高八位为0
MOV R4,LP;加数,代表1,2,3,...,100
CALL ADD16;调用子程序
MOV HB,R7
MOV LB,R6;R6,R7写回内存
INC LP;加数加一
MOV R0,LP;将LP放入寄存器
CJNE R0,#101,LOOP;进行寄存器比较
JMP $;陷入死循环,启动中断服务程序,程序终止
设置栈顶位置为60H,这个是因为元素入栈操作后sp-2,出栈操作后sp+2,低地址存放着栈顶元素,而高地址存放着栈底元素造成的,60H即申请了一块比较大的堆栈空间。
中间给几个寄存器赋值没什么好说的,存入操作数。LOOP前4句是给寄存器赋值,相当于子程序的寄存器传参。
CALL是调用子程序的关键字,这个子程序无论写在该文件的哪里都能被访问到。
做完加法写回内存,将内存中LP(又是加数,又是自增的变量,相当于for循环中的i),与101立即数比较,CJNE,如果不为101则转LOOP(相当于80x86中的JNE)
JMP $中,jump表示跳转,$表示当前程序指针的位置。跳转到当前程序指针的位置什么意思?该指令会反复执行JMP $,直到启动中断服务程序。因此也就结束了这个程序的运行。
综上所述,代码如下:
;00H~1FH依次排列4个工作寄存器区;20H~2FH存放着可位寻址区;用户RAM区从30H开始到7FH,因此从30H存数据。HB EQU 30H;代表和的高8位LB EQU 31H;代表和的低8位LP EQU 32H;代表加数,因为一直加到100,即64H,因此8位够表示ORG 0;上电复位后的程序入口地址0000HJMP MAIN;跳转到MainORG 30H;跳过中断向量表区域
MAIN: MOV A,#60HMOV SP,A;入栈操作后sp-2,出栈操作后sp+2。mov sp,#60H 的意思是设置堆栈的长度为60H byteCLR AMOV HB,A;给HB赋个0INC AMOV LB,A;给LB赋个1MOV LP,#2;给LP赋个2
LOOP:MOV R7,HB;加数高八位MOV R6,LB;加数低八位MOV R5,#0;由于16位加法,加和上限为100,故高八位为0MOV R4,LP;加数,代表1,2,3,...,100CALL ADD16;调用子程序MOV HB,R7MOV LB,R6;R6,R7写回内存INC LP;加数加一MOV R0,LP;将LP放入寄存器CJNE R0,#101,LOOP;进行寄存器比较JMP $;陷入死循环,启动中断服务程序,程序终止ORG 0060H
ADD16:CLR C;先清除进位标志MOV A,R4ADD A,R6MOV R6,A;低位加法,加完存在R6中MOV A,R5ADDC A,R7MOV R7,A;高位加法,加完存在R7中RET
END
编写1加到100的C语言程序
前面步骤差不多,除了拷贝51单片机的启动文件和创建C文件以外,没有什么区别。
#include<stdio.h>
#include<reg51.h>#define OSC 11059200
#define BAUD 9600void main(void){
int i;
int result;
SCON=0x50;
TMOD=0x20;
TH1=TL1=256-(OSC/12/16/BAUD);
TR1=1;
TI=1;
for(i=0;i<=100;i++){
result+=i;
}
printf("%d",result);
while(1);
}
SCON=0x50:
SCON是串行口控制寄存器,0x50为16进制,转换成二进制是01010000,对应下附表,即将串行口控制寄存器设置为串行口工作方式1并允许中断接收数据。
附: scon寄存器结构表
SCON | SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
位地址 | 9FH | 9EH | 8DH | 9CH | 9BH | 9AH | 99H | 98H |
TMOD=0x20:
TMOD是定时/计数器方式控制寄存器,所以TMOD=0x20是将定时/计数器1设置为工作方式2.
TH1=TL1:
给定时/计数器1装初值,即确定定时时长,具体时间与晶振有关.
在方式2下,定时时间T与晶振频率fosc之间满足关系 ,反解得到 。因此如此赋值。
TR1=1:
定时器/计数器1(T1)的运行控制位,置1表示让这个定时器运作起来。(相当于开关开开)
TI=1:
TI是串口送数据完成标志,TI=1说明当前数据(1字节)已经通过串口发送出去了。这里是指数据发送允许标志,通常的发送完成写法如下:
SBUF = senddata; //senddata 是需要发送的数据
while(!TI); //当TI为0是,一直执行while死循环,当TI为1时,跳出while循环
TI=0; //清掉TI,为发送下个数据做准备。
接下来就是纯粹的c语言写法了,不多说了。
注意:
(1)for(int i=0;i<101;i++)是不被允许的,int i需要提前申明。
(2)printf语句是打印设备上的,运行完可以在serial windows打开,点击下面UART #1,可以看到打印了5050.
程序的调试
先build,检查无错误,再调试。
调试如下:
当然也可以点击run(F5)运行代替断点+CTRL+F10,运行结果为13BAH(=5050)
好了,以上就是这一小节讲解的keil5安装及第一个程序从1加到100。感谢友友们一键三连哦!
C51 汇编和C语言编写从1加到100相关推荐
- C语言编写程序,分别求100以内的奇数之和、偶数之和。(用for语句实现)
C语言编写程序,分别求100以内的奇数之和.偶数之和.(用for语句实现) 运行代码: #include <stdio.h> int main() {int i,odd=0,even=0; ...
- 使用C语言编写程序一个皮球从100米高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。求当它第10次落地时,共经过了多少米?第10次反弹多高?写出完整代码并给出解释并对代码作出注释...
使用C语言编写程序一个皮球从100米高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹.求当它第10次落地时,共经过了多少米?第10次反弹多高?写出完整代码并给出解释并对代码作出注释第10次落 ...
- c语言随机产生10个30 100,c语言编写随机产生10个100~200之间整数,幷按从大到小排序...
你所写的代码是正确的,想要查看,请用这个:includeint main(){char ch;scanf("%c",&ch);if(ch>='A'&ch){c ...
- python语言编写从一加到100_python学习: 如何循序渐进学习Python语言
大家都知道Python语言是一种新兴的编程语言.1989年,Python就由Guido van Rossum发明.Python一直发展态势很好. 原因有几点:1.跨平台性好.Linux.Windows ...
- C语言编写程序求1到100的和,C语言菜鸟基础教程之求1到100的和
题目:求1+2+3+--+98+99+100 (1)用数学方法求解 (2)编写C语言程序求解 解: (1)数学方法 S = 1+2+3+--+98+99+100 = (1+100) + (2+99) ...
- python语言编写从一加到100_Python-100-Days
Python - 100天从新手到大师 Python应用领域和就业形势分析 简单的说,Python是一个"优雅"."明确"."简单"的编程语 ...
- 用c语言编写程序,求∑(k=1~100)k+∑(k=1~50)k2,c语言程序,求(100∑k=1 k)+(50∑k=1 k^2)+(10∑k=1 1/k) 这...
满意答案 myhso 2015.10.31 采纳率:54% 等级:8 已帮助:1060人 主函数main没有定义,在c语言中 两个整数相除返回整数 1/1 结果为 1 ,1/2,1/3结果为0, ...
- 用1602液晶显示秒表功能 c语言编写程序 单片机 加注释,单片机课程设计--1602LCD显示的秒表.doc...
单片机课程设计 题目: 1602LCD显示的秒表 系别/班级:信息工程系11级嵌入式技术与应用专业 小组成员: 小组成员学号: 指导老师: 目录 1 单片机原理-------------------3 ...
- java语言50到100之间素数和_用JAVA语言编写一程序,求100以内的所有素数
满意答案 fdewj590 2017.02.13 采纳率:40% 等级:9 已帮助:316人 12345678910111213141516171819public static void ma ...
- 用1602液晶显示秒表功能 c语言编写程序 单片机 加注释,1602LCD液晶显示秒表
1602LCD液晶显示秒表 [源程序:] ;------------------------------------------------------------------ ; ME30 ...
最新文章
- Network 第七篇 - 网络地址转化
- 反引号注入_什么是 SQL 注入?
- 创业新力量缔造新未来,岳麓峰会再增“长沙势能”
- 【阿里妈妈数据科学系列】第五篇:实验指标设定方法与指标体系构建
- 计算机英语女人英语怎么说,英语时差:计算机和女人
- PC软件开发技术之二:用C#开发基于自动化接口的OPC客户端
- 修复mysql的view_MYSQL数据损坏修复方法
- sed,awk,grep学习笔记
- AppScan漏洞“已解密的登陆请求”修复解决方案
- 安卓抓包工具tcpdump
- python使用阿里云企业邮箱发送邮件
- 微信小程序 + 腾讯位置服务SDK 实现路线规划
- 中国(广西)壮语春节联欢晚会将举办
- 免校准的电量计量芯片_【应用】基于高精度免校准电能计量芯片CSE7761的漏电保护设计,可支持单芯片两路计量...
- C语言开发工具(编译器|IDE)推荐
- mac系统和windows系统都有哪些不同
- Vue3基础难点总结
- ps:图像格式的选择
- 2022高考季征文获奖名单公布
- Android打电话 通讯录
热门文章
- 中望cad自定义快捷键命令_CAD如何设置新的命令快捷键
- CSS3:boder-radius
- 编码:隐匿在计算机软硬件背后的语言
- 树莓派接入VGA显示器画面不全偏左的问题与VGA转HDMI连接显示器无法输出声音的解决
- mro python_Python之super与MRO
- 游戏版署过审注意事项
- Mac ssh: connect to host XXX.XXX.XXX.XXX port XX: Operation timed out的问题解决
- 宇宙最帅XX--Alpha阶段项目复审
- 计算机网络——CRC循环冗余检验
- 尜尜送的诗,以及我回的句