ARM:嵌入式系统之硬件总复习

嵌入式系统之硬件总复习

快要期末考试啦,这几天在复习嵌入式系统,想着有好几天没有更新csdn了,就更新一篇嵌入式系统的文章!


本篇文章覆盖以下知识点:

  • 如何亮灯
  • 时钟周期如何计算
  • printf函数如何使用
  • 什么叫以查询的方式实现中断
  • ATPCS规范是什么
  • 中断响应流程
  • pwm蜂鸣器启动方法
  • 片外设备中断编程方法

同时,本文与我写的前几章文章一起看,效果会更好!

链接: 前几章复习文案.


前言

码字不易,抽空写出文章更是不易。如果这篇文章帮助你明白了一些知识点,那就没有违背我写这篇文章的初心:
希望每一位同学都能通过考试。在日后学习上,我们的同学不是竞争对手,而是当成我们最亲密的战友。同时啊把这份善意传递给其他人。
本文开启了打赏模式,如果你觉得这篇文章对你帮助很大,麻烦你可以稍微打赏一下,拒绝用爱发电!

打赏一下,拒绝用爱发电!
打赏一下,拒绝用爱发电!
打赏一下,拒绝用爱发电!


提示:以下是本篇文章正文内容,如果错误,请联系我进行修改。

一、如何点亮LED灯?

这是教材第六章GPIO相关知识点,也就是GPIO编程实例!
点亮灯分为4个步骤:

  1. 查看硬件电路图,找出LED位于CPU的哪个引脚。
  2. 查看相关电路图,搞懂LED灯工作原理。
  3. 查看CPU手册,将相关位置初始化为0x1。
  4. 点亮LED灯,将gpj2dat 低4位 清0,con设置为输出的功能。

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

//con寄存器4位控制一个灯;
//dat寄存器控制相关引脚输出;
//pud一般是控制上拉/下拉电阻,一般不用
#define gpj2con *((volatile unsigned *)0xe020_0280)
#define gpj2dat *((volatile unsigned *)0xe020_0284)

void led_init(void){
	//初始化con寄存器,先把所有位置清0,再赋值1;
	gpj2con 	=	gpj2con & ~(0xffff) | 0x1111;
	//dat寄存器直接赋值1
	gpj2dat 	=	0xf;
}

void led_on(char on){
	//先把dat寄存器清0,然后 | 上on,决定打开哪些灯的开关
	gpj2dat 	=	gpj2dat & ~(0xff) | on;
}

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

期中考试试题就有一道类似的题目,当时是控制1,3位灯亮,然后下一秒换2,4位灯亮,然后循环亮。下面是代码,结合我之前说的,就明白代码意思啦!

//led
#define		gpj2con		*(unsigned*)0xe0200280
#define		gpj2dat		*(unsigned*)0xe0200284

void led_init( void );
void led_on( char on );


int on=0x5;1 分)

void _start(void)
{
	int i;
	for(i=1;i<=20;i++)
	{
		led_on(on);       
		delay(500000);
		on=on^0xf;
}10分)

void led_init( )       
{
	gpj2con = gpj2con & ~0xffff | 0x1111;
	gpj2dat = 0xf;
}5分)
  
void led_on( char on )     
{
	gpj2dat	=	gpj2dat & ~0xf | ~on;
}5分)
void delay( int t)
{
	for(;t-- ; );
}

二、时钟周期的计算

这个地方建议查看开发板说明手册 P355页。

在这里插入图片描述

根据0xE010_0108处的地址值确定PDIV,MDIV,SDIV的值。

在这里插入图片描述

在这里插入图片描述见下图步骤

在这里插入图片描述

三、如何使用printf函数

其实,我刚开始也不知道如何调用printf函数,怎么才能打印,后来问了老师,老师给我说了printf函数原型,才明白我们要如何写printf函数。
先上代码:

int* myprintf)(char *,...=(int (*)(char *,...))0x2fd17b18;

myprintf是我们的函数名,注意,不要使用print还是printf,我忘记了,因为会和开发板本身自带的一个函数名字起冲突,所以我一般习惯性用myprintf做打印函数名。

在实验期末考试中,我们如何打印“hello world!”,其实只需这样一段代码:

 int (*myprintf)(char *,...)=(int (*)(char *,...))0x2fd17b18; 
//不带参数的myprintf函数,带参数的话,就按照我们常用的c语言的printf用即可。
void __attribute__((interrupt)) wdt_isr(void)

{

	myprintf("hello world!");

	clear_int();

}

四、以查询的方式实现中断

这一块主要讲2个函数,先把所要用到的地址放出来。

#define gph3con		*((volatile unsigned*)0xe0200c60)
#define gph3dat		*((volatile unsigned*)0xe0200c64)
#define gph3pud		*((volatile unsigned*)0xe0200c68) 

con寄存器
在这里插入图片描述
date寄存器和pud寄存器
在这里插入图片描述
代码部分:

#define gph3con		*((volatile unsigned*)0xe0200c60)
#define gph3dat		*((volatile unsigned*)0xe0200c64)
#define gph3pud		*((volatile unsigned*)0xe0200c68) 

//将con寄存器配置成输入的功能,这是按键初始化
void key_init(void)
{
	gph3con=gph3con&~(0xffff);
} 
//如何检测那个键被按下了呢?
//如果第一个键被按下了
if((gph3dat & (0x1))==0)
		{
			while(!(gph2dat&(0x1)));
			return 1;
		}
//如果第二个按键被按下了
if((gph2dat & (0x1))==0)
		{
			while(!(gph2dat&(0x1)));
			return 1;
		}

五、ATPCS规范

没有什么比标准答案更好的材料了,直接背标准答案!!!

  1. 子程序通过寄存器r0-r3 来传递参数,如果参数多于4个,多出的部分用堆栈来传递,r0-r3不用恢复。(1分)
  2. R4-r11用来保存局部变量,使用前保存这些寄存器的值,子程序退出时要恢复这些寄存器(1分)
  3. r12 常用保存sp (1分)
  4. r13 用途堆栈指针,记作sp (1分)
  5. r14用作链接寄存器,用来保存程序的返回地址,记叙lr (2分)
  6. r15 即pc,用户程序计数器,不作其他用途 (2分)
    7.函数返回值保存在r0中。 (2分)

调用printf函数过程:
1)将返回地址入lr (2分)
2) 将字符串“x=%d,y=%d,z=%d,s=%d”地址入r0 (3分)
3)x值入r1,y值入r2,z值入r3,s值入栈 (2分)
4) 跳转到0x2fdb1718处执行程序 (3分)

