智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 2311|回复: 9
打印 上一主题 下一主题

新手求教1602问题

[复制链接]

6

主题

166

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1494
威望
886
贡献
326
兑换币
28
注册时间
2010-12-25
在线时间
141 小时
跳转到指定楼层
1#
发表于 2012-2-8 21:27:23 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
51上调通的程序 XS上面不行了  想来应该是时序问题 可是改了好久还是没效果  求高手帮忙看看
typedef unsigned char unchar;                    //用unchar代替unsigned char
  

#define Lcd_RS PORTB_PB6                             //复位端            
#define Lcd_RW PORTB_PB5                      //写数据端
#define Lcd_EP PORTB_PB7                       //使能端


/****************延时函数************************/
void Lcd_delay(int ms)
{                    //延时子程序
int i;
while(ms--)
{
   for(i = 0; i< 500; i++)
   {
    _asm(nop);   //空执行
    _asm(nop);
    _asm(nop);
    _asm(nop);
   }
}
}
/****************测忙函数************************/  
unchar Lcd_bz()
{                        
  unchar result;
  DDRA=0x00;
   
Lcd_RS = 0;
Lcd_RW = 1;
Lcd_EP = 1;
     _asm(nop);   
    _asm(nop);
    _asm(nop);
    _asm(nop);
   
result=(PORTA&0x80); //检测PA最高位是否为1
  
  Lcd_EP = 0;
return result;//返回侧忙结果
}
/****************写命令函数************************/
void Lcd_wcmd(unchar cmd)
{                          // 写入指令数据到Lcd
while(Lcd_bz());
  DDRA=0xff;
  
Lcd_RS = 0;
Lcd_RW = 0;
Lcd_EP = 0;
     _asm(nop);   
    _asm(nop);
    _asm(nop);
    _asm(nop);
  PORTA = cmd;             //将8位指令通过PA口传给1602
     _asm(nop);   
    _asm(nop);
    _asm(nop);
    _asm(nop);
Lcd_EP = 1;
    _asm(nop);   
    _asm(nop);
    _asm(nop);
    _asm(nop);
Lcd_EP = 0;

   
}
/***************位置函数****************************/
void Lcd_pos(unchar pos)
{                          //设定显示位置
Lcd_wcmd(pos | 0x80);
}
/****************写数据函数************************/
void Lcd_wdat(unchar dat)
{                          //写入字符显示数据到Lcd
while(Lcd_bz());
   DDRA=0xff;
   
Lcd_RS = 1;
Lcd_RW = 0;
Lcd_EP = 0;
  PORTA = dat;       //将8位数据通过P0口传给1602
    _asm(nop);   
    _asm(nop);
    _asm(nop);
    _asm(nop);         
Lcd_EP = 1;
   
   _asm(nop);   
    _asm(nop);
    _asm(nop);
    _asm(nop);
Lcd_EP = 0;
  
}

void Lcd_init()
{                            //Lcd初始化设定
Lcd_wcmd(0x38);              //16*2显示,5*7点阵,8位数据
Lcd_delay(2);
Lcd_wcmd(0x0c);              //显示开,关光标
Lcd_delay(2);
Lcd_wcmd(0x06);               //移动光标
Lcd_delay(2);
Lcd_wcmd(0x01);              //清除Lcd的显示内容
Lcd_delay(2);
}


void Display(unchar p,unchar d)
  {
  
    Lcd_pos(p);
    Lcd_wdat(d);
  
  }



2

主题

52

帖子

0

精华

高级会员

Rank: 4

积分
638
威望
400
贡献
86
兑换币
4
注册时间
2011-8-29
在线时间
76 小时
10#
发表于 2012-3-21 18:33:53 | 只看该作者
如何解决楼主的问题,求回复
回复 支持 反对

使用道具 举报

5

主题

75

帖子

0

精华

高级会员

Rank: 4

积分
869
威望
556
贡献
191
兑换币
2
注册时间
2011-9-24
在线时间
61 小时
9#
发表于 2012-2-11 10:17:09 | 只看该作者
看了楼上几位大神,很是膜拜!
但是谁能告诉我楼主错在什么地方?
回复 支持 反对

使用道具 举报

12

主题

202

帖子

0

精华

金牌会员

蓝梦

Rank: 6Rank: 6

积分
2818

活跃会员奖章优秀会员奖章在线王奖章

QQ
威望
1111
贡献
923
兑换币
2
注册时间
2011-5-26
在线时间
392 小时
8#
发表于 2012-2-11 09:50:29 | 只看该作者
如果数据位是8位连续的
void Write (uchar data)
{
    LCD_D0  = data & 0x01;
    LCD_D1  = (data >>= 1)&0x01;
    LCD_D2  = (data >>= 1)&0x01;
    LCD_D3  = (data >>= 1)&0x01;
    LCD_D4  = (data >>= 1)&0x01;
    LCD_D5  = (data >>= 1)&0x01;
    LCD_D6  = (data >>= 1)&0x01;
    LCD_D7  = (data >>= 1)&0x01;
}
就不用这样写了
回复 支持 反对

使用道具 举报

12

主题

202

帖子

