我是从AVR入门ARM的,所以首先想控制IO口实现跑马灯。
用ADS编写了一个程序如下:
int delay(unsigned int i) { unsigned int j,k; for (j=i;j--;j>0) { for(k=20;k--;k>0) {k=k+1;k=k-1;}; }; return 0; } int main(void) { PINSEL0=0x0000; PINSEL1=0x0000; IO0DIR=0xFFFF; IO0CLR=0xFFFF; IO0SET=0XFFFF; while(1) { IO0SET=0xFFFF; delay(2); IO0CLR=0xFFFF; delay(2); } return 0; }
按下Compile按钮,出现下列提示:
Error : C2456E: undeclared name, inventing 'extern int PINSEL0'
....
反正就是那几个寄存器都未定义的意思了。
在ADS目录里面翻来翻去,也没找到一个可以让我include的LPC2000系列的头文件。
那我就自己写吧,于是写成这样:
#define PINSEL0 (*(volatile unsigned long *)0xE002C000) #define PINSEL1 (*(volatile unsigned long *)0xE002C004) #define IO0DIR (*(volatile unsigned long *)0xE0028008) #define IO0CLR (*(volatile unsigned long *)0xE002800C) #define IO0SET (*(volatile unsigned long *)0xE0028004) int delay(unsigned int i) { unsigned int j,k; for (j=i;j--;j>0) { for(k=20;k--;k>0) {k=k+1;k=k-1;}; }; return 0; } int main(void) { PINSEL0=0x0000; PINSEL1=0x0000; IO0DIR=0xFFFF; IO0CLR=0xFFFF; IO0SET=0XFFFF; while(1) { IO0SET=0xFFFF; delay(2); IO0CLR=0xFFFF; delay(2); } return 0; }
编译是通过了。
于是将生成的ELF文件load进Proteus,进行仿真。
看到的结果就是P0.0的点位一直是0,没有进行预计的变换。
仔细找书来看,说是ARM启动需要一段启动代码,用来定义异常向量表、堆栈分配等等
可是我这个超级新手,怎么写那么复杂的东西啊。。。
想想ARM的编译器也不止ADS一个,试试Keil吧
下载了个Keil uVision 3.55,安装以后,把Keil自带的Hello更改了一下,无非就是把printf("Hello")换成跑马灯语句
编译不成功,提示我Keil的演示版已经过期...
哦,对了,我还得找破解版的。。。
在网上找到了一个破解版,又寻找了破解教材,破解后提示说
Device is not supported by Toolchain
网上说是没有破解成功。有可能,那个破解小程序有那么多选项,我就挨个试,还是不行,纳闷中。。。
后来仔细阅读破解教材,又下载了另一个版本的Keil 3.31,安装后编译成功了。原来那个破解程序不支持3.55的
没找到Keil生成ELF文件的方法,就将生成的HEX文件load进Proteus,运行仿真还是不行,P0.0端口的逻辑值显示的是"?"
我的Proteus是这样画的电路:
LPC2104的所有V3脚接3V的电源(自定义的VCC3V),所有V18脚接1.8V的电源(自定义的V18)
(这两个电源配置没有问题)注意,没有放置VCC
运行仿真就是无法看到P0.0电位变换。
是不是Proteus无法识别由3V电源输出的3V的IO口电平是高是低呢?(纯粹是自己的胡乱猜想)
我就在电路和LPC2104毫无关系的地方放了一个电阻,一端接VCC,另一端接GND,两端都放上一个LOGICPROB。
运行仿真,电阻两边的LOGICPROB按照预期出现了1和0,咦?LPC2104的P0.0也同时出现了1,0交替的情景,hoho,开心
总结一下,要使Proteus仿真ARM实现单片机类似的跑马灯,需要如下条件:
1. ARM程序要有启动代码,这个可以用Keil给写好的startup.s
2. Proteus必须有VCC节点
额。。。其实总结一下貌似也没啥特别的东西啊,不过这个经历还是蛮曲折的,带领我进入了ARM的世界