• LED音乐频谱之点阵


    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/37967455

    一.硬件

    这里的LED选择直插的雾面LED,亮度可以还不失美观。

    注意每行要加上限流电阻。74HC138(三八译码器)作为列选,每行都连着74HC595(移位寄存器)实现串行输入,并行输出。

           

    二.软件

    led.h

    #ifndef __Led_H
    #define __Led_H
    
    #include "STC12C5A.h"
    
    #define uint unsigned int
    #define uchar unsigned char
    #define light 127
    
    sbit _SER    = P0^0;				// 74hc595 串行数据输入端
    sbit _RCLK   = P0^1;				// 74hc595 数据输出时钟线
    sbit _SRCLK  = P0^2;				// 74hc595 数据输入时钟线
    sbit ACT_Key = P0^3; 				// 模式开关
    sbit key1	 = P0^6;				// pwm调节+
    sbit Key_2   = P3^3;				// 时钟调节按键
    
    
    extern void delayled(int );
    extern void LineInput(uint dat);
    //extern void DisplayTime(void);
    //extern void TimeSetting(void);
    extern void ruoyun(void);
    
    
    #endif


    led.c


    #include "Led.h"
    
    
    uint   code table1[80]={
    0x0C,0x01,0x10,0x11,0xFE,0x11,0x44,0x3F,
    0x44,0x11,0x44,0x3D,0x7E,0x11,0x00,0x11,/*"若",0*/
    
    0x00,0x00,0x0C,0x01,0x34,0x11,0xC4,0x11,
    0x04,0x11,0x14,0x11,0x0E,0x01,0x00,0x01,/*"云",0*/
    
    0x04,0x10,0xFC,0x1F,0x00,0x1F,0xFC,0x00,
    0x00,0x1F,0xFC,0x1F,0x04,0x10,0x00,0x00,/*"M",0*/
    
    
    0xE0,0x03,0x18,0x0C,0x04,0x10,0x04,0x10,
    0x04,0x10,0x08,0x10,0x10,0x1C,0x00,0x00,/*"C",0*/
    
    
    
    0x00,0x10,0xF8,0x1F,0x04,0x10,0x04,0x00,
    0x04,0x00,0x04,0x10,0xF8,0x1F,0x00,0x10,/*"U",0*/
    
    						};
    
    							
    uchar  code ColScan[16]   =  {0x20,0x24,0x22,0x26,0x21,0x25,0x23,0x27,
    			     0x10,0x14,0x12,0x16,0x11,0x15,0x13,0x17};					    // 74hc138 进行列扫描
    	
    void delayled(int z)				// 延时函数
    {
    	int x,y;
    	for(x=0;x<z;x++)
    		for(y=0;y<110;y++);
    }
    
    void WriteByte(char dat)			//写一个字节的数据
    {
    	char i;								  
    	for(i=0;i<8;i++)				 //循环8次把编码传给锁存器
    		{
    			dat=dat>>1;				 //右移一位。取出该字节的最低位
    			_SER=CY;					 //将该字节的最低位传给R
    			_SRCLK=0;					  //将数据取出,上升沿
    			_SRCLK=1;
    		}
    }
    void LineInput(uint dat)			   	// 单列数据显示
    {
        uchar n;
        _RCLK = 0;
        for(n=0;n<16;n++)
        {
            _SRCLK = 0;
            _SER  = (dat>>n)&0x01;		 //将数据的值串入输入SER中,然后并行输出
            _SRCLK = 1;
        }
        _RCLK = 1;
    }
    
    void ruoyun()
    {
    	int num,k,j;//,move,speed;
    
    		for(k=0;k<25;k++)				  //控制动画移动
    		{	for(j=0;j<150;j++)			  //延时
    			{
     				for(num=0;num<16;num++)			//控制每一帧
    				{
    					WriteByte(table1[2*(num+k)]);		 //送出一个字节
    					WriteByte(table1[2*(num+k)+1]);
    					P2=ColScan[num];						   //行选
    					_RCLK=1;							//输出锁存器数据下降沿
    					_RCLK=0;
    					delayled(2);
    				}
    			}	
    		}				
    



    我想最核心的东西,应该就是怎么通过三个循环实现左移的吧(尽管这样做用来三个循环。如今看来并非非常好),以下具体讲讲这段代码。

    代码思路:我们都知道要想实现点阵显示仅仅要向595串行输入16个字模数据就OK了。那么怎样叫它向左面移动呢?事实上非常easy。以下我绘图说明:


    最里面的那层for循环实现了点阵的显示,就是从左到右刷一遍。

    中间那层for循环是一箭双雕,有两个作用。第一个就是为了点阵可以稳定显示,就是高速的多刷几遍(要不刷一遍谁看得清)。

    第二个作用就是为了向左移动提供延时(要不瞬间不就左移到头了嘛)。

    事实上规范点的写法应该是这个for提供稳定点阵显示。然后外面在加一个延时控制向左移动的速率。后来我看写的太复杂就给省略了。


    最外面的那层循环控制的是左移的列数(就是向左移动多少):

    		for(k=0;k<25;k++)				  //控制动画移动

    K的值代表想做移动的列数。为什么是25。由于一共是5个字每一个字占8行              

    初始状态:                     *若 云*MCU

    终止状态:              若云*MCU*

    也就是像左面移动三个字,3*8=24,所以K<25。


    最后另一个LineInput()函数,干嘛用的呢?留个悬念,兴许博客解说。







  • 相关阅读:
    出差公干,人在北京,欢迎骚扰
    义乌江东货运市场托运指南
    哥伦比亚拖鞋批发,60双起批发仅售11,现货3240双,义乌给力商务有限公司诚意供货,发韵达或指定物流
    员工心态 老板心态 学生心态
    淘宝卖家
    开源问题系统
    当一回"青年导师"
    义乌工商学院到给力百货有多远,怎么走?
    我也八卦,姚晨和它男人离婚的事,意料之外,情理之中,吼吼,我是在迅雷看看的评论中看到的
    新浪车模程序写得很有意思
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10927853.html
  • Copyright © 2020-2023  润新知