0

精华

金牌会员

蓝梦

Rank: 6Rank: 6

积分
2818

活跃会员奖章优秀会员奖章在线王奖章

QQ
威望
1111
贡献
923
兑换币
2
注册时间
2011-5-26
在线时间
392 小时
7#
发表于 2012-2-11 09:47:45 | 只看该作者
#include <hidef.h>        
#include "derivative.h"
#include "LCD1602.h"   


uchar const dis1[] = {"Smart Car  <^_^>"};

void delay(uint ms)
{                           
   uint i;
   while(ms--)
   {
        for(i = 0; i< 250; i++)
        {
            _asm(nop);
            _asm(nop);
            _asm(nop);
            _asm(nop);
        }
   }
}

void SYS_Init( void )
{
    SetBusCLK_24M();
    IO_Init();
    Status_Init();
    PWM_Init();
    PITtimer_Init();
    //nRF905_inti();
}

void main(void)
{
    uchar i;
    SYS_Init();
    /*
    if( LCD == 0 )
    {
        lcd_init();
        lcd_pos(0);
        i = 0;
        while(dis1[i] != '\0')
        {                              
            lcd_wdat(dis1[i]);
            i++;
            delay(30);        
        }      
    }
    */   
    EnableInterrupts;   
    for(;;)
    {         
        Switch_Init();
        /*
        if(LCD == 0)
        {         
            lcd_pos(0x40);
            for(i=0;i<6;i++)
            {
                if(((LD_tmp>>i)&0x01)==0x01)
                {              
                    lcd_wdat('1');
                }
                else
                    lcd_wdat('0');
            }
            delay(30);         
        }
        */                    
    }
       
}




回复 支持 反对

使用道具 举报

12

主题

202

帖子

0

精华

金牌会员

蓝梦

Rank: 6Rank: 6

积分
2818

活跃会员奖章优秀会员奖章在线王奖章

QQ
威望
1111
贡献
923
兑换币
2
注册时间
2011-5-26
在线时间
392 小时
6#
发表于 2012-2-11 09:43:35 | 只看该作者
/**********************1602液晶驱动程序**********************************/
/**********************2011年12月9日   **********************************/
/**********************心晨晨编制      **********************************/
#ifndef _LCD1602_H
#define _LCD1602_H

//LCD引脚定义*************************************************************
#define  LCD_RS     PTH_PTH2         //寄存器选择 1:数据 0:指令      
#define  LCD_RW     PTH_PTH3         //读写选择   1:读   0:写
#define  LCD_EN     PTH_PTH1         //使能信号
//0  1  1读状态   格式:FB AC6 5 4 3 2 1 0 (FB=1为忙 AC:地址计数器)  
//0  0 ↓写指令
//1  1  1读数据
//1  0 ↓写数据

#define  LCD_D0     PORTB_PB7        //数据输入位0
#define  LCD_D1     PORTB_PB5        //数据输入位1
#define  LCD_D2     PORTE_PE2        //数据输入位2
#define  LCD_D3     PORTE_PE3        //数据输入位3
#define  LCD_D4     PORTE_PE4        //数据输入位4
#define  LCD_D5     PORTE_PE5        //数据输入位5
#define  LCD_D6     PORTE_PE6        //数据输入位6
#define  LCD_D7     PORTE_PE7        //数据输入位7
#define  Busy       PORTE_PE7        //忙信号检测
//#define  LCD        PORTA_PA1        //LCD检测

//1602指令*****************************************************************
#define  CLR        0x01            //清屏,清除DDRAM,光标归位,AC=0
#define  RET        0x02            //光标归位,AC=0

#define  IDS1       0x04       //写入数据后光标左移,显示屏不移动
#define  IDS2       0x05       //写入数据后光标左移,显示屏整体右移一个字符
#define  IDS3       0x06       //写入数据后光标右移,显示屏不移动
#define  IDS4       0x07       //写入数据后光标右移,显示屏整体右移一个字符

#define  DCB1       0x08            //指令为0 0 0 0  1 D C B
#define  DCB2       0x09            //D: 0显示关        1显示开
#define  DCB3       0x0a            //C: 0无光标        1有光标
#define  DCB4       0x0b            //B: 0光标不闪烁    1光标闪烁
#define  DCB5       0x0c
#define  DCB6       0x0d
#define  DCB7       0x0e
#define  DCB8       0x0e
                                    //指令 0 0 0 1  S R * *
#define  SR1        0x10            //光标左移1格,且AC值减1
#define  SR2        0x14            //光标右移1格,且AC值加1
#define  SR3        0x18            //显示器上字符全部左移一格,但光标不动
#define  SR4        0x1c            //显示器上字符全部右移一格,但光标不动

#define  DNF1       0x20            //指令 0 0 1 D  N F * *
#define  DNF2       0x24            //0数据总线为4位     1数据总线为8位
#define  DNF3       0x28            //0显示1行           1显示2行
#define  DNF4       0x2c            //0=5×7点阵         1=5×10点阵
#define  DNF5       0x30
#define  DNF6       0x34
#define  DNF7       0x38
#define  DNF8       0x3c

