本帖最后由 缥缈九哥 于 2013-4-29 23:12 编辑
基于新唐NANO120的EBI总线的PT6520的12232显示器驱动程序
新做一个小产品,用到12232的LCD,控制芯片是PT6520,兼容于SED1520的,调了好久发现用80模式的总线不能成功。左右屏都是显示相同的内容,主要原因是WR只有一个,但是RD有两个,强行把另外半屏进入读状态再写另外一屏也无效,因为读写总线冲突时。NANO120的写弱于LCD的读。调了好久都不成功。浪费了一晚上的时间。
后来实不得已,用68模式,开始NANO120的PF2做LCD的RST,怎么配置也不出不来高电平,进入不了68模式,浪费了很多时间最后只好飞线到PA9来做LCD的RST才能成功。
详细源码
ts12232.rar
(2.99 KB)
如下:
/******************************************************************************
* @file ts12232.c
* @brief The Driver code for 122*32 Dots LCD TS12232 with PT6520
* @version 1.0.0
* @date 20, April, 2013
*
* @note
* Copyright (C) 2000-2013 PM9GZY by yuanxihua@21cn.com. All rights reserved.
******************************************************************************/
#include <stdio.h>
/* Includes ------------------------------------------------------------------*/
#include "nano1xx.h"
#include "nano1xx_gpio.h"
#include "nano1xx_ebi.h"
#include "hz.h"
/*
_________________________________________________
| NANO120LE3BN TS12232L |
| |
| EBIAD8- EBIAD15 <---> DB0-DB7 |
| EBIWR PA10 ----> RW |
| EBIAD7 PA6 ----> A0 |
| PF2 RST ----> RST |
| EBIAD4 PC6 ----> E1 |
| EBIAD5 PC7 ----> E2 |
| PA15 BL ----> BL |
|_______________________________________________|
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define LCD_DI GPIOA, 6 /* PA6 */
#define LCD_BL GPIOA, 15 /* PA15 */
//#define LCD_RST GPIOF, 2 /* PF2 */ //ERROR!!! GPIO输出不了高
#define LCD_RST GPIOA, 9 /* PA9 */
// #define BUS_TYPE 8080 //ERROR!!! 共用WR,左右屏显示一样
#define BUS_TYPE 6800 //OK!!!
#if(BUS_TYPE==6800)
#define LCD_RW GPIOA, 10 /* PA10 */
#define LCD_E1 GPIOC, 6 /* PC6 */
#define LCD_E2 GPIOC, 7 /* PC7 */
#endif
#if(BUS_TYPE==8080)
#define LCD_WR GPIOA, 10 /* PA10 */
#define LCD_RD1 GPIOC, 6 /* PC6 */
#define LCD_RD2 GPIOC, 7 /* PC7 */
#endif
#define CMD 0
#define DAT 1
#define E1 1
#define E2 2
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
unsigned char lcdbuf[640];
/* Private function prototypes -----------------------------------------------*/
uint32_t hex2bcd(uint32_t *tmp);
void TS12232_Init(void);
void TS12232_Clr(void);
void TS12232_Display(uint8_t *data);
void TS12232_Configuration(void);
void TS12232_HanZi(uint8_t line,uint8_t column,uint16_t hz_index);
void TS12232_HZ(uint8_t line,uint8_t column,uint16_t hz_index);
void TS12232_SZ(uint8_t line,uint8_t column,uint16_t sz_index,uint8_t onoff);
void TS12232_FH(uint8_t line,uint8_t column,uint16_t fh_index);
void TS12232_Number(uint8_t line,uint8_t column,uint32_t number);
uint32_t hex2bcd(uint32_t *tmp);
/* Private functions ---------------------------------------------------------*/
void TS12232_Test(void)
{
uint32_t i,j=0;
uint8_t buf[640];
TS12232_Configuration();
for(i=0;i<640;i++) buf=0;
while(1)
{ buf[j++]=buf[j]>0?0:0xff;if(j>=488){j=0;}
TS12232_Display(buf);
}
}
uint32_t hex2bcd(uint32_t *tmp)
{
uint32_t t,n=0,v=*tmp,max=1000000000;
for(t=0;t<10;t++){if((*tmp=v/max)>0){*tmp%=10;*tmp++;n++;}max/=10;}
return v?n:1;
}
//显示 宋体12 宽x高=16x16 列精确到点
void TS12232_HanZi(uint8_t line,uint8_t column,uint16_t hz_index)
{
uint8_t i;
for(i=0;i<16;i++)
{ lcdbuf[line*244+column+ 0+i]=hz[hz_index*32+ 0+i];
lcdbuf[line*244+column+122+i]=hz[hz_index*32+16+i];
}
}
//显示 宋体12 宽x高=16x16 列精确到字
void TS12232_HZ(uint8_t line,uint8_t column,uint16_t hz_index)
{TS12232_HanZi(line,column*16,hz_index);}
//显示 数字 宽度x高度=10x16 列精确到点
void TS12232_SZ(uint8_t line,uint8_t column,uint16_t sz_index, uint8_t onoff)
{
uint8_t i;
for(i=0;i<10;i++)
{ lcdbuf[line*244+column+ 0+i]=onoff?sz[sz_index*20+ 0+i]:0;
lcdbuf[line*244+column+122+i]=onoff?sz[sz_index*20+10+i]:0;
}
}
//显示 符号 宽度x高度=6x16 列精确到点
void TS12232_FH(uint8_t line,uint8_t column,uint16_t fh_index)
{
uint8_t i;
for(i=0;i<6;i++)
{ lcdbuf[line*244+column+ 0+i]=fh[fh_index*12+ 0+i];
lcdbuf[line*244+column+122+i]=fh[fh_index*12+ 6+i];
}
}
//显示 32位无符号整形数字 列精确到点
void TS12232_Number(uint8_t line,uint8_t column,uint32_t number)
{
uint32_t i,j,n;
uint32_t tmp[10];
tmp[0]=number;n=hex2bcd(tmp);
for(j=0;j<n;j++)
{ for(i=0;i<10;i++)
{ lcdbuf[line*244+column+j*10+ 0+i]=sz[tmp[j]*20+ 0+i];
lcdbuf[line*244+column+j*10+122+i]=sz[tmp[j]*20+10+i];
}
}
}
#if(BUS_TYPE==8080) /* 80 Mode */
void TS12232_GPIO_init(void)
{
GPIO_ClrBit(LCD_DI); //PA6
GPIO_SetBit(LCD_BL); //PA15 BackLight ON
GPIO_SetBit(LCD_RST); //PF2
GPIO_SetBit(LCD_WR); //PA10
GPIO_SetBit(LCD_RD1); //PC6
GPIO_SetBit(LCD_RD2); //PC7
}
void TS12232_Bus_type(void)
{
GPIO_SetBit(LCD_RST);GPIO_ClrBit(LCD_RST); //Set RST to LOW 8080 Mode
}
void TS12232_Write_Byte(uint8_t cs, uint8_t di, uint8_t wrdata) //8080总线
{
uint32_t tmp,i=0xffff;
/* Waitting for Chip Busy */
GPIO_ClrBit(LCD_DI); //CMD
if(cs==E1)GPIO_ClrBit(LCD_RD1);if(cs==E2)GPIO_ClrBit(LCD_RD2); // Clr RD to LOW
while((*(uint16_t*)(EBI_BASE_ADDR+0x8000)&0x8000)&&(i--)); // Read D15
if(cs==E1)GPIO_SetBit(LCD_RD1);if(cs==E2)GPIO_SetBit(LCD_RD2); // Set RD to HIGH
/* Write Byte to Chip*/
if(di==DAT)GPIO_SetBit(LCD_DI); //DAT
tmp=wrdata;tmp<<=8;*(uint16_t*)(EBI_BASE_ADDR+tmp)=tmp; // Write D8-D15
GPIO_ClrBit(LCD_WR); // Clr WR to LOW
GPIO_SetBit(LCD_WR); // Set WR to HIGH
}
#endif
#if(BUS_TYPE==6800) /* 68 Mode */
void TS12232_GPIO_init(void)
{
GPIO_ClrBit(LCD_DI); //PA6
GPIO_SetBit(LCD_BL); //PA15 BackLight ON
GPIO_ClrBit(LCD_RST); //PF2
GPIO_ClrBit(LCD_RW); //PA10
GPIO_ClrBit(LCD_E1); //PC6
GPIO_ClrBit(LCD_E2); //PC7
}
void TS12232_Bus_type(void)
{
GPIO_ClrBit(LCD_RST);GPIO_SetBit(LCD_RST); //Set RST to HIGH for 6800 Mode
}
void TS12232_Write_Byte(uint8_t cs, uint8_t di, uint8_t wrdata) //6800总线
{
uint32_t tmp,i=0xffff;
/* Waitting for Chip Busy */
if(cs==E1)GPIO_SetBit(LCD_E1);if(cs==E2)GPIO_SetBit(LCD_E2); // Set E to HIGH
GPIO_ClrBit(LCD_DI);GPIO_SetBit(LCD_RW); // CMD Read Mode
while((*(volatile uint16_t*)(EBI_BASE_ADDR+0x8000)&0x8000)&&(i--)); // Read D15
if(cs==E1)GPIO_ClrBit(LCD_E1);if(cs==E2)GPIO_ClrBit(LCD_E2); // Clr E to LOW
/* Write Byte to Chip */
if(cs==E1)GPIO_SetBit(LCD_E1);if(cs==E2)GPIO_SetBit(LCD_E2); // Set E to HIGH
if(di==DAT)GPIO_SetBit(LCD_DI);GPIO_ClrBit(LCD_RW); // Write Mode
tmp=wrdata;tmp<<=8;*(volatile uint16_t*)(EBI_BASE_ADDR+tmp)=tmp;// Write D8-D15
if(cs==E1)GPIO_ClrBit(LCD_E1);if(cs==E2)GPIO_ClrBit(LCD_E2); // Clr E to LOW
}
#endif
//初始化 122x32 点阵屏幕
void TS12232_Init(void)
{
TS12232_Bus_type();
TS12232_Write_Byte(E1,CMD,0XE2);TS12232_Write_Byte(E2,CMD,0XE2);//复位
TS12232_Write_Byte(E1,CMD,0XAE);TS12232_Write_Byte(E2,CMD,0XAE);//关闭显示
TS12232_Write_Byte(E1,CMD,0XA4);TS12232_Write_Byte(E2,CMD,0XA4);//动态驱动
TS12232_Write_Byte(E1,CMD,0XA9);TS12232_Write_Byte(E2,CMD,0XA9);//1/32占空比
TS12232_Write_Byte(E1,CMD,0XA0);TS12232_Write_Byte(E2,CMD,0XA0);//时钟线输出
TS12232_Write_Byte(E1,CMD,0XEE);TS12232_Write_Byte(E2,CMD,0XEE);//取消写修改模式
TS12232_Write_Byte(E1,CMD,0X00);TS12232_Write_Byte(E1,CMD,0XC0);//显示开始行
TS12232_Write_Byte(E2,CMD,0X00);TS12232_Write_Byte(E2,CMD,0XC0);//显示开始行
TS12232_Write_Byte(E1,CMD,0XAF);TS12232_Write_Byte(E2,CMD,0XAF);//打开显示
}
//清除 122x32 点阵屏幕
void TS12232_Clr(void)
{
uint8_t i,page;
for (page=0;page<4;page++)
{
TS12232_Write_Byte(E1,CMD,0xB8|page);TS12232_Write_Byte(E1,CMD,0);//Set E1 page and Column address
TS12232_Write_Byte(E2,CMD,0xB8|page);TS12232_Write_Byte(E2,CMD,0);//Set E2 page and Column address
for(i=0;i<80;i++){TS12232_Write_Byte(E1,DAT,0);TS12232_Write_Byte(E2,DAT,0);}
}
}
//刷新 122x32 点阵屏幕
void TS12232_Display(uint8_t *data)
{
uint8_t page,column;
for(page=0;page<4;page++)
{
TS12232_Write_Byte(E1,CMD,0xB8|page);TS12232_Write_Byte(E1,CMD,0);//Set E1 page and Column address
for(column=0;column<61;column++){TS12232_Write_Byte(E1,DAT,*data++);}
TS12232_Write_Byte(E2,CMD,0xB8|page);TS12232_Write_Byte(E2,CMD,0);//Set E2 page and Column address
for(column=0;column<61;column++){TS12232_Write_Byte(E2,DAT,*data++);}
}
}
// Enable EBI function with 16-bit data width
void NANO_EBI_Init(void)
{
EBI_TIMING_T sEBITiming;
UNLOCKREG();
/* Enable EBI clock */
CLK->AHBCLK |= CLK_AHBCLK_EBI_EN;
/* EBI function enable */
EBI->EBICON |= EBI_EBICON_ExtEN;
EBI->EBICON |= EBI_EBICON_ExtBW16;
// Enable EBI AD High-byte, bit 15~8
GCR->PA_L_MFP = (GCR->PA_L_MFP & ~0x0fffff0) | 0x0222220; //PA5_MFP-PA1_MFP = EBI AD[8] - EBI AD[12]
GCR->PA_H_MFP = (GCR->PA_H_MFP & ~0xfff0000) | 0x2220000; //PA14_MFP-PA12_MFP = EBI AD[15] - EBI AD[13]
sEBITiming.eMCLKDIV = E_EBI_MCLKDIV_1; //OK!!!
sEBITiming.u8ExttALE=sEBITiming.u8ExtIR2R=sEBITiming.u8ExtIR2W = 1;
sEBITiming.u8ExtIW2X=sEBITiming.u8ExttAHD=sEBITiming.u8ExttACC = 1;
EBI_SetBusTiming(sEBITiming);
LOCKREG();
}
void TS12232_Configuration(void)
{
NANO_EBI_Init();*(volatile uint16_t*)EBI_BASE_ADDR=0xFFFF; //Set D0-D15 to HIGH
CLK->AHBCLK|=CLK_AHBCLK_GPIO_EN;
GCR->PA_L_MFP=GCR->PA_L_MFP&0xf0ffffff; //PA6_MFP = GPIOA[6]
GPIO_Open(GPIOA, GPIO_PMD_PMD6_OUTPUT, GPIO_PMD_PMD6_MASK);
GCR->PA_H_MFP=GCR->PA_H_MFP&0x0ffff0ff; //PA15_MFP PA10_MFP = GPIOA[15] GPIOA[10]
GPIO_Open(GPIOA, GPIO_PMD_PMD10_OUTPUT, GPIO_PMD_PMD10_MASK);
GPIO_Open(GPIOA, GPIO_PMD_PMD15_OUTPUT, GPIO_PMD_PMD15_MASK);
GCR->PC_L_MFP=GCR->PC_L_MFP&0x00ffffff; //PC7_MFP PC6_MFP = GPIOC[7] GPIOC[6]
GPIO_Open(GPIOC, GPIO_PMD_PMD6_OUTPUT, GPIO_PMD_PMD6_MASK);
GPIO_Open(GPIOC, GPIO_PMD_PMD7_OUTPUT, GPIO_PMD_PMD7_MASK);
GCR->PF_L_MFP=GCR->PF_L_MFP&0xfffff0ff; //PF2_MFP = GPIOF[2]
GPIO_Open(GPIOF, GPIO_PMD_PMD2_OUTPUT, GPIO_PMD_PMD2_MASK);
GCR->PA_H_MFP=GCR->PA_H_MFP&0x0fffff0f; //PA9_MFP = GPIOA[9]
GPIO_Open(GPIOA, GPIO_PMD_PMD9_OUTPUT, GPIO_PMD_PMD9_MASK);
TS12232_GPIO_init();
TS12232_Init();
TS12232_Clr();
}
--代码完毕。
|