废话
续上篇
《4个74HC595级联控制16x16点阵横向滚动带仿真(一)》
将横向滚动的程序分享给QQ群里后,群内的晚秋兄弟提出了另一种思路——采用行扫描、移位方式做滚动,于是熬夜将其实现了一下。仿真程序还是跟前篇一样,不再赘述。
效果预览
/**
**********************************************************
****** Copyright(C), 2010-2016,吐泡泡的虾 ******
**********************************************************
*@Tittle : 16x16点阵滚动显示汉字——横向滚动 移位方式
*@Version : v1.0
*@Author : 吐泡泡的虾
*@Dat : 2016-08-05 01:11:28
*@Desctription : 16x16点阵采用4个74HC595移位寄存器控制,
* 4个移位寄存器采用串联方式。
* 本例采用行刷新模式。
* 取模方式:横向取模,字节不倒序。
* 适用于普中开发板。
* 为尽量减少RAM占用,未用buff[32]缓存满屏
* 显存的方式来存储要显示的文字码值,而采用
* 3个基准指针和3个缓存字节循环赋值的方式
* 注意:
* 由于采用4个595级联方式,输入数据速度太慢,
* 导致闪烁感较强。可改用6T模式,改善很多。
*
* 更改k值可以更改滚动速度。
* 更改延时也可以更改滚动速度,但注意可能引
* 起闪烁。
*@History :
#v1.0 [Press F5 to insert time]
1. some comment
**********************************************************
**********************************************************
*/
#include #include #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 DelayX10us(uchar multi); //行扫描模式下的行序号,两两一组。如0x80, 0x00为点亮第一行,0x40, 0x00为第二行 uchar code ROW_NUM[] = { 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, //=======================================文字内容替换区============================================ /*-- 文字: ☆ --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x01, 0x00, 0x01, 0x00, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x04, 0x40, 0xFC, 0x7E, 0x40, 0x04, 0x30, 0x18, 0x08, 0x20, 0x08, 0x20, 0x11, 0x90, 0x16, 0x50, 0x18, 0x30, 0x20, 0x08, 0x00, 0x00, /*-- 文字: 左 --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFF, 0xFE, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0F, 0xF8, 0x10, 0x80, 0x10, 0x80, 0x20, 0x80, 0x40, 0x80, 0x80, 0x80, 0x3F, 0xFE, 0x00, 0x00, /*-- 文字: 右 --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFF, 0xFE, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x1F, 0xF8, 0x28, 0x08, 0x48, 0x08, 0x88, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0F, 0xF8, 0x08, 0x08, /*-- 文字: 滚 --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x00, 0x80, 0x20, 0x40, 0x17, 0xFC, 0x11, 0x10, 0x82, 0x48, 0x44, 0x84, 0x41, 0x20, 0x13, 0xF0, 0x10, 0x10, 0x20, 0x88, 0xE1, 0x50, 0x23, 0x20, 0x25, 0x10, 0x29, 0x48, 0x21, 0x86, 0x01, 0x00, /*-- 文字: 动 --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x00, 0x40, 0x00, 0x40, 0x7C, 0x40, 0x00, 0x40, 0x01, 0xFC, 0x00, 0x44, 0xFE, 0x44, 0x20, 0x44, 0x20, 0x44, 0x20, 0x84, 0x48, 0x84, 0x44, 0x84, 0xFD, 0x04, 0x45, 0x04, 0x02, 0x28, 0x04, 0x10, /*-- 文字: ★ --*/ /*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/ 0x01, 0x00, 0x01, 0x00, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x07, 0xC0, 0xFF, 0xFE, 0x7F, 0xFC, 0x3F, 0xF8, 0x0F, 0xE0, 0x0F, 0xE0, 0x1F, 0xF0, 0x1E, 0xF0, 0x18, 0x30, 0x20, 0x08, 0x00, 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, rollSpeed; bit mode = 0; uchar num = 0; //显示缓存,用来存储输入到4个595中的数据。 //displayBuff[0]:0# 595,控制上8行,上为高位 //displayBuff[1]:1# 595,控制下8行,上为高位 //displayBuff[2]:2# 595,控制左8列,左为高位 //displayBuff[3]:3# 595,控制右8列,左为高位 uchar displayBuff[4]; bit moveLeft = 1; //移动方向,1——左移,0——右移 uchar* basePtr[3]; //每8次移位之前的第一行的3个半边字符(即正在显示的左半、正在显示的右半、即将显示的另一半)的基准指针,其他行码值在此基础上偏移 uchar temp[3]; //用来存储三个半边字符的某一行的码值 uchar cache[2]; //中间变量,可不要 uchar wordsCount = sizeof(words) / sizeof(words[0]) / 32; //汉字总数 while (1) { //获取每8次移位前的第一行的基准指针地址 if (mode == 0) //模式0,左右半屏显示同一个字,basePtr[2]指向下一个即将显示的字的左半(左滚时)或右半(右滚时)的首行 { basePtr[0] = words + (num) * 32 + (moveLeft ? 0 : 1); basePtr[1] = words + (num) * 32 + (moveLeft ? 1 : 0); basePtr[2] = words + (num + 1) % wordsCount * 32 + (moveLeft ? 0 : 1); //取余是为了显示到最后一个字时,temp[2]等于首字的左半 } else//模式1,(左滚时)左半屏显示上一个字的右半,右半屏显示下一个字的左半 //(右滚时)右半屏显示上一个字的左半,左半屏显示下一个字的右半 //basePtr[1][2]指向下一个即将显示的两个半边字符码地址的首行 { basePtr[0] = words + (num) * 32 + (moveLeft ? 1 : 0); basePtr[1] = words + (num + 1) % wordsCount * 32 + (moveLeft ? 0 : 1); //取余是显示最后一个字右半时,temp[1]等于首字的左半 basePtr[2] = words + (num + 1) % wordsCount * 32 + (moveLeft ? 1 : 0); //取余是显示最后一个字右半时,temp[1]等于首字的右半 } for (j = 0; j < 8; j++) { rollSpeed = 1; //滚动速度调节 while (rollSpeed--) { //依次显示16列,即显示完一屏 for (i = 0; i < 16; i++) { //移位操作涉及的3个半边字符,往移动方向最先移除屏幕的定义为序号[0] //根据ptr计算,可得左移时,temp[0][1][2]分别对应前左<-前右<-后左或前右<-后左-<后右 //右移时,temp[2][1][0]分别对应后右->前左->前右或后左->后右->前左 temp[0] = *(basePtr[0] + 2 * i); temp[1] = *(basePtr[1] + 2 * i); temp[2] = *(basePtr[2] + 2 * i); if (moveLeft)//左移 { cache[0] = temp[0] << j | temp[1] >> (8 - j); cache[1] = temp[1] << j | temp[2] >> (8 - j); } else { cache[0] = temp[1] >> j | temp[2] << (8 - j);
上一篇:8051系列单片机软件精确延时研究(一)
下一篇:4个74HC595级联控制16x16点阵横向滚动带仿真(一)
推荐阅读最新更新时间:2024-11-03 10:21
设计资源 培训 开发板 精华推荐
- 2017电赛B题-滚球控制系统国一报告
- DC2164A-C,用于 LTM4630EY-1 的演示板,4 个并联降压模块,4.5V = VIN = 15V,Vout = 0.9V 至 1.8V @ 140A
- MC33363A高压开关稳压器典型应用电路
- 使用 Infineon Technologies AG 的 IRU3073 的参考设计
- MAXREFDES1196:使用MAX17499B升压控制器的24V/4A DC-DC升压转换器
- LTM4650AEY-1 50A、3.3V 输出 DC/DC 降压型稳压器的典型应用电路
- 桌面小时钟、电子模具、GPS车速海拔表
- 用于基本连接的 LT6656ACDC-2.5、2.5V 电压基准的典型应用
- 5V 穿越应用电路在 1.42 秒内提供 20W 功率
- MIKROE-2800,带有两个基于 PIC32MZ 32 位 MCU 的 mikroBUS 插座的 Clicker 2 PIC32MZ 开发套件