打印
[AVR单片机]

请教有用tiny13驱动LCD1602的吗?

[复制链接]
1363|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mfkyygt|  楼主 | 2014-5-26 11:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 mfkyygt 于 2014-5-26 22:11 编辑

    最近想把汽车的手动温控改为自动温控,用tiny13驱动1602,遇到查表显示字符串时经常重复显示的问题,不知是否tiny13的flash字节限制原因?哪位大侠有用过tiny13驱动1602的,编程上有哪些注意事项,请指教。
     先打个窝,稍后回办公室了再上代码和图,谢谢。


   回来了,上代码。。。
//---- LCD显示字符表 ----
const unsigned char num[] ={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};   //0~9
const unsigned char str1[] ={0x53,0x45,0x54,0x20,0x54,0x3A,0x20};  //显示 “SET T: ”
const unsigned char str2[] ={0x4E,0x4F,0x57,0x20,0x54,0x3A,0x20};  //显示“NOW T: ”

//---- LCD初始化 ----
void lcd_init()
{
        lcd_wcmd(0x38);        //设置为8位数据,双列,5*7字形
        lcd_wcmd(0x0C);        //开启显示屏,关光标,光标不闪
        lcd_wcmd(0x06);        //显示地址递增
        lcd_wcmd(0x01);        //清屏
}

//---- LCD写指令 ----
void lcd_wcmd(unsigned char cmd)
{
        delay_ms(5);           //延时,相当于忙检测
        CLR(PORTB,PB3);        //rs=0,选择指令寄存器
        send(cmd);             //164送数据
        delay_ms(1);  
        SET(PORTB,PB4);        //LCD使能产生下降沿
        CLR(PORTB,PB4);
}

//---- LCD写数据 ----
void lcd_wdata(unsigned char dat)
{
        delay_ms(5);           //延时,相当于忙检测
        SET(PORTB,PB3);        //rs=1,选择数据寄存器
        send(dat);             //164送数据
        delay_ms(1);
        SET(PORTB,PB4);        //LCD使能产生下降沿
        CLR(PORTB,PB4);
}

//---- 显示提示内容 ----
//void show_lcd(uint t1,uint t2,uint t3,uint t4)
void show_lcd(uint t1,uint t2)
{
        unsigned int j;
        lcd_wcmd(0x80);        //第一行首地址,显示 SET T: 正常
        for (j=0;j<7;j++)
        {
                lcd_wdata(str1[j]);
                delay_ms(2);
        }
        lcd_wcmd(0xC0);        //第二行首地址,目标是显示 NOW T:  但实际却显示了 NOWW,不正常
        for (j=0;j<7;j++)
        {
                lcd_wdata(str2[j]);
                delay_ms(2);
        }
        //----
        lcd_wcmd(0x87);       //设定温度显示位置
        lcd_wdata(num[t1]);   //显示十位
        lcd_wdata(num[t1]);   //显示个位
        lcd_wdata(0x2E);      //显示小数点
        lcd_wdata(num[t2]);   //显示小数位
        //----
        lcd_wcmd(0xC7);        //设定温度显示位置
        lcd_wdata(num[t1]);   //显示十位
        lcd_wdata(num[t1]);   //显示个位
        lcd_wdata(0x2E);      //显示小数点
        lcd_wdata(num[t2]);   //显示小数位

}

/*==== 主程序 ====*/
void main()
{
        PORTB = 0xFF;        //输出高电平
        DDRB  = 0xFE;        //11111110,PB0设为输入
        lcd_init();          //LCD初始化
        //show_lcd(5,6,7,8);         //LCD显示赋值内容
        show_lcd(5,8);         //LCD显示赋值内容
        while (1)      
        {;}
}
奇怪的是,当我把lcd_wdata(num[t1]);  修改为lcd_wdata(num[5]);直接指向数字而不是用变量时,显示是正常的
所以请教tiny13是否不能定义太多的变量和数组? 表述有点乱,望能理解。。。

相关帖子

沙发
huangxz| | 2014-5-26 13:58 | 只看该作者
io口够就行了,1602数据线最少要4根

使用特权

