主题 : 使用mini2440的Bank3外部存储器遇到的一些问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 24317
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
综合积分: 8 分
注册时间: 2010-07-06
最后登录: 2017-09-13
楼主  发表于: 2011-04-22 15:50

 使用mini2440的Bank3外部存储器遇到的一些问题

本人最近使用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++);
}