新闻  |   论坛  |   博客  |   在线研讨会
Freescale MCF52211 QSPI接口
mayer | 2009-06-21 12:57:39    阅读:1688   发布文章

Freescale MCF52211 QSPI接口

 

这两天花了好多时候玩Freescale公司的coldfire处理器MCF52211的QSPI接口。我在板子上用这个QSPI接口连接了一块深圳TOPWAY的128x64的液晶屏(型号:LM6059B)。前几天没有用这个QSPI接口,而是直接用GPIO软件模拟时序操作LCD的,程序很快搞定。

这两天因为好奇就忍不住把这个屏换成mcf52211的qspi接口来操作。没想到调了两天都没有反应,开始是怀疑CPHA,CPOL这个东西设置错了,可是把所有的4种情况全试遍也不行,程序检查也又检查实在看不出有什么问题。今天用示波器看了下信号,才发现问题所在,原来QSPI_CS0的片选一直都是无效的,(LCD的片选连接到了MCF52211的QSPI_CS0上)。原来我对mcf52211手册的理解错了,控制QSPI_CSn片选的寄存器是QCR0~QCR15,手册这里没说清楚,我以为想使能QSPI_CS0就是要把QCRn里面的对应位置1即可,没想到不是这样,应该清0才片选CS0,真是靠。freescale的这个手册在这里说的太含糊,很容易想人产生我那种错误的理解。

下面上个代码,这个代码只是为了驱动lcd,因此,并未用上qspi的那些强大功能。这个代码同样适用于其他coldfire处理器,比如mcf52259上的qspi

 

/********************

** File: qspi.h

** MCF52211 QSPI module driver header file

*************************/

#ifndef _LZP_MCF52211_QSPI_H_
#define _LZP_MCF52211_QSPI_H_
#include "support_common.h" /* include peripheral declarations and more */
#define QSPI_TRANSMIT_ADDRESS  0x00
#define QSPI_RECEIVE_ADDRESS  0x10
#define QSPI_COMMAND_ADDRESS  0x20

void init_qspi();
void qspi_send_byte(uint8 c);

#endif

 

/*************************

** File: qspi.c

** MCF52211 QSPI driver

************************/

#include "qspi.h"

/********************************************************************/
/*
 * Set the transfer command 
 */
static void QSPISetTransferCommand ( uint16 u8Cont)
{
    MCF_QSPI_QDR = MCF_QSPI_QDR_QSPI_CS1 |MCF_QSPI_QDR_QSPI_CS2|MCF_QSPI_QDR_QSPI_CS3|
         MCF_QSPI_QDR_BITSE |MCF_QSPI_QDR_DT|MCF_QSPI_QDR_DSCK | (u8Cont << 15);
    return;
}

/********************************************************************/
/*
 * Transfer data by putting it into QDR 
 */
static void QSPISetTransferData (unsigned char u8Data)
{
    MCF_QSPI_QDR = u8Data;
    return;
}


void init_qspi()
{
 MCF_GPIO_PQSPAR|=MCF_GPIO_PQSPAR_QSPI_DOUT_DOUT |MCF_GPIO_PQSPAR_QSPI_CLK_CLK
   |MCF_GPIO_PQSPAR_QSPI_CS0_CS0 |MCF_GPIO_PQSPAR_QSPI_DIN_DIN;
    //MCF_GPIO_PQSPAR = 0x1555;
 MCF_QSPI_QMR=MCF_QSPI_QMR_BAUD(0xff)|
    MCF_QSPI_QMR_MSTR|MCF_QSPI_QMR_BITS(8)|MCF_QSPI_QMR_DOHIE ;
 MCF_QSPI_QDLYR=MCF_QSPI_QDLYR_DTL(200)|MCF_QSPI_QDLYR_QCD(127);
 MCF_QSPI_QWR|=MCF_QSPI_QWR_CSIV ;
 MCF_QSPI_QIR=0;//disable interrupt
}

void qspi_send_byte(uint8 c)
{

    MCF_QSPI_QAR = MCF_QSPI_QAR_CMD ;
    QSPISetTransferCommand( 0);
   
    MCF_QSPI_QAR = MCF_QSPI_QAR_TRANS;
    QSPISetTransferData(c);
     
     
    MCF_QSPI_QWR = MCF_QSPI_QWR_CSIV| MCF_QSPI_QWR_ENDQP(0x00)|MCF_QSPI_QWR_NEWQP(0x00);
    MCF_QSPI_QDLYR |= MCF_QSPI_QDLYR_SPE;
   
    while (!(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF))
    {
     
    }
    MCF_QSPI_QIR|=0x000D;

}

 

