ARM的SDRAM、LED、中断硬件原理及源程序

集成开发环境的配置说明与ARM的SDRAM、LED、中断硬件原理及源程序


一、实验目的

(1)了解S3C2410X处理器的存储空间分配,学习实验台存储器接口电路原理,并能够对存储区空间进行配置,对存储区空间进行读写访问。

(2)学习实验台地址总线和数据总线的驱动缓冲电路原理,掌握利用S3C2410X处理器地址总线扩展的I/O来点亮LED、驱动蜂鸣器。

(3)掌握S3C2410X处理器中断响应过程,学习实验台外部中断输入电路的原理,掌握ARM中断处理程序的编写方法。

二、实验设备

   硬件:EMBEST实验平台,ULINK2仿真器,PC机,串口线。

    软件:uVision IDE for ARM集成开发环境。

三、实验内容

编写程序,当未按下实验箱上的按键KEY1或KEY2时,LED为常灭,当用户按下实验箱上的按键KEY1或者KEY2时,进入中断服务子程序。

在中断服务子程序中进行如下操作:驱动蜂鸣器响一声,然后驱动LED按规律的点亮和熄灭,接着程序修改SDRAM存储器地址0x30E00000——0x30F00000处的内容。

LED灯具体亮灭规律如下:LED1亮 —>LED2亮—>LED3 亮—>LED4亮    ->LED1灭—>LED2灭—>LED3灭 —>LED4 灭 —> 全亮—> 全灭—>全亮—>全灭。 

修改SDRAM存储器时只对每个地址高半个字处写入1234,低半个字保持原来内容不变。

四、硬件电路原理

     (1)  存储控制器特点及存储器连接原理

  S3C2410X存储控制器主要特性包括:

a)  S3C2410X具有27位地址总线,与8 个片选信号配合可寻址1GB存储空间。

b)  1GB可寻址存储空间划分为8个Bank,每个Bank的存储空间大小为128MB。片选信号线nGCS[0]~nGCS[7]与BANK0~BANK[7]对应。

c)  BANK0~BANK5可配接ROM、SRAM类型的存储器;BANK6和BANK7可配接ROM、SRAM、SDRAM类型的存储器。

d)  BANK0~BANK6 的起始地址是固定,BANK7的起始地址是可变的。

e)  每个BANK的数据总线宽度可设置,其中BANK0可设置为16/32位宽度;BANK1~BANK7可设置为8/16/32位宽度。

f)  支持NAND  FLASH和NOR FLASH两种启动模式,启动模式和BANK0的总线宽度由OM[1:0]引脚决定。

实验箱核心板上有3种类型的存储器, NOR  FLASH(一片Am29LV160DB),NAND  FALSH(一片K9F1208),SDRAM(2片HY57V561620FTP) 。

NORFLASH的特点是应用程序可以直接在FLASH闪存内运行,不必再把代码读到系统RAM中。NOR FLASH的传输效率很高,在1~4MB的小容量时具有很高的成本效益,但是很低的写入和擦除速度大大影响了它的性能。

而NAND FLASH在芯片面积、单元密度、容量、写入数据速度、功耗、使用寿命和成本等方面具有明显优势,但NAND FLASH需要特殊的管理和控制接口。

SDRAM的存储容量大、读写速度快、支持突发式读写,在本系统中两片HY57V561620FTP并联组成位宽32位、存储容量共64MB的SDRAM存储体,用作主内存。

核心板上BOOT跳线可以选择是NAND FLASH启动还是NOR FLASH启动:BOOT跳线断开时为NOR FLASH启动方式,数据总线宽度为16位;BOOT跳线合上时为NAND FLASH启动方式,数据总线宽度为8位。

NANDFLASH和NOR FLASH两种启动模式的存储空间分配如图4-1所示。

 ARM的SDRAM、LED、中断硬件原理及源程序_第1张图片

图4-1 存储空间分配图

 注:(1)SROM表示存储类型为ROM或者SRAM

