搜索
bottom↓
回复: 21

潜水久了浮上来吐个泡,用ATmega16驱动的LCD2004的源程序,望各位多多指教!

[复制链接]

出0入0汤圆

发表于 2005-8-3 15:55:29 | 显示全部楼层 |阅读模式






/*=======================================================

20x4字符液晶主程序,编译软件(ICCAVR_6.31)

CPU内部晶振8M

数据线B0~B7接PORTB, E=D7 RW=D6 RS=D5

=========================================================

接线图如下:

_______________           ______________

               |      --1|GND           |

               |      --2|+5V           |

               |      --3|V0            |

               |         |              |

            PD5|--------4|RS            |

            PD6|--------5|RW            |

            PD7|--------6|E             |

CPU           |         |              |

ATmmega16L PB0|--------7|D0  LCD20x4   |

            PB1|--------8|D1            |

            PB2|--------9|D2            |

            PB3|-------10|D3            |

            PB4|-------11|D4            |

            PB5|-------12|D5            |

            PB6|-------13|D6            |

            PB7|-------14|D7            |

               |         |              |

               |     --15|+LED          |

               |     --16|-LED          |

_______________|         |______________|

========================================================*/

#include<ioM16V.h> //CPU_ATmmega16L

#define RS_H    asm("sbi 0x12,5")  //RS设为高电平

#define RS_L    asm("cbi 0x12,5")  //RS设为低电平

#define RW_H    asm("sbi 0x12,6")  //RW设为高电平

#define RW_L    asm("cbi 0x12,6")  //RW设为低电平

#define E_H     asm("sbi 0x12,7")  //E设为高电平

#define E_L     asm("cbi 0x12,7")  //E设为低电平



//=======================================================

//微秒级延时程序

void delay_us(int time)

{

    do

    {

        time--;

    }       

    while (time > 1);

}

//=======================================================

//毫秒级延时程序

void delay_ms(unsigned int time)

{

    while(time != 0)

    {               

        delay_us(1000);

        time--;

    }

}



//=======================================================

//读取lcd是否内部操作(忙碌)状态

char Lcd_Busy()

{

    char r;

    DDRB = 0x00;       //端口B设为输入方式

    E_L;RS_L;RW_H;     //E=0(致能),RS=0(命令),RW=1(读)

    delay_us(2);       //液晶延时子程序

    E_H;

    delay_us(2);       //液晶延时子程序

    r = PINB & 0x80;   //读取lcd_data第八位

    E_L;

    DDRB=0xff;         //端口B设为输出方式

    return r;          //读取结果返回

}



//=======================================================

//向Lcd发送命令程序

void Lcd_Command(unsigned char Command)

{

    while(Lcd_Busy()); //判断lcd是否内部操作状态

    E_L;RS_L;RW_L;     //E=0(致能),RS=0(命令),RW=0(写)

    delay_us(2);       //液晶延时子程序

    E_H;

    PORTB = Command;   //向Lcd发送命令

    delay_us(2);       //液晶延时子程序

    E_L;

}



//=======================================================

//向lcd写入一个字符程序

void Lcd_Write(unsigned char Data)

{

    while(Lcd_Busy()); //判断lcd是否内部操作状态

    E_L;RS_H;RW_L;     //E=0(致能),RS=1(数据),RW=0(写)

    delay_us(2);       //液晶延时子程序

    E_H;

    PORTB = Data;      //向lcd写入一个字符

    delay_us(2);       //液晶延时子程序

    E_L;

}





/*=======================================================

LCD第1行显示地址1~20(0x80~0x93)

LCD第2行显示地址1~20(0xc0~0xd3)

LCD第3行显示地址1~20(0x94~0xa7)

LCD第4行显示地址1~20(0xd4~0xe7)

=======================================================*/

//初始化LCD_8位接口,4行x20字符的工作方式

void Lcd_Init()

