打印

求助:关于51单片机模拟串口控制lcd12864的问题

[复制链接]
3814|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
libertyzx|  楼主 | 2011-12-17 15:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 libertyzx 于 2011-12-17 15:46 编辑

为什么显示的代码和原来的不一样了,怪···
代码我传附件了
就是字符串最后一个不显示,软件调试过似乎循环少了一次,
怎么少的实在想不通了···


/****************LCD12864-ST7920控制器-并口程序**********************************
//--引脚====名称=============说明====================串口===========I/O===    |**
//-- 01         -- GND      -- GND                       -- 。。        -- GND       |**
//-- 02         -- Vcc      -- +5V                       -- 。。        -- Vcc       |**
//-- 03         -- Vo       -- NC                        -- NC          -- NC        |**
//-- 04         -- RS(CS)   -- 数据/命令(H/L)选择端      -- 片选,L有效 -- P2^0      |**
//-- 05         -- R/W(SID) -- 读/写(H/L)选择端          -- 串数据线    -- P2^1      |**
//-- 06         -- E(SCLK)  -- 使能信号                  -- 串时钟输入  -- P2^2      |**
//--07-10 - DB0~3    -- 低四位数据口              -- NC          -- NC        |**
//--11-14 - DB4~7    -- 高四位数据口(4并口则空接) -- NC          -- NC        |**
//-- 15         -- PSB      -- 并/串(H/L)选择            -- L串口       -- GND       |**
//-- 16         -- NC       -- NC                        -- NC          -- NC        |**
//-- 17         -- /RST     -- 复位信号,L有效           -- 。。        -- Vcc       |**
//-- 18         -- Vout     -- NC                        -- NC          -- NC        |**
//-- 19         -- BLA      -- 背光正                    -- 。。        -- GND              |**
//-- 20         -- BLK      -- 背光地                    -- 。。        -- Vcc       |**
//===功能=====================================================================|**
//-实现数据串行发送显示                                                       |**
/*******************************************************************************/
#include<reg52.h>

//--宏定义-----------------------------------------------------
#define uchar unsigned char
#define uint unsigned int

//--单片机I/0口声明--------------------------------------------
sbit CS=P2^0;      //片选,每次数据操作时必须拉高
sbit SID=P2^1;     //串数据线
sbit SCLK=P2^2;     //串时钟输入

//--函数声明---------------------------------------------------
void LCD_init(void);    //LCD_初始化
void T0_init(void);    //定时器_初始化
void I_com(uchar com);    //写指令
void I_data(uchar Data);    //写数据
void O_bit_8(uchar Data);    //输出8bit
void delay(uint i);    //延时  

//--全局变量---------------------------------------------------
uchar x=1;      //时钟输出端 H/L 赋值选择


/*--主函数-----------------------------------------------------
**-函数名:
**-功能:                                                   |**
**-输入:无                                                 |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void main(void)
{
    uchar code a[]="01234";    //输出数据   ---------------最后的4就是不输出·····
    uchar i=0;    //循环数据输出用
   
    CS=1;    //片选置1允许操作

    T0_init();    //定时器初始化
    LCD_init();    //LCD初始化

    I_com(0x80);    //定位x=1,y=1

    for(i=0;a!='\0';i++)
    {
        I_data(a);    //数据输出   
    }
   
    while(1);   
}

/*--LCD_初始化-------------------------------------------------ok
**-函数名:LCD_init                                         |**
**-功能:LCD12864初始化                                     |**
**-输入:无                                                 |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void LCD_init(void)
{
    delay(40);      //等待40ms
    I_com(0x30);    //8位数据传输
    delay(2);
    I_com(0x0F);    //显示开,游标开
    delay(2);
    I_com(0x01);    //清屏   
    delay(2);
    I_com(0x02);    //地址归位
    delay(2);
    I_com(0x06);    //进入点设定 AC+1            
}

/*--定时器_初始化----------------------------------------------ok
**-函数名:T0_init                                          |**
**-功能:初始化T0(一直打开)                                 |**
**-输入:无                                                 |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void T0_init(void)
{
    TMOD=0x02;  //-0000 0010-T0 方式2-8位初值自装
    TH0=0xA0;   //|-T0-初值244 即定时12us(12MHz)
    TL0=0xA0;   //|
    EA=1;       //开总中断
    ET0=1;      //允许打开T0中断
    TR0=1;       //启动T0        
}

/*--写指令-----------------------------------------------------ok
**-函数名:I_com                                            |**
**-功能:主机向LCD12864写指令(com)                          |**
**-输入:com                                                |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void I_com(uchar com)
{
    uchar temp=0;    //暂时存放数据

    //CS=1;    //片选置1允许操作
    O_bit_8(0xF8);    //串行写指令 指令
    temp=com&0xF0;    //舍弃低4位
    O_bit_8(temp);    //指令高4位传输
    temp=com&0x0F;    //舍弃高4位
    temp<<=4;    //左移4位
    O_bit_8(temp);    //指令低4位传输  
    //CS=0;    //片选置0禁止操作            
}

/*--写数据-----------------------------------------------------ok
**-函数名:I_data                                           |**
**-功能:主机向LCD12864写数据(Data)                         |**
**-输入:Data                                               |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void I_data(uchar Data)
{
    uchar temp=0;    //暂时存放数据

    //CS=1;    //片选置1允许操作
    O_bit_8(0xFA);    //串行写数据 指令
    temp=Data&0xF0;    //舍弃低4位
    O_bit_8(temp);    //数据高4位传输
    temp=Data&0x0F;    //舍弃高4位
    temp<<=4;    //左移4位
    O_bit_8(temp);    //数据低4位传输
    //CS=0;    //片选置0禁止操作     
}

/*--读忙-------------------------------------------------------
**-函数名:bf                                               |**
**-功能:判断LCD12864是否忙                                 |**
**-输入:无                                                 |**
**-返回值:无                                               |**
**-----------------------------------------------------------
void bf(void)      //(D7=1)忙状态不能写
{
           
}     */


