ARM精讲演示代码
《常用ARM指令》课件

算术指令
用于进行数学运算,如ADD 和SUB指令。
逻辑指令
用于执行逻辑运算,如AND 和OR指令。
分支指令
1
B
无条件分支到指定地址的指令。
2
BL
无条件分支并将下一条指令的地址存储到链接寄存器中。
3
CBZ
如果寄存器的值为零,则分支到指定地址。
STR
2
将寄存器中的数据存储到内存。
3
LDM
从内存中加载多个数据到寄存器。
调用子程Байду номын сангаас指令
1 BL
无条件分支并将下一条指令的地址存储到链接寄存器中。
2 BX
无条件分支到另一个指令集的指令。
软件中断指令
软件中断指令用于在程序中插入中断请求,以便处理外部事件。常用的软件 中断指令有SWI和BKPT。
《常用ARM指令》PPT课件
ARM架构是一种广泛应用于移动设备和嵌入式系统的处理器架构。本课程将 详细介绍常用的ARM指令种类,帮助您更好地理解和应用ARM架构。
ARM架构概述
ARM架构是一种RISC(精简指令集计算机)架构,设计用来提供高性能、低功耗和低成本的处理能力。
ARM指令的种类
数据移动指令
比较指令
CMP
用于比较寄存器的值和另一个 操作数。
CMN
用于比较寄存器的值和另一个 操作数的负值。
TST
用于测试寄存器的值和另一个 操作数的位。
条件执行指令
条件执行指令允许根据条件选择性地执行或跳过某个指令。常用的条件执行指令有BEQ、BNE、BGT等。
访问内存指令
1
LDR
从内存中加载数据到寄存器。
第二讲ARM指令集课件

第二讲 ARM指令集
块拷贝与栈操作的对应关系
栈操作
块拷贝
先 增
后
先 减
后
地址变化方向
向上
向下
满
空
满
空
STMIB
LDMIB
STMFA
LDMED
STMIA
LDMIA
STMEA
LDMFD
LDMDB
STMDB
LDMEA
STMFD
LDMDA
STMDA
LDMFA
前变址不回写形式: [<Rn>,+/-<Rm>] 前变址回写形式: [<Rn>,+/-< Rm >]! 后变址回写形式: [<Rn>],+/-< Rm >
第二讲 ARM指令集
偏移量为寄存器值的指令编码类型对应关 系 31 28 27 25 24 23 22 21 20 19 16 15 12 11 8 7 6 5 4 3 0
内容提要
3.1 3.2 3.3 3.4
ARM指令的编码格式 数据处理指令寻址方式 Load/Store指令寻址 批量Load/Store指令寻址方式
第二讲 ARM指令集
3.1 ARM指令的编码格式
一般编码格式 指令条件码
第二讲 ARM指令集
一般编码格式
每条ARM指令占有4个字节,其指令长度为32位
ARM的汇编指令讲解

汇编知识点的要求:1、能看的懂2、可以做修改3、不需要用汇编直接编写程序汇编代码的应用场合:1、ARM的启动代码必须要汇编,如:uboot最开始初始化硬件的代码2、内核在最开始初始化的位置。
一、ARM汇编指令的编码格式1、编码格式ARM汇编指令编译成机器码以后,机器码的长度是32bits,这32bits的编码有一个固定的格式。
不同ARM 汇编指令,编码格式不同。
2、举例C:if(a==10)a++;elsea--;汇编1:CMP R0, #10;ADDEQ R0,R0,#1SUBNE R0,R0,#1汇编2SUBS R1, R0, #10; //S ---运算的结果会影响条件码标志位:CPSR:NZCVADDEQ R0,R0,#1SUBNE R0,R0,#1提示:空指令NOP,实际上是占用CPU的时间,但是执行后,没有什么意义。
NOP ---- MOV R0,R03、条件码标识10 -10Z = 1C = 0N = 0V = 0=================================================================================二、ARM的寻址方式1、立即数寻址操作数,有立即数。
ADD R0,R0,#1MOV R1,#10ORR R1,R1,#0xf @ R1=R1 | 0xfBIC R1,R1,#0xf @R1 = R1&(~(0xf))错误:ADD R1,#1,#2注意:立即数合法的条件在ARM汇编指令中,并不是所有的立即数,立即数是有一定的限制的。
什么样的立即数是合法的???1、如果一个立即数是小于256的(即该立即数是8bits以内的,0~255),该立即数是合法的。
2、如果一个立即数是大于等于256,该立即数经过循环左移偶数位,可以得到一个小于256的数,则该立即数合法。
256 = 0x100 ------→左移20位0x10000000----→左移4 0x1 合法0x111 非法0x102 非法0x104 合法0xfff0xff000x120000x4500000xab原因:在数据处理指令编码的时候,立即数用12bits来表示:高4bits:循环左移左移偶数位除以2低8bits:循环左移后的结果。
ARM指令集详解(超详细!带实例!)

