实验四 C与汇编混合编程及内部可编程模块

该实验旨在通过MDK工具,理解ARM9的启动流程,学习C语言和汇编的混合编程,包括指定代码入口、使用全局变量以及调试技巧。实验涉及C语言延时函数、汇编子程序调用,并展示了如何控制嵌入式系统中的LED灯状态变化。
摘要由CSDN通过智能技术生成

一、 实验目的

  1. 了解 ARM9 的启动过程,学会使用 MDK 编写简单的 C 语言程序和汇编启动代码并进行调试;
  2. 掌握如何指定代码入口地址与入口点;
  3. 掌握通过 memory、register、watch、Local 等窗口分析判断结果;
  4. 掌握在汇编程序中使用C程序的全局变量;
  5. 掌握C语言与汇编程序的混合编程方法;
  6. 掌握嵌入式内部可编程模块的开发方法。

二、 实验设备

  1. 硬件:PC 机。
  2. 软件:µVision IDE for ARM 集成开发环境。

三、 实验任务与要求
1. 用 c 语言编写延时函数,使用嵌入汇编。
(1) 单步执行EduKit2410_for_MDK修正\3.6_c2\CTest2.Uv2工程,理解每条语句的意义;
在这里插入图片描述

IMPORT  __main ;导入c函数_main
LDR     R0, =__main ;用伪指令将_main函数入口地址加载到R0
BX      R0	;跳转执行R0
;    # jump to __main()
	
;# *********************************************************
;# * Loop for ever					                      * 	
;# * End of application. Normally, never occur.        	  *
;# * Could jump on Software Reset ( B 0x0 ).           	  *
;# *********************************************************
End
	b           End

    end
/*********************************************************************************************
* File:		c2.c
* Author:	Wuhan R&D  Center, embest
* Desc:		c language example 2
* History:	
*********************************************************************************************/

/*********************************************************************************************
* name:		_nop_
* func:		The following example embed assembel language 
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void _nop_(void)
{
	int temp=0;
	__asm
	{
		mov temp,temp   //调用mov操作,实现一次“空操作”目的是为了实现一段延时(具体时间由指令周期决定)
	}     
}

/*********************************************************************************************
* name:		delay
* func:		delay time
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void delay(void)		
{
	int i;
	
	for(i=0;i<=10;i++)
	{
		_nop_(); // 调用_nop_()
	}
}

/*********************************************************************************************
* name:		delay10
* func:		delay time
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void delay10(void)
{
	int i;
	
	for(i = 0; i <= 10; i++)
	{
		delay(); // 调用延时函数
	}
}

/*********************************************************************************************
* name:		_main
* func:		c code entry		
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
__main() // __main 函数
{	
	for( ; ; )
	{
		delay10(); // 调用10次延时函数
	}
}

(2) 打开 memory、register、watch、Local 窗口,单步执行,并通过 memory/register/
watch/variable 窗口分析判断结果。注意观察程序如何从跳转进主程序__main,在 call stack 窗口观察当前执行函数之间的调用。在 watch 框中输入要观察变量 I 的值,并记录下来。特别注意在 local 窗口观察变量 I 的变化并记录下;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
一直循环…
在这里插入图片描述

(3) 结合实验内容和相关资料,观察程序运行;
(4) 改写CTest2.Uv2中的程序,实现在 C 语言文件中调用汇编子程序,实现在 C 语言文件中定义全局变量,在汇编代码中读取全局变量并修改在存入全局变量中;

extern void func();
int x;
__main(){
	func();
	for( ; ; ){
		delay10();
	}
}

将全局变量x导入汇编文件,导入编写函数func
将全局变量x的地址装入r0中
给r1赋值6
将r1中的数写入到以r0为地址的内存中
返回主程序

import __main
import x
export func
func
ldr r0,=x
mov r1,#6
str r1,[r0]
bx lr
  1. 编写程序,控制实验平台的发光二极管 LED1,LED2,LED3,LED4,使它们有规律的点亮和熄灭,具体LED灯亮灭顺序请根据给出的程序写出来,并把每个端口寄存器的值写出来。
    在这里插入图片描述

如图 4-14 所示,LED1-4 分别与 GFP7-4 相连,通过 GFP7-4 引脚的高低电平来控制发光二极管的亮与灭。当这几个管脚输出高电平的时候发光二极管熄灭,反之,发光二极管点亮。

(1) 把EduKit2410_for_MDK修正\4.2_led_test\led_test.c中的语句进行解释;

void led_on(void)
{
	int i,nOut;
	nOut = 0xF0;
	
	//rGPFDAT=nOut & 0x10;
	rGPFDAT=nOut & 0xd0;    //1101 0000 
	for(i=0;i<100000;i++);  
	rGPFDAT = nOut & 0x50;  //0101 0000
	for(i=0;i<100000;i++);	
	rGPFDAT=nOut & 0x40;    //0100 0000
	for(i=0;i<100000;i++);	
	rGPFDAT=nOut & 0x00;   //0000 0000
	for(i=0;i<100000;i++);
		rGPFDAT=nOut ;     //熄灭

}

void led_off(void)
{
	int i,nOut;	
	nOut=0;
	rGPFDAT = 0;        //0000 0000
	for(i=0;i<100000;i++);	
	rGPFDAT = nOut | 0x20;   //0010 0000
	for(i=0;i<100000;i++);	
	rGPFDAT |= nOut | 0xa0;  //1010 0000
	for(i=0;i<100000;i++);	
	rGPFDAT |= nOut | 0xb0;//0x20;
	for(i=0;i<100000;i++);	
	rGPFDAT |= nOut | 0xf0;//0x10;
	for(i=0;i<100000;i++);
}

(2) 如果图4-14中四个LED灯LED1-4分别与GPB0-3相连,通过GPB0-3控制LED灯发光,亮灭顺序如下:LED1-4全亮->LED1-4全灭->LED4亮->LED3亮->LED2亮->LED1亮-> LED1-4全灭。请在EduKit2410_for_MDK修正\4.2_led_test\led_test.c代码基础上进行修改。

void led_test(void)
{
	rGPBCON=0x55;								
	rGPBUP=0x0f;											
	uart_printf("\n I/O (Diode Led) Test Example\n");

	rGPBDAT &= 0;  //全亮
	for(i=0;i<100000;i++);
	rGPBDAT |= 0x0f    //全灭
	for(i=0;i<100000;i++);
	rGPBDAT &= 0x07  //led4亮
	for(i=0;i<100000;i++);
	rGPBDAT |=0x0f   //熄灭led4
	rGPBDAT &=0x0b  //点亮led3
	for(i=0;i<100000;i++);
	rGPBDAT |=0x0f //熄灭led3
	rGPBDAT &=0x0d	//点亮led2
	for(i=0;i<100000;i++);
	rGPBDAT |=0x0f  //熄灭led2
	rGPBDAT &=0x0e  //点亮led1
	for(i=0;i<100000;i++);
	rGPBDAT |=0x0f  //全部熄灭
	for(i=0;i<100000;i++);
	uart_printf(" end.\n");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

okfang616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值