4个74HC595级联控制16x16点阵横向滚动

废话:

  淘宝买的51开发板16*16点阵屏是4个74HC595级联控制,这样方便更改行、列刷新模式,但速度较慢,容易产生闪烁感。而且配套教程太垃圾,。。太多槽点就不吐槽了,全靠自力更生,新手初学,个中辛苦就不谈了。

  教程没有横向滚动的例程,于是自己写了一个,记录一下。也画了个Protues的原理图,供没有这款开发板的朋友研究。


原理图:

DSN文件下载地址链接: http://pan.baidu.com/s/1qYzTOHQ 密码: j4yh

代码:

/**
 **********************************************************
 ******     Copyright(C), 2010-2016, 吐泡泡的虾       ******
 **********************************************************

 *@Tittle        :    16x16点阵滚动显示汉字——横向滚动
 *@Version       :    v1.0
 *@Author        :    吐泡泡的虾
 *@Dat           :    2016-08-04 14:23:59
 *@Desctription  :    16x16点阵采用4个74HC595移位寄存器控制,
 *                    4个移位寄存器采用串联方式。
 *                    本例采用列刷新模式。
 *                    取模方式:纵向取模,字节不倒序。
 *                注意:
 *                    由于采用4个595级联方式,输入数据速度太慢,
 *                    导致闪烁感较强。可改用6T或1T模式,改善很多。
 *@History       :
 * *
 **********************************************************
 **********************************************************
 */

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit DS_595 = P3 ^ 4;        //P3^4: 595的数据输入管脚
sbit SHCP_595 = P3 ^ 6;        //P3^6: 595的移位寄存器时钟管脚 SCK
sbit STCP_595 = P3 ^ 5;        //P3^5: 595的输出寄存器时钟管脚 RCK
// sbit MR_595 = P2 ^ 3;    //P0^3: 595的输出输出寄存器重置管脚 MR

void InputTo595(uchar *displayBuff, uchar len);
void OutputFrom595();
void Init_IO();
void DelayX10us(uchar multi);

//列扫描模式下的列序号,两两一组。如0x80, 0x00为点亮第一列,0x40, 0x00为第二列
uchar code COL_CODE[] = {
    0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00,
    0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01,
};

//要显示的字符。开头和末尾均留1个空白字符,以显示滚入、滚出效果
uchar code words[] =
{

    /*--  起始空白,滚入效果,可去掉  --*/
    /*--  宽度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,

    /*--  文字:  售  --*/
    /*--  Trebuchet MS12;  此字体下对应的点阵为:宽x高=16x16   --*/
    0x04, 0x08, 0x10, 0x3F, 0xEA, 0x2A, 0x2A, 0xAA, 0x7F, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xDF, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x9F, 0x80, 0x00, 0x00,

    /*--  文字:  后  --*/
    /*--  Trebuchet MS12;  此字体下对应的点阵为:宽x高=16x16   --*/
    0x00, 0x00, 0x00, 0x3F, 0x24, 0x24, 0x24, 0x24, 0x44, 0x44, 0x44, 0xC4, 0x44, 0x04, 0x04, 0x00,
    0x02, 0x04, 0x18, 0xE0, 0x00, 0x7F, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7F, 0x00, 0x00, 0x00,

    /*--  文字:  真  --*/
    /*--  Trebuchet MS12;  此字体下对应的点阵为:宽x高=16x16   --*/
    0x00, 0x20, 0x20, 0x2F, 0x2A, 0x2A, 0x2A, 0xFA, 0x2A, 0x2A, 0x2A, 0x2F, 0x20, 0x20, 0x00, 0x00,
    0x08, 0x08, 0x09, 0xFA, 0xAC, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xAC, 0xFA, 0x09, 0x08, 0x08, 0x00,

    /*--  文字:  烂  --*/
    /*--  Trebuchet MS12;  此字体下对应的点阵为:宽x高=16x16   --*/
    0x01, 0x0E, 0x00, 0xFF, 0x08, 0x10, 0x04, 0x44, 0x34, 0x04, 0x04, 0x14, 0x64, 0x04, 0x04, 0x00,
    0x01, 0x06, 0x18, 0xE0, 0x10, 0x08, 0x02, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02, 0x00,

    /*--  末尾空白,必须,否则有乱码  --*/
    /*--  宽度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,
};

void main()
{
    uint i, j = 0, k;
    uchar X10us = 1;
    uchar displayBuff[4];    //显示缓存

    Init_IO();

    while (1)
    {
        k = 4;    //每屏重复刷新次数,滚动速度调节。
        while (--k)
        {
            //依次显示16列,即显示完一屏
            for (i = 0; i < 16; i++)
            {
                // //程序测试块,用以确定缓存数组元素对应的行或列
                // displayBuff[0] = 0x82;        /*0b10000010 上8行,上为高位*/
                // displayBuff[1] = 0x44;        /*0b01000100 下8行,上为高位*/
                // displayBuff[2] = ~0x80;        /*0b10000000 左8列,左为高位*/
                // displayBuff[3] = ~0x03;        /*0b00000011 右8列,左为高位*/

                displayBuff[0] = *(words + (j + i) % 16 + (j + i) / 16 * 32 );    //每一列对应的上8行码值
                displayBuff[1] = *(words + (j + i) % 16 + (j + i) / 16 * 32 + 16);    //每一列对应的下8行码值

                displayBuff[2] = ~ COL_CODE[2 * i];    //左8列码值,左为高位
                displayBuff[3] = ~ COL_CODE[2 * i + 1];    //右8列码值,左为高位

                InputTo595(displayBuff, 4);
                _nop_();
                OutputFrom595();
                // DelayX10us(X10us);//当前列显示时间延时,会引起闪烁感
            }
        }

        //达到边界后j清0,以便循环显示
        //必须用works总字符数-1,不减1的话displayBuff[0]和[1]就出边界了
        if (++j == (sizeof(words) / sizeof(words[0]) / 32 - 1) * 16)
            j = 0;

    }
}

