IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> C51 汇编和C语言编写从1加到100 -> 正文阅读

[嵌入式]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是因为ROM00H~30H有如下中断向量表,不应覆盖(不同于之前的RAM):

外部中断00003H
定时器/计数器T0000BH
外部中断10013H
定时器/计数器T1001BH
串行口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;上电复位后的程序入口地址0000H
	JMP MAIN;跳转到Main
	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 $;陷入死循环,启动中断服务程序,程序终止
	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	

编写1加到100的C语言程序?

??????? 前面步骤差不多,除了拷贝51单片机的启动文件创建C文件以外,没有什么区别。

#include<stdio.h>
#include<reg51.h>

#define OSC 11059200
#define BAUD 9600

void 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寄存器结构表

SCONSM0SM1SM2RENTB8RB8TIRI
位地址9FH9EH8DH9CH9BH9AH99H98H

????????TMOD=0x20:

??????? TMOD是定时/计数器方式控制寄存器,所以TMOD=0x20是将定时/计数器1设置为工作方式2.

??????? TH1=TL1:

??? ??? 给定时/计数器1装初值,即确定定时时长,具体时间与晶振有关.

??????? 在方式2下,定时时间T与晶振频率fosc之间满足关系 \large T=(2^8-TLx)*12/focs,反解得到 \large TLx=2^8-T/12/(1/focs)=256-focs/12/16/BAUD。因此如此赋值。??

??????? 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。感谢友友们一键三连

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-11-16 18:59:57  更:2021-11-16 19:01:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:16:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码