打印

学习嵌入式的最佳路线ARM7—Max7219驱动8段数码管

[复制链接]
5335|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
即时生效|  楼主 | 2011-3-2 23:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一般的MCU因IO脚驱动能力不够,再加之MCU IO口资源有限,产品开发中通常是通过专门的驱动IC来驱动数码管。
  7.1 学会看Datasheet
  MAX7219就是一款可以同时驱动8个数码管的IC。下图是其引脚图及典型应用电路:
  我们的CPU只须三根线就可以控制MAX7219,这三根线是:
  DIN(第一脚),CS(第12脚),CLK(第13脚)。
  DIN是数据输入脚,我们要显示的数据就是通过这根线发送到MAX7219的;
  CS是片选脚,MCU通过把该脚电平拉低来选中MAX7219,或者说MAX7219通过判断该引脚是否为低电平来使能该芯片。
  CLK是时钟引脚,该时钟频率是MCU给到MAX7219的,MCU与7219之间的通信频率就根据该信号做基准。
  7.2 MAX7219数据格式
  我们要让8个数码管显示"12345678",这个过程是怎么实现的呢?
  首先,要搞清楚MAX7219的数据格式,看图:
  MAX7219是以16位数据接收和发送的,也就是MCU传给MAX7219的数据必须是16位。下面分析这16位数据格式:
  D15~D12为X:表示可以为任意值,因为这四位MAX7219目前还用不到。
  D11~D8为ADDRESS:表示MAX7219的地址。
  D7~D0为DATA,并且位7为高位(最先发送),位0位低位(最后发送)。
  也就是当MCU向MAX7219发送一个16位数据时,其中的D11~D8表示选择MAX7219哪个地址,即数据D7~D0是送到该地址的。
  7.3 地址译码
  MAX7219可以挂8个数码管,MCU是怎么把数据显示到指定的数码管的呢?这就要理解MAX7219的地址译码原理。下图为MAX7219的地址映射图:
  D15~12以X表示,代表可为0,也可为1。
  Digit0~7对应到8个数码管的地址。
  Decode Mode:解码模式寄存器,其地址用16进制表示为0x09;
  Intensity:亮度调节寄存器,其地址用16进制表示为0x0A;
  Scan Limit:扫描范围寄存器,其地址用16进制表示为0x0B;
  Shutdown:省电模式,其地址用16进制表示为0x0C;
  Display Test:测试寄存器,其地址用16进制表示为0x0F;
  如果,我们要让第一个数码管显示,那么我们这里送到MAX7219的16位数据中的D11~8应该为0001。
  7.4 数据编码
  当我们选中了要显示的数码管,如果要显示"8",应该在16位数据里面的D7~D0放什么内容呢?
  MAX7219已做的很智能,你想显示"8"就在D7~D0里面放"8"(二进制0000 1000),如果要显示"9",就在D7~D0里面放"9"(二进制0000 1001)。
  下面来分析它是怎么做到的:看数据格式图(也叫Code B Font)
  这个图由三部分组成:
  第一部分:是要显示的数据
  第二部分:是要发送的数据D7~D0
  第三部分:是数码管的八个段,分别用DP*,A,B,C,D,E,F,G(DP*表示小数点)
  在弄清这个图之前,我们有必要了解数码管的构造。
  下面是数码管的构造图:
  数码管有八个段(DP,A,B,C,D,E,F,G)每个段都有一个电路来驱动它,
  当你要显示"0",就让A,B,C,D,E,F亮,让G灭。
  当你要显示"1",就让B,C亮,让A,D,E,F,G灭。
  其他的就不用多说了。
  我们再回过头去看Code B Font图,
  当我们想让数码管显示"0",就向数据位D3~D0赋值"0000",那么MAX7219就会让A,B,C,D,E,F亮,让G灭。
  当我们想让数码管显示"1",就向数据位D3~D0赋值"0001",那么MAX7219就会让B,C亮,让A,D,E,F,G灭。
  至此,读者应该是迫不及待的想写程序一试身手了!
  但,还有几个MAX7219的控制寄存器需要弄清楚:
  7.5 MAX7219的控制寄存器
  7.5.1 Decode Mode 解码模式寄存器
  该寄存器的主要功能有两个:
  1 选择解码模式,MAX7219有两种解码模式,Code B 和 No decode。
  2 选择解码个数(或范围) (MAX7219最多可以解码8个数码管)
  该寄存器所在地址为0x9(D15~D12设置为0)
  当我们向该地址写数据0x00,则选择No decode解码模式,并且解码数码管7到0。此时,Code B解码模式无效;
  当我们向该地址写数据0x01,则Code B解码0号数码管,No decode解码7-1号数码管;
  当我们向该地址写数据0x0F,则Code B解码3-0号数码管,No decode解码7-4号数码管;
  当我们向该地址写数据0xFF,则选择Code B解码模式,并且解码数码管7到0。此时,No decode解码模式无效;

相关帖子