/**
 * 将displayBuff数组输入级联的595芯片,最后一个元素先输入,从低位到高位顺序输入
 * @param displayBuff 输入数组地址
 * @param len      要输入的数组元素个数,从数组第一个元素开始计
 */
void InputTo595(uchar *displayBuff, uchar len)
{
    uchar i, j;

    for (j = len; j > 0; j--)
    {
        for (i = 0; i < 8; i++)
        {
            DS_595 = displayBuff[j - 1] & 0x01 ;    //先输入最低位
            displayBuff[j - 1] >>= 1;

            SHCP_595 = 0;
            _nop_();
            SHCP_595 = 1;    //上升沿,输入到移位寄存器
        }

    }
}

void OutputFrom595()    //595输出
{
    STCP_595 = 0;
    _nop_();
    STCP_595 = 1;
    STCP_595 = 0;
}

void Init_IO()
{
    P3 = 0x0;
}

//延时10us的倍数,误差5us
void DelayX10us(uchar multi)
{
    do
    {
        _nop_(); _nop_(); _nop_(); _nop_();
        _nop_(); _nop_(); _nop_(); _nop_();
    } while (--multi);
}
时间: 2024-10-05 01:45:58

4个74HC595级联控制16x16点阵横向滚动的相关文章

4个74HC595级联控制16x16点阵横向滚动带仿真(二)

废话 续上篇 <4个74HC595级联控制16x16点阵横向滚动带仿真(一)> 将横向滚动的程序分享给QQ群里后,群内的晚秋兄弟提出了另一种思路——采用行扫描.移位方式做滚动,于是熬夜将其实现了一下.仿真程序还是跟前篇一样,不再赘述. 效果预览 代码 /** ********************************************************** ****** Copyright(C), 2010-2016,吐泡泡的虾 ****** ****************

微信小程序-scroll-view横向滚动和上拉加载

今天介绍微信小程序中scroll-view实现横向滚动和上拉加载的实现及需要注意的地方. 先看最终效果. 横向滚动 1.设置滚动项display:inline-block; 2.设置滚动视图容器white-space: nowrap; 3.滚动项不要用float 为什么会有以上三点要求呢? 其实横向滚动官方文档中是没有做太多说明的,只说明需要定义scroll-view滚动方向scroll-x=true允许横向滚动,但是我在实践的时候我发现,你要横向滚动,首先你得是一排吧.所以才发现需要定义滚动项

Android TextView 横向滚动(跑马灯效果)

Android TextView 中当文字比较多时希望它横向滚动显示,下面是一种亲测可行的方法. 效果图: 1.自定义TextView,重写isFocused()方法返回true,让自定义TextView一直处于获取焦点状态. package com.example.shen.marqueedemo; import android.content.Context; import android.util.AttributeSet; import android.widget.TextView;

李洪强实现横向滚动的View&lt;二&gt;

上一节中我们已经实现了一个带有图片,标题和价格label 的UIView 这节我们用这个view实现一个横向滚动的UIcollectionView 实现的效果如下:  01 - 创建CFTyreScrollViewCell,继承自UICollectionViewCell

jQuery实现文字横向滚动效果

HTML代码: <div id="aaa" style="width:100px; position:relative; white-space:nowrap; overflow:hidden; height:20px;"> <div id="noticeList" style="position:absolute; top:0; height:20px;"> <span>jQuery文字横

解决iScroll横向滚动区域无法拉动页面的问题

近期项目中使用iScroll遇到一个问题,在设定wrapper为横向滚动时,如果你手指放在该区域,将无法拉动页面,也就是说该区域取消了默认事件.这个体验是实在是无法接受,特别是页面中有多个横向滚动区域时,很容易触碰到这种区域,这时用户将觉得页面很卡. Google搜了一下,看来很多人都为这个问题而烦恼.有高人给出了解决方案,在 这里 可以找到. 代码如下: myScroll = new iScroll('scrollpanel', { // other options go here... vS

web开发 小方法1-禁止横向滚动

最近学了学做了个公司的网站  总结了一些小方法 比如取消横向滚动条并禁止的横向滚动 这样就可以吧超出的切掉让网页更和谐 在body 标签 body{ text-align: center; overflow:scroll; overflow-x:hidden} 加入该代码就行  overflow属性详情可以去 w3cSchool 或者菜鸟教程

scroll-view——小程序横向滚动

这是官方给的布局代码 <view class="section"> <view class="section__title">vertical scroll</view> <scroll-view scroll-y style="height: 200px;" bindscrolltoupper="upper" bindscrolltolower="lower" b

html5 横向滚动,无滚动条(transform:translate)

html5 横向滚动,用到了 touchstart.touchmove.touchend 控制修改transform:translate属性;[手机端或者浏览器模拟手机模式才有效果] [转载请注明出处] 回头准备封装成插件都放到 github上  https://github.com/wt9213 html: <div class="tab" id="tab"> <div class="scroll-tab" id="