{

    DDRB = 0xff;       //端口B设为输出方式

    DDRD = 0xff;       //端口D设为输出方式

    Lcd_Command(0x38); //

    Lcd_Command(0x38); //

    Lcd_Command(0x38); //

    Lcd_Command(0x38); //

    Lcd_Command(0x08); //令显示器off

    Lcd_Command(0x01); //清除显示器

    Lcd_Command(0x06); //令LCD每接收到1Byte数据后,AC自动加1

    Lcd_Command(0x0C); //令光标,0x0c=不显示,0x0d=显示闪动.

}



//=======================================================

//写ASCII字符串程序

void asc_tran(unsigned char *asc)

{

    while((*asc) != 0)   //判断字是否结束

    {

        Lcd_Write(*asc); //向lcd写入字符串

        asc++;           //移下一个字符

    }

}



//=======================================================

//测试主LCD主程序

void main()

{

    Lcd_Init(); //初始化LCD

    while(1)

    {

        Lcd_Command(0x83);               //设置显示位址

        asc_tran("-----__@------");      //显示字符串

        Lcd_Command(0x97);               //设置显示位址

        asc_tran("www.ouravr.com");      //显示字符串

        delay_ms(1000);                  //延迟1秒

        Lcd_Command(0x01);               //清除显示器



        Lcd_Command(0x83);               //设置显示位址

        asc_tran("-----^_^------");      //显示字符串

        Lcd_Command(0x94);               //设置显示位址

        asc_tran("http://59.36.96.196"); //显示字符串

        delay_ms(1000);                  //延迟

        Lcd_Command(0x01);               //清除显示器

    }

}

点击此处下载armok0160569.rar









在这里好多谢阿莫给予这个网站有机会潜水学习AVR,谢谢各位!


-----此内容被LaoHou于2005-08-03,16:20:13编辑过

出0入0汤圆

发表于 2005-8-3 23:15:34 | 显示全部楼层
谢谢共享~!

出0入0汤圆

发表于 2005-8-4 16:52:21 | 显示全部楼层
XIE写的很好~!!

支持一下

出0入0汤圆

发表于 2006-5-18 10:39:39 | 显示全部楼层
顶!!!

出0入0汤圆

发表于 2006-5-18 11:31:29 | 显示全部楼层
敬礼!!!

出0入0汤圆

发表于 2006-7-12 23:09:17 | 显示全部楼层
谢谢贡献!

出0入0汤圆

发表于 2006-7-13 09:26:12 | 显示全部楼层
能注明LCD是什么控制芯片吗?

出0入0汤圆

发表于 2006-7-13 09:58:05 | 显示全部楼层
LCD控制芯片应该是ST7920的吧!!

出0入0汤圆

发表于 2006-7-13 10:16:18 | 显示全部楼层
字符型器件接线图画得真漂亮!



出0入0汤圆

发表于 2006-7-14 01:16:42 | 显示全部楼层
20*4的字符屏控制芯片和16*2的兼容,HD44780/SED1278

出0入0汤圆

发表于 2006-9-19 09:12:30 | 显示全部楼层
不错!多顶几下!

出0入0汤圆

发表于 2006-11-10 21:22:47 | 显示全部楼层
大家好,我想问一下,我把上面楼主的程序下载到单片机中,刚开始可以显示。几个小时后再也不能显示,这是什么原因呢?

    换新的LCD与单片机都不行。

    我用的单片机是ATmega16,LCD1602C。下载成功时用的同样是这个型号的单片机与LCD。

出0入0汤圆

发表于 2007-5-3 18:29:08 | 显示全部楼层
//测试主LCD主程序

void main()