(2)本次实验将程序下载到NOR  FLASH中运行,所以跳线断开。程序中对地址为0x30E00000——0x30F00000处的内容进行读写访问也即访问SDRAM存储器中内容。

    SDRAM的电路连接原理图如图4-2所示:nGCS6(nSCS0)与片选信号相连,表明SDRAM占用BANK6,实际的物理地址为0x30E00000——0x33FFFFFF。

 ARM的SDRAM、LED、中断硬件原理及源程序_第2张图片

图4-2 SDRAM的电路连接原理图

     (2)    地址总线扩展I/O

实验台上有4个状态可编程的LED灯(LED1~LED4),这四个LED的状态通过扩展的I/O接口进行控制。

所用的扩展I/O电路原理图如图4-3和4-4所示。

图4-3为S3C2410地址线和数据线经过驱动缓冲芯片74LVTH162245后,作为外设电路的总线信号。74LVTH162245芯片提高了总线的驱动能力、又隔离了外设电路。

图4-4为LED灯和BEEP蜂鸣器驱动电路原理图。

ARM的SDRAM、LED、中断硬件原理及源程序_第3张图片

图4-3 地址总线、数据总线原理图

ARM的SDRAM、LED、中断硬件原理及源程序_第4张图片

图4-4 LED和BEEP控制原理图

图4-4中利用3/8译码器将地址线A18-A20扩展了7个片选信号CS1-CS7 。其中 CS5 , CS6 , CS7 3 个片选信号和写使能信号WE通过 74HC32 或门输出一个选通信号OLE (低电平有效)。 OLE3 选通信号经过 74HC04 反相得到高电平连接给扩展输出芯片 74HC573 的使能端LE。

数据线DB0-DB7经过74LVTH162245驱动缓冲后再经过MC74VHC245驱动(即经过了两级驱动)后给具有锁存的D触发器74VHC573DT芯片。D触发器的输出B1-B4用于驱动4个LED,B8用于驱动蜂鸣器。

由原理图可知,芯片74HC573 DT的物理选通地址为0x21180000,当访问这个物理地址时,就可以访问其上的硬件资源了。这里可以把其理解为一个寄存器,寄存器地址是0x21180000,它的第四位控制了4个LED,它的第8位控制了蜂鸣器。

(3)按键中断

    S3C2410的中断控制器可以从60个中断源接收中断请求,这些中断源可分为内部中断和外部中断。内部中断有内部外设如DMA控制器、UART、IIC等功能模块产生;外部中断有24个,输入引脚EINTn与GPF和GPG端口复用。

    本次实验主要用到实验平台主板上的两路外部按键,当键被按下时,会产生按键中断信号。按键产生的中断信号经过CPLD逻辑处理后连接到CPU的中断引脚 INT9。

ARM的SDRAM、LED、中断硬件原理及源程序_第5张图片

图4-5 按键中断框图

 

    CPLD的内部逻辑如图4-6所示:

ARM的SDRAM、LED、中断硬件原理及源程序_第6张图片

图4-6 CPLD中断部分逻辑原理图

如图4-6所示为CPLD 扩展中断。ISAIRQ0~ISAIRQ7 、IRQNET、IRQKEY 、EINT0 、EINT1 等信号是外部设备的中断信号, 它们作为CPLD 芯片的输入。CPLD 芯片上设计了两个中断控制器:CtrlReg0 与 CtrlReg1 , 设计了两个状态寄存器StatusReg0 与 StatusReg1 。 从图4-6可以看出,按键中断EINT0 是由中断控制器CtrlReg1 来控制的,状态寄存器 StatusReg1 每个位分别实时反映了一个外部中断信号的状态,按键中断EINT0 与其它外部中断(如IRQCAN、IRQCF等)共享了CPU中断INT9,在初始状态, 这些引脚信号为高电平。

表 4-1 中断控制寄存器 CtrlReg1 (地址 0x26600000 )

BIT7

BIT6

BIT5

BIT4

BIT3

BIT2

BIT1

BIT0

IRQNET

IRQKEY

IRQCF

IRQCAN

Reserved

EINT1

EINT0

Reserved

中断控制寄存器 CtrlReg1 是 8 位只写寄存器。它的每个位分别控制了一个外部中断。 其中按键中断EINT1位于 BIT2 位。往寄存器相应位写 1 ,则相应中断被屏蔽;相应位清零,则相应中断被打开。

