OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6208|回复: 4

关于段式液晶动态显示

[复制链接]

3

主题

8

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2013-6-8
在线时间
0 小时
发表于 2013-7-13 19:42:39 | 显示全部楼层 |阅读模式

程序来自阿莫论坛的一位,他写的是静态显示,稍微修改一下后如下:
//硬件:ATmega48v,16脚5位段式液晶
//说明:程序采自阿莫论坛坛友,引脚接线不同,所以程序结果不同
//引脚说明:PB0-3接的是四个COM口,PD0-7接SEG0-7  PC0-3接SEG8-11


#include<iom48v.h>
#include<macros.h>
// 设置某个COM IO输出低电平
#define COM0_LOW()         do{PORTB &=~BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_LOW()         do{PORTB &=~BIT(1); DDRB |= BIT(1);}while(0)
#define COM2_LOW()         do{PORTB &=~BIT(2); DDRB |= BIT(2);}while(0)
#define COM3_LOW()         do{PORTB &=~BIT(3); DDRB |= BIT(3);}while(0)
// 设置某个COM IO输出高电平
#define COM0_HIGH()        do{PORTB |=BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_HIGH()        do{PORTB |=BIT(1); DDRB |=BIT(1);}while(0)
#define COM2_HIGH()        do{PORTB |=BIT(2); DDRB |=BIT(2);}while(0)
#define COM3_HIGH()        do{PORTB |=BIT(3); DDRB |=BIT(3);}while(0)
// 设置所有COM IO输出VDD/2
#define COM_ALL_HALF()     do{PORTB &=0XF0; DDRB &=0XF0;}while(0)

// 设置所有COM/SEG IO输出低电平
#define COM_SEG_ALL_LOW()  do{PORTB &=0XF0; DDRB |= 0X0F; PORTC &=0XF0ORTD &=0X00;}while(0)
// 定义SEG端口
#define SEG_LOAD(x)        do{PORTD = (x); PORTC |= ((x) >> 8) &0X0F;}while(0)

#define uchar unsigned char
#define uint unsigned int
typedef uint  u16;
typedef uchar u8;
uchar number[] = {0x7E, 0x0A, 0xBC, 0x9E, 0xCA, 0xD6, 0xF6, 0x0E, 0xFE, 0xDE};  //定义数组
u16 frame[4];// LCD帧缓存
uchar Turn = 0, COM = 0;

/********************************************************延时函数**********************************************************/
void delayms(uint ms)
{
    uint i;

    for (; ms>0; ms--)
        for (i=1000; i>0; i--);
}
/********************************************************液晶驱动**********************************************************/
void yjdis(u8 *x)
{
    u8 i, Show_Char;

    frame[0] = 0;
    frame[1] = 0;
    frame[2] = 0;
    frame[3] = 0;

    for (i=0; i<6; i++)
    {
        if((*(x + i) < 0x3A) && (*(x + i) > 0x2F))
            Show_Char = number[*(x + i) - 0x30];
        if(Show_Char & 0x01) frame[0] |= 0x0001 << (i << 1);
        if(Show_Char & 0x10) frame[0] |= 0x0002 << (i << 1);
        if(Show_Char & 0x02) frame[1] |= 0x0001 << (i << 1);
        if(Show_Char & 0x20) frame[1] |= 0x0002 << (i << 1);
        if(Show_Char & 0x04) frame[2] |= 0x0001 << (i << 1);
        if(Show_Char & 0x40) frame[2] |= 0x0002 << (i << 1);
        if(Show_Char & 0x08) frame[3] |= 0x0001 << (i << 1);
        if(Show_Char & 0x80) frame[3] |= 0x0002 << (i << 1);
    }
}
/********************************************************中断部分  产生脉冲**********************************************************/
#pragma interrupt_handler t0:15  // 捕获中断  定时器0比较匹配A
void t0()
{
    TIFR0 &= ~0x02;

    if(Turn++ == 0)
    {
        SEG_LOAD(frame[COM]);
        COM_ALL_HALF();
        if(COM == 0)      {COM0_LOW();}
         if(COM == 1) {COM1_LOW();}
         if(COM == 2) {COM2_LOW();}
         if(COM == 3) {COM3_LOW();}
    }
    else
    {
        Turn = 0;
        SEG_LOAD(~frame[COM]);
        COM_ALL_HALF();
        if(COM == 0)      {COM0_HIGH();}
         if(COM == 1) {COM1_HIGH();}
         if(COM == 2) {COM2_HIGH();}
         if(COM == 3) {COM3_HIGH();}

        if(++COM > 3) COM = 0;
    }
}
#pragma interrupt_handler t0yc:17   // 定时器0溢出中断
void t0yc()
{
    TIFR0 &= ~0x01;
    COM_SEG_ALL_LOW();
}
/********************************************************端口初始化和寄存器初始化**********************************************************/
void t0init()  // Timer0快速PWM初始化
{
    DDRB |= 0X0F;    // COM0~3
    DDRD |= 0xfF;    // SEG0~7

    TCCR0A = 0x03;   // 配置定时器工作在快速PWM模式,8分频
    TCCR0B = 0x02;
    OCR0A = 0x9F;    // 设置捕捉比较初值,0x3f
    TIMSK0 |= 0x03;  // 开捕获中断,溢出中断
    SREG |= 0x80;    // 开总中断
}
/*******************************************************主函数*********************************************************/
void main()
{
    t0init();  //定时器0快速PWM初始化及IO口初始化

        yjdis("3210");
        while(1);

}



