菜鸟ARM学习笔记proteus仿真.docx

上传人:b****6 文档编号:6799555 上传时间:2023-01-10 格式:DOCX 页数:30 大小:176.57KB
下载 相关 举报
菜鸟ARM学习笔记proteus仿真.docx_第1页
第1页 / 共30页
菜鸟ARM学习笔记proteus仿真.docx_第2页
第2页 / 共30页
菜鸟ARM学习笔记proteus仿真.docx_第3页
第3页 / 共30页
菜鸟ARM学习笔记proteus仿真.docx_第4页
第4页 / 共30页
菜鸟ARM学习笔记proteus仿真.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

菜鸟ARM学习笔记proteus仿真.docx

《菜鸟ARM学习笔记proteus仿真.docx》由会员分享,可在线阅读,更多相关《菜鸟ARM学习笔记proteus仿真.docx(30页珍藏版)》请在冰豆网上搜索。

菜鸟ARM学习笔记proteus仿真.docx

菜鸟ARM学习笔记proteus仿真

菜鸟的ARM学习笔记

下面就是我学习ARM的第一阶段的记录,这段时间的学习基本上是使用Proteus配合KEIL做简单的实验(最后有实验的目录以及下载地址)。

通过该阶段的学习,算是对ARM的基本结构有了了解。

该阶段主要学习资料是《基于PROTEUS的ARM虚拟开发技术》,以及另外一本ARM体系结构的书籍,感觉这类书都差不多。

学习ARM前需要的基础

1.前辈学习ARM的经验!

