[资料分享与下载] 动态扫描4位数码管

[复制链接]
2147|10
 楼主| 芙蓉洞 发表于 2015-8-29 14:55 | 显示全部楼层 |阅读模式
电路原理:


    由原理图可知道 MCU 的 SPI 接口控制 2 片 74HC595 带锁存的移位寄存器驱动共阴式的 LN3461BS 数码管,其中 U4 控制 8 位数据管的位选位,U6 控制 4 位数码管的段选位,也就是说只要给数码管的位选位输送低电平,给数码管的段选位输送高电平,即可点亮数码管。






在 74HC595 芯片中, 如果要将 8 位串行输入数据并行输出到 QA、 QB、 QC、 QD、 QE、
QF、QG、QH,则需要满足以下条件:
  首先必须保证在 SCK 引脚输入连续的时钟信号;
  在 SCK 引脚输入信号的上升沿, 在 SI 引脚输入的数据被送入 QA 的第 1 级移位寄
存器,QA 移位寄存器原有的值移入 QB 移位寄存器,QB 移位寄存器原有的值移
入 QC 移位寄存器,以此类推;
  在 RCK 引脚输入信号的上升沿,移位寄存器中的数据被送入锁存器;
  若 OE 引脚输入低电平,则锁存器的值将在 QA~QH 引脚输出。

编程思路



(1) 发送 8 位“位选”数据,且被保存在 U6 的移位寄存器中;
(2) 紧接再发送“段选”数据时,刚才发送的“位选”数据将通过级联方式移位到 U4的移位寄存器中,后发送的“段选”数据则被保存在 U6 的移位寄存器;
(3) 当数据移位完成后, 在 RCK 产生一个上升沿将移位寄存器中的数据移位到锁存器;
(4) 由于 OE 为低电平,锁存器的数据送到 U4、U6 的 QA~QH 数据引脚上。
其中 U4、U6 的 RCK 引脚连接到 i.MX283 处理器的 GPIO3.21 引脚。



硬件跳线接法






SPI_2 -> COM 全部接上。
P3.21 -> COM.


 楼主| 芙蓉洞 发表于 2015-8-29 14:55 | 显示全部楼层
程序代码
SPI 和 P.21 初始化
  1.     int SPI1_Init( void )
  2.     {
  3.             unsigned long mode = 0;
  4.             unsigned long speed = 10000;
  5.             unsigned long bits = 8;

  6.             int fd;
  7.             DIR *dir;

  8.             dir = opendir( GPIO_RCK_PATH );
  9.             if( dir == NULL )
  10.             {
  11.                     fd = open( "/sys/class/gpio/export", O_WRONLY );
  12.                     if( fd )        
  13.                     {
  14.                             if( write( fd, "117", strlen( "117") ) == -1 )
  15.                             {
  16.                                     close( fd );
  17.                                     printf( "GPIO 3.21 export fail" );
  18.                                     return -1;
  19.                             }
  20.                     }
  21.                     close( fd );
  22.             }        
  23.             closedir( dir );

  24.             fd = open( GPIO_RCK_PATH"/direction", O_WRONLY );
  25.             write( fd, "out", strlen( "out" ) );
  26.             close( fd );
  27.            
  28.             RCK_fd = open( GPIO_RCK_PATH"/value", O_RDWR );

  29.             spi_fd = open( "/dev/spidev1.0", O_RDWR );
  30.             if( spi_fd < 0 )
  31.             {
  32.                     printf( "can not open spi device\n" );
  33.                     return -1;
  34.             }

  35.             if( ioctl( spi_fd, SPI_IOC_WR_MODE, &mode ) == -1 )
  36.             {
  37.                     printf( "can not set SPI mode\n" );
  38.                     return -1;
  39.             }

  40.             if( ioctl( spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits ) )
  41.             {
  42.                     printf( "can not set bits per word\n" );
  43.             }
  44.             if( ioctl( spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed ) == -1 )
  45.             {
  46.                     printf( "can not set max speed HZ\n" );
  47.                     return -1;
  48.             }

  49.             return 0;

  50.     }



 楼主| 芙蓉洞 发表于 2015-8-29 14:56 | 显示全部楼层