/******************************

** File: lcd.h

** LM6059B LCD driver header file

*****************************/

#ifndef _LZP_MCF52211_LCD_H_
#define _LZP_MCF52211_LCD_H_
#include "support_common.h" /* include peripheral declarations and more */

 

void lcd_reset();
void lcd_write_data(uint8 dat);
void lcd_write_cmd(uint8 cmd);
void init_lcd();
void lcd_clear();
void lcd_contrast(uint8 contrast);
void lcd_display_english_str(uint8 x, uint8 y, uint8 *str);
void lcd_display_chinese_str(uint8 x, uint8 y, uint8 *str);

#endif

 

/*************************************

** File: lcd.c

** LM6059B LCD driver

*************************************/

#include "lcd.h"
#include "delay.h"
#include "qspi.h"
#define LCD_RES_SET do\
{\
 MCF_GPIO_PORTTC|=MCF_GPIO_PORTTC_PORTTC3 ; \
}while(0)

#define LCD_RES_RESET do\
{\
 MCF_GPIO_PORTTC&=~MCF_GPIO_PORTTC_PORTTC3 ; \
}while(0)

#define LCD_A0_SET do\
{\
 MCF_GPIO_PORTTC|=MCF_GPIO_PORTTC_PORTTC2 ; \
}while(0)

#define LCD_A0_RESET  do\
{\
 MCF_GPIO_PORTTC&=~MCF_GPIO_PORTTC_PORTTC2 ; \
}while(0)


void lcd_write_cmd(uint8 cmd)
{
 LCD_A0_RESET;
 qspi_send_byte(cmd);
// LCD_A0_SET;
}

void lcd_write_data(uint8 dat)
{
 LCD_A0_SET;
 qspi_send_byte(dat);
}


void lcd_reset()
{
 LCD_RES_RESET;
 delay_ms(10);
 LCD_RES_SET;
}

void init_lcd()
{
 MCF_GPIO_PTCPAR&=0xf3;
 MCF_GPIO_DDRTC|=MCF_GPIO_DDRTC_DDRTC3|MCF_GPIO_DDRTC_DDRTC2;
 
 lcd_write_cmd(0xaf);//display on
 lcd_write_cmd(0x40);//set display start line to 0
 lcd_write_cmd(0xa0);//set ADC select,0=normal
 lcd_write_cmd(0xa6);//normal display
 lcd_write_cmd(0xa4);//entire display off
 lcd_write_cmd(0xa2);//set LCD bias="1/9" bias
 lcd_write_cmd(0xc8);//SHL select="1",flipped in y direction
 lcd_write_cmd(0x2f);//power control set,VF=VR=VC=1
// lcd_write_cmd(0x26);//set the built in resistor ratio
// lcd_write_cmd(0xf8);
// lcd_write_cmd(0x01);
 lcd_write_cmd(0x81);//set contrast
 lcd_write_cmd(0x2c);
 
}

void lcd_clear()
{
 uint8 i,j;
 
 for(i=0;i<8;i++)
 {
  lcd_write_cmd(i|0xb0);
  lcd_write_cmd(0x10);
  lcd_write_cmd(0x00);
  for(j=0;j<128;j++)
  {
   lcd_write_data(0);
  }
 }
}


void lcd_contrast(uint8 contrast)
{
 lcd_write_cmd(0x81);
 lcd_write_cmd(contrast);
}

void lcd_display_english_str(uint8 x, uint8 y, uint8 *str)
{
 uint8 i;
 uint16 addr;
 lcd_write_cmd(y|0xb0);
 lcd_write_cmd((x>>4)|0x10);
 lcd_write_cmd(x&0x0f);
 while(*str!=0)
 {
  addr=*str++;
  addr=(addr-0x20)*8;
  for(i=0;i<6;i++)
  {
   lcd_write_data(ASCIITAB[addr+i]);
  }
 }
}

void lcd_display_chinese_str(uint8 x, uint8 y, uint8 *str)
{
 uint8 i,j;
 uint16 addr;
 
 while(*str!=0)
 {
  addr=*str++;
  addr=(addr-1)*32;
  for(i=0;i<2;i++)
  {
   lcd_write_cmd(y|0xb0);
   lcd_write_cmd((x>>4)|0x10);
   lcd_write_cmd(x&0x0f);
   for(j=0;j<16;j++)
   {
    lcd_write_data(CCTAB[addr+j+i*16]);
   }
   y++;
  }
  y-=2;
  x+=16;
 }
}





*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客