资源描述
摘 要
广告灯是用于广告匾,楼宇装饰和户外装潢灯具,最近伴随国家经济快速发展,人民物质文化生活水平不停提升,对于装饰美化美观要求也越来越高,广告灯越来越多出现在个大家视野中。多年来伴随科技飞速发展,单片机应用正在不停地走向深入,同时自动控制系统日新月益更新。
本文结合中国外霓虹灯控制技术发展情况设计了一个采取美国ATMEL企业生产AVR系列单片机中ATmega8作控制芯片霓虹灯控制器.经过ATmega8芯片控制驱动电路,在由驱动电路驱动继电器,而继电器则作为霓虹灯功率控制。其中,和别产品在设计上不一样是,功率控制板块采取是继电器阵列,而不是通常见可控硅,将继电器阵列模块化,电路设计条理也很清楚,既方便检验线路故障,有方便技术维修。该板块设计也是此次设计关键和难点。另外,文中还介绍了电源电路、PC机和单片机通讯接口电路设计原理。软件设计部分采取是ICC-AVR环境下C语言进行编写程序,使用AVR Studio进行仿真说明。本文设计霓虹灯单片机控制器,电路简单,抗干扰性强,图案改变方法多,可适适用于多种霓虹灯牌面,可依据用户要求,经过修改软件,控制多个多样花样改变,是一代新型霓虹灯控制器。
关键字:霓虹灯;控制器;继电器;ATmega8
目录
摘 要 1
目录 2
一 系统方案论证和比较 4
方案一:使用CD4060和KD5603作为主控制器 4
方案二:NE555和CD4541作为主控制器 5
方案三:采取LED点阵和ATmega8作为主驱动器 6
二 元器件介绍 8
1.主控芯片ATmega8介绍 8
(1)产品特征 8
(2)外设特点 9
(3)特殊处理器特点 9
(4)I/O 和封装 9
(5)工作电压 9
(6)速度等级 10
(7)引脚说明 11
(8)ATmega8状态寄存器 12
(9)通用寄存器 13
(10)堆栈指针 14
(11)复位和中止 15
2. 点阵显示器 16
(1)8*8点阵原理图 16
(2)8*8点阵实物图 17
(3)8*8点阵扫描方法 17
(4)8*8点阵应用举例 17
3.驱动芯片4-16译码器CC4514 19
(1)推荐工作条件 19
(2)工作温度范围 19
(3)极限值 19
三 广告控制器系统设计 21
1.系统硬件设计 21
(1)主控制器ATmega8 21
(2)点阵扫描驱动电路 21
2.系统软件设计 22
(1)程序步骤图 22
(2)程序清单 23
一 系统方案论证和比较
方案一:使用CD4060和KD5603作为主控制器
这是一例变色广告灯自动控制电路,它采取了两种控制方法:①光控方法,白天自动关闭,夜晚自动开启;②时间控制方法,夜晚自动开启后,经过定时控制 使其在预定时间自动关闭,以节省电能。在广告灯开启后,经过控制电路使两种彩色广告灯光交替循环显示,增强广告效果。电路在灯光显示同时还伴有广告 语言,介绍广告要说明内容,是一个功效较完善广告灯控制器。变色广告灯控制器电路组成图6-45 所表示。
电路工作原理分析
变色广告灯控制器电路由光控电路、时间控制电路、语言电路、彩灯循环控制电路和电源电路组成。光控电路是本电路主控电路,它经过为其它控制电路接通工作电源方法控制着整个工作电路开启时间。光控电路关键由光敏电阻RG 和由VTl 、VT2 组成直接桐合式晶体管放大电路组成。白天, RG 受光照射阻值变小, VTl 基极得到较大偏置电压而导通,VT2 则因VTl导通而截止。IC2~1C4因无工作电源而停止工作。
夜晚来临时,光照减弱, RG 阻值升高, VTl 截止, VT2 因VTl 截止而导通, 12V电源经VT2 向IC2~IC4 提供工作电源,使其进入工作状态。时间控制电路作用是:当夜晚来临后使电路投入工作,夜深人静时停止工作,以避免无须要电源消耗。时间控制电路由一只14 级二进制计数/分频电路CD4060 组成。该电路经过外接R4 、C7 组成一个RC 振荡器,其振荡周期T= 2. 2R4C7 = LIs 。经内部14 级分频(分频系数为16384) 后,控制时间约为5 小时( 1. 1 X 16384 =18022s , 18022/3600≈5小时)。当VT2 导通后,电源经过C6 、R3 形成复位脉冲使CD4060 复位,随即电路工作,产生脉冲并分频。在接通电源之初,因为IC2 ③脚输出低电平, VT3 导通,为IC3 及IC4提供工作电源。5 小时后定时结束,③脚输出高电平, VT3 截止,切断了IC3 和IC4工作电源,广告灯和语言电路因失去控制电源而停止工作。
方案二:NE555和CD4541作为主控制器
广告灯控制器由NE555组成光控及抗干扰电路、CD4541定时电路、继电器控制、电源电路等部分组成。电原理图图1所表示。
NE555时基电路接成施密特触发器,对光敏电阻RC接收到信号进行整形和功率放大以后,驱动后续电路。当白天有光照时,其第③脚输出低电平,夜晚无光照时输出高电平。
CD4541是一块含有振荡计数、定时功效IC,在电路中作为定时控制,各脚功效如表1所表示。CD4541工作时,第①脚接振荡电阻,第②脚接振荡电容,第③脚接保护电阻,第⑧脚为输出脚,第⑨脚可选择第⑧脚输出状态,第⑩脚接低电平为单定时模式,接高电平为循环定时模式,第12、13脚可设定时间或设定输出频率,CD4541分频或计数次数如表2所表示。220V交流市电经R9、C6阻容降压.D2~D5整流,C5滤波,WD2稳压,给继电器提供24V吸合电压。此电压经过R8和WD1稳压,C4滤波,给IC1和IC2提供9.1V工作电压。
白天,光敏电阻RG阻值很小,经过RG和WR1分压,NE555第⑥脚电压大于2/3Vcc,使第③脚输出为低电平,三极管BG1截止。CD4541第⑥脚复位端为高电平,其内部计数器清零复位,第⑧脚输出端为低电平,BG2截止,继电器常开触电断开,其受控电路不工作。
当夜幕降临时候,RG阻值逐步增大,NE555第②脚电位逐步降低,当小于1/3Vcc时,NE555第③脚输出端信号翻转为高电平。BG1基极电位升高而导通,给CD4541第⑥脚提供一个由高电平变为低电平脉冲负跳变沿,使内部电路开始计数,输出端第⑧脚输出高电平。BG2导通,继电器K1得电,常开触点闭合,受控电路工作。WR2和C3为CD4541外接振荡电阻和振荡电容,当经t=32768×2.3RC≈24871秒时间后,输出端第⑧脚变为低电平。VT2截止,K1常开触点失电而断开,受控电路停止工作。经过微调WR2,可改变定时时长。此电路对于外界干扰引发白天瞬间变暗不会造成继电器误动作,因为NE555第②、⑥脚所接R1和C1组成延时抗干扰电路,当RG阻值瞬间增大时,因为电容C1两端电压不能突变,从而保持第⑥脚电位基础不变,第③脚输出仍为低电平。但当RG阻值长时间较大时,C1充电完成后,NE555第⑥脚电压降低,第③脚输出高电平,从而造成继电器动作。
方案三:采取LED点阵和ATmega8作为主驱动器
数控广告灯扫描器有以下关键特点:
(1)分体联控结构:处理了大型广告灯工程既要求扫描器分体就近安装又要求扫描器整体调控矛盾。
(2)强抗干扰设计:经过系统软件抗干扰处理,避免了广告灯乱闪及抖动现象,使版面极为洁净。
(3)自动同时:当遇强干扰造成扫描器不能同时工作时,系统软件将在1分钟内自动修复。
(4)调试开关:对于大型广告灯工程调试,这个功效极为有用。
(5)接插件结构:整个线路全部采取接插件绘声结构,拆卸简单,维修方便。
图3 ATmega8和点阵显示广告控制系统
总而言之,我们选择方案三。
二 元器件介绍
1.主控芯片ATmega8介绍
(1)产品特征
● 高性能、低功耗 8 位AVR® 微处理器
● 优异RISC 结构
● 130 条指令 – 大多数指令实施时间为单个时钟周期
● 32个8 位通用工作寄存器
● 全静态工作
● 工作于16 MHz 时性能高达16 MIPS
● 只需两个时钟周期硬件乘法器
● 非易失性程序和数据存放器
● 8K 字节系统内可编程Flash
● 擦写寿命: 10,000 次
● 含有独立锁定位可选Boot 代码区
● 经过片上Boot 程序实现系统内编程
● 真正同时读写操作
● 512 字节EEPROM
● 擦写寿命: 100,000 次
● 1K字节片内SRAM
● 能够对锁定位进行编程以实现用户程序加密
(2)外设特点
● 两个含有独立预分频器8 位定时器/ 计数器, 其中之一有比较功效
● 一个含有预分频器、比较功效和捕捉功效16 位定时器/ 计数器
● 含有独立振荡器实时计数器RTC
● 三通道PWM
● TQFP和MLF 封装8 路ADC
● 路10 位ADC
● 8 路10 位ADC
● 面向字节两线接口
● 两个可编程串行USART
● 可工作于主机/ 从机模式SPI 串行接口
● 含有独立片内振荡器可编程看门狗定时器
● 片内模拟比较器
(3)特殊处理器特点
● 上电复位和可编程掉电检测
● 片内经过标定RC 振荡器
● 片内/ 片外中止源
● 5种睡眠模式: 空闲模式、ADC 噪声抑制模式、省电模式、掉电模式及Standby 模式。
(4)I/O 和封装
● 23个可编程I/O 口
● 28引脚PDIP 封装,32 引脚TQFP 封装,32 引脚MLF 封装
(5)工作电压
● 2.7 - 5.5V (ATmega8L)
● 4.5 - 5.5V (ATmega8)
(6)速度等级
● 0 - 8 MHz (ATmega8L)
● 0 - 16 MHz (ATmega8)
● 4 Mhz 时功耗, 3V, 25°C
● 工作模式: 3.6 mA
● 空闲模式: 1.0 mA
● 掉电模式: 0.5 μA
● 含有8KB 系统内可编程 Flash
● 8 位 微控制器
ATmega8引脚图
ATmega8内部结构简图
(7)引脚说明
VCC 数字电路电源。
GND 地。
端口B(PB7..PB0)XTAL1/XTAL2/TOSC1/TOSC2
端口B 为8 位双向I/O 口,含有可编程内部上拉电阻。其输出缓冲器含有对称驱动特征,能够输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口B 处于高阻状态。经过时钟选择熔丝位设置, PB6 可作为反向振荡放大器或时钟操作电路输入端。经过时钟选择熔丝位设置PB7 可作为反向振荡放大器输出端。若将片内标定RC 振荡器作为芯片时钟源,且ASSR 寄存器AS2 位设置,PB7..6 作为异步 T/C2 TOSC2..1 输入端。端口B 其它功效见P55“ 端口B 第二功效” 及P 22“ 系统时钟立即钟选项” 。
端口C(PC5..PC0) 端口C 为7 位双向I/O 口,含有可编程内部上拉电阻。其输出缓冲器含有对称驱动特征,能够输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口C 处于高阻状态。
PC6/RESET 若RSTDISBL 熔丝位编程, PC6 作为I/O 引脚使用。注意PC6 电气特征和端口C 其它引脚不一样若RSTDISBL 熔丝位未编程,PC6 作为复位输入引脚。连续时间超出最小门限时间低电平将引发系统复位。门限时间见P 35Table 15 。连续时间小于门限时间脉冲不能确保可靠复位。
端口C 其它功效见后。
端口D(PD7..PD0) 端口D 为8 位双向I/O 口,含有可编程内部上拉电阻。其输出缓冲器含有对称驱动特征,能够输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,则端口被外部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口D 处于高阻状态。端口D 其它功效见后。
RESET 复位输入引脚。连续时间超出最小门限时间低电平将引发系统复位。门限时间见 P35Table 15 。连续时间小于门限时间脉冲不能确保可靠复位。
AVCC AVCC 是A/D转换器、端口C (3..0) 及ADC (7..6) 电源。不使用ADC时,该引脚应直接和VCC 连接。使用ADC 时应经过一个低通滤波器和VCC 连接。注意,端口C (5..4) 为数字电源, VCC。
AREF A/D 模拟基准输入引脚。
ADC7..6(TQFP 和MLF 封装) TQFP和MLF封装ADC7..6作为A/D转换器模拟输入。为模拟电源 且作为10位ADC通
道。
(8)ATmega8状态寄存器
状态寄存器包含了最近实施算术指令结果信息。这些信息能够用来改变程序步骤以实现条件操作。如指令集所述,全部ALU 运算全部将影响状态寄存器内容。这么,在很多情况下就不需要专门比较指令了,从而使系统运行愈加快速,代码效率更高。在进入中止服务程序时状态寄存器不会自动保留,中止返回时也不会自动恢复。这些工作需要软件来处理。
AVR 中止寄存器 SREG 定义以下:
• Bit 7 – I: 全局中止使能I 置位时使能全局中止。单独中止使能由其它独立控制寄存器控制。假如I 清零,则不管单独中止标志置位是否,全部不会产生中止。任意一个中止发生后I 清零,而实施RETI指令后I 恢复置位以使能中止。I 也能够经过SEI 和CLI 指令来置位和清零。
• Bit 6 – T: 位拷贝存放位拷贝指令BLD 和BST 利用T 作为目标或源地址。BST 把寄存器某一位拷贝到T,而BLD 把T 拷贝到寄存器某一位。
• Bit 5 – H: 半进位标志半进位标志H 表示算术操作发生了半进位。此标志对于BCD 运算很有用。详见指令集说明。
• Bit 4 – S: 符号位, S = N ⊕ VS 为负数标志N 和2 补码溢出标志V 异或。详见指令集说明。
• Bit 3 – V:2 补码溢出标志支持2 补码运算。详见指令集说明。
• Bit 2 – N: 负数标志表明算术或逻辑操作结果为负。详见指令集说明。
• Bit 1 – Z: 零标志表明算术或逻辑操作结果为零。详见指令集说明。
• Bit 0 – C: 进位标志
(9)通用寄存器
文件寄存器文件针对AVR 增强型 RISC 指令集做了优化。为了取得需要性能和灵活性,寄存器文件支持以下输入/ 输出方案:
• 输出一个 8 位操作数,输入一个 8 位结果。
• 输出两个 8 位位操作数,输入一个 8 位结果。
• 输出两个 8 位位操作数,输入一个 16 位结果。
• 输出一个 16 位位操作数,输入一个 16 位结果。
CPU 32 个通用工作寄存器结构
(10)堆栈指针
堆栈指针关键用来保留临时数据、局部变量和中止/ 子程序返回地址。堆栈指针总是指向堆栈顶部。要注意AVR 堆栈是向下生长,即新数据推入堆栈时,堆栈指针数值将减小。堆栈指针指向数据SRAM 堆栈区。在此聚集了子程序堆栈和中止堆栈。调用子序和使能中止之前必需定义堆栈空间,且堆栈指针必需指向高于0x60 地址空间。使用PUSH指令将数据推入堆栈时指针减一;而子程序或中止返回地址推入堆栈时指针将减二。使用POP 指令将数据弹出堆栈时,堆栈指针加一;而用RET 或RETI 指令从子程序或中止返回时堆栈指针加二。AVR堆栈指针由I/O空间中两个8位寄存器实现。实际使用位数和具体器件相关。请注意一些AVR 器件数据区太小,用SPL 就足够了。此时将不给出SPH 寄存器。
指令实施时序这一节介绍指令实施过程中访问时序。AVR CPU 由系统时钟clkCPU 驱动。此时钟直接来自选定时钟源。芯片内部不对此时钟进行分频。Figure 5 说明了由Harvard 结构决定并行取指和指令实施,和能够进行快速访问寄存器文件概念。这是一个基础流水线概念,性能高达1 MIPS/MHz,含有优良性价比、功效/ 时钟比、功效/ 功耗比。
(11)复位和中止
处理AVR有不一样中止源。每个中止和复位在程序空间全部有独立中止向量。全部中止事件全部有自己使能位。当使能位置位,且状态寄存器全局中止使能位I 也置位时,中止能够发生。依据程序计数器PC 不一样,在引导锁定位BLB02 或BLB12 被编程情况下,中止可能被自动严禁。这个特征提升了软件安全性。详见 P 209“ 存放器编程” 描述。程序存放区最低地址缺省为复位向量和中止向量。完整向量列表请参见P 43“ 中止”列表也决定了不一样中止优先级。向量所在地址越低,优先级越高。RESET 含有最高优先级,第二个为INT0 – 外部中止请求0。经过置位通用中止控制寄存器 (GICR) IVSEL,中止向量能够移至引导Flash起始处,参见P 43“中止” 。编程熔丝位BOOTRST也能够将复位向量移至引导Flash 起始处。具体参见P 196“ 支持引导装入程序 -在写同时能够读(RWW, Read-While-Write) 自我编程能力” 。任一中止发生时全局中止使能位I 被清零,从而严禁了全部其它中止。用户软件能够在中止程序里置位I 来实现中止嵌套。此时全部中止全部能够中止目前中止服务程序。实施RETI 指令后I 自动置位。从根本上说有两种类型中止。第一个由事件触发并置位中止标志。对于这些中止,程序计数器跳转到实际中止向量以实施中止处理程序,同时硬件将清除对应中止标志。中止标志也能够经过对其写”1” 方法来清除。当中止发生后,假如对应中止使能位为"0",则中止标志位置位,并一直保持到中止实施,或被软件清除。类似,假如全局中止标志被清零,则全部已发生中止全部不会被实施,直到I 置位。然后挂起各个中止按中止优先级依次实施。
2. 点阵显示器
(1)8*8点阵原理图
(2)8*8点阵实物图
图为8×8点阵LED外观及引脚图,其等效电路图(2)所表示,只要其对应X、Y轴顺向偏压,即可使LED发亮。比如假如想使左上角LED点亮,则Y0=1,X0=0即可。应用时限流电阻能够放在X轴或Y轴
(3)8*8点阵扫描方法
LED通常采取扫描式显示,实际利用分为三种方法
(1)点扫描
(2)行列扫描
16×64=1024Hz,周期小于1ms即可。若使用第二和第三种方法,则频率必需大于16×8=128Hz,周期小于7.8ms即可符合视觉暂留要求。另外一次驱动一列或一行(8颗LED)时需外加驱动电路提升电流,不然LED亮度会不足。
(4)8*8点阵应用举例
点阵内部结构及外形以下,8X8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线交叉点上,当对应某一行置1电平,某一列置0电平,则对应二极管就亮;如要将第一个点点亮,则9脚接高电平13脚接低电平,则第一个点就亮了;假如要将第一行点亮,则第9脚要接高电平,而(13、3、4、10、6、11、15、16)这些引脚接低电平,那么第一行就会点亮;如要将第一列点亮,则第13脚接低电平,而(9、14、8、12、1、7、2、5)接高电平,那么第一列就会点亮。
通常我们使用点阵显示汉字是用16*16点阵宋体字库,所谓16*16,是每一个汉字在纵、横各16点区域内显示。也就是说得用四个8*8点阵组合成一个16*16点阵。以下图所表示,要显示“你”则对应点就关键点亮,因为我们点阵在列线上是低电平有效,而在行线上是高电平有效,所以要显示“你”字话,它位代码信息要取反,即全部列(13~16脚)送(1111,0xF7,0x7F),而第一行(9脚)送1信号,然后第一行送0。再送第二行要显示数据(13~16脚)送(1111,0xF7,0x7F),而第二行(14脚)送1信号。依这类推,只要每行数据显示时间间隔够短,利用人眼视觉暂停作用,这么送16次数据扫描完16行后就会看到一个“你”字;第二种送数据方法是字模信号送到行线上再扫描列线也是一样道理。一样以“你”字来说明,16行(9、14、8、12、1、7、2、5)上送(0000,0x00,0x00)而第一列(13脚)送、“0”。同理扫描第二列。当行线上送了16次数据而列线扫描了16次后一个“你”字也就显示出来了。
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
●
所以,形成列代码为 00H,00H,3EH,41H,41H,3EH,00H,00H;只要把这些代码分别依次送到对应列线上面,即可实现“0”数字显示。
3.驱动芯片4-16译码器CC4514
(1)推荐工作条件
电源电压范围…………… ….3V~15V
输入电压范围………………..0V~VDD
(2)工作温度范围
M 类……………….-55℃~125℃
E 类…………… ….-40℃~85℃
(3)极限值
电源电压… ...-0.5V~18V
输入电压… …-0.5V~VDD+0.5V
输入电流… ……….±10mA
储存稳定…………….-65℃~150℃
CD4514引脚图
三 广告控制器系统设计
1.系统硬件设计
(1)主控制器ATmega8
本控制系统采取存放容量大AVR单片机ATmega8作为主控制器,直接能够将容量较大系统字库存放在ATmega8内部存放器内,节省了资源,也使整个系统变得简练。
(2)点阵扫描驱动电路
扫描电路采取CD4514,即4-16译码器来进行行列扫描,用单片机控制其选通端INH来控制送行列字库码,控制扫描,并在输出端加一个非门,来提升其驱动能力,以满足点阵发光需求。
2.系统软件设计
(1)程序步骤图
(2)程序清单
**********************************************/
#include <32x16led.h>
void main (void)
{
while (1)
{
led_initial();
print_char("TEST LED abc");
print_char("我爱金鱼");
delay(50);
// led_initial();
print_char("自己编练习程序,");
print_char("显示效果和延时参数和电脑速度有很大关系.");
print_char("我电脑太差运行起来老是一顿一顿^_^");
print_char("相信换台好点电脑会有愈加好效果! 刘伟");
delay(50);
}
}
/**********************************************
#include <iom16v.h>
#include <macros.h>
#include <font.h>
#define LED_DATA_LOW PORTA
#define LED_DDR_LOW DDRA
#define LED_DATA_HIGH PORTB
#define LED_DDR_HIGH DDRB
#define LED_SCAN_DATA PORTC
#define LED_SCAN_DDR DDRC
#define uchar unsigned char
#define uint unsigned int
//缓存大小,对应LED屏大小
#define buffer_long 64
//定义字模数据数组大小,即所存字个数
#define gb16_tabel_long 62
/* 利用定时器1 定时扫描LED屏 */
/* 定时参数对显示效果影响很大 */
#define T1_TIME_H 0xe7
#define T1_TIME_L 0x50
enum direction {right,left}dir_f;
uchar display_buffer[buffer_long];
/**************** LED屏初始化**************************/
void led_initial ( void )
{
uchar i;
//display_buffer initial
for (i=0; i<buffer_long; i++)
display_buffer[i] = 0x00;
// port initial
LED_DDR_LOW = 0xff;
LED_DDR_HIGH = 0xff;
LED_SCAN_DDR = 0x1f;
//移动方向 right or left
dir_f = left;
//t0 initial
CLI(); //disable all interrupts
TCCR1B = 0xe0; //stop
TCNT1H = T1_TIME_H; //setup
TCNT1L = T1_TIME_L;
OCR1AH = 0x01;
OCR1AL = 0xF4;
OCR1BH = 0x01;
OCR1BL = 0xF4;
ICR1H = 0x01;
ICR1L = 0xF4;
TCCR1A = 0x00;
TCCR1B = 0x02; //start Timer
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04; //timer interrupt sources
SEI(); //re-enable interrupts
}
/*************** 字符串输出子程序***********************/
void print_char (char *p)
{
uchar tab_n,j,i=0;
int k;
uchar d0,d1;
while(p[i] > 0)
{
if (p[i] >=128)//假如是汉字
{
/* 查找 移位输出 */
for(j=0; j<=gb16_tabel_long; j++)
{
if ((gb_16[j].index[0] == p[i]) && (gb_16[j].index[1] == p[i+1]))
{
if ( dir_f == left )//假如字向左移动就次序读字模
for (k=0; k<32; k++)
{
d0 = gb_16[j].mask[k];
k++;
d1 = gb_16[j].mask[k];
move_to_buffer (d0,d1);
delay(1);
}
else //假如字向右移动就逆序读字模
for (k=31; k>=0; k--)
{
d1 = gb_16[j].mask[k];
k--;
d0 = gb_16[j].mask[k];
move_to_buffer (d0,d1);
delay(1);
}
break;//找到了就退出循环
}
}
/* 字库没有字,则输出空白0x00 */
if (j>gb16_tabel_long)//
for (k=0; k<16; k++)
{
d0 = 0x00;
d1 = 0x00;
move_to_buffer (d0,d1);
delay(1);
}
i+=2;
}
else //假如是字符
{
j = p[i]-32;
if (dir_f == left)
for (k=0; k<16; k++)
{
d0 = ASC_MSK[(j*16)+k];
k++;
d1 = ASC_MSK[(j*16)+k];
move_to_buffer (d0,d1);
delay(1);
}
else
for (k=15; k>=0; k--)
{
d1 = ASC_MSK[(j*16)+k];
k--;
d0 = ASC_MSK[(j*16)+k];
move_to_buffer (d0,d1);
delay(1);
}
i++;
}
}
}
/******************** 数据移入缓存*********************/
// d0 移入数据高八位
// d1 移入数据低八位
void move_to_buffer (uchar d0,uchar d1)
{
uchar i;
if ( dir_f == right)//判定移动方向
{
for (i=0; i<(buffer_long-2); i++)
{
display_buffer[buffer_long-1-i] = display_buffer[buffer_long-1-i-2];
}
display_buffer[0] = d0;
display_buffer[1] = d1;
}
else
{
for (i=0; i<(buffer_long-2); i++)
{
display_buffer[i] = display_buffer[i+2];
}
display_buffer[buffer_long-2] = d0;
display_buffer[buffer_long-1] = d1;
}
}
/*********************显示数据扫描********************/
#pragma interrupt_handler scan_led:9
void scan_led (void)
{
uchar buf_c,scan_c=0;
TCNT1H = T1_TIME_H; //reload counter high value
TCNT1L = T1_TIME_L;; //reload counter low value
for (buf_c=0; buf_c<buffer_long;)
{
//LED_DDR_LOW = 0xff;
//LED_DDR_HIGH = 0xff;
LED_DATA_HIGH = display_buffer[buf_c];
buf_c++;
LED_DATA_LOW = display_buffer[buf_c];
buf_c++;
LED_SCAN_DATA = scan_c;
delay(8);
//LED_DDR_LOW = 0x00;
//LED_DDR_HIGH = 0x00;
scan_c++;
}
}
/**********************延时子程序*********************/
void delay (uchar d_time)
{
uchar i,j;
for (i=0; i<=d_time; i++)
{
j=25;
while(j--);
}
}
展开阅读全文