栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32的C与汇编语言混合编程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32的C与汇编语言混合编程

目录

一、新建工程

二、配置环境

1.选择设备

2.选择运行环境 

 3.添加源文件

三、测试代码 

1.汇编语言源代码

2.C语言源代码

3.仿真器设置 

4.调试

四、扩展

五、汇编语言调用C语言

六、参考资料


一、新建工程

打开Keil uVision5

 点击project,在弹出的窗口点击选项New uVision Project,创建新的工程

在弹出的窗口设置工程路径和名称,然后点击保存

二、配置环境

1.选择设备

设置工程的目标环境,本文基于STM32F103ZET6,因此在弹出的窗口选择相应的选项,点击OK即可


 

2.选择运行环境 

ARM的CMSIS已经把开发所需要的软件组件都封装好了,因此直接选择打勾即可;在CMSIS下勾选CORE,在Device下勾选Startup,然后点击OK

 3.添加源文件

鼠标右键单击Source Group 1,选择Add New Item to Group

选择 Asm File (.s) ,创建汇编文件,在Name栏设置源文件的名称,点击Add

用同样的步骤,选择C File(.c),创建C语言文件,设置源文件名称

三、测试代码 

1.汇编语言源代码
    AREA My_Function,CODE,READonLY
	EXPORT Init_1
		
Init_1
    MOV R1,#0
	MOV R2,#0
	
LOOP
    CMP R1,#10
	BHS LOOP_END
	ADD R2,#1
	ADD R1,#1
	B LOOP
	
LOOP_END
	NOP
	
	
	END

2.C语言源代码
#include

extern void Init_1(void);
	
int main()
{
	Init_1();
	return 0;
}

3.仿真器设置 

点击魔法棒,在弹出的窗口点击Debug,选择左边的Use Simulator,调节相关参数如下图所示,(因为是网络仿真,没有芯片加持);

点击Output,勾选Create HEX File,然后点击OK

4.调试

点击Rebuild进行编译  

点击Start/Stop Debug Session进入调试,运行结果如下

test2.c是C语言程序,test2.s是汇编程序。主要是Init_1这个函数的实现在汇编文件里面,使用汇编语言实现的。首先在C里面用 extern 声明 Init_1这个函数,在test2里面调用好了。然后在汇编里面用EXPORT Init_1与C联系起来就可以实现C语言与汇编语言的混合编程。

四、扩展

修改参考代码,将原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。
修改代码如下:

test2.c

#include

extern int Init_1(int x);

	
int main()
{
  int xx;	
  xx=Init_1(20);
  printf("%d",xx);
	
	return 0;
}

test2.s

    AREA My_Function,CODE,READonLY
	EXPORT Init_1
     
		
Init_1
    ADD R0,#100
	MOV PC,LR
	
LOOP
    CMP R1,#10
	BHS LOOP_END
	ADD R2,#1
	ADD R1,#1
	B LOOP
	
LOOP_END
	NOP
	END

在ARM中,子函数的参数值传递按顺序存放在R0,R1,R2,R3里,超过4个参数值传递放栈帧里。 因此 Init_1(20)传入的20放到了 R0,由 MOV PC ,LR 返回 120。

设置断点:

点击右上角Run进行调试

 可以看到20的值已给到R0

此时,xx 的值为 0x78 ,即 120,调用成功。

五、汇编语言调用C语言

在上面操作的基础上,再修改代码:

test2.c

# include

extern void	Init_1(void);

int ret(void);

int main(){
	
	printf("1111111111n");
	Init_1();

	
	return 0;
}

int ret()
{
	return 100;
}

test2.s

    AREA	MY_Function,CODE,READonLY
	EXPORT 	Init_1  ; 与在c文件中定义的Init_1函数关联起来
	import  ret    ; 声明ret 为外部引用
	; 高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可
Init_1

	MOV R1,#0     ; 设R1寄存器为i
	MOV R2,#0	  ; 设R2寄存器为j
	
LOOP	; 写在最左边的是程序段的段名,执行跳转程序时用到
	CMP R1,#10	  ; 比较R1和10的大小
	BHS LOOP_END  	  ; 如果R1大于等于10,则跳转到LOOP_END程序段,反之忽略该语句,直接执行下面的语句
	ADD R2,#1	  ; j++
	ADD R1,#1     ; i++
	BL ret  	  ; 调用get5,返回的值传入R0
	B LOOP		  ; 循环
	
LOOP_END
	NOP	
	
	END  ; 必须空格后再写END,不然会被认为是段名,表示程序结束

设置断点:

点击右上角Run进行调试

六、参考资料

用Keil uVision5实现C语言与汇编语言的混合编程

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/316074.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号