表 4-2 中断状态寄存器 StatusReg1 (地址 0x06200000 )

BIT7

BIT6

BIT5

BIT4

BIT3

BIT2

BIT1

BIT0

IRQNET

IRQKEY

IRQCF

IRQCAN

Reserved

EINT1

EINT0

Reserved

状态寄存器 StatusReg1 是 8 位只读寄存器。它的每个位分别实时反映了一个外部中断信号的状态,其中 BIT2 位反映了按键中断 EINT0 的状态, 比如当前按建 KEY2 没有键按下, 则中断信号引脚 EINT1为高电平, 此时寄存器 StatusReg1 的 BIT2 位也为高电平; 当有键按下, EINT1 变为低电平,则 StatusReg1 的 BIT2位也变为低电平。

五、软件部分说明

(1)     工程配置

在集成开发环境中选择project-Option for target选项进行工程配置。主要对Target配置页面、Linker配置页面、Debug配置页面以及Utilities配置页面作一说明。

ARM的SDRAM、LED、中断硬件原理及源程序_第7张图片

图5-1  Target配置页面

 ARM的SDRAM、LED、中断硬件原理及源程序_第8张图片

   

图5-2 Linker配置页

 

Linker即链接器/定位器用于将目标模块进行段合并,并对其定位,生成程序。有三种方式配置链接器。

本此实验中勾选Use Memory Layout fromTarget Dialog选项,则MDK默认在Target中对FLASH和RAM的地址配置,编译链接时会产生一个默认的分散加载文件,最后链接器会根据此文件中的信息对目标文件进行链接,生成axf镜像文件。

ARM的SDRAM、LED、中断硬件原理及源程序_第9张图片

图5-3 Debug配置页面

 ARM的SDRAM、LED、中断硬件原理及源程序_第10张图片

图5-4  Utilities工具选项卡配置

调试脚本文件除了可以初始化软/硬件的调试环境以外,还可以初始化Flash的烧写环境,此处的FLASH.ini调试脚本文件是在进行FLASH下载程序时,对目标板的硬件环境的配置。

(2)  程序设计

在建立工程时可以自动添加S3C2410的启动文件,该文件是用混编语言编写。主要完成系统的硬件初始化操作。用户可以利用图形化界面来进行初始化配置,修改图形界面上的内容后,MDK能自动实时更新启动文件中的内容。

ARM的SDRAM、LED、中断硬件原理及源程序_第11张图片

图5-5 启动代码的图形配置界面

如图5-5所示,以堆栈配置为例,只要修改各堆栈对应Value一栏的值即可初始化各堆栈大小。

由于我们选择在C语言程序中进行大部分的初始化操作(时钟、中断、I/O端口初始化),所以本实验启动代码使用默认设置即可(主要是堆的设置、栈的设置、存储控制器设置)。

程序流程图如图所示:

ARM的SDRAM、LED、中断硬件原理及源程序_第12张图片

图程序流程图

由于例程中都已经完成初始化配置,仅以时钟配置为例作说明。

时钟配置由如下两个公式给出:

 

Mpll配置:选择 M=0Xc3  Fin=12MHz p=0x04   s=0x01 Mpll=202.8MHz      

Upll配置:选择M=0x78  Fin=12MHz p=0x02   s=0x03   Upll=48MHz      

六、实验结果

(1)对SDRAM存储器地址0x30E00000——0x30F00000处的内容进行写数据操作。SDRAM中每个地址高半个字处写入1234,低半个字保持原来内容不变。

在调试窗口中观察地址从0x30e00000开始的内容,结果如图6-1所示。

ARM的SDRAM、LED、中断硬件原理及源程序_第13张图片

图 6-1 存储器地址中的内容

(2)为了验证在脱离仿真调试模式下,对存储器写操作的正确性,程序又对0x30e00000中的内容修改为0xfffffff0,并从该地址出读出数据驱动4个LED。

ARM的SDRAM、LED、中断硬件原理及源程序_第14张图片