沙发
即时生效|  楼主 | 2011-3-2 23:13 | 只看该作者
7.5.2 Scan Limit 扫描限制寄存器
  该寄存器所在地址为0xB(D15~D12设置为0)
  该寄存器的主要功能是设置扫描数码管的个数(范围)。
  当我们向该地址写数据0x00,则MAX7219只扫描第0个数码管,其他数码管将呈灰色,即不工作,这样达到降低功耗的作用。
  7.5.3 Shutdown 关断模式寄存器
  该寄存器所在地址为0xC(D15~D12设置为0),主要功能是为了在不需要数码管显示的时候方便进入省电模式。
  当向该地址写0x00,则MAX7219进去shutdown模式;
  当向该地址写0x01,则MAX7219进去正常操作模式;
  7.6 MAX7219驱动4个数码管源代码
  /*******************************************************************************
  *文件名:digit_led.c
  *功能:数码管显示程序
  *作者:parson
  *创建日期:2010-05-01
  *版本:Ver10.05
  *版权:ShangHai Somy Technology LTD.
  *********************************************************************************/
  #include  "config.h"
  #define CS   1 << 5                     //选择P0.5作为CS
  #define DI  0x1 << 6                    //选择P0.6作为数据输入
  #define CLK  0x1 << 7           //选择P0.7作为时钟
  #define DECODE_MODE 0x09                //译码控制寄存器
  #define INTENSITY 0x0A                  //亮度控制寄存器
  #define SCAN_LIMIT 0x0B                 //扫描界限寄存器
  #define SHUT_DOWN 0x0C                  //关断模式寄存器
  #define DISPLAY_TEST 0x0F               //测试控制寄存器
  void Write7219(uint8 address,uint8 dat);
  /*******************************************************************************
  *函数名Init_Max7219
  *功能:MAX7219 初始化,设置MAX7219 内部的控制寄存器
  *参数:无
  *返回值:无
  ********************************************************************************/
  void Init_Max7219(void)
  {
  Write7219(SHUT_DOWN,0x01);// 开启正常工作模式(0xX1)
  Write7219(DISPLAY_TEST,0x00);// 选择测试模式(0xff)
  Write7219(DECODE_MODE,0xf);//选用CODEB 0-3
  Write7219(SCAN_LIMIT,0x03);//选择0-3
  Write7219(INTENSITY,0x04);//设置初始亮度
  //Write7219(DISPLAY_TEST,0x00);// 选择工作模式(0xX0)
  }
  /*******************************************************************************
  *函数名delay
  *功能:延时
  *参数 time:要延时的时间
  *返回值:无
  ********************************************************************************/
  void delay(uint32 time)
  {
  int i;
  for(i=0;i<time;i++);
  }
  /*******************************************************************************
  *函数名Write7219
  *功能:地址、数据发送子程序
  *参数 :无
  *返回值:无
  ********************************************************************************/
  void Write7219(uint8 address,uint8 dat)
  {
  uint8 i;
  IO0CLR = CS; // 拉低片选线, 选中器件
  for (i=0;i<8;i++) // 移位循环8 次
  {
  IO0CLR = CLK; // 清零时钟总线
  if( (address &0x80))// 每次取高字节
  IO0SET = DI;
  else
  IO0CLR = DI;
  address <<=1; // 左移一位
  IO0SET = CLK; // 时钟上升沿,发送地址
  }
  for (i=0;i<8;i++)
  {
  IO0CLR = CLK;  
  if( (dat&0x80))
  IO0SET = DI;
  else
  IO0CLR = DI;
  dat <<=1;
  IO0SET = CLK;
  }
  IO0SET = CS; // 发送结束,上升沿锁存数据
  }
  /*******************************************************************************
  *函数名init_system
  *功能:初始化CS | DI | CLK,并使CS | DI | CLK初始状态为高
  *参数 :无
  *返回值:无
  ********************************************************************************/
  void init_system()
  {
  //PINSEL0 = PINSEL0 & ;
  IO0DIR  = CS | DI | CLK;
  IO0SET  = CS | DI | CLK;
  }
  /*********************************************************************************
  *函数名main
  *功能:4个数码管同时显示"0","1","2","3","4","5","6","7","8","9","-","E","H","L","P","不显示",
  *参数:无
  *返回值:0(int类型)
  *********************************************************************************/
  int main (void)
  {
  uint8 i;
  init_system();
  Init_Max7219();
  while(1)
  {
  for(i=0;i<0xf;i++){
  Write7219(1,i); // 第一个数码管(从右到左)
  delay(0x800000);   
  Write7219(2,i); //
  delay(0x800000);
  Write7219(3,i); //
  delay(0x800000);
  Write7219(4,i); //
  delay(0x800000);
  }
  }
  return 0;
  }
  7.7独立完成No decode程序设计
  如果,MAX7219的控制原理理解了,上面的例程也运行成功了。还剩下No code解码模式的代码还没有实现,这部分留给各位自己完成。

使用特权

评论回复
板凳
huzixian| | 2011-3-3 22:56 | 只看该作者
我感觉我就不会看数据手册啊

使用特权

评论回复
地板
6019赵文| | 2011-3-10 20:40 | 只看该作者
数码管也这么高深啊

使用特权

评论回复
5
小云001| | 2011-3-18 21:52 | 只看该作者
高深

使用特权

评论回复
6
dzxc| | 2011-3-19 15:53 | 只看该作者
7219够贵的

使用特权

评论回复
7
3B1105| | 2011-3-20 17:24 | 只看该作者
真是大材小用!MAX7219都跟单片机一个价了,不值

使用特权

评论回复
8
奔腾2.0| | 2011-3-22 09:31 | 只看该作者
够高深,够莫测

使用特权

评论回复
9
老大的幸福| | 2011-3-22 11:28 | 只看该作者
太贵

使用特权

评论回复
10
njnh| | 2014-3-10 11:22 | 只看该作者
你好,我用MAX7219驱动数码管,上电后,都显示8 ,不会改变,什么原因??求指导,

使用特权

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

本版积分规则

0

主题

685

帖子

3

粉丝