#define  DDR        0x80            //设定显示地址
#define  CGR        0x40            //设定CGRAM地址


//***************************************************************************
//***************************************************************************

void LCDdelay(uint ms)
{                           
   uint i;
   while(ms--)
   {
     for(i = 0; i< 250; i++)
     {
        _asm(nop);
        _asm(nop);
        _asm(nop);
        _asm(nop);
     }
   }
}

void Write (uchar data)
{
    LCD_D0  = data & 0x01;
    LCD_D1  = (data >>= 1)&0x01;
    LCD_D2  = (data >>= 1)&0x01;
    LCD_D3  = (data >>= 1)&0x01;
    LCD_D4  = (data >>= 1)&0x01;
    LCD_D5  = (data >>= 1)&0x01;
    LCD_D6  = (data >>= 1)&0x01;
    LCD_D7  = (data >>= 1)&0x01;
}
                                                                                         
//检查LCD忙状态************************************************************         
uchar lcd_busy()
{                          
    uchar result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;   
    //检测忙信号时,单片机IO口设置为输入口                    
    DDRE_DDRE7 = 0;
      
    _asm(nop);
    _asm(nop);
    _asm(nop);
    _asm(nop);
    result = Busy;
    LCD_EN = 0;
    //检测忙信号完成后单片机IO口设置为输出口  
    DDRE_DDRE7 = 1;
      
    return result;
}     
//写指令到LCD***************************************************************
//RS=L,RW=L,E=下降沿脉冲,D0-D7=指令码************************************
void lcd_wcmd(uchar cmd)
{                          
    while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _asm(nop);
    _asm(nop);
    Write(cmd);
    _asm(nop);
    _asm(nop);
    _asm(nop);
    _asm(nop);   
    LCD_EN = 1;
    _asm(nop);
    _asm(nop);
    _asm(nop);
    _asm(nop);   
    LCD_EN = 0;  
}                                                                                                                                
//写显示数据到LCD*************************************************************   
//RS=H,RW=L,E=下降沿脉冲,D0-D7=指令码**************************************
void lcd_wdat(uchar dat)
{                          
    while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    Write(dat);
    _asm(nop);
    _asm(nop);
    _asm(nop);
    _asm(nop);
    LCD_EN = 1;
    _asm(nop);
    _asm(nop);
    _asm(nop);
    _asm(nop);
    LCD_EN = 0;
}
//数据指针=80+地址变量**********************************************************
void lcd_pos(uchar pos)
{                          
    lcd_wcmd(pos|DDR);      
}                                                                                                                                 
//LCD初始化设定*****************************************************************                                                                                                           
void lcd_init()
{                        
    lcd_wcmd(DNF7);          //16*2显示,5*7点阵,8位数据
    LCDdelay(5);
    lcd_wcmd(DNF7);         
    LCDdelay(5);
    lcd_wcmd(DNF7);         
    LCDdelay(5);
    lcd_wcmd(DCB5);          //显示开,关光标
    LCDdelay(5);
    lcd_wcmd(IDS3);          //移动光标
    LCDdelay(5);
    lcd_wcmd(CLR);           //清除LCD的显示内容
    LCDdelay(5);
}

#endif
//*******************************************************************************
//*******************************************************************************
回复 支持 反对

使用道具 举报

6

主题

166

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1494
威望
886
贡献
326
兑换币
28
注册时间
2010-12-25
在线时间
141 小时
5#
 楼主| 发表于 2012-2-10 21:14:19 | 只看该作者
问乐寻音 发表于 2012-2-9 19:05
这个……一点都没有显示吗?还有dat定义成char试试,不要定义成uchar。字符记得加单引号。再不行我就不知 ...

还是不行,不过谢谢你了。。
回复 支持 反对

使用道具 举报

34

主题

500

帖子

1

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3183

推广达人奖章优秀会员奖章活跃会员奖章

威望
2298
贡献
257
兑换币
597
注册时间
2011-10-2
在线时间
314 小时
4#
发表于 2012-2-9 19:05:58 | 只看该作者
719167267 发表于 2012-2-9 14:48
还是不行啊。。。

这个……一点都没有显示吗?还有dat定义成char试试,不要定义成uchar。字符记得加单引号。再不行我就不知道了。
回复 支持 反对

使用道具 举报

6

主题

166

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1494
威望
886
贡献
326
兑换币
28
注册时间
2010-12-25
在线时间
141 小时
3#
 楼主| 发表于 2012-2-9 14:48:24 | 只看该作者
问乐寻音 发表于 2012-2-9 00:24
nop在51里有1us,操作LCD的函数里要求延时4us或更多,所以4个nop不够啦。

还是不行啊。。。
回复 支持 反对

使用道具 举报

34

主题

500

帖子

1

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3183

推广达人奖章优秀会员奖章活跃会员奖章

威望
2298
贡献
257
兑换币
597
注册时间
2011-10-2
在线时间
314 小时
2#
发表于 2012-2-9 00:24:54 | 只看该作者
nop在51里有1us,操作LCD的函数里要求延时4us或更多,所以4个nop不够啦。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-22 07:06 , Processed in 0.063876 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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