图6-2 修改了0x30e00000地址处的内容

(3) LEED和BEEP蜂鸣器运行结果请看视频演示。

7.实验部分源代码

#define rCPLDIntControl     (*(volatile unsigned char*)0x22600000)                        

#define rCPLDIntStatus      (*(volatile unsigned char*)0x22200000)                         

#define rCPLDLEDADDR   (*(volatile unsigned char*)0x21180000)

#define rCPLDBEEPADDR  (*(volatile unsigned char*)0x21180000)

 voidint_init(void)                     //  中断初始化函数

{

    rSRCPND =rSRCPND;                                 // 清楚中断请求标志

    rINTPND = rINTPND;                              //清楚挂起寄存器

         rGPGCON|= (0xf<<0);                          

rGPGCON &=(0xa<<0);                //设置端口GPG1为INT9,GPG0为INT8

rCPLDIntControl= 0xFF;           

         rCPLDIntControl= 0xF9;          //CPLD控制寄存器中断按键中断

         pISR_EINT8_23=(UINT32T)int_int;           //中断服务子程序入口地址

         rEINTPEND= 0xffffff;                     //清楚外部中断请求标志

      rEXTINT1 &=~((0x7<<4)|(0x7<<0));

         rEXTINT1|= ((0x2<<4)|(0x2<<0));                 //设置中断触发方式

         rEINTMASK&= ~(3<<8);                //允许外部中断EINT9、EINT8 

rINTMSK  &= ~(BIT_EINT8_23);             //设置中断屏蔽寄存器允许

}

void  __irqint_int(void)             //中断服务子程序

{

        unsigned char Status;

         UINT32T*pt;

         unsignedint j,k;

         Status =rCPLDIntStatus;

         Status =~(Status & 0x6);

         rCPLDBEEPADDR=0xFF;

   k=rCPLDBEEPADDR;

         j=~(1<<7);

         rCPLDBEEPADDR&= ~(1<<7);

         j=rCPLDBEEPADDR;

         delay(3000);

         rCPLDBEEPADDR|=(1<<7);

         j=rCPLDBEEPADDR;

         led_on();

         led_off();

         led_on_off();

         led_on_off();

pt=(UINT32T*)(_RAM_STARTADDRESS + 0x00E00000);

         while((UINT32T)pt< (_RAM_STARTADDRESS + 0x00F00000))

    {

             j=*pt&0x0000FFFF;

                   *pt=0x12340000+j;

                   pt=pt++;

    }

         uart_printf("EINT1 interrupt occurred.\n");

         pt=pt--;

         uart_printf("\n%d",*pt);

         rCPLDIntControl|= (1<<2);

         rCPLDIntControl&= ~(1<<2);

rEINTPEND=(1<<9);

ClearPending(BIT_EINT8_23);

}

void led_off(void) //灯熄灭控制程序

{

         inti,nOut; 

         nOut =0xF0;

         rCPLDLEDADDR= nOut | 0x01;

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

         rCPLDLEDADDR= nOut | 0x03;

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

         rCPLDLEDADDR= nOut | 0x07;

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

         rCPLDLEDADDR= nOut | 0x0F;

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

}

void led_on(void)  //灯点亮控制程序

{

         inti,nOut;

         nOut =0xFF;

 

         rCPLDLEDADDR= nOut & 0xFE;

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

         rCPLDLEDADDR= nOut & 0xFC; 

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

         rCPLDLEDADDR= nOut & 0xF8;  

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

         rCPLDLEDADDR= nOut & 0xF0; 

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

}

void led_on_off(void)   //小灯亮灭控制

{

         int i; 

         rCPLDLEDADDR= 0xF0;

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

         rCPLDLEDADDR= 0xFF;

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

}

void int_test(void)              //主程序部分

{

         uart_printf("\nExternal Interrupt Test Example\n");

         int_init();

         rCPLDBEEPADDR=0xFF;

         rCPLDLEDADDR= 0xFF;

         while(1)

         {

           rCPLDLEDADDR = 0xFE;

         }

}


你可能感兴趣的:(裸机实验,32位,c语言,硬件,存储,flash)