大循环中 动态扫描4位数码管,每隔 0.5 s 向左移动一个字符。 实现滚动显示 "HELLO.    **"
  1.     unsigned char led_table[] =
  2.             { 0x89, 0x86, 0xc7, 0xc7, 0x40, 0xFF, 0xFF, 0x86, 0xc7, 0x86, 0xc6, 0x8E, 0x88, 0xc8, 0x92, 0xFF, 0xFF, 0xFF };
  3.     int main( void )
  4.     {
  5.             unsigned char LedValueIndex = 0;
  6.             unsigned char LedDig = 0;
  7.             unsigned int Times = 0;
  8.             unsigned char tx_buffer[2];

  9.             struct spi_ioc_transfer tx[] =
  10.             {
  11.                     {
  12.                             .tx_buf = ( unsigned long ) tx_buffer,
  13.                             .rx_buf = 0,
  14.                             .len = 2,
  15.                             .delay_usecs = 0,
  16.                             .speed_hz = 10000,
  17.                             .bits_per_word = 8,
  18.                     },
  19.             };

  20.             if( SPI1_Init() == -1 )
  21.             {
  22.                     return 0;
  23.             }

  24.             while( 1 )
  25.             {

  26.                     tx_buffer[0] = led_table[LedValueIndex + LedDig];
  27.                     tx_buffer[1] = 1 << LedDig;
  28.                     ioctl( spi_fd, SPI_IOC_MESSAGE(1), & tx );

  29.                     write( RCK_fd, "0", 1 );
  30.                     usleep( 100 );
  31.                     write( RCK_fd, "1", 1 );

  32.                     usleep( 1000 );

  33.                     if( ++LedDig > 3 )
  34.                             LedDig = 0;

  35.                     if( ++Times > 500 )
  36.                     {
  37.                             Times = 0;
  38.                             if( ++LedValueIndex > 14 )
  39.                                     LedValueIndex = 0;
  40.                     }
  41.                   

  42.             }

  43.             return 0;

  44.     }
大苏牙 发表于 2015-8-29 16:49 | 显示全部楼层
由原理图可知道 MCU 的 SPI 接口控制 2 片 74HC595 带锁存的移位寄存器驱动共阴式的 LN3461BS 数码管,其中 U4 控制 8 位数据管的位选位,U6 控制 4 位数码管的段选位,也就是说只要给数码管的位选位输送低电平,给数码管的段选位输送高电平,即可点亮数码管。
734774645 发表于 2015-8-29 18:15 | 显示全部楼层
数码管是应用基础,当年学这个时候,没有少下功夫
天灵灵地灵灵 发表于 2015-8-29 18:26 | 显示全部楼层
建议使用MAX7219,可以控制8个数码管,爽的很。
玛尼玛尼哄 发表于 2015-8-29 18:52 | 显示全部楼层
数码管如果直接控制最好要用三极管驱动,不然亮度不够的。
yiyigirl2014 发表于 2015-8-29 18:57 | 显示全部楼层
动态扫描没有用驱动芯片做静态扫描的爽啊。手机拍照会闪烁的。
kafeng 发表于 2015-8-29 20:53 | 显示全部楼层
天灵灵地灵灵 发表于 2015-8-29 18:26
建议使用MAX7219,可以控制8个数码管,爽的很。

MAX7219确实很好用:lol
天灵灵地灵灵 发表于 2015-8-30 19:25 | 显示全部楼层
自从用过了7219,我就是一发不可收拾了。
捉虫天师 发表于 2015-8-30 20:09 | 显示全部楼层
一个数码管需要一个三极管驱动。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

42

主题

398

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部