/*--输出8bit---------------------------------------------------ok
**-函数名:O_bit_8                                          |**
**-功能:主机向LCD12864输入8位数据(Data)                    |**
**-输入:Data                                               |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void O_bit_8(uchar Data)
{
    uchar i=0;    //循环用
   
    while(i!=8)
    {
        if(TF0==1)    //T0溢出标志,溢出硬置1,需软置0
        {
            TF0=0;    //软置0
            if((SCLK=x=!x)==0)
            {
                SID=(bit)((((Data<<i)&0x80)==0)?0:1);
                i++;
            }
        }
    }
}      


/*--读入8bit---------------------------------------------------
**-函数名:I_bit_8                                          |**
**-功能:从LCD12864读数据到主机                             |**
**-输入:无                                                 |**
**-返回值:读出的数据                                       |**
**-----------------------------------------------------------
uchar I_bit_8(void)
{
   
}  */


/*--延时-------------------------------------------------------ok
**-函数名:delay                                            |**
**-功能:延时 i*1ms 时间                                    |**
**-输入:i                                                  |**
**-返回值:无                                               |**
**-----------------------------------------------------------*/
void delay(uint i)           //- 11.0592情况下 延时995.01us 约1ms
{
        uint j=0;
        for(i;i>0;i--)
                for(j=113;j>0;j--);          
}

LCD_12864_串行.zip

2.03 KB

相关帖子

沙发
libertyzx|  楼主 | 2011-12-17 21:42 | 只看该作者
为什么就没有人说一句话 :'(

使用特权

评论回复
板凳
NE5532| | 2011-12-17 22:00 | 只看该作者
想不通就测,一般谁有耐心去看你的软件呢?大不了给你指个大方向罢了。本版上面的“黑宝书”就是你的救星。

使用特权

评论回复
地板
libertyzx|  楼主 | 2011-12-17 22:05 | 只看该作者
3# NE5532

我测了两天了,就是测不出,不然我就不会来提问了,哎

使用特权

评论回复
5
NE5532| | 2011-12-17 22:07 | 只看该作者
那说说你咋测的?

使用特权

评论回复
6
libertyzx|  楼主 | 2011-12-17 22:12 | 只看该作者
5# NE5532

keil软件测,一步一步看其变量输出,
我又从写了一遍,
解决方法我找到一个,可是找到这个答案让我更纠结了,
只要改主函数里的while语句就可以解决,
可是这个语句和输出没有什么关系啊,所以更纠结了

使用特权

评论回复
7
NE5532| | 2011-12-17 22:15 | 只看该作者
你的程序调试方法有问题,程序要分模块,建议你读下我的帖子,我们再来讨论。

使用特权

评论回复
8
libertyzx|  楼主 | 2011-12-17 22:40 | 只看该作者
7# NE5532