评论回复
评论
mfkyygt 2014-5-26 20:24 回复TA
谢谢关注,是的,目前我是用164来送数,也算是4根吧 
评分
参与人数 1威望 +3 收起 理由
mfkyygt + 3 很给力!
板凳
zrcb| | 2014-5-26 17:15 | 只看该作者
本帖最后由 zrcb 于 2014-5-26 17:17 编辑

使用I2C,只用2个端口,使用PCF8574方案,目前可以最大程度降低资源使用的情况。
1、PCF8574方案选购,使用下面的解决方案:

2、T13驱动调试,i2c使用软件模拟效果不错。(板上有3个地址编码位,接通为40,未接则为4E)

3、背光显示由1位控制,忘了哪个。
t13只有1K flash,功能太弱,我用的t45

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
mfkyygt + 3 神马都是浮云
地板
mfkyygt|  楼主 | 2014-5-26 20:44 | 只看该作者
原来也考虑用M8来做的,但看中的是tiny13体积够小,改装空间限制,所以如果功能做简单点,应该1k还是够用的。
为了显示固定提示字符的问题,原也考虑过直接一个一个字符赋值,不用数组的,但写了一下,一个一个显示语句太多了,空间有限。

使用特权

评论回复
5
mfkyygt|  楼主 | 2014-5-27 00:18 | 只看该作者
本帖最后由 mfkyygt 于 2014-5-27 00:20 编辑

问题耐心调试修改,还是解决了,但似乎未知所以然,做法主要为:
1、修改了数组把重复的字符尽量放在同一个数组中,减少数组数;
2、子程序尽量少用嵌套,估计可以减少堆栈频繁调用;
不知以上是否问题的所在,但确实达到期望要求了。。。

主要修改代码:
//---- LCD显示字符表 ----
const unsigned char num[] ={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
const unsigned char str1[] ={0x53,0x45,0x54,0x4E,0x4F,0x57,0x20,0x54,0x3A,0x20};

显示固定字符与动态显示温度数值分开两个子程序来写:
//---- 显示固定提示内容 ----
void show_lcd()
{
        uint j;
        lcd_wcmd(0x80);       //第一行显示SET T:
        for (j=0;j<10;j++)
        {
                if (j==3)
                {j =j+3;}
                lcd_wdata(str1[j]);
                delay_ms(2);
        }
        lcd_wcmd(0xC0);       //第二行显示NOW T:
        for (j=3;j<10;j++)
        {
                lcd_wdata(str1[j]);
                delay_ms(2);
        }
        //---- 显示“℃”
        lcd_wcmd(0x8B);      //第一行尾显示℃
        lcd_wdata(0xDF);     
        lcd_wdata(0x43);
        lcd_wcmd(0xCB);      //第二行尾显示℃
        lcd_wdata(0xDF);     
        lcd_wdata(0x43);
}

//---- 逐位显示温度值 ----
void show_T(uint t1,uint t2,uchar row)
{
        uchar s;
        if (t1>=10)
        {
                s =t1/10;          //转换十位数字
                t1 =t1-s*10;       //转换个位数字
        }
        else
        {s =0;}
        //----
        if (row==0)
        {lcd_wcmd(0x87);}
        else
        {lcd_wcmd(0xC7);}
        lcd_wdata(num);   //显示十位数
        lcd_wdata(num[t1]);  //显示个位数
        lcd_wdata(0x2E);     //显示小数点
        lcd_wdata(num[t2]);  //显示一位小数
}
这样修改就可以达到理想要求了:

QQ图片20140527001031.jpg (33.73 KB )

QQ图片20140527001031.jpg

使用特权

评论回复
6
mfkyygt|  楼主 | 2014-5-27 00:32 | 只看该作者
感慨呐。。。学习avr编程,有时遇到问题,确实比较纠结,经常希望在坛子里能遇到好心人,但很多时候可能是当局者迷,自己提问题也未必能把问题说清楚,让高手们也无从下手帮忙,这个时候只要有人能关注,我想会是最大的支持和鼓励,或许别人的一句说话,恰恰是转变思路的灵感,感谢网友关注!

QQ图片20140527002447.jpg (157.81 KB )

T13驱动LCD1602的完整测试电路图

T13驱动LCD1602的完整测试电路图

使用特权

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

本版积分规则

11

主题

65

帖子

0

粉丝