一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 2756|回复: 8
收起左侧

求助,如何用AVR M8点亮32*16LED点阵屏

[复制链接]
发表于 2012-2-23 22:09 | 显示全部楼层 |阅读模式
  以前跟沈老师要了2块红色32*16LED点阵屏(164+595),并顺带要了一块51单片机(最小系统),当时点亮后因为工作忙,就放一边去了。现在想学着用AVR M8驱动那块点阵屏,不过自己水平有限,搞不定,上网搜索到了一个GCC程序,是138+595的,看几天还是没弄明白,老师帮修改一下,如何修改程序点亮那块点阵屏,谢谢! 2字红色屏164原理图OK_我要的屏.jpg            
 楼主| 发表于 2012-2-23 22:10 | 显示全部楼层
在ourdev搜索到r的一个GCC程序:
#include <avr/io.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include<util/delay.h>     
#define uint unsigned int
#define uchar unsigned char
#define NOP   _nop_()  
#define screen_size    4   
#define    hanzi_size_S    25   
uchar  disrow;
int col=0 ;
uchar word=0,zishu=0;   
uchar  BUFF[10];
#define    OE1  PORTD|=(1<<7)    //显示允许控制信号端口,为低电平可以显示
#define    DR1  PORTB|=(1<<1)       //串行数据输入R
#define    ST1  PORTC|=(1<<0)        //输出锁存器控制脉冲
#define    SK1  PORTC|=(1<<1)       //移位时钟脉冲
#define    OE0  PORTD&=~(1<<7)      //显示允许控制信号端口,为低电平可以显示
#define    DR0  PORTB&=~(1<<1)       //串行数据输入R
#define    ST0  PORTC&=~(1<<0)        //输出锁存器控制脉冲
#define    SK0  PORTC&=~(1<<1)        //移位时钟脉冲
unsigned char const HZ[ ]=
{
  
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  文字:  床  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x01,0x00,0x00,0x80,0x3F,0xFE,0x20,0x80,0x20,0x80,0x20,0x80,0x3F,0xFC,0x21,0x80,
0x21,0xC0,0x22,0xA0,0x22,0x90,0x24,0x88,0x24,0x86,0x48,0x84,0x50,0x80,0x80,0x80,


/*--  文字:  前  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x08,0x10,0x06,0x18,0x04,0x20,0xFF,0xFE,0x00,0x00,0x3E,0x08,0x22,0x48,0x3E,0x48,
0x22,0x48,0x22,0x48,0x3E,0x48,0x22,0x48,0x22,0x48,0x2A,0x08,0x24,0x28,0x00,0x10,


/*--  文字:  明  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,
0x44,0xFC,0x7C,0x84,0x00,0x84,0x01,0x04,0x01,0x04,0x02,0x04,0x04,0x14,0x00,0x08,


/*--  文字:  月  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,
0x07,0xF0,0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x20,0x50,0x40,0x20,0x00,0x00,


/*--  文字:  光  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x01,0x00,0x21,0x10,0x19,0x18,0x0D,0x10,0x09,0x20,0x01,0x04,0x7F,0xFE,0x04,0x40,
0x04,0x40,0x04,0x40,0x04,0x40,0x08,0x42,0x08,0x42,0x10,0x42,0x20,0x3E,0x40,0x00,
  

/*--  文字:  疑  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x20,0x00,0x2D,0xFC,0x30,0x08,0x22,0x50,0x22,0x20,0x1D,0xFE,0x40,0x22,0x7E,0x24,
0x48,0xA0,0x88,0xBC,0xFE,0xA0,0x18,0xA0,0x15,0x60,0x21,0x30,0x42,0x0E,0x84,0x04,
  
/*--  文字:  是  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x0F,0xF0,0x08,0x10,0x0F,0xF0,0x08,0x10,0x0F,0xF0,0x00,0x00,0xFF,0xFE,
0x01,0x00,0x09,0x00,0x09,0xF8,0x09,0x00,0x15,0x00,0x23,0x00,0x40,0xFE,0x00,0x00,   
/*--  文字:  地  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x20,0x11,0x20,0x11,0x20,0x11,0x24,0xFD,0x3E,0x11,0xE4,0x17,0x24,0x11,0x24,
0x11,0x24,0x11,0x34,0x11,0x28,0x1D,0x20,0x31,0x02,0xC1,0x02,0x00,0xFE,0x00,0x00,

/*--  文字:  上  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0xF8,0x01,0x00,
0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x04,0x7F,0xFE,0x00,0x00,
   
/*--  文字:  霜  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x1F,0xF8,0x01,0x00,0x7F,0xFE,0x41,0x04,0x1D,0x70,0x01,0x00,0x1D,0x70,0x08,0x00,
0x08,0xF8,0x7E,0x88,0x1C,0xF8,0x2A,0x88,0x28,0xF8,0x48,0x88,0x08,0xF8,0x08,0x88,

/*--  文字:  。  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x30,0x00,0x48,0x00,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00,

   
/*--  文字:  举  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x24,0x10,0x12,0x18,0x09,0x10,0x09,0x20,0xFF,0xFE,0x04,0x40,0x09,0x20,0x11,0x10,
0x2F,0xE8,0x41,0x06,0x81,0x00,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
  

/*--  文字:  头  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x80,0x10,0x80,0x0C,0x80,0x04,0x80,0x10,0x80,0x0C,0x80,0x08,0x80,0x00,0x80,
0xFF,0xFE,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x30,0x08,0x18,0x10,0x0C,0x20,0x08,
   

/*--  文字:  望  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x10,0x00,0x08,0xFC,0xFE,0x84,0x20,0xFC,0x20,0x84,0x24,0xFC,0x28,0x84,0x31,0x1C,
0x00,0x00,0x3F,0xFC,0x01,0x00,0x1F,0xF8,0x01,0x00,0x01,0x00,0x7F,0xFE,0x00,0x00,
  
/*--  文字:  明  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,0x44,0xFC,0x7C,0x84,0x44,0x84,0x44,0x84,
0x44,0xFC,0x7C,0x84,0x00,0x84,0x01,0x04,0x01,0x04,0x02,0x04,0x04,0x14,0x00,0x08,
   

/*--  文字:  月  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,0x07,0xF0,0x04,0x10,0x04,0x10,0x04,0x10,
0x07,0xF0,0x04,0x10,0x08,0x10,0x08,0x10,0x10,0x10,0x20,0x50,0x40,0x20,0x00,0x00,

/*--  文字:  ,  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x20,0x00,0x00,0x00,

/*--  文字:  低  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x08,0x18,0x0C,0x7C,0x1B,0xA0,0x12,0x20,0x22,0x20,0x62,0x20,0xA3,0xFE,0x22,0x20,
0x22,0x20,0x22,0x20,0x22,0x10,0x22,0x52,0x22,0x8A,0x23,0x46,0x22,0x22,0x00,0x00,


/*--  文字:  头  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x80,0x10,0x80,0x0C,0x80,0x04,0x80,0x10,0x80,0x0C,0x80,0x08,0x80,0x00,0x80,
0xFF,0xFE,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x30,0x08,0x18,0x10,0x0C,0x20,0x08,
   
/*--  文字:  思  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x1F,0xF8,0x11,0x08,0x11,0x08,0x1F,0xF8,0x11,0x08,0x11,0x08,0x1F,0xF8,
0x00,0x00,0x01,0x00,0x08,0x88,0x48,0x84,0x48,0x16,0xC8,0x12,0x07,0xF0,0x00,0x00,

/*--  文字:  故  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x10,0x40,0x10,0x60,0x10,0x40,0x10,0x40,0xFE,0xFE,0x10,0x88,0x10,0x88,0x7D,0x88,
0x46,0x50,0x44,0x50,0x44,0x20,0x44,0x20,0x7C,0x50,0x41,0x8E,0x06,0x04,0x00,0x00,
   
/*--  文字:  乡  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x01,0x00,0x01,0x80,0x03,0x10,0x06,0x18,0x08,0x30,0x1F,0xE0,0x00,0x88,0x03,0x0C,
0x0C,0x78,0x1F,0x90,0x08,0x10,0x00,0x20,0x00,0xC0,0x07,0x00,0x78,0x00,0x00,0x00,

/*--  文字:  。  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x30,0x00,0x48,0x00,0x48,0x00,0x30,0x00,0x00,0x00,0x00,0x00,
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,


};
//延时
int   InIt (void )
{
DDRD|=0XFC;//端口D3-7设置为输出
PORTD|=0Xff;
DDRB|=0X02;//端口B1设置为输出
PORTB|=0Xff;
DDRC|=0X03;//端口C01设置为输出
PORTC|=0Xff;
  return (0);
}


void DelayMS (uint x)
{
uchar i;
while(x--)
{
  for(i=0;i<2;i++);
}

}   
//行显控制  
void HC138_scan(uchar temp)  
{   
    PORTD=(temp<<3);   //选行
ST0 ;    //置数
//_nop();
ST1;
OE1;     //开行                 
   DelayMS (10000);  //消隐
   OE0;ST0;      
}  


uchar BUFF_1[screen_size*2+2];      //缓存                  
uchar disrow;                       //disrow 为16行变量

uchar temp_up;
uchar Move_up;
uchar temp_up;
uint  zimo_up;

#define     HC595_data1_H()      PORTB|=(1<<1) ;   
#define     HC595_data1_L()      PORTB&=~(1<<1) ;  

#define     HC595_clk_H          PORTC|=(1<<1) ;   
#define     HC595_clk_L           PORTC&=~(1<<1) ;  
#define     HC595_lock_H          PORTC|=(1<<0) ;
#define     HC595_lock_L        PORTC&=~(1<<0) ;  
/********************************************************
*             函数说明:595发送一个字节数据             *
********************************************************/
void HC595_send_2byte(uchar byte)
{
uchar i;
  
HC595_lock_L;
for (i=0;i<8;i++)
  {
   if(byte&0x80)
      {HC595_data1_L();}
   else
      {HC595_data1_H();}
  

   HC595_clk_H;
   HC595_clk_L;
   byte1<<=1;
   }
}

/*********************************************************
函数名:void Move_Up(const uchar *p,uint f)
功能:上半屏缓存数据 左移
输入:
输出:
/*********************************************************/                     
void Move_Up(const uchar *p,uint f)
{
signed char s;
    for(s=0;s<=screen_size;s++)      
    {
     BUFF_1[2*s]=p[f+32*s+2*disrow];     
     BUFF_1[2*s+1]=p[f+1+32*s+2*disrow];            
    }
}   


/*********************************************************
函数名:void display(void)
功能:显示刷新
输入:
输出:
/*********************************************************/  
void display(void)
{
  uchar i = Move_up;
  uchar s;
  uchar inc,tempyid,temp;
   
  if(i<8)
    inc=0;
  else  
    inc=1;
  for(s=0+inc;s<screen_size*2+inc;s++)        //发送16字节数据
    {
      if(i<8)  
        tempyid=i;
      else  
       tempyid=i-8;
      temp=((BUFF_1[s]<<tempyid)|(BUFF_1[s+1]>>(8-tempyid)));
      
       HC595_send_2byte(temp);    //发送数据  
     }
}

void Speed_up(speed)
{

       if(temp_up++>=speed)            
      {
         temp_up=0 ;
        if(Move_up++>=15)
         {
          Move_up=0;            //16列移位计数器清零     
          zimo_up=zimo_up+32;      //取字模计数器加32,准备下一个字
          if(zimo_up>=(hanzi_size_S*32)) //字模是否到最后来。
             zimo_up=0;           
         }
       }            
}


void main(void)
{
  InIt();
while(1)                           //重复循环显示
  {   
         
     for(disrow=0;disrow<16;disrow++)
         {
                  
          Move_Up(HZ,zimo_up);       //上屏移断允?
           
          display();                 //刷新显示数据
     
          PORTD=(disrow<<3);            //输出行信号
           
          HC595_lock_H;           //锁存为高,595锁存信号
          HC595_lock_L;
        
         DelayMS(200);
          }        
        Speed_up(4);   //移动速度控制
   }
}
发表于 2012-2-23 22:17 | 显示全部楼层
我有快16×16的,同样164,595,51都还没点亮起来,你ok了?
 楼主| 发表于 2012-2-23 22:50 | 显示全部楼层
是用沈老师51最小系统点亮的的。51程序: LED8_ct.rar (1.84 KB, 下载次数: 296)
发表于 2012-2-24 01:33 | 显示全部楼层
我自己写了个,可以显示,其实明白原理就行了,和138不一样,行和列一起锁存就行了。
 楼主| 发表于 2012-2-24 12:44 | 显示全部楼层
回复 5# efan


    能否把代码发上来,学习一下?
发表于 2012-2-24 13:46 | 显示全部楼层
回复  efan


    能否把代码发上来,学习一下?
a_TI 发表于 2012-2-24 12:44 https://www.yleee.com.cn/images/common/back.gif



    你的接口名称定义与我的不太一样,给你分析下你的接口吧,你会明白如何编程了。
1、H-MR:数据清空引脚,可以不用,接VCC;如果不用要清屏的话就全部送0或者1(具体看屏的型号,是共阴还是共阳),麻烦点,但是节省了一个I/O口。
2、H-AB:行扫数据输入,要看是0有效还是1有效,如果是1有效,那么在16扫描开始时送一个1,然后后面全部送0,这样的话1就会随着列锁存信号一同被锁存到行寄存器了;反之就先送0,后面全是1。
3、L-STR/CLK:两个作用,列扫描的锁存和行扫描的锁存信号,把595中的数据送到QA~QH,同时把行扫描数据送到164。
4、L-CLK:列扫的时钟信号,每个上升沿移一位数据到595寄存器。
5、L-R:列数据输入。

编程的话你可以这样:
1、定义一个16*4的uchar数组,初始化这个数组,把你要显示的东西放进去,测试的时候可以全部为0或1(具体看屏的型号,是共阴还是共阳),不确定的话就设置为0x0f,看看是怎么显示的。
2、把一行数据送到595,4*8循环。
3、锁存列信号,同时行选也锁存了,这样就显示一行了,然后等上几百微妙,不然亮度会低一些。
4、2-3循环,直到16行数据全部显示。

我是这么实现,可能会有其他方法。
发表于 2012-2-24 13:59 | 显示全部楼层
是用沈老师51最小系统点亮的的。51程序:
a_TI 发表于 2012-2-23 22:50 https://www.yleee.com.cn/images/common/back.gif



    看了下这个例子,可以用啊,只不过他的列锁存和行锁存是分开,而你的板子是同一个,还省事了,他的程序中还专门处理这个拖尾的问题,原因就是行锁和列锁不是同一个输入,同一个输入的话不存在拖尾的问题。


  1. void display()//显示
  2. {
  3. unsigned char i,ia,j,tmp;  //定义变量
  4. DATAOUT=0XFF;     //置位高电平做准备
  5. AB=1;       //将行数据位清0,准备移位
  6. for(i=0;i<16;i++){  //循环输出16行数据
  7.   CLK=1;    //为行移位做准备
  8.   LSTR=1;   //为列锁存做准备
  9.   for(ia=4;ia>0;){ //每行32个点,循环位移四个字节
  10.   ia--;  //循环四次
  11.   tmp=~lhj[i*4+ia]; //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第四个字节,因一行32个点由四个字节组成,
  12.        //电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第四个字节数据
  13.   for(j=0;j<8;j++){ //循环两次,每次移一个字节,
  14.    LCLK=0;   //为列移位做准备
  15.        LR=tmp&0x01;      //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位
  16.    tmp>>=1;    //将数据缓冲右移一位,为下次输出做准备
  17.        LCLK=1;    //将DATA上的数据移入寄存器
  18.   }     //移入单字节结束
  19.   }     //移入两个字节结束
  20.   DATAOUT|=0X24; //此句可以用以下两句来理解,如果不将两句合为一句,将出现拖影现像
  21.   //SCK=1;  //SCK拉高,行数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)
  22.                  LSTR=0;
  23.   LSTR=1; //SCLT拉高,将数据锁存输出到相应列的点阵发光管显示,显示一行后将保持到下一行显示开始
  24.   AB=0;  //列数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,
  25.      //移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱
  26. }
  27. j=128;
  28. while(j--);  //每一行的显示,保持4个字节的移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度
  29. CLK=0;   //
  30. CLK=1;   //将最后一行数据移出
  31. }

复制代码
 楼主| 发表于 2012-2-25 11:24 | 显示全部楼层
谢谢efan ,有空试试看。

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-20 03:37 , Processed in 0.078525 second(s), 47 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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