六、中断响应流程

我理解的中断响应过程指的是WDT看门狗这个实验!
这个我觉得应该没必要再说了!期中考试考这个!期末考试考这个!应该都会了!
我就直接把我以前写的那篇wdt看门狗文章链接丢在这,然后看一下就行了!
链接: WDT看门狗实验.

七、pwm蜂鸣器

蜂鸣器应该是我们做的倒数第二个实验了!!!我自己的话有一个点不太确定,就是1200,我个人的想法是:根据题目给的,如果有同学知道1200怎么来的,请告诉我!!!万分感谢!!!
正式开始说明:
在这里插入图片描述

蜂鸣器启动步骤:

  1. 初始化时钟(分频器、选频器);
  2. 初始化tchtb,tcmpb,调整占空比;
  3. 停止auto-reload,使能manual update
  4. 使能auto-reload,清除manual update

具体步骤见代码注释,边写代码边说明,我知道的我都会说,emmm我也很菜的!!!我也靠不住,呜呜呜。

1、初始化时钟频率(分频器,选频器)
#define		gpd0con		*(volatile unsigned*)0xe02000a0
	gpd0con		=	gpd0con & ~0xf|0x2;//配置成time0

//设置预分频器的值
#define		tcfg0		*(volatile unsigned*)0xe2500000
	tcfg0		=	一个不超过255的整数;

//设置选频器的值
#define		tcfg1		*(volatile unsigned*)0xe2500004
	tcfg1		= 0000 || 0001 || 0010 || 0011 || 0100 || 0101; //选一个即可,见下面的说明

2、初始化tcntb,tcmpb的值
#define		tcntb0		*(volatile unsigned*)0xe250000c
#define		tcmpb0		*(volatile unsigned*)0xe2500010
	tcntb0		=	150;
	tcmpb0		=	50;
备注:占空比= 1 - (tcmpb/tcntb)


#define		tcon		*(volatile unsigned*)0xe2500008
3、停止auto-reload,使能manual update
	tcon		=	tcon & ~(0x1<<3) | (0x1<<1);
4、使能auto-reload,清除manual update,并启动蜂鸣器
	tcon		=	tcon & ~(0x1<<1)|(0x1<<3) | 0x1;

预分频器

在这里插入图片描述
选频器

在这里插入图片描述
tcon=0xe250_0008

在这里插入图片描述
还要在设置这个地方,设置1,允许中断
在这里插入图片描述

八、片外设备中断处理

这个指的是实验10。
在这里插入图片描述

步骤:
初始化片外设备中断控制器---------->初始化中断控制器----------->开cpu中断

/ about vic0
//[27]=0  select IRQ
#define vic0intselect		*(volatile unsigned*)0xf200000c
//[27]=1 enable wtd int
#define vic0intenable		*(volatile unsigned*)0xf2000010
// contains isr 
#define vic0vectaddr16		*(volatile unsigned*)0xf2000140

//ext_int_2
//[0:15]=0x3333 rising edge triggered
#define 		ext_int_2_con		*(volatile unsigned*)0xe0200e08
//[0:31]=0x80808080  delay flt
#define 		ext_int_2_fltcon0	*(volatile unsigned*)0xe0200e90
//[0:3]=0x0  enable interrupt
#define 		ext_int_2_mask		*(volatile unsigned*)0xe0200f08

void vic0_init( void )
{
	vic0intselect	=	vic0intselect & ~(0x1<<16);
	vic0intenable	=	vic0intenable | (0x1<<16);
	vic0vectaddr16	=	key_isr;
} 

void ext_int_2_init( void )
{
	ext_int_2_con		=	ext_int_2_con & ~0xffff | 0x3333;
	ext_int_2_fltcon0	=	0x80808080;
	ext_int_2_mask		=	ext_int_2_mask & ~0xf;
} 


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

在这里插入图片描述

最后,很感谢大家的观看!其实呢,我很想净化 班级内卷的氛围,人人都在偷偷学习,真的少了很多快乐。
社会达尔文主义不能拯救你,内卷你跳不出来的,我也没办法跳出来,但是我们可以尝试不要那么内卷,当我们陷入内卷的氛围中,社会达尔文主义已经让你丧失了一个作为人最基本的尊严!我们是人,不是兽。身边的小伙伴不是我们的竞争对手,而是我们最亲密的战友!!!
去拥抱我们身边的每一个人吧,带着我们的善意,传递下去!


总结

嵌入式系统硬件部分就说到这里,系统的过了一遍。祝各位取得好成绩!

如果你觉得看的很爽,那就点点赞,打赏一波!

拒绝白嫖伸手党!!!
拒绝白嫖伸手党!!!
拒绝白嫖伸手党!!!
在这里插入图片描述

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不安分实验室

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

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

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

打赏作者

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

抵扣说明:

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

余额充值