(我是在嵌入式开发联盟的新人区看的帖子。

2.掌握C语言编程。

3.了解简单的微机算计原理知识,例如二进制,计算机程序的执行过程,总线(数据、地址、控制),软件系统(系统软件与应用软件)。

4.听说过RISC与CISC,高级语言与低级语言的区别。

5.最好听说过串行传输与并行传输。

6.普林斯顿(ARM7)和哈佛结构(ARM9、10、11—)。

什么是ARM?

学ARM,自然要理解ARM是什么,也好明确学习目标。

网上的资料很多,“ARM是一家公司,也是一个处理器体系”……我将学ARM分为以下几类:

1.做ARM的核心研发。

也就是进ARM公司做IP核,应该是学电子之类的东西吧。

2.买ARM的IP核,做具体的嵌入式处理器、核心板,例如三星和NXP。

3.买ARM核心板,连接外围电路制作教育用或开发用的开发板,或者直接开发其它中断产品。

4.买ARM开发板做产品,要做系统软件和应用软件。

3和4基本并列了。

ARM基础

任何一本介绍ARM体系结构书籍都应该有这些内容。

处理器模式

用户模式、特权模式又分为系统模式、管理模式、快中断模式、中断模式、终止模式、未定义指令终止模式。

2.寄存器

R0-R7、R15和CPSR是所有模式共享的。

R8-R12出快中断模式有RX-fiq外所有模式共享。

R13、R14和SPSR只有用户模式和系统模式共享,其它都有似有SPSR。

R15(PC)程序计数器

R16(CPSR)程序转台寄存器

R13(SP)堆栈指针

P14(LR)链接寄存器

ARM指令集汇编程序设计

略了,我看了,但是做Proteus仿真实验没用上,两天就忘了。

LPC2000

我买的3本ARM入门书籍中有两本都是以LPC2000系列为例的,其实从网上可以下载到具体LPC2XXX处理器的datasheet,上面的资料是最权威和详尽的。

引脚选择

PINSEL0、PINSEL1设置各个引脚的功能。

中断

中断的寄存器太多了,没记。

GPIO

做输入输出。

以P0口为例,寄存器有IO0PIN、IO0SET、IO0DIR、IO0CLR。

存储器

1.LPC2000可用地址为4GB,内部2GB(0~0x7FFFFFFF),外部2GB(0x80000000~0xDFFFFFFF),高0.5GB是I/O设备地址空间(0xE0000000~0xFFFFFFFF)。

2.内部最低128KB或256KB为Flash。

3.高1GB(0x40000000~0x7FFFFFFF)为SRAM。

其中0x40000000~0x40001FFF为片内SRAM。

4.I/O部分,低2MB(0xE0000000~0xE001FFFFF)为VPB外设空间,高2MB(0xFFE00000~0xFFFFFFFF)为AHB外设空间。

5.FLASH加速模块。

MAMCR设置是否允许加速、MAMTIM设置预取处理器时钟。

时钟

cclk、pclk

分振荡器模式和从属模式,振荡器Fosc经PLL升频为cclk,cclk经过VPB分频后为pclk。

设置cclk

PLLCFG设置PLL倍频M,PLL分频器值P

PLLCONPLL的允许与连接

PLLSTAT读取PLL状态

PLLFEED使PLL设置生效

例Fosc=12MHz,cclk=60MHz,则M=60/12-1=4,因为Fcco=P*cclk*2(要求156M~320MHz)。

设置pclk

由VPBDIV设置00为4分频、01为不分频、10为二分频。

定时器

pclk定时,定时器为32位,从0计数到0xFFFFFFFF。

以T0为例

T0TC,计数器初值

T0PR,定时计数器分频,pclk/(PR+1)

T0MR0~3,匹配值,当计数带到时候,按照T0MCR的设置触发不同动作。

T0MCR,计数器到达匹配值的动作(复位、中断、停止)

T0EMR,外部匹配寄存器,到达匹配值时候外部引脚的操作(MAT0.0~3)

T0CCR,外部引脚有特定动作时候,计数值存入T0CR0~3,设置是否触发中断

T0CR0~3,在T0CCR控制下存TC值。

T0TCR,复位与使能

T0IR,对应MR与CR中断

PWM

看门狗

Pclk四分频后控看门狗的32为计数器减一。

WDTC,看门狗计数器初值。

WDMOD,看门狗工作模式,可以开启和复位看门狗。

WDFEED,喂狗寄存器。

WDTV,看门狗计数器当前值。

UART

引脚RxD0,TxD0

U0RBR,暂存接受数据。

U0THR,暂存发送数据。

访问它时,U0LCR的DLAB位为0。

U0IER,串口个状态的中断允许。

U0IIR,中断标志。

U0FCR,控制UART的FIFO(暂时没明白)。

U0LCR,传输模式。

U0LSR,当前状态(错误指示)。

U0DLL、U0DLM,pclk/(U0DLLU0DLM),访问时UOLCR的DLAB位为1。

SPI

全双工同步串行接口

引脚:

SCK0,串行时钟。

SSEL0,从机选择。

MISO,主机输入,从机输出。

MOSI,主机输出,从机输入。

寄存器:

S0SPCR,SPI控制。

S0SPSR,SPI状态。

S0SPDR,SPI数据。

S0SPCCR,控制SCK的频率。

必须为偶数且大于等于8。

(指示一个SCK周期中的pclk周期)

S0SPINT,SPI中断。

I2C

引脚:

SDA,SCL

寄存器:

I2CONSET

I2CONCLR

I2CON

上面三个寄存器控制应答标志位,中断标志、停止和起始以及I2C使能。

I2STAT,I2C状态。

I2DAT,I2C数据。

I2ADR,I2C从模式地址。

I2STAT,I2C状态。

I2SCLH,高电平占空比占pclk周期个数。

I2SCLL,低电平占空比占pclk周期个数。

分频fpclk/(I2SCLH+I2SCLL)。

AD转换

引脚:

AIN0~3

寄存器:

ADCR,工作模式选择。

ADDR,转换数据以及标志的暂存。

基于Proteus的ARM实验目录

菜鸟的ARM学习笔记(第一阶段)

1.LED闪烁——ARM的Proteus实验

2.开关控制LED——ARM的Proteus实验

3.LCD——ARM的Proteus实验

4.UART——ARM的Proteus实验

5.Eint1外部中断——ARM的Proteus实验

6.多个外部中断——ARM的Proteus实验

7.中断结合串口——ARM的Proteus实验

8.定时器——ARM的Proteus实验

9.SPI通信——ARM的Proteus实验

10.SPI通信(多从设备)——ARM的Proteus实验

11.ADC数模转换——ARM的Proteus实验

1、LED闪烁——ARM的Proteus实验

实验原理

ARM(LPC21XX)的一个I/O口接LED,通过给它送0和1来设置LED的亮和灭。

Proteus仿真电路图

步骤

KEIL

1.创建新工程

2.选择ARM型号(KEIL会自动生成启动代码startup.s)

3.添加源文件,编写程序

4.设置项目选项(是否输出hex、lst文件,设置linkerscript)

Proteus

1.绘制电路图

2.载入程序

3.仿真

C语言源程序

/******************************************************************************/

/**/

/*led.c:

用ARM点亮一个led并闪烁,有点浪费……*/

/**/

/******************************************************************************/

#include

/*******************************************************************************

**函数名:

delay()

**描述:

软件延时

********************************************************************************/

voiddelay(void){

unsignedvolatilelongi,j;

for(i=0;i<60000;i++)

for(j=0;j<5;j++)

;

}

intmain(void){

PINSEL0=0;/*设置引脚为GPIO*/

IO0DIR=0x000001;/*将P0.0设置为输出*/

IO0SET=0x000001;/*将P0.0置1,也就是让led灭*/

while

(1){

IO0CLR=0x000001;

delay();

IO0SET=0x000001;

delay();

}

}

2、开关控制LED——ARM的Proteus实验

实验原理

ARM的P0.1口接按钮,再通过P0.0控制LED的亮、灭。

本实验的电路图以及实验均在上一个实验基础之上修改。

其中电路图只多了一个开关。

Proteus仿真电路图

实验步骤略(与上一实验相同)

C语言源程序

/******************************************************************************/

/**/

/*led.c:

用ARM实现开关控制led并亮灭,还是有点浪费……*/

/**/

/******************************************************************************/

#include

#defineP0_10x02;/*P0.1*/

/*******************************************************************************

**函数名:

delay()

**描述:

软件延时

********************************************************************************/

voiddelay(void){

unsignedvolatilelongi;

for(i=0;i<10000;i++)

;

}

intmain(void){

intp01State;

PINSEL0=0;/*设置引脚为GPIO*/

IO0DIR=0x000001;/*将P0.0设置为输出*/

IO0SET=0x000001;/*将P0.0置1,也就是让led灭*/

while

(1){

p01State=IO0PIN&P0_1;/*读取开关状态*/

if(p01State==0){

IO0CLR=0x000001;

delay();

}

else{

IO0SET=0x000001;

delay();

}

}

}

3、LCD——ARM的Proteus实验

实验原理

ARM的P0.0口到P0.10口接LCD,P0.11接LED。

每过一段时间LED状态改变,LCD显示LED的状态。

Proteus仿真电路图

C语言源程序

#include

#definers(1<<8)

#definerw(1<<9)

#defineen(1<<10)

#definebusy(1<<7)//P0.7

typedefunsignedcharuint8;

uint8ledDown[]={"TheLEDisdown!

"};

uint8ledUp[]={"TheLEDisup!

"};

voidwaitLCD()/*等待LCD*/

{

IO0DIR=0xf00;

while

(1)

{

IO0CLR=rs;

IO0SET=rw;

IO0SET=en;

if(!

(IO0PIN&busy))break;

IO0CLR=en;

}

IO0DIR=0xfff;

}

voidlcdOp(uint8dat)/*送LCD控制码*/

{

waitLCD();

IO0CLR=rs;

IO0CLR=rw;

IO0CLR=0xff;

IO0SET=dat;

IO0SET=en;

IO0CLR=en;

}

voidlcdData(uint8dat)/*送LCD显示数据*/

{

waitLCD();

IO0SET=rs;

IO0CLR=rw;

IO0CLR=0xff;

IO0SET=dat;

IO0SET=en;

IO0CLR=en;

}

voidlcdInit(void)/*初始化LCD,DataSheet里有建议的初始化代码*/

{

/*LCD配置为两行,5*7字体*/

lcdOp(0x38);

lcdOp(0x38);

lcdOp(0x06);

lcdOp(0x0E);

lcdOp(0x01);

/*LCD配置为一行,5*10字体

lcdOp(0x34);

lcdOp(0x34);

lcdOp(0x06);

lcdOp(0x0E);

lcdOp(0x01);

*/

}

voidlcdDisplay(uint8addr,uint8*p)/*LCD显示字符串*/

{

lcdOp(addr);

while(*p!

='\0'){

lcdData(*(p++));

}

}

voidlcdClear(void)/*LCD清屏*/

{

lcdOp(0x01);

}

voiddelay(void){

unsignedvolatilelongi,j;

for(i=0;i<60000;i++)

for(j=0;j<10;j++)

;

}

intmain(void)

{

lcdInit();/*初始化LCD显示*/

IO0DIR=0xfff;//设置为输出口

IO0CLR=0xfff;

while

(1){

IO0CLR=0x000800;

lcdDisplay(0x80,ledUp);

delay();

lcdClear();

IO0SET=0x000800;

lcdDisplay(0x80,ledDown);

delay();

lcdClear();

}

}

4、UART——ARM的Proteus实验

实验原理

ARM的P0.0口接LED,串口接Proteus的虚拟终端。

每隔一段时间改变一次LED的状态,并且在串口上输出LED的当前状态。

Proteus仿真电路图

C语言源程序

#include

#include"uart.h"

#defineCR0x0D

charledDown[]={"TheLEDisdown!

\n"};

charledUp[]={"TheLEDisup!

\n"};

intputchar(intch){/*向串口输出一个字符*/

if(ch=='\n'){

while(!

(U1LSR&0x20));

U1THR=CR;a

}

while(!

(U1LSR&0x20));

return(U1THR=ch);

}

voiddelay(void){

unsignedvolatilelongi,j;

for(i=0;i<60000;i++)

for(j=0;j<5;j++)

;

}

voidserialPuts(char*p){/*向串口输出字符串*/

while(*p!

='\0'){

putchar(*p++);

}

}

intmain(void){

/*开始初始化串口*/

PINSEL0=0x00050000;/*设置引脚,开串口功能*/

U1LCR=0x83;/*8位数据,无效验,一个停止位*/

U1DLL=97;/*VPB15MHz的时候波特率为9600*/

U1LCR=0x03;/*DLAB=0*/

/*结束初始化串口*/

IO0DIR=0x000001;/*将P0.0设置为输出*/

while

(1){

IO0CLR=0x000001;

serialPuts(ledUp);

delay();

IO0SET=0x000001;

serialPuts(ledDown);

delay();

}

}

5、Eint1外部中断——ARM的Proteus实验

实验原理

ARM的P0.25接一个LED,引脚设置时连接EINT1功能,按钮触发中断。

中断服务程序另LED快速闪烁。

Proteus仿真电路图

C语言源程序

#include

#defineLEDCON0x02000000/*LED接在P0.25上*/

typedefunsignedintuint32;

voidIRQ_Eint1(void)__attribute__((interrupt));/*声明某函数为中断服务子程序的方法*/

uint32times=100;/*循环次数默认为100*/

voidIRQ_Eint1(void){

times=5;

while((EXTINT&0x02)!

=0){

EXTINT=0x02;//清除EINT1中断标志

}

VICVectAddr=0;

}

voiddelay100(void){

unsignedvolatilelongi,j;

for(i=0;i<10000;i++)

for(j=0;j

;

if(times>100){

times--;

}elseif(times<100){

times++;

}

}

intmain(void)

{

IO0DIR=LEDCON;

PINSEL0=0x20000000;/*引脚选中EINT1功能*/

PINSEL1=0x00000000;

/*以下为中断控制部分*/

VICIntSelect=0;/*全部中断设置为IRQ,若某位为1是FIQ*/

VICIntEnable=0x00008000;/*使能EINT1,EINT为第15位*/

VICVectCntl1=0x2F;/*0xF,15号中断*/

VICVectAddr1=(int)IRQ_Eint1;/*设置中断服务子程序*/

EXTINT=0x07;

while

(1){

IO0CLR=LEDCON;

delay100();

IO0SET=LEDCON;

delay100();

}

}

6、多个外部中断——ARM的Proteus实验

实验原理

ARM开启两个中断源Eint1与Eint2,分别用一个按钮来控制。

在没有中断的时候两个LED都缓慢闪烁,当任何一个中断被出发的时候,对应的LED会急促闪烁,逐渐回复正常。

Proteus仿真电路图

C语言源程序

#include

#defineLED10x02000000/*LED1接在P0.25上*/

#defineLED00x01000000/*LED0接在P0.24上*/

typedefunsignedintuint32;

voidEint1_ISR(void)__attribute__((interrupt));/*声明某函数为中断服务子程序的方法*/

voidEint0_ISR(void)__attribute__((interrupt));

uint32times=40;/*循环次数默认为40*/

voiddelay40(void){

unsignedvolatilelongi,j;

for(i=0;i<10000;i++)

for(j=0;j

;

if(times>40){

times-=2;

}elseif(times<40){

times+=2;

}

}

voidEint0_ISR(void){

times=0;

while(times!

=40){

IO0CLR=LED0;

delay40();

IO0SET=LED0;

delay40();

}

while((EXTINT&0x01)!

=0){

EXTINT=0x01;/*清除EINT0中断标志*/

}

VICVectAddr=0x00;

}

voidEint1_ISR(void){

times=0;

while(times!

=40){

IO0CLR=LED1;

delay40();

IO0SET=LED1;

delay40();

}

while((EXTINT&0x02)!

=0){

EXTINT=0x02;/*清除EINT1中断标志*/

}

VICVectAddr=0;

}

intmain(void)

{

IO0DIR=LED1|LED0;

PINSEL0=0x20000000;/*引脚选中EINT1功能*/

PINSEL1=0x00000001;/*引脚选中EINT0功能*/

/*以下为中断控制部分*/

VICIntSelect=0;/*全部中断设置为IRQ,若某位为1是FIQ*/

VICIntEnable=0x0000C000;/*使能EINT1、0,EINT1为第15位,0为14位*/

VICVectCntl0=0x2E;/*EIN

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1