EDN首页   博客首页

最新日志

发表于:2006/10/23 15:09:56
标签:无标签

5

Gun汇编的保留字

Gun汇编的保留字不是很多书会提到的, 查找起来很不方便, 我自己整理了一下. 希望对以后有用. 

.ascii  “<string>”

string当成数据插入汇编中,armasmDCB类似.

.ascix  “<string>”

类似 .ascii , 但在每个字符串后面跟一个零字节.

.balign <power_of_2> {, <fill_value> {, <max_padding> } }

对齐地址到<power_of_2>字节. 汇编器通过添加<fill_value>字节或者默认值来对齐, 如果需要填充的字节数大于<max_padding>, 则对齐不会发生.

.byte  <bytr1> {, <byte2>} ….

把一系列的字节当成数据插入汇编, armasmDCB类似.

.code  <number_of_bits>

bit 位役置指令的长度. 16位是Thumb, 32位是ARM, 这和armasmCODE16CODE32类似.

.else

使用在.if .endif 之间. armasmr ELSE类似.

.end

标记一个汇编文件的结束. 这个通常被省略.

.endif

标志着条件汇编代码块的结束, armasmENDIF类似

.endm

结束一上宏定义. armasmMEND类似

.endr

结束一个循环, armasmWEND类似

.equ <symbol name>, <value>

设置一个标号(symbol)的值, armasmEQU类似

.err

以一个错误导致汇编的结束.

.exitm

从当前宠定义体中提前退出. armasmMEXIT类似

.global <symbol>

给标号<symbol>一个外部连接. armasmr EXPORT类似

.hword <short1> {, <short2>} …

把一系列的16位数当成数据插入汇编, armasm DCW类似

.if < logical_expression>

定义一个条件块, .endif 结束. armasmr IF类似

.ifdef <symbol>

    如果<symbol> 是定义了的,则包含(include)下面的一段代码块, 这个代码块以 .endif来结束.

.ifndef <symbol>

   如果<symbol> 是没有定义了的,则包含(include)下面的一段代码块, 这个代码块以 .endif来结束.

.include  “<filename>”

包含指定的源文件. armasmr INCLUDE或者和C#INCLUDE类似

.irp <param> {, <val_1>} {, <val_2>}….

    开启一个循环的代码块,块中每个value列表的value 执行一次, 块以一个 .endr 来标记结束. 在循环的代码块中, 使用 \<param>来替代value列表中的value.

.macro <name> { <arg_1>} {,<arg_2>} …{, <arg_k>}

    定义一个含有k个参数的名为<name>的宏. 宏定义必须以 .endm 来标记结束. 如果想提前跳出宏, 则可使用 .exitm . 这些和armasm中的MACRO, MEND和平MEXIT类似, 必须在宏参数前加一个”\”

.macro SHIFTLEFT a, b

      .if  \b<0

          MOV \a, \a, ASR #-\b

          .exitm

      .endif

      MOV  \a, \a, LSL #\b

.endm

.rept <number_of_times>

按照指定的次数重复执行一个代码块, 这个块以 .endr 来标记结束

<register_name> .req <register_name>

     为一个寄存器取个名字, tkg armasmRN类似, 但这里右边的寄存器不能只给出寄存器号, 必须给出具体的寄存器, acc  .req  r0.

.section <section_name> {, “<flags>”}

开始一个新的代码段或者数据段, 通常, 代码段称为 .text, 一个经过初始化的数据段称为 .data,  一个没有初始化的数据段称为 .bss . 它们都有默认的标记(flag), 连接器识别它们的默认名字, armasmAREA类似,

ELF格式文件的<flag>

     标记                      含义

       a                      可分配段

       w                      可写段

       x                       可执行段

.set <variable_name> , <variable_value>

设置一个变量的值, armasmSETA类似

.space <number_of_byte> {,<fill_byte>}

生成给定数量的字节, 如果指定了<fill_byte>, 则以指定的值填充每个字节, 如果没指定, 则以0 填充每个字节. armasmSPACE类似

.word <word1> {,<word2>}…

        把一系列的32位字当成数据插入汇编, armasmDCD类似

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(3) | 阅读(1595)
发表于:2006/10/14 21:18:02
标签:无标签

18

ARM学习笔记

