1.硬件电路
见x.png
2.擎天柱Ai8051U转89C52-DIP40核心板
见11.jpg
3.汉字取码软件与取码
采用PCtolc2002,见图12.png
由于端口改了,用STC下载器自带的点阵生成工具按逐列取码,8种方式竟没有一种适合,没办法,只得采用PCtolc2002软件生成点阵数据,但又不甘心,STC的生态做得这么好,不会出这么明显的错误吧,由于初次使用STC取码工具,由于自己的疏忽,STC取码工具中还有一个存储顺序栏未改动,本例取码模式:扫描模式选:垂直扫描,从上到下,从左到右,存储顺序:低位优先,生成的代码与PCtoLCD2002一样。
启动STC下载软件,执行菜单命令:工具\字库生成工具,即可打开取码工具,很方便,见图14.png。
想要向右滚动显示“技师学院好”+2黑屏,取码要按“好院学师技”+2黑屏,加上2屏黑屏码可以确保显示时无乱码。
硬件电路的一列从上到下,依次是P27~20、P07~00,输入数据P2=0x17,P0=0x55,扫描码输入0x00,可见最右边的1列点亮,P2=B1110 1000,P0=B10101010,所以取码要逆序(低位在前,低字节在前),扫描是自右向左逐列扫描。
4、编程
原则:先找到最后一个字的最后一列(15列)的2个字节并扫描,即字库表中最后的2个0x00,前一个送P2口,后一个送P0口,扫描码(0~15)也要先找到最后1列的扫描码,即15。
为了充分发挥Ai8051U单片机的性能,采用100us定时中断,从而提高刷新率,这样在录像的时候也无闪烁感。
- //版本3 在16x16LED点阵上多个汉字向右滚动进入 难
- //基于“擎天柱Ai8051U转89C52-DIP40核心板”驱动16x16LED点阵显示汉字向右滚动进入
- //
-
- /************* 功能说明 **************
- 32bit Keil uVision C251_32bit开发
- T0中断100us显示1列
-
- ******************************************/
-
- #include "AI8051U.h"
- #include "stdio.h"
- #include "intrins.h"
-
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
-
- #define MAIN_Fosc 24000000UL
-
- //==========================================================================
- //各定时器加载初值
-
- //24MHZ,1T,一条指令耗时1/24us,定时100us,初值2400
- //Timer 0 中断频率, 10000次/秒,定时100us,1/100us=10000HZ
- #define Timer0_Reload (MAIN_Fosc / 5000) //定时100us,初值2400
- //#define Timer0_Reload (MAIN_Fosc / 2000) //定时500us,初值1200
-
- //#define Timer0_Reload (MAIN_Fosc / 1000) //Timer 0 中断频率, 1000次/秒,初值24000
- //#define Timer1_Reload (MAIN_Fosc / 2000) //Timer 1 中断频率, 2000次/秒
- //#define Timer2_Reload (MAIN_Fosc / 3000) //Timer 2 中断频率, 3000次/秒
- //#define Timer3_Reload (MAIN_Fosc / 4000) //Timer 3 中断频率, 4000次/秒
- //#define Timer4_Reload (MAIN_Fosc / 5000) //Timer 4 中断频率, 5000次/秒
-
- void Timer0_init(void);
- //void Timer1_init(void);
- //void Timer2_init(void);
- //void Timer3_init(void);
- //void Timer4_init(void);
-
- bit T0_flag = 0; //T0中断标志
- #define DUAN1 P0 //段码直驱,NPN管同相驱动,硬件:下半列,bit7在前
- #define DUAN2 P2 //段码直驱,NPN管同相驱动,硬件:上半列,bit7在前
- #define SCAN P1 //扫描码经4-16译码器驱动
-
- u8 code tab1 [ ]={
-
-
- //为何STC带的取码软件却无法取到相同的数据码,试遍8种逐列取码方式都不行,原来还有存储顺序
- //那项未选择,选择垂直扫描,从上到下,从左到右,低位优先,生成的代码与PCtoLCD2002一样
-
- //用PCtoLCD2002完美版取码软件 阴码 逆向(低位在前,低字节在前) 逐列 ,
- //软件中规定: 从第一列开始向下每取8个点作为一个字节,如果最后不足8个点就补满8位。
- //取模顺序是从低到高,即第一个点作为最低位。如*-------取为00000001。
-
- //想向右滚动显示“技师学院好”+2黑屏,取码要按“好院学师技”+2黑屏
-
- //向右滚动显示5个汉字,要先显示最后一个字的最末一列的2个码
- //好(0) 院(1) 学(2) 师(3) 技(4)
- //逆向
-
- 0x10,0x40,0x10,0x22,0xF0,0x15,0x1F,0x08,0x10,0x16,0xF0,0x61,0x00,0x00,0x80,0x00,
- 0x82,0x40,0x82,0x80,0xE2,0x7F,0x92,0x00,0x8A,0x00,0x86,0x00,0x80,0x00,0x00,0x00,/*"好",0*/
-
- 0x00,0x00,0xFE,0xFF,0x22,0x04,0x5A,0x08,0x86,0x07,0x10,0x80,0x0C,0x41,0x24,0x31,
- 0x24,0x0F,0x25,0x01,0x26,0x01,0x24,0x3F,0x24,0x41,0x14,0x41,0x0C,0x71,0x00,0x00,/*"院",1*/
-
- 0x40,0x04,0x30,0x04,0x11,0x04,0x96,0x04,0x90,0x04,0x90,0x44,0x91,0x84,0x96,0x7E,
- 0x90,0x06,0x90,0x05,0x98,0x04,0x14,0x04,0x13,0x04,0x50,0x04,0x30,0x04,0x00,0x00,/*"学",2*/
-
- 0x00,0x00,0xFC,0x87,0x00,0x40,0x00,0x30,0xFF,0x0F,0x00,0x00,0x02,0x00,0xE2,0x1F,
- 0x22,0x00,0x22,0x00,0xFE,0xFF,0x22,0x08,0x22,0x10,0xE2,0x0F,0x02,0x00,0x00,0x00,/*"师",3*/
-
- 0x10,0x04,0x10,0x44,0x10,0x82,0xFF,0x7F,0x10,0x01,0x90,0x80,0x08,0x80,0x88,0x40,
- 0x88,0x43,0x88,0x2C,0xFF,0x10,0x88,0x28,0x88,0x46,0x88,0x81,0x08,0x80,0x00,0x00,/*"技",4*/
-
- 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, //黑屏
-
- 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, //黑屏
-
- }; //
-
- u8 code tab2[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
- 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; //扫描码
-
- /******************** 主函数 **************************/
- void main(void)
- {
- //u16 j = 0; //1个字的字节数
- u16 zishu = 6 * 16; //总列数,7个字,总列数取(7-1) * 16无乱码
- u8 lie = 0; //每个字的列数,1列2个字节,兼作取码序号
- u8 times = 0; //每个字重复显示的遍数
-
- WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
- EAXFR = 1; //扩展寄存器(XFR)访问使能
- CKCON = 0; //提高访问XRAM速度
-
- P0M1 = 0x00; P0M0 = 0xff; //设置P0为推挽输出
- P1M1 = 0x00; P1M0 = 0xff; //设置P1为推挽输出
- P2M1 = 0x00; P2M0 = 0xff; //设置P2为推挽输出
-
- //不用的端口要配置为准双向口,确保系统的稳定性和可靠性
- P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
- P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
- P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
- P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
- P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
-
-
-
- Timer0_init(); //T0初始化
-
- TF0 = 0; //清除TF0标志
- ET0 = 1; //打开T0中断
- EA = 1; //打开总中断
- while (1)
- { //原则:先找到最后一个字的最后一列(15列)的2个字节并扫描
- LOOP:
- if(1 == T0_flag)
- {
- T0_flag = 0;
- DUAN2 = 0x00; //清屏
- DUAN1 = 0x00; //清屏
- DUAN2 = tab1[32 - lie + 2 * zishu]; //此处DUAN2先输出数据
-
- DUAN1 = tab1[32 - lie + 1 + 2 * zishu]; //此处DUAN1后输出数据
- SCAN = tab2[ 15-lie / 2]; //0~15列
-
- lie += 2; //下一列
- if(lie < 32) //一个汉字16列,32个字节的数据
- goto LOOP; //从最外层的if语句跳出来
- lie = 0; //下个字的首列
- //P3 ^= 0xff; //测试用
- if(++times < 100) //一个屏重复显示遍数,1屏维持时间
- goto LOOP; //从最外层的if语句跳出来
- times = 0;
- if(--zishu > 0) //7个字,共(7-1)*16列,无乱码
- goto LOOP; //从最外层的if语句跳出来
- zishu = 6 * 16;
- }
- }
- }
-
- //========================================================================
- // 函数: void Timer0_init(void)
- // 描述: timer0初始化函数.
- // 参数: none.
- // 返回: none.
- // 版本: V1.0, 2015-1-12
- //========================================================================
- void Timer0_init(void)
- {
- TR0 = 0; //停止计数
-
- #if (Timer0_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
- #error "Timer0设置的中断过快!"
-
- #elif ((Timer0_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
- ET0 = 1; //允许中断
- // PT0 = 1; //高优先级中断
- TMOD &= ~0x03;
- TMOD |= 0; //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
- // T0_CT = 1; //计数
- T0_CT = 0; //定时
- // T0CLKO = 1; //输出时钟
- T0CLKO = 0; //不输出时钟
-
- #if (Timer0_Reload < 65536UL)
- T0x12 = 1; //1T mode
- TH0 = (u8)((65536UL - Timer0_Reload) / 256);
- TL0 = (u8)((65536UL - Timer0_Reload) % 256);
- #else
- T0x12 = 0; //12T mode
- TH0 = (u8)((65536UL - Timer0_Reload/12) / 256);
- TL0 = (u8)((65536UL - Timer0_Reload/12) % 256);
- #endif
-
- TR0 = 1; //开始运行
-
- #else
- #error "Timer0设置的中断过慢!"
- #endif
-
- }
-
-
- //========================================================================
- // 函数: void timer0_int (void) interrupt TIMER0_VECTOR
- // 描述: timer0中断函数.
- // 参数: none.
- // 返回: none.[apoyl_aliyunvideo]1074[/apoyl_aliyunvideo]
- // 版本: V1.0, 2015-1-12
- //========================================================================
- void timer0_int (void) interrupt 1
- {
- //P07 = ~P07;
- T0_flag = 1; //T0中断标志置1
- }
-
-
复制代码 5、动画效果
|