原创 Freescale MCF52211 QSPI接口

2009-6-19 12:04 3183 3 5 分类: MCU/ 嵌入式

这两天花了好多时候玩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;
 }
}


 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1361860 2009-6-19 15:50

Freescale的coldfire系列处理器是32位的,他不是ARM核心的,他是freescale自己的核心,是以前著名的m68k的改进版

tengjingshu_112148725 2009-6-19 14:19

有时间给俺介绍一下Freescale的这东东。8位的还是32位的?是单片机还是ARM?
相关推荐阅读
用户1361860 2012-06-28 23:44
Nicrosystem Freescale Kinetis教程---SDHC
这是研究生翻译的SDHC的中文文档,里面很多句子不通,但我现在没时间去修改了。先放出来,应该还是会有一点作用  ...
用户1361860 2012-06-26 12:39
Nicrosystem Freescale Kinetis教程--低功耗定时器
Freescale Kinetis内部集成了一个独特的低功耗定时器,它可以在系统处于低功耗模式下,仍然以极低功耗运行,可以用于在适当时候唤醒系统进入正常工作模式  ...
用户1361860 2012-06-24 22:11
Nicrosystem Freescale Kinetis教程----RTC实时时钟
Nicrosystem的飞思卡尔kinetis教程之片上RTC  ...
用户1361860 2012-06-22 10:21
TI C2000微控制器指南
这是官方的C2000的介绍,C2000做电机控制那是业界最好的。  ...
用户1361860 2012-06-20 23:52
Nicrosystem Freescale Kinetis教程--PIT定时器教程
这是PIT定时器的教程,PIT是 Kinetis支持的另一种定时器,相对于上一讲的flextimer要简单。 今晚赶到北京,到宾馆发一篇博客  ...
用户1361860 2012-06-19 13:15
Nicrosystem Freescale Kinetis教程--Flextimer教程
Kinetis的Flextimer定时器教程 kinetis集成了众多功能各异的定时器,flextimer是其中最为复杂的一个  ...
我要评论
2
3
关闭 站长推荐上一条 /3 下一条