1寄存器R16用作CPSR(Current Program Status Register,当前程序状态寄存器)CPSR可在任何运行模式下被访问,它包括条件标志位、中断禁止位、当前处理器模式标志位,以及其他一些相关的控制和状态位。

每一种运行模式下又都有一个专用的物理状态寄存器,称为SPSRSaved Program Status Register,备份的程序状态寄存器),当异常发生时,SPSR用于保存CPSR的当前值,从异常退出时则可由SPSR来恢复CPSR

由于用户模式和系统模式不属于异常模式,他们没有SPSR,当在这两种模式下访问SPSR,结果是未知的

    当中断产生的时候,把CPSR保存在SPSR是自动完成的。

 

对异常的响应

当一个异常出现以后,ARM微处理器会执行以下几步操作:

1、将下一条指令的地址存入相应连接寄存器LR,以便程序在处理异常返回时能从正确的位置重新开始执行。若异常是从ARM状态进入,LR寄存器中保存的是下一条指令的地址(当前PC4PC8,与异常的类型有关);若异常是从Thumb状态进入,则在LR寄存器中保存当前PC的偏移量,这样,异常处理程序就不需要确定异常是从何种状态进入的。例如:在软件中断异常SWI,指令MOV PCR14_svc总是返回到下一条指令,不管SWI是在ARM状态执行,还是在Thumb状态执行。

2、将CPSR复制到相应的SPSR中。

3、根据异常类型,强制设置CPSR的运行模式位。

4、强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。

还可以设置中断禁止位,以禁止中断发生。

如果异常发生时,处理器处于Thumb状态,则当异常向量地址加载入PC时,处理器自动切换到ARM状态

 

从异常返回

异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回:

1、将连接寄存器LR的值减去相应的偏移量后送到PC中。

2、将SPSR复制回CPSR中。

3、若在进入异常处理时设置了中断禁止位,要在此清除。

可以认为应用程序总是从复位异常处理程序开始执行的,因此复位异常处理程序不需要返回。

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(9) | 阅读(6676)
发表于:2006/10/14 21:12:40
标签:无标签

10

画中画的硬件原理

要实现画中画功能,首先得有两个前提,背景图片,动画或视频,在图片中嵌入视频信息。

    先用ARM产生图片信息,用视频解码芯片解调视频信息,再用FPGA把这两路信号合成,输出到FTF LCD上显示,难点在FPGA上。

利用这种方法已经可以实现640X480,320X240,600X800三种格式的画中画了。

 

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(1) | 阅读(1983)
发表于:2006/10/14 21:03:22
标签:无标签

8

44B0的初始化程序的理解

 44B0的初始化程序就是初始化各个关键的寄存器,建立中断向量,然后转移到主函数去执行程序。
      不过44B0不支持地址映射,所以程序不COPY到RAM种执行。44B0初始化对我们广大初学者来说,比较难理解的是中断的处理和一些少见的操作符号,44b0的中断子程序地址存放在初始化程序最后就是

HandleADC # 4
HandleRTC # 4
HandleUTXD1 #   4
HandleUTXD0 # 4
HandleSIO # 4
HandleIIC # 4
HandleURXD1 # 4
HandleURXD0 # 4
      这一段,它的其实地址是ISR_STARTADDRESS,个人写中断程序的时候,子程序地址被编译器连放在相应的位置。初始化完成后,程序转通过BL Main 转到用户定义的主程序上执行。以下是我个人的一些理解,有错误的地方
希望大家指出来。


    GBLL    THUMBCODE
    [ {CONFIG} = 16 
THUMBCODE SETL {TRUE}
    CODE32
    |  
THUMBCODE SETL {FALSE}
    ]

    [ THUMBCODE
    CODE32   ;for start-up code for Thumb mode
    ]
×××××××××××××××××××××××
其中[=IF ,|=ELSE ,]= ENDIF, CODE32 表明一下操作都在ARM状态。这些都是伪操作
这段我理解为设定THUMCODE的值,然后确定,用户的程序是在ARM状态还是THUM状态。不过不管THUMCODE是何值,下面代码都是ARM状态
这段没有什么很复杂的,就是这三个[,|,]操作符让我迷惑了半天,翻了半天书才找到解释


    MACRO 宏 伪操作