静态显示没有问题,但是想做个钟来着,所以尝试了下动态显示,也就是将四位拆开,


//硬件:ATmega48v,16脚5位段式液晶
//说明:程序采自阿莫论坛坛友,引脚接线不同,所以程序结果不同
//引脚说明:PB0-3接的是四个COM口,PD0-7接SEG0-7  PC0-3接SEG8-11


#include<iom48v.h>
#include<macros.h>
// 设置某个COM IO输出低电平
#define COM0_LOW()         do{PORTB &=~BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_LOW()         do{PORTB &=~BIT(1); DDRB |= BIT(1);}while(0)
#define COM2_LOW()         do{PORTB &=~BIT(2); DDRB |= BIT(2);}while(0)
#define COM3_LOW()         do{PORTB &=~BIT(3); DDRB |= BIT(3);}while(0)
// 设置某个COM IO输出高电平
#define COM0_HIGH()        do{PORTB |=BIT(0); DDRB |=BIT(0);}while(0)
#define COM1_HIGH()        do{PORTB |=BIT(1); DDRB |=BIT(1);}while(0)
#define COM2_HIGH()        do{PORTB |=BIT(2); DDRB |=BIT(2);}while(0)
#define COM3_HIGH()        do{PORTB |=BIT(3); DDRB |=BIT(3);}while(0)
// 设置所有COM IO输出VDD/2
#define COM_ALL_HALF()     do{PORTB &=0XF0; DDRB &=0XF0;}while(0)

// 设置所有COM/SEG IO输出低电平
#define COM_SEG_ALL_LOW()  do{PORTB &=0XF0; DDRB |= 0X0F; PORTC &=0XF0ORTD &=0X00;}while(0)
// 定义SEG端口
#define SEG_LOAD(x)        do{PORTD = (x); PORTC |= ((x) >> 8) &0X0F;}while(0)

#define uchar unsigned char
#define uint unsigned int
typedef uint  u16;
typedef uchar u8;
uchar number[] = {0x7E, 0x0A, 0xBC, 0x9E, 0xCA, 0xD6, 0xF6, 0x0E, 0xFE, 0xDE};  //定义数组
u16 frame[4];// LCD帧缓存
uchar Turn = 0, COM = 0;