算术和逻辑指令ADC : 带进位的加法(Ad dition with C arry)ADC{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 + op_2 + carryADC将把两个操作数加起来,并把结果放置到目的寄存器中。
它使用一个进位标志位,这样就可以做比32 位大的加法。
下列例子将加两个128 位的数。
128 位结果: 寄存器0、1、2、和3第一个128 位数: 寄存器4、5、6、和7第二个128 位数: 寄存器8、9、10、和11。
ADDS R0, R4, R8 ; 加低端的字ADCS R1, R5, R9 ; 加下一个字,带进位ADCS R2, R6, R10 ; 加第三个字,带进位ADCS R3, R7, R11 ; 加高端的字,带进位如果如果要做这样的加法,不要忘记设置S 后缀来更改进位标志。
ADD : 加法(Add ition)ADD{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 + op_2ADD将把两个操作数加起来,把结果放置到目的寄存器中。
操作数 1 是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即值:ADD R0, R1, R2 ; R0 = R1 + R2ADD R0, R1, #256 ; R0 = R1 + 256ADD R0, R2, R3,LSL#1 ; R0 = R2 + (R3 << 1)加法可以在有符号和无符号数上进行。
AND : 逻辑与(logical AND)AND{条件}{S} <dest>, <op 1>, <op 2>dest = op_1 AND op_2AND将在两个操作数上进行逻辑与,把结果放置到目的寄存器中;对屏蔽你要在上面工作的位很有用。
ARM指令集详解ppt课件

精选ppt课件2021
17
比较指令
• CMP : 比较 • CMP{条件}{P} <op 1>, <op 2>
• status = op_1 - op_2
• CMP 允许把一个寄存器的内容如另一个寄存器的内容 或立即值进行比较,更改状态标志来允许进行条件执行。 它进行一次减法,但不存储结果,而是正确的更改标志。 标志表示的是操作数 1 比操作数 2 如何(大小等)。如果 操作数 1 大于操作操作数 2,则此后的有 GT 后缀的指 令将可以执行。不需要显式的指定 S 后缀来更改状态标 志,如果指定了它则被忽略。
精选ppt课件2021
14
EOR : 逻辑异或
• EOR{条件}{S} <dest>, <op 1>, <op 2> • dest = op_1 EOR op_2 EOR • 将在两个操作数上进行逻辑异或,把结果放置到
目的寄存器中;对反转特定的位有用。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被 移位的寄存器,或一个立即值: • EOR R0, R0, #3 ; 反转 R0 中的位 0 和 1
精选ppt课件2021
21
数据传送指令
• MOV{条件}{S} <dest>, <op 1>
• dest = op_1
• MOV 从另一个寄存器、被移位的寄存器、或一个立即 值装载一个值到目的寄存器。可以指定相同的寄存器来 实现 NOP 指令的效果,还可以专门移位一个寄存器:
• MOV R0, R0 ; R0 = R0... NOP 指令
ARM汇编指令机器码举例详解

ARM汇编指令机器码举例详解
ARM7内核采用的是RISC精简指令集,所有的ARM指令都是32bits的,在这32bits里既包含了指令的指令码,也包含了指令需要运算的数据,以MOV 指令为例,通过MOV指令的32bits可以识别出这是一个MOV指令,又可以在这32bits里找到源寄存器和目的寄存器。
我们来看一下MOV指令的机器
码格式:
28~31bits(cond)是条件码,就是表明这条语句里是否有大于、等于、非零等的条件判断,这4bits共有16种状态,分别为:
表 1 汇编语言条件码
指令与条件码可以有多种组合,比如MOV指令可以有MOV、MOVEQ、MOVLT等多种形式。
前面我们说过状态寄存器里有NZCV的状态标志,
当执行一条指令时,芯片就会将这条指令的条件码与状态寄存器中的状态标志做比较,如果状态寄存器中的状态标志满足这条指令的条件码时,则执行这条语句,如果不满足则不执行这条指令。
状态寄存器中的状态标志是受某些指令影响的,因此在使用有条件码的
指令进行判断前,必然会有其它指令配合使用,先修改状态寄存器中的状态标志。
ARM的指令系统 ppt课件

;读取R1地址上的存储器单元内容,即R0←[R1],无条件执行
Lable
;跳转指令B,执行条件EQ,即相等则程序跳转到Lable处
R1,R1,R2 ;加法指令,R1 + R2→R1,即R1 + R2的结果送给R1
R1,R1,#1 ;加法指令,R1 + 1→R1,并影响状态寄存器(S)
第3条指令的R2和第4条指令的#1都是第二操作数。 第二操作数可以是:
和逻辑运算的单纯移位操作,操作数乘以2n可以 用左移n位来实现 ④ 当PC(R15)用作目的寄 存器时,可以实现程序跳转。如“MOV PC, LR”,所以这种跳转可以实现子程序调用及从子 程序返回,代替指令“B,BL” ⑤ 当PC作为目标 寄存器且指令中S位被设置时,指令在执行跳转 操作的同时,将当前处理器模式的SPSR寄存器 的内容复制到CPSR中。这种指令“MOVS PC LR”可以实现从某些异常中断中返回。
ppt课件
19
2.6 其他后缀
④ 索引后缀与堆栈后缀 索引后缀包括IA、IB、DA、DB; 堆栈后缀包括FD、ED、FA、EA。 这些后缀用于多寄存器加载/存储指令。
⑤ T后缀 T后缀含义是:指令在特权模式下对存储器的访问,将被存储器看成是 用户模式的访问。 T后缀一般只用在字传送和无符号字节传送中。
SUB R0,R0,#1 ;将R0减1,结果放入R0 MOV R0,#0xFF ;将立即数0xFF装入R0寄存器
ppt课件
7
2.2 寄存器寻址
寄存器寻址是指:操作数的值在寄存器中,指令中的地址码字段 指出的是寄存器的编号,指令执行时直接取出寄存器值来操作。
例:寄存器寻址举例
MOV R1, R2
;将R2的值存入R1中
arm编程技巧PPT教学课件

-O1---DEBUGREL 多数优化选项许可 给一个满意的调试,好的代码密度
-O2---RELEASE (default) 完全的优化 有限的调试信息,最好的代码密度
为代码大小或运行速度的优化,可选择: -Ospace (默认的)或 -Otime. 使用-g 选像可包含源码级调试信息
ADD r1,r1,r1,LSL #1 LDR r0,[r0,#0] ADD r0,r0,r1 ; interlock on ARM9 MOV pc,lr
armcc –cpu arm7tdmi
使用指令编排 (-O1,-O2)
LDR r0,[r0,#0] ADD r1,r1,r1,LSL #1 ADD r0,r0,r1 MOV pc,lr
int a=10, b=20; int c; c=a+b; return 0; }
armcc -c -O1
dummy MOV r0, #0 MOV pc, lr
103v04 C/C++ Compiler Hints & Tips
TM
6
6
指令编排
指令编排在高级优化选项中是有效的(-O1, -O2). 指令的重新编排是为了使要运行的代码更适合对应的核
103v04 C/C++ Compiler Hints & Tips
TM
3
3
ADS 编译器在所有级别中执行一些简单的优化 i.e. -O0, -O1, -O2
下面是一个例子:即使用-O0,多余的表达式也被清除了: ATPCS标准中子程序结果返回规则
结果为32位整数,R0返回 结果为64位整数,R0,R1返回 位数更多时,用内存来传递 ……
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ARM精讲演示代码串口程序设计/************************************************* Function name: 这是基础实验的一个模版Parameter : 无Description : 做基础实验,直接调用该模板即可Return : 无Argument : 无Autor & date : Daniel**************************************************/ #define GLOBAL_CLK 1#include <stdlib.h>#include <string.h>#include "def.h"#include "option.h"#include "2440addr.h"#include "2440lib.h"#include "2440slib.h"#include "mmu.h"#include "profile.h"#include "memtest.h"static void cal_cpu_bus_clk(void);void Set_Clk(void);void beep_init(void);void beep_run(void);/************************************************* Function name: delayParameter : timesDescription : 延时函数Return : voidArgument : voidAutor & date : Daniel**************************************************/ void delay(int times){int i,j;for(i=0;i<times;i++)for(j=0;j<400;j++);}/*************************************************Function name: MainParameter : voidDescription : 主功能函数,实现了串口的收发功能首先想串口发送十次“hello world”,然后从键盘输入R,则蜂鸣器连续响5次。
Return : voidArgument : voidAutor & date : Daniel**************************************************/ void Main(void){int i;int Scom=0;Set_Clk();beep_init();/*设置波特率、数据位、停止位、校验位*/Uart_Init(0,115200);Uart_Select(Scom);for(i=0;i<10;i++)Uart_Printf("\nHello World!\n");}/************************************************* Function name: Set_Clk()Parameter : voidDescription : 设置CPU的时钟频率Return : voidArgument : voidAutor & date : Daniel**************************************************/ void Set_Clk(void){int i;U8 key;U32 mpll_val = 0 ;i = 2 ; //don't use 100M!//boot_params.cpu_clk.val = 3;switch ( i ) {case 0: //200key = 12;mpll_val = (92<<12)|(4<<4)|(1);break;case 1: //300key = 13;mpll_val = (67<<12)|(1<<4)|(1);break;case 2: //400key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;case 3: //440!!!key = 14;mpll_val = (102<<12)|(1<<4)|(1);break;default:key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;}//init FCLK=400M, so change MPLL firstChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCONChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bitcal_cpu_bus_clk(); //HCLK=100M PCLK=50M}/*************************************************Function name: cal_cpu_bus_clkParameter : voidDescription : 设置PCLK\HCLK\FCLK的频率Return : voidArgument : voidAutor & date : Daniel**************************************************/static void cal_cpu_bus_clk(void){static U32 cpu_freq;static U32 UPLL;U32 val;U8 m, p, s;val = rMPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;//(m+8)*FIN*2 不要超出32位数!FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; //FCLK=400M FIN=12000000val = rCLKDIVN;m = (val>>1)&3;p = val&1;val = rCAMDIVN;s = val>>8;switch (m) {case 0:HCLK = FCLK;break;case 1:HCLK = FCLK>>1;break;case 2:if(s&2)HCLK = FCLK>>3;elseHCLK = FCLK>>2;break;case 3:if(s&1)HCLK = FCLK/6;elseHCLK = FCLK/3;break;}if(p)PCLK = HCLK>>1;elsePCLK = HCLK;if(s&0x10)cpu_freq = HCLK;elsecpu_freq = FCLK;val = rUPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;UPLL = ((m+8)*FIN)/((p+2)*(1<<s));UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;}/************************************************* Function name: beep_init()Parameter : voidDescription : 初始化蜂鸣器Return : voidArgument : voidAutor & date : Daniel**************************************************/ void beep_init(void){rGPBCON &= ~(0x3<<0);rGPBCON |= (0x1<<0);}/************************************************* Function name: beep_run()Parameter : voidDescription : 运行蜂鸣器Return : voidArgument : voidAutor & date : Daniel**************************************************/ void beep_run(void){rGPBDAT |= (0x1<<0);delay(5000);rGPBDAT &= (0x0<<0);delay(5000);}触摸屏程序设计#define GLOBAL_CLK 1#include <stdlib.h>#include <string.h>#include "def.h"#include "option.h"#include "2440addr.h"#include "2440lib.h"#include "2440slib.h"#include "mmu.h"#include "profile.h"#include "memtest.h"#define ADC_FREQ 2500000int count = 0;volatile U32 preScaler;int xdata,ydata;void Test_Touchpanel(void);static void __irq AdcTsAuto(void);static void cal_cpu_bus_clk(void); void Set_Clk(void);/*延时函数*/void delay(int times){int i,j;for(i=0;i<times;i++)for(j=0;j<400;j++);}/*主函数*/int Main(void){int Scom=0;Set_Clk();Uart_Init(0,115200);Uart_Select(Scom);Test_Touchpanel();while(1);return 0;}/*触摸屏初始化*/void Test_Touchpanel(void){rADCDLY=50000; //Normal conversion mode delay about (1/3.6864M)*50000=13.56ms/*设置AD转频率*/preScaler = ADC_FREQ;preScaler = 50000000/ADC_FREQ - 1; //PCLK=50MrADCCON = (1<<14)|(preScaler<<6); //ADCPRS En,PRSCVL/*设置触摸屏为等待中断模式,等待触摸笔被按下*/rADCTSC=0xd3; //Wfait,XP_PU,XP_Dis,XM_Dis,YP_Dis,YM_En/*clear irq*/rSRCPND = 0x80000000;rINTPND = 0x80000000;ClearSubPending(BIT_SUB_TC);pISR_ADC = (U32)AdcTsAuto;/*enable INT_TC irq*/rINTMSK = 0x7fffffff;EnableSubIrq(BIT_SUB_TC);}/*************************************************Function name: AdcTsAutoParameter : voidDescription : 中断服务程序Return : voidArgument : voidAutor & date : Daniel**************************************************/static void __irq AdcTsAuto(void){U32 saveAdcdly;/****************stylus down************************//*检测子中断源,判断是否是INT_TC中断,且触摸笔按下*/if(rSUBSRCPND & (BIT_SUB_TC))if( !(rADCDAT0&0x8000))Uart_Printf("\nStylus down\n");elseUart_Printf("\nStylus up\n");}/*pull-up disable,自动连续X,Y坐标转换*/rADCTSC = (1<<3)|(1<<2);saveAdcdly=rADCDLY;rADCDLY=40000; //Normal conversion mode delay about (1/50M)*40000=0.8ms/*开始AD转换*/rADCCON|=0x1; //start ADCwhile(rADCCON & 0x1); //check if Enable_start is lowwhile(!(rADCCON & 0x8000)); //check if EC(End of Conversion) flag is high, This line is necessary~!!while(!(rSRCPND & 0x80000000)); //check if ADC is finished with interrupt bit/*获取X,Y坐标*/xdata=(rADCDAT0&0x3ff);ydata=(rADCDAT1&0x3ff);ClearSubPending(BIT_SUB_TC);//ClearPending(BIT_ADC);rSRCPND = 0x80000000;rINTPND = 0x80000000;EnableSubIrq(BIT_SUB_TC);//EnableIrq(BIT_ADC);rINTMSK = 0x7fffffff;/****************stylus down************************//****************stylus up**************************//*设置触摸屏为等待中断模式,等待触摸笔抬起*/rADCTSC =0xd3; //Waiting for interruptrADCTSC=rADCTSC|(1<<8); // Detect stylus up interrupt signal.while(1) //to check Pen-up state{if(rSUBSRCPND & (BIT_SUB_TC)) //check if ADC is finished with interrupt bit{Uart_Printf("Stylus Up Interrupt~!\n");break; //if Stylus is up(1) state}}/****************stylus up**************************/Uart_Printf("count=%03d XP=%04d, YP=%04d\n", count++, xdata, ydata);rADCDLY=saveAdcdly;/*设置触摸屏为等待中断模式,等待下次触摸笔按下*/rADCTSC =0xd3; //Waiting for interruptClearSubPending(BIT_SUB_TC);//ClearPending(BIT_ADC);rSRCPND = 0x80000000;rINTPND = 0x80000000;EnableSubIrq(BIT_SUB_TC);//EnableIrq(BIT_ADC);rINTMSK = 0x7fffffff;}/*************************************************Function name: Set_Clk()Parameter : voidDescription : 设置CPU的时钟频率Return : voidArgument : voidAutor & date : Daniel**************************************************/void Set_Clk(void){int i;U8 key;U32 mpll_val = 0 ;i = 2 ; //don't use 100M!//boot_params.cpu_clk.val = 3;switch ( i ) {case 0: //200key = 12;mpll_val = (92<<12)|(4<<4)|(1);break;case 1: //300key = 13;mpll_val = (67<<12)|(1<<4)|(1);break;case 2: //400key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;case 3: //440!!!key = 14;mpll_val = (102<<12)|(1<<4)|(1);break;default:key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;}//init FCLK=400M, so change MPLL firstChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCONChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bitcal_cpu_bus_clk(); //HCLK=100M PCLK=50M}/*************************************************Function name: cal_cpu_bus_clkParameter : voidDescription : 设置PCLK\HCLK\FCLK的频率Return : voidArgument : voidAutor & date : Daniel**************************************************/static void cal_cpu_bus_clk(void){static U32 cpu_freq;static U32 UPLL;U32 val;U8 m, p, s;val = rMPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;//(m+8)*FIN*2 不要超出32位数!FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; //FCLK=400M FIN=12000000val = rCLKDIVN;m = (val>>1)&3;p = val&1;val = rCAMDIVN;s = val>>8;switch (m) {case 0:HCLK = FCLK;break;case 1:HCLK = FCLK>>1;break;case 2:if(s&2)HCLK = FCLK>>3;elseHCLK = FCLK>>2;break;case 3:if(s&1)HCLK = FCLK/6;elseHCLK = FCLK/3;break;}if(p)PCLK = HCLK>>1;elsePCLK = HCLK;if(s&0x10)cpu_freq = HCLK;elsecpu_freq = FCLK;val = rUPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;UPLL = ((m+8)*FIN)/((p+2)*(1<<s));UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;}ADC驱动程序设计/************************************************* Function name: 这是基础实验的一个模版Parameter : 无Description : 做基础实验,直接调用该模板即可Return : 无Argument : 无Autor & date : Daniel**************************************************/ #define GLOBAL_CLK 1#include <stdlib.h>#include <string.h>#include "def.h"#include "option.h"#include "2440addr.h"#include "2440lib.h"#include "2440slib.h"#include "mmu.h"#include "profile.h"#include "memtest.h"#define ADC_FREQ 2500000volatile U32 preScaler;volatile U32 adc_value=0;void adc_init(void);int ReadAdc(int channel);static void cal_cpu_bus_clk(void);void Set_Clk(void);void beep_init(void);void beep_run(void);/************************************************* Function name: delayParameter : timesDescription : 延时函数Return : voidArgument : voidAutor & date : Daniel**************************************************/ void delay(int times){int i,j;for(i=0;i<times;i++)for(j=0;j<400;j++);}/************************************************* Function name: MainParameter : voidDescription : 主功能函数Return : voidArgument : voidAutor & date : Daniel**************************************************/ void Main(void){/*时钟初始化*/Set_Clk();/*adc初始化*/adc_init();while(1){/*读取转换值*/adc_value=ReadAdc(0);delay(1000) ;}}Function name: adc_init()Parameter : int channelDescription : adc初始化Return : voidArgument : voidAutor & date : Daniel**************************************************/void adc_init(void){//选择输入通道,AIN0,对应开发板上W1可调电阻int channel=0;/*设置分频时钟*/preScaler = ADC_FREQ;preScaler = 50000000/ADC_FREQ - 1; //PCLK=50M/*AD转换频率设置,最大频率为2.5MHz*/rADCCON = (1<<14)|(preScaler<<6)|(channel<<3); //setup channeldelay(1000);}/*************************************************Function name: ReadAdc(int channel)Parameter : int channelDescription : 获取AD 转换后的值Return : intArgument : voidAutor & date : Daniel**************************************************/int ReadAdc(int channel){/*开始AD转换*/rADCCON |= 0x01; //start ADCwhile(rADCCON & 0x1); //check if Enable_start is low/*检查转换是否结束*/while(!(rADCCON & 0x8000)); //check if EC(End of Conversion) flag is high return ( (int)rADCDAT0 & 0x3ff );}Function name: Set_Clk()Parameter : voidDescription : 设置CPU的时钟频率Return : voidArgument : voidAutor & date : Daniel**************************************************/void Set_Clk(void){int i;U8 key;U32 mpll_val = 0 ;i = 2 ; //don't use 100M!//boot_params.cpu_clk.val = 3;switch ( i ) {case 0: //200key = 12;mpll_val = (92<<12)|(4<<4)|(1);break;case 1: //300key = 13;mpll_val = (67<<12)|(1<<4)|(1);break;case 2: //400key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;case 3: //440!!!key = 14;mpll_val = (102<<12)|(1<<4)|(1);break;default:key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;}//init FCLK=400M, so change MPLL firstChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCONChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit cal_cpu_bus_clk(); //HCLK=100M PCLK=50M}Function name: cal_cpu_bus_clkParameter : voidDescription : 设置PCLK\HCLK\FCLK的频率Return : voidArgument : voidAutor & date : Daniel**************************************************/static void cal_cpu_bus_clk(void){static U32 cpu_freq;static U32 UPLL;U32 val;U8 m, p, s;val = rMPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;//(m+8)*FIN*2 不要超出32位数!FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; //FCLK=400M FIN=12000000val = rCLKDIVN;m = (val>>1)&3;p = val&1;val = rCAMDIVN;s = val>>8;switch (m) {case 0:HCLK = FCLK;break;case 1:HCLK = FCLK>>1;break;case 2:if(s&2)HCLK = FCLK>>3;elseHCLK = FCLK>>2;break;case 3:if(s&1)HCLK = FCLK/6;elseHCLK = FCLK/3;break;}if(p)PCLK = HCLK>>1;elsePCLK = HCLK;if(s&0x10)cpu_freq = HCLK;elsecpu_freq = FCLK;val = rUPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;UPLL = ((m+8)*FIN)/((p+2)*(1<<s));UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;}LCD驱动程序设计#define GLOBAL_CLK 1#include <stdlib.h>#include <string.h>#include "def.h"#include "option.h"#include "2440addr.h"#include "2440lib.h"#include "2440slib.h"#include "mmu.h"#include "profile.h"#include "memtest.h"#define LCD_N35 //NEC 256K色240*320/3.5英寸TFT真彩液晶屏,每一条水平线上包含240个像素点,共有320条这样的线#if defined(LCD_N35)#define LCD_WIDTH 240#define LCD_HEIGHT 320#define LCD_PIXCLOCK 4#define LCD_RIGHT_MARGIN 39#define LCD_LEFT_MARGIN 16#define LCD_HSYNC_LEN 5#define LCD_UPPER_MARGIN 1#define LCD_LOWER_MARGIN 5#define LCD_VSYNC_LEN 1#endifvoid TFT_LCD_Test(void);#define LCD_XSIZE LCD_WIDTH#define LCD_YSIZE LCD_HEIGHT#define SCR_XSIZE LCD_WIDTH#define SCR_YSIZE LCD_HEIGHTvolatile static unsigned short LCD_BUFFER[SCR_YSIZE][SCR_XSIZE]; //定义320行,240列的数组,用于存放显示数据extern unsigned char sunflower_240x320[];#define M5D(n) ((n)&0x1fffff)#define LCD_ADDR ((U32)LCD_BUFFER)#define ADC_FREQ 2500000volatile U32 preScaler;static void cal_cpu_bus_clk(void);void Set_Clk(void);/*演示函数*/void delay(int times){int i,j;for(i=0;i<times;i++)for(j=0;j<400;j++);}/*在屏幕上画图*/static void Pait_Bmp(int x0,int y0,int h,int l,const unsigned char *bmp) {int x,y;U32 c;int p = 0;for( y = 0 ; y < l ; y++ ){for( x = 0 ; x < h ; x++ ){c = bmp[p+1] | (bmp[p]<<8) ;if ( ( (x0+x) < SCR_XSIZE) && ( (y0+y) < SCR_YSIZE) ) LCD_BUFFER[y0+y][x0+x] = c ;p = p + 2 ;}}}/*填充全屏为某一颜色*/static void Lcd_ClearScr( U16 c){unsigned int x,y ;for( y = 0 ; y < SCR_YSIZE ; y++ ){for( x = 0 ; x < SCR_XSIZE ; x++ ){LCD_BUFFER[y][x] = c ;}}}/*LCD开关*/static void Lcd_EnvidOnOff(int onoff){if(onoff==1)rLCDCON1|=1; // ENVID=ONelserLCDCON1 =rLCDCON1 & 0x3fffe; // ENVID Off}/*端口初始化*/static void Lcd_Port_Init( void ){rGPCUP=0xffffffff; // Disable Pull-up registerrGPCCON=0xaaaa02a8; //Initialize VD[7:0],VM,VFRAME,VLINE,VCLKrGPDUP=0xffffffff; // Disable Pull-up registerrGPDCON=0xaaaaaaaa; //Initialize VD[15:8]}/*LCD初始化*/static void LCD_Init(void){Lcd_Port_Init();/*显示模式初始化*//*bit[17:8](4:CLKV AL);bit[6:5](11:TFT LCD panel);bit[4:1](1100:16 bpp for TFT)*/rLCDCON1 = (LCD_PIXCLOCK << 8) | (3 << 5) | (12 << 1);/*bit[31:24](1:VBPD);bit[23:14](320-1:行数);bit[13:6](5:VFPD);bit[5:0](1:VSPW)*/rLCDCON2 = (LCD_UPPER_MARGIN << 24) | ((LCD_HEIGHT - 1) << 14) | (LCD_LOWER_MARGIN << 6) | (LCD_VSYNC_LEN << 0);/*bit[25:19](36:HBPD);bit[18:8](240-1:列数);bit[7:0](19:HFPD)*/rLCDCON3 = (LCD_RIGHT_MARGIN << 19) | ((LCD_WIDTH - 1) << 8) | (LCD_LEFT_MARGIN << 0);/*bit[15:8](13:MV AL,只有当LCDCON1 bit[7]MMODE=1才有效);bit[7:0](5:HSPW)*/rLCDCON4 = (13 << 8) | (LCD_HSYNC_LEN << 0);/*bit[11](5:6:5 Format);bit[9](VLINE/HSYNC polarity inverted);bit[8](VFRAME/VSYNC inverted)bit[3](Enalbe PWERN signal),bit[1](half-word swap control bit)*/rLCDCON5 = (1<<11) | (1 << 9) | (1 << 8) | (1 << 3) | (1 << 0);/*帧缓冲地址初始化*//*LCDBANK: 视频帧缓冲区内存地址30-22位LCDBASEU: 视频帧缓冲区的开始地址21-1位LCDBASEL: 视频帧缓冲区的结束地址21-1位*//*bit[29:21]:LCDBANK,bit[20:0]:LCDBASEU*/rLCDSADDR1 = ((LCD_ADDR >> 22) << 21) | ((M5D(LCD_ADDR >> 1)) << 0);/*bit[20:0]:LCDBASEL*/rLCDSADDR2 = M5D((LCD_ADDR + LCD_WIDTH * LCD_HEIGHT * 2) >> 1);/*PAGEWIDTH:虚拟屏幕一行的字节数,如果不使用虚拟屏幕,设置为实际屏幕的行字节数OFFSIZE:虚拟屏幕左侧偏移的字节数,如果不使用虚拟屏幕,设置为0 *//*bit[21:11]:OFFSIZE; bit[10:0]:PAGEWIDTH*/rLCDSADDR3 = LCD_WIDTH;/*屏蔽中断*/rLCDINTMSK |= 3;rTCONSEL &= (~7);/*disable调色板*/rTPAL = 0x0;/*禁止LPC3600/LCC3600模式*/rTCONSEL &= ~((1<<4) | 1);/*打开LCD*/Lcd_EnvidOnOff(1);}void TFT_LCD_Show(void){/*红(255:0:0);绿(0:255:0);蓝(0:0:255);黑(0:0:0);白(255,255,255)*//*在屏幕上显示三基色*/Lcd_ClearScr( (0x00<<11) | (0x00<<5) | (0x00) ) ; //clear screen blackdelay(10000);Lcd_ClearScr((0x1f<<11) | (0x00<<5) | (0x00)); //reddelay(10000);Lcd_ClearScr((0x00<<11) | (0x3f<<5) | (0x00)); //greendelay(10000);Lcd_ClearScr((0x00<<11) | (0x00<<5) | (0x1f)); //bluedelay(10000);Lcd_ClearScr( (0x1f<<11) | (0x3f<<5) | (0x1f) ) ; //clear screen white delay(10000);/*显示一副图片在屏幕上*/Pait_Bmp(0, 0, 240, 320, sunflower_240x320);}/*************************************************Function name: Set_Clk()Parameter : voidDescription : 设置CPU的时钟频率Return : voidArgument : voidAutor & date : Daniel**************************************************/void Set_Clk(void){int i;U8 key;U32 mpll_val = 0 ;i = 2 ; //don't use 100M!//boot_params.cpu_clk.val = 3;switch ( i ) {case 0: //200key = 12;mpll_val = (92<<12)|(4<<4)|(1);break;case 1: //300key = 13;mpll_val = (67<<12)|(1<<4)|(1);break;case 2: //400key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;case 3: //440!!!key = 14;mpll_val = (102<<12)|(1<<4)|(1);break;default:key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;}//init FCLK=400M, so change MPLL firstChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3); //set the register--rMPLLCONChangeClockDivider(key, 12); //the result of rCLKDIVN [0:1:0:1] 3-0 bit cal_cpu_bus_clk(); //HCLK=100M PCLK=50M}/*************************************************Function name: cal_cpu_bus_clkParameter : voidDescription : 设置PCLK\HCLK\FCLK的频率Return : voidArgument : voidAutor & date : Daniel**************************************************/static void cal_cpu_bus_clk(void){static U32 cpu_freq;static U32 UPLL;U32 val;U8 m, p, s;val = rMPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;//(m+8)*FIN*2 不要超出32位数!FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100; //FCLK=400M FIN=12000000val = rCLKDIVN;m = (val>>1)&3;p = val&1;val = rCAMDIVN;s = val>>8;switch (m) {case 0:HCLK = FCLK;break;case 1:HCLK = FCLK>>1;break;case 2:if(s&2)HCLK = FCLK>>3;elseHCLK = FCLK>>2;break;case 3:if(s&1)HCLK = FCLK/6;elseHCLK = FCLK/3;break;}if(p)PCLK = HCLK>>1;elsePCLK = HCLK;if(s&0x10)cpu_freq = HCLK;elsecpu_freq = FCLK;val = rUPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;UPLL = ((m+8)*FIN)/((p+2)*(1<<s));UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;Uart_Printf("\nFCLK:%dMHz,HCLK:%dMHz,PCLK=%dMHZ\n",FCLK/1000/1000,HCLK/1000/1000,PCLK/1000/1000); }/*主函数*/int Main(void){Set_Clk();LCD_Init();TFT_LCD_Show();return 0;}。