本人最近使用mini2440的外部扩展总线,通过Bank3连接了一块多串口芯片TL16C554D,现在遇到了这样的问题:我是这样定义地址的#define ST16C554D_A_BASE 0x18000000
#define ST16C554D_A_THR ((volatile unsigned char *)(ST16C554D_A_BASE)+(0x00));
在main()函数中,我首先初始化了rBWSCON&=~(0x0f<<12)|(0x0c<<12); //bank3=8-bits
rBANKCON3=(3<<11)|(0x07<<8)|(0x01<<6)|(0x03<<4)|(0x03<<2);//Bank3设置
然后初始化我需要用到的芯片,但是运行程序后出现了这样的问题,串口输出的是乱码。请问下友善之臂的技术人员,在使用Bank3空间对芯片进行参数设置前,需要进行哪些关于Bank3的设置和初始化,才能使用这个空间的地址吗?
下面是我写的程序,一部分参考了友善之臂的程序:
#define GLOBAL_CLK 1
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include <stdlib.h>
#include <string.h>
#include "mmu.h"
void ST16C554D_A_Init(void);
void Send_A_Byte(char data);
U8 Receive_A_Byte(void);
static void Init_Interrupt();
static void __irq extint4_7();
U8 interrupt_flag=0;
U8 interrupt_count=0;
///////////////////////////COM0_init heyi_write
void COM0_init();
void COM0_TxEmpty(void);
char COM0_GetChar(void);
void COM0_SendByte(int data);
void COM0_SendString(char *pt);
void dely(U32 tt)
{
U32 i;
for(;tt>0;tt--)
{
for(i=0;i<10000;i++){}
}
}
static U32 cpu_freq;
static U32 UPLL;
static void cal_cpu_bus_clk(void)
{
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;
val = 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;
else
HCLK = FCLK>>2;
break;
case 3:
if(s&1)
HCLK = FCLK/6;
else
HCLK = FCLK/3;
break;
}
if(p)
PCLK = HCLK>>1;
else
PCLK = HCLK;
if(s&0x10)
cpu_freq = HCLK;
else
cpu_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;
}
int consoleNum;
int Main(int argc, char **argv)
{
int i;
U8 key;
U32 mpll_val=0;
int data;
mpll_val = (92<<12)|(1<<4)|(1);
//init FCLK=400M, so change MPLL first
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(key, 12);
cal_cpu_bus_clk();
dely(2);
MMU_Init();
Port_Init();
COM0_init();
// Init_Interrupt();
rGPBCON = 0x155555;
data = 0x06;
ST16C554D_A_Init();
while(1)
{
/*rGPBDAT = (data<<5);
dely(4200);
data =~data;
rGPBDAT = (data<<5);
*/
if(interrupt_flag)
{
rGPBDAT = (data<<5);
}
else
{
data =~data;
rGPBDAT = (data<<5);
}
dely(4200);
interrupt_flag=~interrupt_flag;
//COM0_SendByte(65);
Send_A_Byte(69);
}
return;
}
/////////////////////////////多串口ST16C554D初始化
void ST16C554D_A_Init(void)
{
U8 i=0;
rBWSCON&=~(0x0f<<12)|(0x0c<<12); //bank3=8-bits
rBANKCON3=(3<<11)|(0x07<<8)|(0x01<<6)|(0x03<<4)|(0x03<<2);//Bank3设置
do
{
*ST16C554D_A_LCR=0x80; //设置baud rate
*ST16C554D_A_DLL=0x0C;
*ST16C554D_A_DLM=0x00; //1.8432Mhz,9600(00,0C);115.2k(00,01);4800(00,18)
*ST16C554D_A_LCR=0x03; //无奇偶,1-stop,8-bits
*ST16C554D_A_FCR=0x00; //禁止FIFO
i=(*ST16C554D_A_LSR); //先读取一次LSR,使LSR复位
}while((i&0x60)!=0x60);
COM0_SendByte(65);
*ST16C554D_A_IER=0x01; //00表示关闭中断,0x01表示接受中断使能,0x02表示发送中断使能
*ST16C554D_A_MCR=0x08; //0x08表示使能总中断,外部中断;0x00表示关闭总中断
i=(*ST16C554D_A_RHR); //先读取一次RHR中的数据,使之为空
i=(*ST16C554D_A_LSR); //读取LSR状态,为0x01时,表示已经读取到接受寄存器中去了
}
///////////////////////////发送数据
void Send_A_Byte(char data)
{
U8 i=0;
U32 j;
do
{
i=(*ST16C554D_A_LSR);
}while((i&0x20)!=0x20);
*ST16C554D_A_THR=data;
for(j=0;j<10000;j++);
COM0_SendByte(68);
}
///////////////////////////接受数据
U8 Receive_A_Byte(void)
{
U8 i,j;
i=(*ST16C554D_A_LSR);
// while((i&0x01)!=0x01); //wait until receive data is in
// while(((*ST16C554D_A_LSR)&0x01)!=0x01);
if((i&0x01)==0x01)
{j=(*ST16C554D_A_RHR);
return j;
}
}
/*static void Init_Interrupt() //中断初始化
{
rINTMOD=0x0; // All=IRQ mode ?
//Uart_Printf("\nKey Scan Test, press ESC key to exit !\n"); //超级终端提示
//注意这里rGPGCON必须这样写!将GPG0,3,5,6,7,11设置为中断功能键EINT8,11,13,14,15,19
rGPGCON =rGPGCON& (~((3<<22)|(3<<6)|(3<<0)|(3<<10)|(3<<12)|(3<<14))) | ((2<<22)|(2<<14)|(2<<12)|(2<<10)|(2<<6)|(2));
//将GPF5设置为中断功能键EINT5,6,7
rGPFCON =rGPFCON&(~((3<<10)|(3<<12)|(3<<14)))|((2<<10)|(2<<12)|(2<<14));
/////////设置rEXTINT0寄存器的5,6,7为高电平触发
rEXTINT0 &=(~((7<<20)|(7<<24)|(7<<28)))|((1<<20)|(1<<24)|(1<<28));
//设置rEXTINT1寄存器的EINT8,11,13,15均为低电平触发!
rEXTINT1 &=~((7<<0)|(7<<12)|(7<<20)|(7<<24)|(7<<28));//低电平触发方式
//设置rEXTINT2寄存器的EINT19为低电平触发!
rEXTINT2 &=~(7<<12);
//按键各个中断源不屏蔽!rEINTMASK中的EINT5,EINT6,EINT7,EINT8,EINT11,EINT13,EINT14,EINT15,EINT19
rEINTMASK &=~((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<11)|(1<<13)|(1<<14)|(1<<15)|(1<<19));
//开始初始化时rEINTPEND,rSRCPND,rINTPND本身都是0,也就是没有中断请求,如果有的话,会自动置1
//将中断服务函数的地址传给对应的中断向量表位置
pISR_EINT4_7=(U32)extint4_7; //#define pISR_EINT8_23 _ISR_STARTADDRESS+0x34 //_ISR_STARTADDRESS=0x33ffff00
//按键总中断源EINT8_23不屏蔽! 注意这里是寄存器rINTMSK!
//rINTMSK &=~BIT_EINT8_23; //#define BIT_EINT8_23 (0x1<<5)
rINTMSK &=~BIT_EINT4_7;
}
*/
/**********************************************************************************************
** Function name: extint4_7 (函数名可以任意取)
** Descriptions: 外部中断源rINTPND[5]=EINT8_23的中断服务函数,中断源EINT8_23为共享的中断源
包括EINT8---EINT23,由于是共享的,故中断发生时需要由rEINTPEND进一步判断
当中断发生后,必须在服务程序中手动清除中断请求!包括rINTPND,rSRCPND,rEINTPEND相应位!
** Created by: 冬夜喜雨
** Created Date: 2010-4-16
***********************************************************************************************/
static void __irq extint4_7()
{
U8 key;
if(rINTPND == BIT_EINT4_7) //rINTPND判断是哪个外部中断源有中断请求
{
rINTPND |= BIT_EINT4_7; //It is cleard by writing “1” 有中断请求后,需要置1来清除该中断
rSRCPND |= BIT_EINT4_7; //这里注意要同时把中断源也要写1清除中断请求
//因为外部中断8-23共享中断源EINT8_23=rINTPND[5],所以需要用rEINTPEND来进一步判断到底是哪一个发生了请求!
if(rEINTPEND&(1<<5)) //如果EINT5发生了中断,则写1进行清除中断请求!
{
interrupt_count++;
key= *ST16C554D_A_RHR;
if(key==0xaa)
interrupt_flag=1;
if(interrupt_count==8)
{
interrupt_count=0;
interrupt_flag=~interrupt_flag;
}
rEINTPEND |= 1<< 5; //It is cleard by writing “1”
}
}
}
/**********************************************************
**function name:COM0_init()
**Descriptions:COM0初始化
**Created by:Heyi
**Created Data:2011-4-21
**********************************************************/
void COM0_init()
{
int i;
rUFCON0=0X0; //chanel 0,FIFI disable
rUMCON0=0x0; //MODEM Control,AFC disable
rULCON0=0x3; //Normal,无奇偶,1-stop,8-bits
rUCON0 =0x245;
rUBRDIV0=((int)(PCLK/16./115200+0.5)-1); //Baud rate divisior register0
for(i=0;i<100;i++); //延迟一段时间,以完成COM0的初始化
}
/**********************************************************
**function name:COM0_TxEmpty()
**Descriptions:查看发送寄存器是否为空
**Created by:Heyi
**Created Data:2011-4-21
**********************************************************/
void COM0_TxEmpty(void)
{
while(!(rUTRSTAT0&0x4)); //wait until Tx shifter is empty;
}
/**********************************************************
**function name:COM0_GetChar()
**Descriptions:获取单个字符
**Created by:Heyi
**Created Data:2011-4-21
**********************************************************/
char COM0_GetChar(void)
{
while(!(rUTRSTAT0&0x1)); //receive data ready
return RdURXH0(); //RdURXH0()为一地址,0x50000024
}
/**********************************************************
**function name:COM0_SendByte(int data)
**Descriptions:发送一个int字节
**Created by:Heyi
**Created Data:2011-4-21
**********************************************************/
void COM0_SendByte(int data)
{
if(data=='\n') //如果是换行符
{
while(!(rUTRSTAT0&0x2)); //wait until THR is empty
WrUTXH0('\r');
}
while(!(rUTRSTAT0&0x2)); //wait until THR is empty
WrUTXH0(data); //格式转换为unsigned char
}
/**********************************************************
**function name:COM0_SendString(char *pt)
**Descriptions:发送一个字符串
**Created by:Heyi
**Created Data:2011-4-21
**********************************************************/
void COM0_SendString(char *pt)
{
while(*pt)
COM0_SendByte(*pt++);
}