/********************************************************延时函数**********************************************************/
void delayms(uint ms)
{
    uint i;

    for (; ms>0; ms--)
        for (i=1000; i>0; i--);
}
/********************************************************液晶驱动**********************************************************/
void yjdis(u8 *x,uchar i)
{
    u8  Show_Char;

    frame[0] = 0;
    frame[1] = 0;
    frame[2] = 0;
    frame[3] = 0;
    {
        if((*(x + i) < 0x3A) && (*(x + i) > 0x2F))
            Show_Char = number[*(x + i) - 0x30];
        if(Show_Char & 0x01) frame[0] |= 0x0001 << (i << 1);
        if(Show_Char & 0x10) frame[0] |= 0x0002 << (i << 1);
        if(Show_Char & 0x02) frame[1] |= 0x0001 << (i << 1);
        if(Show_Char & 0x20) frame[1] |= 0x0002 << (i << 1);
        if(Show_Char & 0x04) frame[2] |= 0x0001 << (i << 1);
        if(Show_Char & 0x40) frame[2] |= 0x0002 << (i << 1);
        if(Show_Char & 0x08) frame[3] |= 0x0001 << (i << 1);
        if(Show_Char & 0x80) frame[3] |= 0x0002 << (i << 1);
    }
}
/********************************************************中断部分  产生脉冲**********************************************************/
#pragma interrupt_handler t0:15  // 捕获中断  定时器0比较匹配A
void t0()
{
    TIFR0 &= ~0x02;

    if(Turn++ == 0)
    {
        SEG_LOAD(frame[COM]);
        COM_ALL_HALF();
        if(COM == 0)      {COM0_LOW();}
         if(COM == 1) {COM1_LOW();}
         if(COM == 2) {COM2_LOW();}
         if(COM == 3) {COM3_LOW();}
    }
    else
    {
        Turn = 0;
        SEG_LOAD(~frame[COM]);
        COM_ALL_HALF();
        if(COM == 0)      {COM0_HIGH();}
         if(COM == 1) {COM1_HIGH();}
         if(COM == 2) {COM2_HIGH();}
         if(COM == 3) {COM3_HIGH();}

        if(++COM > 3) COM = 0;
    }
}
#pragma interrupt_handler t0yc:17   // 定时器0溢出中断
void t0yc()
{
    TIFR0 &= ~0x01;
    COM_SEG_ALL_LOW();
}
/********************************************************端口初始化和寄存器初始化**********************************************************/
void t0init()  // Timer0快速PWM初始化
{
    DDRB |= 0X0F;    // COM0~3
    DDRD |= 0xfF;    // SEG0~7

    TCCR0A = 0x03;   // 配置定时器工作在快速PWM模式,8分频
    TCCR0B = 0x02;
    OCR0A = 0x9F;    // 设置捕捉比较初值,0x3f
    TIMSK0 |= 0x03;  // 开捕获中断,溢出中断
    SREG |= 0x80;    // 开总中断
}
/*******************************************************主函数*********************************************************/
void main()
{
    t0init();  //定时器0快速PWM初始化及IO口初始化


        while(1)
        {
                yjdis("   2",3);//前面一个参数选择数组中的第几个,后一个参数是第几位显示,
                            //注意,当参数二为123时,前面要加入多个空格,格入如下:
                            //(" 2",1)("  2",2)("   2",3)
                delayms(5);

                //yjdis(" 1",1);delayms(5);

            //    yjdis("  2",2);delayms(1);

                //yjdis("   3",3);delayms(1);
        }

}



显示两个勉强能看清,三个一起扫描的时候就不行了。

有朋宇有能用的程序共享吗,
或者在这程序上修改下

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 21:11:59 | 显示全部楼层
这个倒是没研究,呵呵,用mega48直接驱动?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

8

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2013-6-8
在线时间
0 小时
 楼主| 发表于 2013-7-14 19:17:29 | 显示全部楼层
回复【2楼】正点原子:
http://www.amobbs.com/forum.php?mod=viewthread&tid=4560171&highlight=%E6%AE%B5%E5%BC%8F%E6%B6%B2%E6%99%B6

厂里的电子秤块了,我就把液晶拆下来,然后上网打资料,在阿莫论坛看到了。
今天把程序改了改,能显示了,就是程序有点大,光液晶驱动就1.8K的ROM,

虽然同是液晶,这玩意还不要几十微安,而1602则要几十毫安
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-14 21:20:18 | 显示全部楼层
回复【3楼】 堪称学电子 :
---------------------------------
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

60

主题

225

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
483
金钱
483
注册时间
2013-7-27
在线时间
4 小时
发表于 2014-10-27 16:00:52 | 显示全部楼层
你用的单片机啥型号?  带lcd驱动吗?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-29 22:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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