智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 3323|回复: 3
打印 上一主题 下一主题

[控制类] 液晶!!跪求高手解答,我都郁闷两天了~~~~~~~~

[复制链接]

0

主题

8

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
210
威望
180
贡献
22
兑换币
0
注册时间
2009-7-30
在线时间
4 小时
跳转到指定楼层
1#
发表于 2009-8-8 11:27:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1贡献
我用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;}//连续检查两次,如果检查到了那么中断禁止

}

最佳答案

查看完整内容

1 看硬件管脚是否联错了。 2 测试一下下时序,主要是延时要求。 这个驱动网上很多,改改就成。 // LCD上文本区 64 字节 LCD上图形区 1024 字节 // ┌──────────────┐ ┌──────────────┐ // │ 第一行 │ │ 前半屏 │ // │地址x: 0x80 --- 0x87 │ │ 64 * 128 点阵 = 512 Byte │ // ├──────────── ...

14

主题

929

帖子

1

精华

功勋会员

WJ

Rank: 10Rank: 10Rank: 10

积分
6304

特殊贡献奖章

威望
1456
贡献
4674
兑换币
17
注册时间
2008-4-6
在线时间
87 小时
2#
发表于 2009-8-8 11:27:58 | 只看该作者
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++);
   
}
回复

使用道具 举报

0

主题

150

帖子

0

精华

高级会员

Rank: 4

积分
749
QQ
威望
361
贡献
238
兑换币
0
注册时间
2009-3-20
在线时间
75 小时
3#
发表于 2009-8-8 13:53:43 | 只看该作者
金鹏的液晶资料上有说明呀,用过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[]={"      模式选择      "};
回复

使用道具 举报

0

主题

8

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
210
威望
180
贡献
22
兑换币
0
注册时间
2009-7-30
在线时间
4 小时
4#
 楼主| 发表于 2009-8-8 15:29:02 | 只看该作者
2# 烙铁头
51的程序改过,主程序开头的SP不知道是什么,51上没问题,s12却提示未定义
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-20 17:55 , Processed in 0.077764 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表