智能车制作
标题:
液晶!!跪求高手解答,我都郁闷两天了~~~~~~~~
[打印本页]
作者:
笑傲江湖
时间:
2009-8-8 11:27
标题:
液晶!!跪求高手解答,我都郁闷两天了~~~~~~~~
我用s12显示一个很简单的字符,就是显示不出来(型号OCMJ4X8C,带字库)
delay()延时函数也挺长的
都郁闷两天了,一直做不出来,各位大侠们务必看一下
在下感激不尽!!!!!
代码如下:
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include<mc9s12dg128.h>
#include<string.h>
//sbit RS = PORTA_BIT0; //1 data 0 instruction mode
//sbit R/W = PORTA_BIT1; //1 data 0 command
//sbit E = PORTA_BIT2; //enable
//sbit PSB = PORTA_BIT3; //H=并口; L=串口;
//sbit RST = PORTA_BIT4; //Reset Signal 低电平有效
//DB0_DB7分别为PTP0—PTP7
#define uchar unsigned char
static int i;
unsigned char tab1[]={"智能车制作"};
/*----------延时函数----------------*/
void delay()
{
int i;
int j;
for (i=0;i<100;i++)
for (j=0;j<1000;j++)
{;}
}
/*-----------侧忙碌子程------------*/
void m_busy()
{
DDRA=0xff;
DDRP=0x00;
PORTA_BIT0=0;
PORTA_BIT1=1;
PORTA_BIT2=1;
while(PTP_PTP7)
{
;
}//读取忙状态
PORTA_BIT2=0;
}
/*------------发送指令------------*/
void send_comd(uchar comd)
{
m_busy();//测试忙状态
PORTA_BIT0=0;
PORTA_BIT1=0;
DDRP=0xff;
PTP=comd;
PORTA_BIT2=1;
delay();
PORTA_BIT2=0;
}
/*----------发送数据子函数----------*/
void send_data(uchar data)
{
m_busy(); //测试忙状态
send_comd(0x30);
send_comd(0x80);
PORTA_BIT0=1;//写资料到RAM
PORTA_BIT1=0;
DDRP=0xff;
PTP=data;
PORTA_BIT2=1;
delay();
PORTA_BIT2=0;
}
/*------------LCD初始化--------------*/
void LCD_init()
{
delay();
send_comd(0x01); //清屏
send_comd(0x30); //基本指令动作
delay();
send_comd(0x06); //光标右移
send_comd(0x0c); //整体显示ON,光标不显示,不反白闪烁
}
/*-----------定时器函数---------------*/
void TimerInit(void)
{
TSCR2=0x0c; //1100prescale factor is 16, bus clock/16=8Mhz/16=500000
TSCR1_TEN = 1; //Timer enable
TIOS=0x01; //channel0 as output compare
TC0=0x2710; //TC0 register init 10000 时间:10000*0.000002=0.02s
TIE=0x01; //enable interrupts
TCTL2=0X01 ;
}
/*-----------主函数-------------------*/
void main()
{
TimerInit();
LCD_init();
EnableInterrupts;
for(;;)
{}
}
/*-----------中断服务程序--------------*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 8 void timeroverflow1(void) //0.02s
{
DisableInterrupts;
TFLG1_C0F=1; // 中断标志位清零
send_data(tab1[i]);
i++;
if(tab1[i]<32) //检查是否还有要显示的字符,
{i++;}
if (tab1[i]<32){TIE=0x00;}//连续检查两次,如果检查到了那么中断禁止
}
作者:
whut_wj
时间:
2009-8-8 11:27
1 看硬件管脚是否联错了。
2 测试一下下时序,主要是延时要求。
这个驱动网上很多,改改就成。
// LCD上文本区 64 字节 LCD上图形区 1024 字节
// ┌──────────────┐ ┌──────────────┐
// │ 第一行 │ │ 前半屏 │
// │地址x: 0x80 --- 0x87 │ │ 64 * 128 点阵 = 512 Byte │
// ├──────────────┤ │每 32*128 点阵 为一行,共2行│
// │ 第二行 │ │行0: 首址y=0x80 前半屏首 │
// │地址x 0x90 --- 0x97 │ │行1: 首址y=0x90 址x = 0x80│
// ├──────────────┤ ├──────────────┤
// │ 第三行 │ │ 后半屏 │
// │地址x 0x88 --- 0x8f │ │ 64 * 128 点阵 = 512 Byte │
// ├──────────────┤ │每 32*128 点阵 为一行,共2行│
// │ 第四行 │ │行2: 首址y=0x80 后半屏首 │
// │地址x 0x90 --- 0x9f │ │行3: 首址y=0x90 址x = 0x88│
// └──────────────┘ └──────────────┘
// 文本区4行,每行可显示8个汉字,或16个字符。文本区的
// 座标位,即文本区的地址x值,如上图所示,或数组TextLine[][8]。
// 图形区分为上下两部份,即上半屏和下半屏。每个半屏的点阵 = 64 * 128,即
// 64行,每行16字节128个bit位。y 座标上下半屏相同都是: 0x80 - 0x9f 共32行。
// 每行行首的x 座标上半屏是 0x80,而下半屏是 0x88。
// 行内的16字节是地址是由操作自动+1,末位加到15,再加又回 0。
下面是底层驱动程序:
// ㈠ ************* 端口设置 *************
extern void _nop_ (void);
#define LCD ((unsigned char volatile xdata *) 0xf010) // 液晶显示器首地址
#define RS 0 // 寄存器选择选择口,=0 指令寄存器,=1 数据寄存器
#define RW 1 // 读写操作控制口,=0 写操作,=1 读操作
#define RST 2 // 液晶显示器复位口,低电平有效
#define BK 3 // 液晶显示器背光口
#define COMM 6 // 液晶显示器命令口
#define DATA 6 // 液晶显示器数据口
#define EN 7 // 液晶显示器使能口,高电平有效
#define STATE 8 // 液晶显示器状态口
// ㈡ ************* 底层驱动程序 *************
/****************************************
测试液晶是否忙 LCD_Busy()
****************************************/
void LCD_Busy(void)
{
LCD[DATA]=0xff; // 数据口先送 0xff
LCD[RS]=0; // 指令
LCD[RW]=1; // 读出忙标志(BF)及地址记数器(AC)
LCD[EN]=1; // 使能
while(LCD[STATE] & 0x80); // 最高位为1则忙,再读
LCD[EN]=0;
}
/***************************************
送指令或数据 LCD_cmd()
参数 md 类别(0/1),md=0 命令 md="1" 数据
dt 命令或数据的值
****************************************/
void LCD_cmd(char md,char dt)
{
LCD_Busy(); // 测试液晶是否忙
if(md) LCD[RS]=1; // 判断是数据还是命令
else LCD[RS]=0;
LCD[RW]=0; // 写
LCD[COMM]=dt; // 送数据或命令
LCD[EN]=1; // 使能
_nop_();
//_nop_();
LCD[EN]=0;
}
/****************************************
从液晶读数据 LCD_Read()
读一字节数据,需读2次。第一次读为空操作
****************************************/
char LCD_Read(void)
{ LCD_Busy(); // 测试液晶是否忙
LCD[RS]=1; // 数据
LCD[RW]=1; // 读
LCD[EN]=1; // 使能
_nop_();
return LCD[DATA]; // 读数据
//LCD[EN]=0;
}
/****************************************
液晶背光控制 LCD_Back(md)
md=0xff 点亮背光,md=0 关背光
****************************************/
void LCD_Back(unsigned char md)
{
LCD[BK] = md;
}
// ㈢ ************* 显示基本函数 *************
code const unsigned char TextLine[][8]= // TS7920 128x64 文本显示行列地址
{{0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87}, // 第一行
{0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97}, // 第二行
{0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f}, // 第三行
{0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f}}; // 第四行
/****************************************
液晶显示器初始化 LCD_init()
****************************************/
void LCD_init(void)
{
LCD[BK]=0;
LCD[RST]=1;
LCD_cmd(0,0x34); // 关闭图形显示 *
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x01); // 清屏,地址指针指向00H
LCD_cmd(0,0x06); // 光标的移动方向
LCD_cmd(0,0x0c); // 开显示,关光标
ClearGraph(); // 清图形区
ClearText(4); // 清文本区
}
/****************************************
清图形区 ClearGraph()
****************************************/
void ClearGraph(void)
{ xdata char i,j,k,x;
x=0x80; // 图型上半区开始位置
for(k=0;k<2;k++)
{ for(j=0;j<32;j++)
{ LCD_cmd(0,0x34); // 扩充指令,关图形显示
LCD_cmd(0,0x80+j); // 确定垂值座标
LCD_cmd(0,x); // 确定水平座标
LCD_cmd(0,0x30); // 基本指令动作
for(i=0;i<16;i++)
LCD_cmd(1,0); // 送数据 0
}
x="0x88"; // 图型下半区开始位置
}
LCD_cmd(0,0x36); // 扩充指令集动作且开图形显示
}
/****************************************
清文本区 ClearText(row)
参数 row 行号(0-4),若 row="4" 清屏
****************************************/
void ClearText(char row)
{ xdata char k,i=0;
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x0c); // 开显示,关光标
if (row>4) return;
if (row==4)
for (k=0;k<4;k++,i=0) // 清四行
{LCD_cmd(0,TextLine[k][0]); // 送出行地址
while (i++<16) LCD_cmd(1,0x20);
}
else
{ LCD_cmd(0,TextLine[row][0]); // 送出行地址
while (i++<16) LCD_cmd(1,0x20);
}
}
/****************************************
显示一屏汉字或字符 DisplayScreen(*p)
参数: *p 待显字符串指针
说明: 数组第2行和第3行显示时将被对调
****************************************/
void DisplayScreen(char *p)
{ xdata char k,i=0;
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x0c); // 开显示,关光标
for (k=0;k<4;k++,i=0) {
LCD_cmd(0,TextLine[k][0]); // 送出行地址
while (*p && i++<16)
LCD_cmd(1,*p++);
if (!(*p)) break;
}
}
/****************************************
显示一行字符串 DisplayRow(row,*p)
参数 row 行号(0-3)
*p 待显字符串指针
****************************************/
void DisplayRow(char row,char *P)
{ char i="0";
if (row>3) return;
LCD_cmd(0,0x30); // 基本指令动作
LCD_cmd(0,0x0c); // 开显示,关光标 *
LCD_cmd(0,TextLine[row][0]); // 送出行地址
while (*P && i++<16)
LCD_cmd(1,*P++);
}
作者:
烙铁头
时间:
2009-8-8 13:53
金鹏的液晶资料上有说明呀,用过OCMJ2*10C,一下是51c程序,移植一下
char putchar (char c)
{ wr_lcd (comm,0x30);
if(DOW<=0x99)
{
wr_lcd (comm,DOW);
wr_lcd (dat,c);
DOW++;
}
else
{
DOW=0x91;
wr_lcd (comm,DOW);
wr_lcd (dat,c);
}
return c;
}
void initlcd (void)
{
wr_lcd (comm,0x30); /*30---基本指令动作*/
wr_lcd (comm,0x01); /*清屏,地址指针指向00H*/
delay (80);
wr_lcd (comm,0x06); /*光标的移动方向*/
wr_lcd (comm,0x0c); /*开显示,关游标*/
}
void clrram (void)
{
wr_lcd (comm,0x30);
wr_lcd (comm,0x01);
delay (120);
DOW=0x91;
}
void wr_lcd (uchar dat_comm,uchar content)
{
uchar a,i,j;
delay (80);
a=content;
cs=1;
sclk=0;
std=1;
for(i=0;i<5;i++)
{
sclk=1;
sclk=0;
}
std=0;
sclk=1;
sclk=0;
if(dat_comm)
std=1; //data
else
std=0; //command
sclk=1;
sclk=0;
std=0;
sclk=1;
sclk=0;
for(j=0;j<2;j++)
{
for(i=0;i<4;i++)
{
a=a<<1;
std=CY; //?
sclk=1;
sclk=0;
}
std=0;
for(i=0;i<4;i++)
{
sclk=1;
sclk=0;
}
}
}
void delay (uint us) //delay time
{
while(us--);
}
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<15;j++)
delay(1);
}
//主程序
void main(void){
SP=0x7f;
initlcd();
while(1)//全局循环
{
disp(tab1);
}//模式处理完成
}
汉字集合放在h文件中
uchar code tab1[]={" 模式选择 "};
作者:
笑傲江湖
时间:
2009-8-8 15:29
2#
烙铁头
51的程序改过,主程序开头的SP不知道是什么,51上没问题,s12却提示未定义
欢迎光临 智能车制作 (http://www.znczz.com/)
Powered by Discuz! X3.2