这两天花了好多时候玩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;
}
}
用户1361860 2009-6-19 15:50
tengjingshu_112148725 2009-6-19 14:19