好吧,我刚刚看了一遍你的程序调试黑皮书,我也懂分模块来写程序,调试程序
也一直这样做(比如注释,我觉得我写得够多了,感觉太多了,但是我**力不好我怕下次看不懂所以猛写)
    在调试这块,在小的程序里面我是写完一块在调试的,像我提问的问题,只是一个单片机向lcd液晶传输数据,分两块,一个是传输指令,一个是传输数据,我写完后先调试了传输指令,通过,没有问题,因为指令与数据传输上是相同的,所以我没有在思考什么直接就写传输数据了,可写好后问题来了,显示数据少了一个,然后我调试,排除指令的问题(不然它一个数据都显示不出来了)然后在主函数的头文件上发现,她少循环了一次,但这怎么可能??语法是对的,我可以坑定,但它就是少了次循环·····
    无奈在想再调试,在该代码比如lcd的初始设定,还是无力,无奈下我就来提问了,
提问好,我整理了下思路,从新写了一遍,就是主函数while语句位置改下让它不断循环数据输出语句就好了,可是我还是不知道原来的问题在哪,while和输出数据是无关的啊····

使用特权

评论回复
9
NE5532| | 2011-12-18 09:27 | 只看该作者
所以说你没看懂我的帖子呢,你为什么不测试一下显示1,显示12,显示123,看是不是都是最后一个不显示,积累足够的判据来促使自己找问题呢?

a!='\0',这个条件真的能成立么?你前面定义的是 uchar code a[]="01234"; 字符串末尾的'\0'系统帮你填写了么?如果没有,那for循环退得出来么?01、23刚好配对,4就跟后面的FF组成非显示字符了,当然不显示。


添不添0我是不记得了,诸位大可以来BS偶的C语言,但是我不需要知道,开list文件一看不就知道了。虽然我C没你熟,但是我会想办法。

使用特权

评论回复
10
libertyzx|  楼主 | 2011-12-18 11:59 | 只看该作者
9# NE5532

你说的我都试过了,一个数值,两个数字,一个汉字两个汉字,也把循环改成过i<5,什么的
都还是这样,也试过,没有用循环一个一个的输出,最后一个还是没有输出,昨天晚上我换了种思想写了void O_bit_8(uchar Data)
函数
然后所有问题都解决了,可是我还是不懂  上面程序void O_bit_8(uchar Data)错在那,为什么会让最后一个字符不输出。
   

使用特权

评论回复
11
NE5532| | 2011-12-18 15:00 | 只看该作者
如果始终都是最后一个不能显示的话,肯定是结束条件有问题。

使用特权

评论回复
12
libertyzx|  楼主 | 2011-12-18 15:33 | 只看该作者
11# NE5532


始终不显示最后一个,解决方法到是有,只要以后不这样写就可以了,这样就可以避免问题了,哎,不深究了,太浪费时间了:D

使用特权

评论回复
13
NE5532| | 2011-12-18 21:53 | 只看该作者
不研究对你的成长不利。

使用特权

评论回复
14
libertyzx|  楼主 | 2011-12-18 22:09 | 只看该作者
13# NE5532


好吧,那你说怎么研究啊,这个错在那?没有人回答我,问了好几个论坛,都无解,靠自己吧,我是把问题解决了,可是就是不知道错在那,那唯一能做的是避免这个错误,也许等到下次遇到时就可以解决了~惆怅啊····

使用特权

评论回复
15
joyme| | 2011-12-19 15:16 | 只看该作者
     while(i!=8)
    {
        if(TF0==1)    //T0溢出标志,溢出硬置1,需软置0
        {
            TF0=0;    //软置0
            if((SCLK=x=!x)==0)
            {
                SID=(bit)((((Data<<i)&0x80)==0)?0:1);
                i++;
            }
        }
    }


你的SCLK执行完这个循环后会为0,最后一个数据应为没有SCLK=1(上升沿)从而读不到最后一位数据,所以不管怎么样你最后一个字符都显示不了。要改也很简单,跳出循环加一句话就好了

使用特权

评论回复
16
libertyzx|  楼主 | 2011-12-19 18:17 | 只看该作者
15# joyme

谢谢了,我调试,试试

使用特权

评论回复
17
libertyzx|  楼主 | 2011-12-19 18:22 | 只看该作者
15# joyme

真是谢谢了,问题终于解决了,原来少了个上升沿啊:handshake

使用特权

评论回复
18
NE5532| | 2011-12-19 21:32 | 只看该作者
对咯,就是始终“最后一个”问题三。下次就学会方法了,恭喜。

使用特权

评论回复
19
libertyzx|  楼主 | 2011-12-20 11:50 | 只看该作者
18# NE5532

嘎嘎,谢了~~~:D

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:日子真难过····

2

主题

39

帖子

1

粉丝