{

    Lcd_Init(); //初始化LCD

    while(1)

    {

        Lcd_Command(0x83);               //设置显示位址

        asc_tran("-----__@------");      //显示字符串

        Lcd_Command(0x97);               //设置显示位址

        asc_tran("www.ouravr.com");      //显示字符串

        delay_ms(1000);                  //延迟1秒

        Lcd_Command(0x01);               //清除显示器





这个例子是显示固定的文字符号的,但当要在液晶上同步显示一个变量的时候该怎么处理呢,在“asc_tran("-----__@------");      //显示字符串”中直接把括号里的内容换掉是不行的,望高手指教。

出0入0汤圆

发表于 2007-5-4 18:23:01 | 显示全部楼层
那公司的

出0入0汤圆

发表于 2007-5-6 20:53:44 | 显示全部楼层
//测试主LCD主程序  

void main()  

{  

    Lcd_Init(); //初始化LCD  

    while(1)  

    {  

        Lcd_Command(0x83);               //设置显示位址  

        asc_tran("-----__@------");      //显示字符串  

        Lcd_Command(0x97);               //设置显示位址  

        asc_tran("www.ouravr.com");      //显示字符串  

        delay_ms(1000);                  //延迟1秒  

        Lcd_Command(0x01);               //清除显示器





这个例子是显示固定的文字符号的,但当要在液晶上同步显示一个变量的时候该怎么处理呢,在“asc_tran("-----__@------");      //显示字符串”中直接把括号里的内容换掉是不行的,望大家指教。

出0入0汤圆

发表于 2007-5-6 21:53:29 | 显示全部楼层
行的,是显示一个字串,而不是一个变量.显示一个字符是Lcd_Write函数.



void main()

{

    unsigned char aa[]="-----__@------";

    Lcd_Init(); //初始化LCD

    aa[0]='*';

    aa[1]='*';

    while(1)

    {

        Lcd_Command(0x83);               //设置显示位址

        asc_tran(aa);                   //显示字符串

        Lcd_Command(0x97);               //设置显示位址

        asc_tran("www.ouravr.com");      //显示字符串

        delay_ms(1000);                  //延迟1秒

        Lcd_Command(0x01);               //清除显示器

出0入0汤圆

发表于 2007-5-6 22:20:34 | 显示全部楼层
谢谢15楼的热心,

那假如我想说我想把PORTB口的值不停的刷新显示到LCD上又该怎么处理呢,这样可以吗?



void main()

{

    unsigned char aa[]="-----__@------";

    Lcd_Init(); //初始化LCD

    aa[0]=PINB;

//  aa[1]='*';

    while(1)

    {

        Lcd_Command(0x83);               //设置显示位址

        asc_tran(aa);              //显示字符串

        Lcd_Command(0x97);               //设置显示位址

        asc_tran("www.ouravr.com");      //显示字符串

        delay_ms(1000);                  //延迟1秒

        Lcd_Command(0x01);               //清除显示器

出0入0汤圆

发表于 2007-5-7 12:46:50 | 显示全部楼层
不行,需要把PINB存储到一个整型的变量里面,然后用

itoa(),sprintf()之类的函数,把该变量转换成一个字串,然后再显示.



而且按照你说的不停地转换,则上述过程需放在while (1)循环中.

出0入0汤圆

发表于 2007-5-8 13:14:42 | 显示全部楼层
高手,能不能举个简单的例子给我学习一下呀。

出0入0汤圆

发表于 2007-5-8 20:23:49 | 显示全部楼层
#include <stdlib.h>



...



void main()

{

    unsigned char aa[4];   //需要显示的字串

       

    DDRC=0xff;   //设定为输入,使能上拉电阻

    PORTC=0xff;       



    Lcd_Init(); //初始化LCD

       

    while(1)

    {

        Lcd_Command(0x83);          //设置显示位址



        itoa(aa,PINC,10);                //转换成字串,10表示10进制

        asc_tran(aa);                    //显示字符串

               

        Lcd_Command(0x97);               //设置显示位址

        asc_tran("www.ouravr.com");      //显示字符串

        delay_ms(10);                  //延迟

        //Lcd_Command(0x01);             //清除显示器

    }

}

出0入0汤圆

发表于 2009-10-2 11:07:09 | 显示全部楼层
很好学习啦

出0入0汤圆

发表于 2009-11-26 18:07:51 | 显示全部楼层
收藏了,好资料!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 16:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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