银杏黄ARM项目总结
今天基本上完成了银杏黄的项目,该项目主要包括两个部分开发板上串口和键盘驱动的编写和pc机上位机程序的编写,今天的工作实际上在做前者;
在这个过程中比较有趣的是机子居然三次蓝屏,估计是串口驱动和机子不兼容造成的,本来打算昨天就把它干掉的,但是昨天又在写入党的思想汇报,手都快写断了。。。。。
在这个过程中遇到了不少的问题,我想有必要把它记录下来。。。。。。。。
我和刘柳共同出资买的开发板,在一次和高毅的意外操作中失去了BootLoader。。。。,最后高毅又下了个2440的uboot进去,勉强用吧。。。。。
由于高毅那个BootLoader是2440的,我一直在怀疑它功能的正确性,所以使用的nm命令来操作板子上的LED,最后证明uboot是没有问题的,可以把程序直接下载到SDRAM中运行。
LQFP也就是薄型QFP(Low rofile Quad Flat Package)
居然找出了以前板子的电路图,厚着脸皮还是用DXP.exe把它打开了,虽然很不专业啦,呵呵。。。
ARM有272个引脚,采用的FBGA封装,以前一直都没有搞清楚,现在才知道,它与51单片机和freescale是不一样的(A~U,1~17),17*17=289,但是中间去了17个,所以呢就只有272个引脚了(感觉很巧的哈,呵呵)。。。。。。。
用nm命令来操纵板子上的LED灯还是有不少知识的,我还是要在这里简单的记录下;
1. I/O端口的设置方式
板子上用GPB7-GPB10连接四个LED(LED1~LED4),除了GPA用一位控制一个引脚外,其他口都用两位来控制一个port口,所以GPB7用GPBCON寄存器(00:输入;01:输出;10:特殊功能;11:保留不用)的GPBCON14、和GPBCON15来控制, GPB8用GPBCON寄存器的GPBCON16、和GPBCON17来控制,GPB9用GPBCON寄存器的GPBCON18、和GPBCON19来控制,GPB10用GPBCON寄存器的GPBCON20、和GPBCON21来控制。例如要把GPB7 ~GPB10设置成输出口,则可按如下操作进行:
#define GPBPORT_8 1<<(2*8)
#define GPBPORT_9 1<<(2*9)
#define GPBPORT_10 1<<(2*10)
GPBCON |= GPBPORT_7 | GPBPORT_8 | GPBPORT_9 | GPBPORT_10;
此时GPBCON = 0001 0101 0100 0000 0000 0000 = 0x154000;
所以在使用nm命令时:
就把四个口全部设置成输出口了就可以对LEDi(i=1...4)直接进行操作了.
对于数据寄存器GPBDAT 每一位对应于一个口,所以该寄存器的7-10位用来控制输出的数据:
case 0x00000700: putc('1');break;
case 0x00000680: putc('2');break;
case 0x00000580: putc('3');break;
case 0x00000380: putc('4');break;
代码中数据分别将LED1~LED4打开;
2. LED分别对应于ARM板上的那些引脚(在上面都回答了)
关于ADS开发环境啰嗦两句:
设置放在image文件头部的符号,这非常重要。。。。。当时就是因为这个原因导致编译生成的文件无法再板子上运行,当时使用汇编将其引导到适当位置的:
点击调试按钮,进入调试界面:
进入调试界面,点击带有ab的图标,可以看到各个符号在空间的地址分布情况:
关于键盘扫描程序
在写键盘扫描程序时,没有看电路图结果纠结了好久:
根据这个电路(我没有学过电路分析,哎。。。。),是键盘按下的时候PORTF口应该是低电平,而在没有按下的时候是高电平,当时就正好搞反了,哎,要细心啊。。。。。所以把GPFDAT = 0xffffffff;初始化为全一了。。。。
还有就是要注意消除键盘的抖动,说白了就是用一个延时就够了。。。。
Key1-key4分别对应于GPF的1、2、3和7口。。。。所以 & 的条件就是2^1、2^2、2^3、2^7。。。。。。。。。。。。。。。。。。。
2011年12月29日23:36:19
贴上代码:
Button_Serial.c
#define TXD0READY (1<<2)
#define RXD0READY (1)
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
/*GPIO registers*/
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPHCON (*(volatile unsigned long *)0x56000070)
#define GPHDAT (*(volatile unsigned long *)0x56000074)
#define GPHUP (*(volatile unsigned long *)0x56000078)
/*UART registers*/
#define ULCON0 (*(volatile unsigned long *)0x50000000)
#define UCON0 (*(volatile unsigned long *)0x50000004)
#define UFCON0 (*(volatile unsigned long *)0x50000008)
#define UMCON0 (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0 (*(volatile unsigned long *)0x50000010)
#define UTXH0 (*(volatile unsigned char *)0x50000020)
#define URXH0 (*(volatile unsigned char *)0x50000024)
#define UBRDIV0 (*(volatile unsigned long *)0x50000028)
/*
LED1-4对应GPB7-10
*/
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
#define GPB9_out (1<<(9*2))
#define GPB10_out (1<<(10*2))
/*
K1-K3对应GPF1-3
K4对应GPF7
*/
#define GPF1_in ~(3<<(1*2))
#define GPF2_in ~(3<<(2*2))
#define GPF3_in ~(3<<(3*2))
#define GPF7_in ~(3<<(7*2))
void putc(unsigned char c);
unsigned char getc(void);
void init_uart(void);
void delay(int count);
int umain()
{
//unsigned int mask = 0xffffffff;
//init_uart();
GPBCON =GPB7_out | GPB8_out | GPB9_out | GPB10_out ; //LED1-LED4对应的4根引脚设为输出
GPFCON &= GPF1_in & GPF2_in & GPF3_in & GPF7_in ; //K1-K4对应的4根引脚设为输入
GPBDAT = 0x00000000;
GPFDAT = 0xffffffff;
while(1){
GPBDAT = ((GPFDAT & 0x0e)<<6) | ((GPFDAT & 0x80)<<3); //若Kn为0(表示按下),则令LEDn为0(表示点亮)
//mask = GPBDAT & mask;
/*switch(GPBDAT)
{
case 0x00000700: putc('1');break;
case 0x00000680: putc('2');break;
case 0x00000580: putc('3');break;
case 0x00000380: putc('4');break;
//default :putc('c');break;
}*/
//putc('c');
//mask = 0xffffffff;
if ((GPFDAT & 0x00000002) == 0)
{
putc('1');
delay(200);
}
else if((GPFDAT & 0x04) == 0)
{
putc('2');
delay(200);
}
else if((GPFDAT & 0x08) == 0)
{
putc('3');
delay(200);
}
else if((GPFDAT & 0x80) == 0)
{
putc('4');
delay(200);
}
else
;//putc('c');
}
return 0;
}
void init_uart(void )
{//初始化UART
GPHCON |= 0xa0; //GPH2,GPH3 used as TXD0,RXD0
GPHUP = 0x0c; //GPH2,GPH3内部上拉
ULCON0 = 0x03; //8N1
UCON0 = 0x05; //查询方式
UFCON0 = 0x00; //不使用FIFO
UMCON0 = 0x00; //不使用流控
//UBRDIV0 = 12; //波特率为57600
UBRDIV0 = 20; //波特率为115200
}
void putc(unsigned char c)
{
while( ! (UTRSTAT0 & TXD0READY) );
UTXH0 = c;
}
unsigned char getc( void )
{
while( ! (UTRSTAT0 & RXD0READY) );
return URXH0;
}
void delay(int count)
{
int i;
while(count--)
{
for(i=0; i < 60000; i++)
;
}
}
------------------------------------------------------------
Button_Serial_Boot.s
----------------------------------
area boot,code,readonly import umain entry start ldr sp, =1024*4 ;ldr pc,=umain bl umain end