void Port_Init(void) { //CAUTION:Follow the configuration order for setting the ports. // 1) setting value(GPnDAT) // 2) setting control register (GPnCON) // 3) configure pull-up resistor(GPnUP) rGPACON = 0x7fffff; rGPBCON = 0x015550; rGPBUP = 0x7ff; // The pull up function is disabled GPB[10:0] rGPCCON = 0xaaa956aa; rGPCUP = 0xffff; // The pull up function is disabled GPC[15:0] rGPDCON = 0xaaaaaaaa; rGPDUP = 0xffff; // The pull up function is disabled GP[15:0] rGPECON = 0xa02aa800; // For added AC97 setting rGPEUP = 0xffff; rGPFCON = 0x55aa; rGPFUP = 0xff; // The pull up function is disabled GPF[7:0] rGPGCON = 0x00a2aaaa;// GPG9 input without pull-up rGPGUP = 0xffff; // The pull up function is disabled GPG[15:0] rGPHCON = 0x00faaa; rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0] rGPJCON = 0x02aaaaaa; rGPJUP = 0x1fff; // The pull up function is disabled GPH[10:0] //External interrupt will be falling edge triggered. rEXTINT0 = 0x22222222; // EINT[7:0] rEXTINT1 = 0x22222222; // EINT[15:8] rEXTINT2 = 0x22222222; // EINT[23:16] }
A口:有23个引脚,GPA0到GPA11地址信号;GPA12到GPA16为nGCS[1-5];GPA17(CLE)、GPA18(ALE)、GPA19(nFWE)、GPA20(nFRE)、GPA21(nRSTOUT)、GPA22(nFCE) 一个位控制一个引脚的状态。0表示输出,1表示地址位或者状态引脚。(23根A口引脚全为输入)
B口:有11根引脚,输入输出口配置:两位控制一根引脚状态:00 00 00 01 01 01 01 01 01 01 00 00 (B口0,1为输入;2、3、4、5、6、7、8为输出;9、10为输入)
上拉与否:0111 1111 1111
GPB10 [21:20] 00 = 输入 01 = 输出 10 = nXDREQ0 11 = 保留 0
GPB9 [19:18] 00 = 输入 01 = 输出 10 = nXDACK0 11 = 保留 0
GPB8 [17:16] 00 = 输入 01 = 输出 10 = nXDREQ1 11 = 保留 0
GPB7 [15:14] 00 = 输入 01 = 输出 10 = nXDACK1 11 = 保留 0
GPB6 [13:12] 00 = 输入 01 = 输出 10 = nXBREQ 11 = 保留 0
GPB5 [11:10] 00 = 输入 01 = 输出 10 = nXBACK 11 = 保留 0
GPB4 [9:8] 00 = 输入 01 = 输出 10 = TCLK [0] 11 = 保留 0
GPB3 [7:6] 00 = 输入 01 = 输出 10 = TOUT3 11 = 保留 0
GPB2 [5:4] 00 = 输入 01 = 输出 10 = TOUT2 11 = 保留 0
GPB1 [3:2] 00 = 输入 01 = 输出 10 = TOUT1 11 = 保留 0
GPB0 [1:0] 00 = 输入 01 = 输出 10 = TOUT0 11 = 保留 0
C口引脚:16根引脚 1010 1010 1010 1001 0101 0110 1010 1010
GPC15 [31:30] 00 = 输入 01 = 输出 10 = VD[7] 11 = 保留 0
GPC14 [29:28] 00 = 输入 01 = 输出 10 = VD[6] 11 = 保留 0
GPC13 [27:26] 00= 输入 01 = 输出 10 = VD[5] 11 = 保留 0
GPC12 [25:24] 00 = 输入 01 = 输出 10 = VD[4] 11 = 保留 0
GPC11 [23:22] 00 = 输入 01 = 输出 10 = VD[3] 11 = 保留 0
GPC10 [21:20] 00 = 输入 01 = 输出 10 = VD[2] 11 = 保留 0
GPC9 [19:18] 00 = 输入 01 = 输出 10 = VD[1] 11 = 保留 0
GPC8 [17:16] 00 = 输入 01 = 输出 10 = VD[0] 11 = 保留 0
GPC7 [15:14] 00 = 输入 01 = 输出 10 = LCD_LPCREVB 11 = 保留 0
GPC6 [13:12] 00 = 输入 01 = 输出 10 = LCD_LPCREV 11 = 保留 0
GPC5 [11:10] 00 = 输入 01 = 输出 10 = LCD_LPCOE 11 = 保留 0
GPC4 [9:8] 00 = 输入 01 = 输出 10 = VM 11 = 保留 0
GPC3 [7:6] 00 = 输入 01 = 输出 10 = VFRAME 11 = 保留 0
GPC2 [5:4] 00 = 输入 01 = 输出 10 = VLINE 11 = 保留 0
GPC1 [3:2] 00 = 输入 01 = 输出 10 = VCLK 11 = 保留 0
GPC0 [1:0] 00 = 输入 01 = 输出 10 = LEND 11 = 保留 0
//16根Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 ,10 10
rGPDCON = 0xaaaaaaaa;
rGPDUP = 0xffff; // The pull up function is disabled GPD[15:0]
//16根Binary :1010 0000 0010 1010 1010 1000 0000 0000
rGPECON = 0xa02aa800; // For added AC97 setting 0、1、2、3、4、11、12、13 输入,其他功能角10
rGPEUP = 0xffff;
//8根Binary : 01 01 , 01 01 , 10 10 , 10 10
rGPFCON = 0x55aa;
rGPFUP = 0xff; // The pull up function is disabled GPF[7:0]
//Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0
//Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0
//Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10
rGPHCON = 0x00faaa;
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]
//Ports : GPJ12 GPJ11 GPJ10 GPJ9 GPJ8 GPJ7 GPJ6 GPJ5 GPJ4 GPJ3 GPJ2 GPJ1 GPJ0
//Signal : CAMRESET CAMPCLKOUT CAMHREF CAMVSYNC CAMPCLKIN CAMDAT[7] CAMDAT[6] CAMDAT[5] CAMDAT[4] CAMDAT[3] CAMDAT[2] CAMDAT[1] CAMDAT[0]
//Binary : 10 10 10 10 10 10 10 10 10 10 10 10 10
rGPJCON = 0x02aaaaaa;
rGPJUP = 0x1fff; // The pull up function is disabled GPH[10:0]
//External interrupt will be falling edge triggered.
rEXTINT0 = 0x22222222; // EINT[7:0]
rEXTINT1 = 0x22222222; // EINT[15:8]
rEXTINT2 = 0x22222222; // EINT[23:16]
1 void Isr_Init(void) 2 { 3 pISR_UNDEF=(unsigned)HaltUndef; 4 pISR_SWI =(unsigned)HaltSwi; 5 pISR_PABORT=(unsigned)HaltPabort; 6 pISR_DABORT=(unsigned)HaltDabort; 7 rINTMOD=0x0; // All=IRQ mode 8 rINTMSK=BIT_ALLMSK; // All interrupt is masked. 9 10 //pISR_URXD0=(unsigned)Uart0_RxInt; 11 //rINTMSK=~(BIT_URXD0); //enable UART0 RX Default value=0xffffffff 12 13 //#if 1 14 // pISR_USBD =(unsigned)IsrUsbd; 15 // pISR_DMA2 =(unsigned)IsrDma2; 16 //#else 17 // pISR_IRQ =(unsigned)IsrUsbd; 18 //Why doesn't it receive the big file if use this. (???) 19 //It always stops when 327680 bytes are received. 20 //#endif 21 // ClearPending(BIT_DMA2); 22 // ClearPending(BIT_USBD); 23 //rINTMSK&=~(BIT_USBD); 24 25 //pISR_FIQ,pISR_IRQ must be initialized 26 }
ARM C中中断程序和其他的c的中断程序一样,就是有中断向量表,入口地址,中断应用程序三部分组成
pISR_UNDEF=(unsigned)HaltUndef; 就是将函数HaltUndef的地址强制转换为unsigned类型,赋给指针pISR_UNDEF。由pISR_UNDEF定义知,
#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))
pISR_UNDEF为相应的异常中断地址。 函数名称代表函数的地址,即将HaltUndef函数的地址赋值到_ISR_STARTADDRESS+0x4中。 当发生中断时,系统会去pISR_UNDEF定义的地址里取出中断函数的地址也就是HaltUndef的地址,然后执行. 就相当于当发生中断时,执行HaltUndef函数.
void HaltUndef(void)
{
Uart_Printf("Undefined instruction exception!!!
");
while(1);
}
表示处理相应中断。
//中断向量表:7个中断地址:
#define _ISR_STARTADDRESS 0x33ffff00
#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0))
#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4))
#define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8))
#define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xc))
#define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10))
#define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14))
#define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18))
#define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1c))
1 pISR_UNDEF=(unsigned)HaltUndef; 就是将函数HaltUndef的地址强制转换为unsigned类型,赋给指针pISR_UNDEF。由pISR_UNDEF定义知, 2 #define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4)) 3 pISR_UNDEF为相应的异常中断地址。 函数名称代表函数的地址,即将HaltUndef函数的地址赋值到_ISR_STARTADDRESS+0x4中。 当发生中断时,
4、系统会去pISR_UNDEF定义的地址里取出中断函数的地址也就是HaltUndef的地址,然后执行. 就相当于当发生中断时,执行HaltUndef函数.
S3C2440A的UART 0和UART 1支持nRTS和nCTS信号的自动流控制。UART 2不支持AFC接口,因为S3C2440A没有nRTS2和nCTS2。
非自动流控制的例子(软件控制nRTS和nCTS)
带FIFO的Rx操作
1. 选择接收模式(中断或DMA模式)。
2. 检查UFSTATn寄存器中Rx FIFO的计数。如果该值小于32,用户必须设置UMCONn[0]的值为'1' (激活nRTS),
并且如果该值大于等于32用户必须设置UMCONn[0]的值为'0'(取消激活nRTS)。
3. 重复步骤2。
带FIFO的Tx操作
1. 选择发送模式(中断或DMA模式)。
2. 检查UMSTATn[0]的值。如果值为'1'(激活nCTS),用户写入数据到Tx FIFO寄存器中。
如果用户希望连接UART到调制解调接口(代替零调制解调模式),则需要nRTS,nCTS,nDSR,nDTR,DCD和nRI信号。在此情况下,由于AFC不支持RS-232C接口,用户可以通过软件使用通用I/O 口控制这些信号。
1 void Uart_Init(int pclk,int baud) 2 { 3 int i; 4 if(pclk == 0) 5 pclk = PCLK; 6 rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable 7 rUFCON1 = 0x0; //UART channel 1 FIFO control register, FIFO disable 8 rUFCON2 = 0x0; //UART channel 2 FIFO control register, FIFO disable 9 rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable 10 rUMCON1 = 0x0; //UART chaneel 1 MODEM control register, AFC disable 11 //UART0 12 rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits 13 // [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0] 14 // Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode 15 // 0 1 0 , 0 1 0 0 , 01 01 16 // PCLK Level Pulse Disable Generate Normal Normal Interrupt or Polling 17 rUCON0 = 0x245; // Control register 18 rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 19 //UART1 20 rULCON1 = 0x3; 21 rUCON1 = 0x245; 22 rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 ); 23 //UART2 24 rULCON2 = 0x3; 25 rUCON2 = 0x245; 26 rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 ); 27 28 for(i=0;i<100;i++); 29 }
ARM与PC机通信,常通过Uart_Printf()这个函数在上位机里输出信息。下面来详细分析这个函数功能。
原形:
//-----------------------------------------------------------------
void Uart_Printf(char *fmt,...) //...表示可变参数(多个可变参数组成一 个列表,后面有专门的指针指向他),不限定个数和类型,
{
va_list ap; //初始化指向可变参数列表的指针
char string[256];
va_start(ap,fmt); //将第一个可变参数的地址付给ap,即ap指向可变参数列表的开始
vsprintf(string,fmt,ap);//将参数fmt、ap指向的可变参数一起转换成格式化字符串,放string数组中,其作用同sprintf(),只是参数类型不同
Uart_SendString(string); //把格式化字符串从开发板串口送出去
va_end(ap); //ap付值为0,没什么实际用处,主要是为程序健壮性
}//-----------------------------
va_list 在这个宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个文件。
(1)格式化字符串
printf(“%s, %-19s: %6.2”,lastname,firstname,prize);
打印结果:Bechr,Teddy ;2000.00
我们说“ Bechr,Teddy ;2000.00 ”就是一个格式化字符串,printf的作用就是把(“%s, %-19s: 6.2”,lastname,firstname,prize)翻译成电脑认识的字符串,而对于“%s, %-19s: 6.2”,lastname,firstname,prize电脑根部不认识,故需要printf翻译。
(2)vsprintf
函数名: vsprintf
功 能: 送格式化输出串到指定数组中
用 法: int vsprintf(char *string, char *format, va_list param);
vsprintf与sprintf功能是一样的,即把格式化字符串输出到指定数组中,sprintf(char *string, char *farmat [,argument,...])函数的参数从第二个参数开始与printf是一样的,只是sprintf是输出到指定数组中,printf是输出到屏幕(一个标准输出文件),因而sprintf多了char *string这参数。
Uart_Printf()这个函数在三星提供的库函数44blib.c中,其中的va_start,vsprintf,va_end等都是在stdarg.h中宏定义的,这个文件在linux内核中,这里不多加分析了,先掌握怎么用它。
总之,这个函数可以简单的理解为将你C语言里的输出习惯转化为硬件底层能认识的字符串。调用这个函数是可以按照标准C里面向终端输出的方法,输出自己的要输出内容。