/*-----------------------------------------------
- 名称:双色点阵滚动播放
- 内容:使用hc595驱动双色点阵
- ------------------------------------------------*/
- #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #include //内置函数,一般指一些由编译器实现的函数,比如一些数学函数内部
- //基本都是用内置函数实现的,或者一些无法使用库实现的功能函数,比如调用特殊的汇编指令,
- //目的其实就是更好的利用当前的硬件功能和让编译器实现一些原生的代码做不到的事,编译器
- //看到这些函数调用时会进行特殊处理。c51里的intrins.h包含了一些跟汇编对应的函数,直接
- //翻译成对应的汇编指令,比如左右移位,nop之类的,主要就是避免让你在想用这些汇编指令的
- //功能时却只能内联汇编的情况,这些函数也确实是由编译器实现,c51里就是直接换成对应的汇
- //编指令而不会进行函数调用。
- unsigned char segout[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- unsigned char code tab[96]={
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //空格
- 0x00,0x7E,0xFF,0xC3,0xC3,0xFF,0x7E,0x00, //字符0
- 0x00,0x00,0x43,0xFF,0xFF,0x03,0x00,0x00, //字符1
- 0x00,0x63,0xC7,0xCF,0xDB,0xF3,0x63,0x00, //字符2
- 0x00,0x42,0xDB,0xDB,0xDB,0xFF,0x66,0x00, //字符3
- 0x00,0x1E,0x3E,0x66,0xFF,0xFF,0x06,0x00, //字符4
- 0x00,0xF6,0xF7,0xD3,0xD3,0xDF,0xDE,0x00, //字符5
- 0x00,0x7E,0xFF,0xDB,0xDB,0xDF,0x4E,0x00, //字符6
- 0x00,0xC0,0xC0,0xC7,0xFF,0xF8,0xC0,0x00, //字符7
- 0x00,0x66,0xFF,0xDB,0xDB,0xFF,0x66,0x00, //字符8
- 0x00,0x72,0xFB,0xDB,0xDB,0xFF,0x7E,0x00, //字符9
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 //空格
- };
- // tab[1]2 3 4 5 6 7 8[2]2 3 4 5 6 7 8[3]2 3 4 5 6 7 8[4]2 3 4 5 6 7 8[5]2 3 4 5 6 7 8[6]2 3 4 5 6 7 8[7]2 3 4 5 6 7 8[8]2 3 4 5 6 7 8[9]2 3 4 5 6 7 8[0]2 3 4 5 6 7 8[1]2 3 4 5 6 7 8
- //segout[1] = 0x01 = 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0
- //segout[2] = 0x02 = 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0
- //segout[3] = 0x04 = 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0
- //segout[4] = 0x08 = 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 1 0
- //segout[5] = 0x10 = 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 0
- //segout[6] = 0x20 = 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 1 1 0
- //segout[7] = 0x40 = 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0
- //segout[8] = 0x80 = 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0
- // tab[1]2 3 4 5 6 7 8[2]2 3 4 5 6 7 8[3]2 3 4 5 6 7 8[4]2 3 4 5 6 7 8[5]2 3 4 5 6 7 8[6]2 3 4 5 6 7 8[7]2 3 4 5 6 7 8[8]2 3 4 5 6 7 8[9]2 3 4 5 6 7 8[0]2 3 4 5 6 7 8[1]2 3 4 5 6 7 8
- //segout[1] = 0x01 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[2] = 0x02 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[3] = 0x04 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[4] = 0x08 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[5] = 0x10 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[6] = 0x20 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[7] = 0x40 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- //segout[8] = 0x80 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- /*------------------------------------------------
- 硬件端口定义
- ------------------------------------------------*/
- ***it LATCH = P1^0; //锁存端口
- ***it SRCLK= P1^1; //串行时钟输入端口
- ***it SER = P1^2; //串行数据输入端口
- //公共端信号控制
- ***it LATCH_B = P2^2; //锁存端口
- ***it SRCLK_B = P2^1; //串行时钟输入端口
- ***it SER_B = P2^0; //串行数据输入端口
- /*------------------------------------------------
- uS延时函数
- ------------------------------------------------*/
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延时函数
- ------------------------------------------------*/
- void DelayMs(unsigned char t)
- {
- while(t--)
- {
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*------------------------------------------------
- 发送字节程序
- (带有方向参数,可以选择从高位节写入或者低位写入)
- ------------------------------------------------*/
- void SendByte(unsigned char dat,bit direction)
- {
- unsigned char i,temp;
- if(direction==0)
- temp=0x80;
- else
- temp=0x01;
- for(i=0;i<8;i++)
- {
- SRCLK=0;
- SER=dat&temp;
- if(direction==0)
- dat<<=1;
- else
- dat>>=1;
- SRCLK=1;
- }
- }
- /*------------------------------------------------
- 发送双字节程序
- ------------------------------------------------*/
- void Send2Byte(unsigned char dat1,unsigned char dat2,bit direction)
- {
- SendByte(dat1,direction); //第一个字节将会被送到末尾的U6 595
- SendByte(dat2,direction); //最后一个字节将会被送到首位的U4 595
- }
- /*------------------------------------------------
- 595锁存程序
- ------------------------------------------------*/
- void Out595(void)
- {
- LATCH=1; //边沿触发器 上升沿触发
- _nop_(); //内置函数#include 中的一个空指令
- LATCH=0; //锁存同时控制U4、U6 595 8个输出端和级联端的信号输出
- }
- /*------------------------------------------------
- 发送位码字节程序
- (使用另外一片单独595)
- ------------------------------------------------*/
- void SendSeg(unsigned char dat)
- {
- unsigned char i;
- for(i=0;i<8;i++) //发送字节
- {
- SRCLK_B=0; //公共端U5 74HC595芯片的时钟打开 边沿触发器 上升沿触发
- SER_B=dat&0x80; //dat是一个8个
- dat<<=1;
- SRCLK_B=1; //公共端U5 74HC595芯片的时钟关闭
- }
- LATCH_B=1; //边沿触发器 上升沿触发
- _nop_(); //内置函数#include 中的一个空指令
- LATCH_B=0; //锁存同时控制U4、U6 595 8个输出端和级联端的信号输出
- }
- /*------------------------------------------------
- 主程序
- ------------------------------------------------*/
- void main()
- {
- unsigned char i,k,l;
- while(1)
- {
- for(k=0;k<=88;k++) //k增加一次,显示移动一列,tab【】有96行数列,从左到右一共要移动96-8=88次
- for(l=20;l>0;l--) //延时长度,改变此值可以改变流动速度,约等于0.16ms移动一列
- for(i=0;i<=7;i++) //8列显示
- {
- SendSeg(segout[i]); //指定哪一列公共端接通,0000 0001代表第一列公共端接通
- //Send2Byte(~(*(tab+i+k)),0xff,0); //指定那几行接通,1111 1110代表第一行接通,第1字节代表绿色,第2字节代表红色,第3个数代表正反显示
- Send2Byte(~tab[i+k],0xff,0);
- Out595(); //红绿第几行点亮16组数据串着传输到位后同时并着从16个端口放出
- DelayMs(1); //等待1ms
- Send2Byte(0xff,0xff,0); //发一组空指令让灯熄灭一下,防止重影
- Out595(); //放行
- }
- for(k=0;k<=88;k++) //所有的字符个数
- for(l=20;l>0;l--) //延时长度,改变此值可以改变流动速度
- for(i=0;i<=7;i++) //8列显示
- {
- SendSeg(segout[7-i]);
- //Send2Byte(0xff,~(*(tab+i+k)),1); //红色,反向显示
- Send2Byte(0xff,~tab[i+k],1);
- Out595();
- DelayMs(1);
- Send2Byte(0xff,0xff,0);//delay(10); //防止重影
- Out595();
- }
- }
- }
复制代码
|