$HandlerLabel HANDLER(宏的名称) $HandleLabel(宏的参数)

$HandlerLabel
    sub     sp,sp,#4     ;decrement sp(to store jump address)
    stmfd   sp!,{r0}     ;PUSH the work register to stack(lr does't push because it return to original address)
    ldr     r0,=$HandleLabel;load the address of HandleXXX to r0
    ldr     r0,[r0]     ;load the contents(service routine start address) of HandleXXX
    str     r0,[sp,#4]     ;store the contents(ISR) of HandleXXX to stack
    ldmfd   sp!,{r0,pc}     ;POP the work register and pc(jump to ISR)
    MEND
*******************************
      这段当初我觉得比较难理解,不过通过看各种程序,对这段有了一个基本的理解。这个宏的作用是把各个中断程序的地址装入当前的PC,44B0有两种装断模式 一种是没有中断向量表,一种是使用中断向量表的
使用中断向量表只能是IRQ方式,当使用中断向量表的时候,中断发生时由44B0的中断控制器自动跳转到相应的位置。比如在中断向量表的模式下,一个外部中断0发生程序自动跳转到 地址0X20处,0X20地址单元的指令时ldr pc,=HandlerEINT0因而程序PC跳到HandlerEINT0处,执行这个宏操作,把外部中断的函数的地址赋给PC。 44B0里面定义了一个

#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x84)) ,_ISR_STARTADDRES是中断程序地址的起始地址,_ISR_STARTADDRESS+0X84是HandleEINT0的地址


      例如一个外部中断函数名void EXINT(),程序里执行 pISR_EINT0=(unsigned)EXIT,就把自己的函数地址赋给了标号为HandleEINT0处的内存单元
IMPORT |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
    IMPORT |Image$$RW$$Base|   ; Base of RAM to initialise
    IMPORT |Image$$ZI$$Base|   ; Base and limit of area
    IMPORT |Image$$ZI$$Limit|  ; to zero initialise
××××××××××××××××××××××××××××××××××
这段我个人的理解为这些是连接器生成的于输出段相关的符号,是在没有使用SCATTER文件的情况可以调用。这段指出了在ROM和RAM种的数据的地址,这些地址应该是连接器生成的,不过为什么能调用
连接器生产的符号,我不大明白其中的原因,还希望各位说说自己的理解
IsrIRQ ;using I_ISPR register.
    sub     sp,sp,#4       ;reserved for PC
    stmfd   sp!,{r8-r9}  

 ;IMPORTANT CAUTION
 ;if I_ISPC isn't used properly, I_ISPR can be 0 in this routine.

    ldr     r9,=I_ISPR
    ldr     r9,[r9]
    mov     r8,#0x0
0
    movs    r9,r9,lsr #1
    bcs     %F1
    add     r8,r8,#4
    b     %B0

1
    ldr     r9,=HandleADC
    add     r9,r9,r8
    ldr     r9,[r9]
    str     r9,[sp,#8]
    ldmfd   sp!,{r8-r9,pc}
×××××××××××××××××××××××
这段是没有使用装断向量模式下如何装载中断子程序,因为44B0有30个中断源,所以需要程序处理以确定调用那个中断程序
0,1是局部标号,%B是向后搜索局部标号, %F是向前搜索局部标号 。都是伪操作
I_ISPR寄存器各位表明发生了应该调用那个中断子程序。只能1位置位,其它位为0,比如说串口1发送中断发生,这时I_ISPR的
值为0X04,ldr     r9,=I_ISPR
           ldr r9,[r9] 两条指令后,r9的内容为0X4 ,
 movs    r9,r9,lsr #1 r9内容右移一位
 bcs     %F1  判断是否把置位是否转移到C位,
    add     r8,r8,#4 如果没有的R8加4
如果r9内容为0x04 需要右移3次 ,之后r8的内容为8 然后HandleADC的地址 加上r8的值 就是串口1发送中断的地址,这个地址的内容是中断子程序的地址
再说明几个伪操作:^=MAP.       #=field

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(4) | 阅读(2153)
发表于:2006/10/14 21:02:39
标签:无标签

9

通过网络烧写39VF160步骤

通过FTP烧写FLASH是一个编程工具,提供对39VF160的编程,这个程序出售时已经烧写到ARM anywhereII的29F040中,用户拿到开发板后可以直接使用。具体内容

1.电路连接:

 

 

 

 

 

 


 

或者这样连接

HUB

 

 

 

 

 

 

 

 


 

S1

 

S2

 
2.拨码开关设置如下:

 

 


 

拨向上方ON:                     拨向下方OFF

 

(设置说明:BOOTROM宽度-8位;CS0-28SF040(39VF040);CS1-39vf160,endian-little)

 

3.打开超级终端:

4.根据情况选择一个串口(例子中选择COM1):

5.在属性中进行如下配置:

6.打开FTP SERVER(FTP SERVER在随机所配的光盘中有):

在“Security”菜单下的“Users/Rights...”下设置登录用户名为someone,密码为 0000,文件路径为d:\downFiles,并在选中后面的“Restricted home”。在"logging"菜单下的“log option...”下选中“Enable logging”、“logs”、“gets”、“commands”、“warning”就可以了。

需要在D盘下建立一个文件夹名为downfiles,把需要下载到39VF160的二进制格式文件拷贝到该目录下,例如BOOTROM.BIN。主机IP必须为192.168.0.X; X不能为221,因为这是烧写程序设定开发板的IP。

7.接通开发板电源

可以在超级终端中看到如下的启动界面:

 

然后按照提示输入主机IP地址,如果直接回车,这将以默认的IP“192.168.0.110”当作主机的IP,本例中主机IP为:192.168.0.31,回车后,提示输入文件名,例如需要下载BOOTROM.BIN到39VF160中,则输入 BOOTROM.BIN(该文件必须拷贝到D:/downfiles目录下,而且是BIN格式,不能为HEX等其他格式)。

回车后,程序将通过网络,以FTP方式把存在主机中的BOOTROM.BIN文件下载到开发板中,然后烧写到39VF160中。烧写成功后,将提示file Write successed!,如下图:

 

8.关闭电源

S1

 

S2

 
9.然后把拨码开关按照下图设置(little endian):

 

 

 


 

拨向上方ON:        拨向下方OFF:

 

 


 

(设置说明:BOOTROM宽度-16位;CS0-39VF160,U1、U2未使用,endian-little)

 

S1

 

S2

 
或者按照下图设置(big endian):

 

 

 


 

(设置说明:BOOTROM宽度-16位;CS0-39VF160,U1、U2未使用,endian-big)

 

10.上电后,程序将从39VF160开始执行

 

补充说明:

    如果没有特殊说明,该开发板出厂时,39VF040(28SF040)中默认的是固化该烧录程序。

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(1794)
发表于:2006/10/13 20:39:59
标签:无标签

9

砌墙工人的命运

三个工人砌一堵墙
   有人过来说:“你们在干什么?”
   第一个没好气的地说:“没看见吗?砌墙。”
   第二个抬头笑了笑,说:“我们在盖一幢高楼。”
   第三个边干边哼着歌曲,他的笑容很灿烂开心:我们正在建设一个新城市。”
   10年后,第一个人在另一个工地上砌墙;第二个人坐在办公室画图纸,他成了工程师;第三个呢,是前两个的老板。

系统分类: 生活点滴   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(799)
发表于:2006/10/13 20:38:58
标签:无标签

15

DSP的双电源解决方案

DSP的供电电路设计是DSP应用系统设计的一个重要组成部分。TIDSP家族(C6000和C54xx)要求有独立的内核电源和I/O电源,如TMS320VC5402,它的内核电压是1.8V,I/O电压是3.3V。由于DSP一般在系统中要承担大量的实时数据计算,在其CPU内部,频繁的部件开关转换会使系统功耗大大增加。所以降低为DSP内部CPU供电的核心电压无疑是降低系统功耗的最有效的办法之一。
  虽然TI的DSP不要求内核电源和I/O电源之间有特殊的上电顺序,但是假如有一个电源低于正常的工作电压,设计时就要确保没有任何一个电源在这个时间段处于上电状态,如果违反此规则,将严重影响器件的长期可靠性。另外,从系统级考虑,总线竞争就要求按顺序上电。这种情况下,内核电源的上电就应当同步或提前于I/O控制器。
  讲究供电次序的原因在于:如果只有CPU内核获得供电,周边I/O没有供电,对芯片是不会产生任何损害的,只是没有输入/输出能力而已;如果反过来,周边I/O得到供电而CPU内核没有加电,那么芯片缓冲/驱动部分的三极管将处于一个未知状态下工作,这是非常危险的。在有一定安全措施保障的前提下,允许两个电源同时加电,两个电源都必须在25ms内达到规定电平的95%。


1 输入电压等于3.3V的情况
1.1 使用场效应管和有PG引脚的直流电压转换器
  这种方案是所有方案中最简单的一种。它用一个P沟道的场效应管作为电源分配开关。这种方法要求直流电压转换器具有PG(Power Good)引脚。在核电压输出未到达额定值之前,PG引脚一直输出为高。当核电压输出达到额定值后,PG引脚变低,驱动场效应管打开,把外部3.3V电压加到DSP的I/O上。所以,这种方法可以保持正确的上电顺序。

 

断电时的情况则比较复杂,有很多因素将会影响断电的顺序,如负载电流的驱动能力、电容的大小等。不过一种可能的顺序是:在去除了外部33V的电压后,直流电压转换器的输出电压降低,同时PG引脚变高,关闭了场效应管,去除了DSPIO电压。
  需要说明的一点是:因为PG引脚是漏极开路输出,所以要在源极与栅极之间加一个电阻,以确保当PG引脚变成高阻时,场效应管能够关闭。
1
2 使用场效应管和电源监测芯片
  如果直流电源转换器没有PG管脚,则可以使用电源监测芯片(Supply Voltage SupervisorSVS)来完成这个功能。这样不仅可以很好地保证上电和断电的顺序,还可以实现对DSP的复位。
  在这个电路里,SVS负责监测外部输入电压。上电时,当33V电压超过SVS的门限电压200ms后,RESET引脚输出为低,驱动场效应管工作,把外部的33V电压加到DSPIO上。这里假设直流电源转换器的响应时间小于200ms

在断电时,当去除33V的外部电压后,SVS检测到并马上输出一个RESET高,关闭场效应管,这样就可以保证在去除核电压前去除IO电压。同样,这里也有一个假设,那就是在33V的电压衰减后,直流电压变换器还能持续输出很短时间的电压。当然,这也是一个合理的假设。
  在这个电路里,TPS382433专门用来监测33V电压。这一系列的芯片可以监测11V6V的电压,同时,SVS还有看门狗引脚WDI供设计者使用。SVS内部集成了一个带电复位生成器,只要其自身的供电电压在1V以上,就可以保证输出有效的RESET信号。一旦监测电压低于阈值电压时,复位逻辑输出被激活并使处理器复位。
  如果直流电压转换器有PG引脚,则可以如图2所示:把PG引脚和RESET引脚用一个与门相连,输出到DSPRESET引脚。当SVSRESET引脚输出为低,或者DCDCPG引脚输出为低(表示现在电源输出未达到正常),都将实现对DSP的复位操作。
2
 输入电压高于33V的情况
  由于输入电压高于33V,所以在电路中还必须使用电压调节器。这里选用的是TI的低压差电压调节器(LDO),在实际设计中选用具体的LDO时,还要考虑输出电流的驱动能力等因素。在TI的网站上有为C5000C6000系列推荐的电源系列。
2
1 带有PG引脚的低压差电压调节器
  这种方案要求低压差电压调节器具有ENABLE引脚,直流电压转换器具有PG引脚。在上电时,当直流电压转换器输出正常电压后,PG引脚变低,使能LDOENABLE引脚,LDO工作,输出DSPIO电压,这样就可以让IO电压的上电电压滞后于核电压的上电。这里的直流电压转换器可以是LDO也可以是开关电源,这取决于输出电流的要求。
  同样,在断电时由于有很多不确定的因素,将无法保证准确的断电顺序。一种可能的顺序是:当去除外部33V电压后,直流电压转换器输出衰减,同时PG引脚输出为高,关闭LDO,去除DSPIO电压。对于特定的某一系统,需要通过试验来确定准确的断电顺序。TPS76733有一个加电启动的PORPoweronReset)引脚,它与DSPRESET引脚直接相连。

22 低压差电压调节器和SVS
  如果对核电压供电的直流电压转换器没有PG引脚,则需要使用SVS来实现对IO电压的延迟。这种方案与12小节介绍的方案很类似。在上电时,当输入电压超过阈值电压200ms后,RESET输出高,使能LDO输出IO电压。在断电时,当外部电压衰减后,SVSRESET输出高,关闭LDO从而关闭IO电压,而直流电压转换器仍然可以持续供电很短的时间,这样就保证了断电的正确时序。在这里,SVS选用的是TPS382450,专门用来监测5V的输入电压。

如果对核电压供电的直流电压转换器有PG引脚,则若成本允许,也可以使用这种方法,同时还可以实现对DSP的复位。把SVSRESET引脚和DCDCPG引脚通过一个与门相连,输出到DSPRESET引脚,具体电路可以参考图2
3
 结束语
  本文从总体上介绍了DSP的双电源解决方案,但是针对具体的电源要求,如最大输出电流、输出纹波电压、电源效率、输出电压容差等,都必须在电路设计和电源芯片的选择上加以考虑。值得注意的是文中没有包括必须的退耦电容。

系统分类: DSP   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(1004)
发表于:2006/10/13 20:21:09
标签:无标签

12

如何在FreeRTOSforx256中增加自己的中断

中断的添加过程:

首先,因为中断要调用上下文切换代码,所以用汇编语言入口。

再从汇编语言中调用C语言。 需然在中断程序中不会完成多少任务,但是用C毕竟简化了工作,并给了代码充分的可读性。

最后就是将中断向量写入AIC的中断向寄存器了。

中断程序:

汇编部分:

  RSEG ICODE:CODE
  CODE32

  EXTERN vUARTISR
  PUBLIC vUARTISREntry

; Wrapper for the EMAC interrupt service routine.  This can cause a
; context switch so requires an assembly wrapper.

; Defines the portSAVE_CONTEXT and portRESTORE_CONTEXT macros.


#include "ISR_Support.h"

vUARTISREntry:

 portSAVE_CONTEXT   ; Save the context of the current task.

 bl vUARTISR    ; Call the ISR routine.

 portRESTORE_CONTEXT   ; Restore the context of the current task -
        ; which may be different to the task that
        ; was interrupted.

  END

C语言部分:

 __arm void vUARTISR( void )
{
        unsigned int status;
        int i;
       
        status = AT91C_BASE_US0->US_CSR;
        AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;
       
       if(  status & AT91C_US_ENDRX )
        {
                for( i = 0; i < Rx_Count; i++ )
                {
                        US0_BuffTx[ i ] = US0_BuffRx[ i ];
                }


                Tx_Count = Rx_Count;
                AT91C_BASE_US0->US_TPR = ( unsigned int )US0_BuffTx;
                AT91C_BASE_US0->US_TCR = ( unsigned int )Tx_Count;
               
                AT91C_BASE_US0->US_RPR = (unsigned int )US0_BuffRx;
                Rx_Count = 8;
                AT91C_BASE_US0->US_RCR = Rx_Count;
        }
        else if( status & AT91C_US_ENDTX )
        {
          
        }
        else
        {
                AT91C_BASE_US0->US_THR = 'C';
        }
        

        //中断结束之后要通知系统中断处理完毕,否则下次此器件将不会产生中断
        AT91C_BASE_AIC->AIC_EOICR = 0x1234;
              
}


其中有一部分是在外面定义的全局变量。

unsigned int US0_BuffRx[256];
int Rx_Count;
unsigned int US0_BuffTx[256];
int Tx_Count;

中断设置部分:

/*-----------------------------------------------------------*/
void Init_UART_DMA()
{
        AT91PS_PIO pIO = AT91C_BASE_PIOA;
        pIO->PIO_PDR |= 0x03;
        pIO->PIO_ASR |= 0x03;
       
        AT91C_BASE_PMC->PMC_PCER |=  ( 1 << AT91C_ID_US0 );
        //USART :Normal Mode
        //USCLKS:MCK
        //CHRL(CHARACTER LENGTH):8BIT(11)
        //SYNC:0 In Asynchronous Mode
        //PAR:(100) No Parity
        //NBSTOP:1 stop bit
        //CHMODE(CHANNEL MODE):Normal Mode
        AT91C_BASE_US0->US_MR = 0x08C0;
       
        //baudrate = Select_Clock/(8(2-over)CD) = 47923200/(16*312) = 9600
        AT91C_BASE_US0->US_BRGR = 312;
       
        //reset usart0
        AT91C_BASE_US0->US_CR = 0x010C;
        //set interrupt bit
        AT91C_BASE_US0->US_IDR = 0xFFFFF;
        //enable rxen and txen
        AT91C_BASE_US0->US_CR = 0x0050;
        //Disable AIC interrupt
        AT91F_AIC_DisableIt( AT91C_BASE_AIC, AT91C_ID_US0 );
        //Enable Interrupt in us0
        AT91C_BASE_US0->US_IER = 0x00018;
      
        AT91F_DBGU_Print32( AT91C_BASE_US0->US_CSR );
       
        AT91C_BASE_US0->US_PTCR = 0x00000101;
       
        prvSetupUARTInterrupt( );
       
        AT91C_BASE_US0->US_RPR = ( unsigned int )US0_BuffRx;
        Rx_Count = 8;
        AT91C_BASE_US0->US_RCR = Rx_Count;
 
}
/*-----------------------------------------------------------*/

static void prvSetupUARTInterrupt( void )
{
   /* Enable the interrupts in the AIC. */
   AT91F_AIC_ConfigureIt(

           AT91C_BASE_AIC,

           AT91C_ID_US0, 6,  

           AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,

           ( void (*)( void ) ) vUARTISREntry

          );

           AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_US0 );

}

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(892)
发表于:2006/10/13 20:18:16
标签:无标签

12

ucgui的44b0移植简要过程

1。修改宏LCD_BITSPERPIXEL

2。修改宏 LCD_INIT_CONTROLLER()  LcdInit()  ,LcdInit为我们自己写的lcd的初始化函数,不要去管什么registers

3。选用合适的调色板 LCD_FIXEDPALETTE

4。定义宏SETPIXEL,GETPIXEL,XORPIXEL

5。去掉一些关于windows 模拟器的一些宏以及调用(比如在LCDwin。c 去掉WIN32的预编译宏,以及引用的<windows.h>库)。

6。修改TimerTicks的读取。(在timer中断中加入相应的递增)。

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(0) | 阅读(1136)
发表于:2006/10/13 20:16:38
标签:无标签

15

RTL8019驱动

首先,我们要编写一个读写8019寄存器的函数

 

 /*****************************************************************************************************
//函数名:uint8 readRegister(uint8 address)
//描述  :
//参数  : address-- 地址
//返回  : 寄存器的值
//其他  :
******************************************************************************************************/
uint8 readRegister(uint8 address)
{
 uint8  temp;
 uint8  addr;
 uint32 rdata;
 temp = address;
 temp &=  0x1f; //only 5 bits
/*
 addr = (~temp) ;
 IO0SET = (IO0SET & 0xff00ffff) | (temp<<16);
 IO0CLR = (IO0CLR & 0xff00ffff) | (addr<<16);*/
 addr = (~temp) & 0x1f;
 IO0SET = (IO0SET & 0xffe0ffff) | (temp<<16);
 IO0CLR = (IO0CLR & 0xffe0ffff) | (addr<<16);
 
 //IO1SET |=0x
 IO1SET |=0x00ff0000;//IOCON;
 
 //set to read
 IO0CLR |=RTL8019_R;
 IO0CLR |=RTL8019_RDY;
 //change dir to input
 IO1DIR &=0xff00ffff;//改变为输入
 //read the data
 rdata="IO1PIN";
 
 //end read
 IO0SET |=RTL8019_RDY;
 IO0SET |=RTL8019_R;
 
 //change dir to output
 IO1DIR |=0x00ff0000;
 return (uint8 )(rdata>>16);
 }

/*****************************************************************************************************
//函数名:void writeRegister(uint8 address,uint8 val)
//描述  :
//参数  :
//返回  :
//其他  :
******************************************************************************************************/
void writeRegister(uint8 address,uint8 val)
{
 uint8  temp;
 uint8  addr;
 
 
 temp = address;
 temp &=  0x1f; //only 5 bits
/*
addr = (~temp);

 IO0SET= (IO0SET & 0xff00ffff) | (temp<<16);

 IO0CLR = (IO0CLR & 0xff00ffff) | (addr<<16);*/
 addr = (~temp)& 0x1f;
 IO0SET= (IO0SET & 0xffe0ffff) | (temp<<16);
 IO0CLR = (IO0CLR & 0xffe0ffff) | (addr<<16);


 //output data
 IO1DIR |=0x00ff0000;
 //IO1SET |= val<<16;
 //IO1CLR |= (~val)<<16;
 
  addr = (~val);
  IO1SET = (IO1SET & 0xff00ffff) | (val<<16);
 
  IO1CLR= (IO1SET & 0xff00ffff) | (addr<<16);

  
 //active write
 IO0CLR |=RTL8019_W;
 IO0CLR |=RTL8019_RDY;
 IO0SET |=RTL8019_RDY;
 IO0SET |=RTL8019_W;
 
 IO1SET |=0x00ff0000;//IOCON;
 }

 

RTL的寄存器分为4页,可以通过设定CR(command Register)的PS1 PS0 来选择.

/*****************************************************************************************************
//函数名:void PageSelect(uint8 pageNum)
//描述  :
//参数  :
//返回  :
//其他  :
********************************************************************************************************/
void PageSelect(uint8 pageNum)
{
 uint8 temp;
 
 temp = readRegister(RTL8019_CR);
 temp &= 0x3b;
 temp |=(pageNum<<6);
 writeRegister(RTL8019_CR,temp);
 }

有了这3个函数,我们就只需要对RTL8019的寄存器进行设置就可以了.就是说,剩下的工作就是进行配置.下面有个比较典型的配置.

/*****************************************************************************************************
//函数名:void netInit(void)
//描述  :
//参数  :
//返回  :
//其他  :本程序参考过www.laogu.com ,zlg的TCP/IP,想对程序进行更深入的了解可以到他们的网站获取
********************************************************************************************************/
void netInit(void)
{
 HardWareInit();
 delayMs(200);
 writeRegister(0x1f,0x00);
 delayMs(200);
 writeRegister(0x00,0x21);//stop net card
 delayMs(200);
 
 PageSelect(0);
 writeRegister(0x0a,0x00);
 writeRegister(0x0b,0x00);
 writeRegister(0x0c,0xe0);//RCR
 writeRegister(0x0d,0xe2);//TCR

 PageSelect(0);
 writeRegister(0x01,0x4c);//PStart
 writeRegister(0x02,0x80);//PStop
 writeRegister(0x03,0x4c);//Bnry
 PageSelect(0);
 writeRegister(0x04,0x40);//TPSR
 writeRegister(0x07,0xff);//clear intrrput bit
 writeRegister(0x0f,0x11);
 //writeRegister(0x0e,0xcb);
 writeRegister(0x0e,0xc8);///8bits DMA
 PageSelect(1);
 writeRegister(0x07,0x4d);//CURR
 writeRegister(0x08,0x00);
 writeRegister(0x09,0x00);
 writeRegister(0x0a,0x00);
 writeRegister(0x0b,0x00);
 writeRegister(0x0c,0x00);
 writeRegister(0x0d,0x00);
 writeRegister(0x0e,0x00);
 writeRegister(0x0f,0x00);
 writeRegister(0x00,0x22);
 writeMAC(NetPort[0].My_Mac);
 
 PageSelect(0);
 writeRegister(0x0c,0xcc);
  ////RCR 1 1 MON PRO AM AB AR SEP
 //bit.5 MON = 1 这只检查地址,不存入缓冲
 //bit.4 PRO = 1 所有包的目标MAC地址都接收
 //bit.3 AM  = 1 接收目标地址为组播地址
 //bit.2 AB  = 1 接收目标地址为广播地址
 //bit.1 AR  = 1 长度小于64字节的也接收
 //bit.0 SEP = 1 包有接收错误也接收
 writeRegister(0x0d,0xe0);
 writeRegister(0x00,0x22);
 //writeRegister(0x0f,0xff);//IMR
 writeRegister(0x07,0xff);
 
 }

经过这样的配置以后,连接上网络看到接收的LED在闪烁,说明已经可以接收到网络上的数据.下面要做的就是把数据从8019的ram中读入来.

系统分类: ARM   |    用户分类: 无分类    |    来源: 无分类

评论(1) | 阅读(2653)
23456Next >Total , Page /