在线时间1445 小时
UID267320
ROHM金币505
注册时间2018-4-27
该用户从未签到
论坛元老
- 最后登录
- 2024-4-18
|
本帖最后由 Angel_YY 于 2019-4-3 20:09 编辑
由于最近正在准备为自家孩子教授编程课程,所以准备为孩子做一个可以编程控制的led阵列显示屏,可以用来显示字母、汉字和简单的图形,甚至可以编程实现贪吃蛇这类简单的游戏,阵列显示定义为16*16的方阵。
主控:Arduino UNO。
驱动:74HC138*2、74HC595*2
LED:SML-S13UT
数量:256颗
在LED驱动部分,使用两片74HC138作为点阵的行控制驱动芯片。
使用两片74HC595作为LED阵列的列控制。
电源采用外接5V,通讯接口通过杜邦线连接到Arduino UNO的数字2~9接口。
Arduino代码如下:
- #include <Arduino.h>
- //IO配置
- #define LEDARRAY_D 2
- #define LEDARRAY_C 3
- #define LEDARRAY_B 4
- #define LEDARRAY_A 5
- #define LEDARRAY_G 6
- #define LEDARRAY_DI 7
- #define LEDARRAY_CLK 8
- #define LEDARRAY_LAT 9
- #define led 13
- #define Num_Word 1 //液晶能显示的汉字个数
- unsigned char Display_Buffer[2];
- unsigned char Display_Swap_Buffer[Num_Word][32]={0}; //显示缓冲区
- bool Shift_Bit = 0;
- bool Flag_Shift = 0;
- unsigned char Timer0_Count = 0;
- unsigned char temp = 0x80;
- unsigned char Shift_Count = 0;
- unsigned char Display_Word_Count = 0;
- #define Num_Of_Word 6
- const unsigned char Word[Num_Of_Word][32] =
- {
-
- 0xFF,0xC0,0xDB,0xDB,0xDB,0xC0,0xFD,0xFB,0xF0,0xEF,0x97,0xFB,0xFD,0xFC,0xE3,0x1F,
- 0xFF,0x07,0xB7,0xB7,0xB7,0x07,0xFF,0xFF,0x0F,0xEF,0xDF,0xBF,0x7F,0xFF,0xFF,0xFF,/*"罗",0*/
- 0xEF,0xEF,0xEF,0xEF,0x03,0xDB,0xDB,0xD8,0xDA,0xB6,0xD6,0xEE,0xD6,0xBB,0x7B,0xFF,
- 0xFF,0x03,0x7B,0x5B,0x6B,0x7B,0x7B,0x01,0xFB,0xBB,0xDB,0xFB,0x01,0xFB,0xD7,0xEF,/*"姆",1*/
- 0xEF,0xEF,0xEF,0xEC,0x03,0xEF,0xEF,0xEA,0xE7,0xCF,0x2F,0xEF,0xEF,0xEF,0xAE,0xD9,
- 0xDF,0xDF,0xDF,0x01,0xDF,0xDF,0xDF,0x03,0x7B,0x77,0xB7,0xAF,0xDF,0xAF,0x77,0xF9,/*"技",2*/
- 0xFE,0xFE,0xFE,0xFE,0x80,0xFC,0xFA,0xFA,0xF6,0xEE,0xDE,0xBE,0x7E,0xFE,0xFE,0xFE,
- 0xFF,0xDF,0xEF,0xEF,0x03,0x7F,0xBF,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFF,0xFF,0xFF,/*"术",3*/
- 0xDF,0xEF,0xEF,0x07,0xF7,0xEF,0xEC,0xC7,0xAB,0x6B,0xEF,0xEF,0xEF,0xEF,0xE8,0xEF,
- 0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0x01,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0x01,0xFF,/*"社",4*/
- 0xFF,0x80,0xBF,0xBF,0xBB,0xBD,0xBE,0xBF,0xBE,0xBD,0xBB,0xB7,0xBF,0xBF,0x80,0xFF,
- 0xFF,0x03,0xFF,0xEF,0xEF,0xDF,0xBF,0x7F,0xBF,0xDF,0xEF,0xEF,0xFF,0xFF,0x01,0xFF,/*"区",5*/
- };
- void setup()
- {
- pinMode(LEDARRAY_D, OUTPUT);
- pinMode(LEDARRAY_C, OUTPUT);
- pinMode(LEDARRAY_B, OUTPUT);
- pinMode(LEDARRAY_A, OUTPUT);
- pinMode(LEDARRAY_G, OUTPUT);
- pinMode(LEDARRAY_DI, OUTPUT);
- pinMode(LEDARRAY_CLK, OUTPUT);
- pinMode(LEDARRAY_LAT, OUTPUT);
- Clear_Display();
- }
- void loop()
- {
- unsigned int i;
- for(i = 0 ; i < 10; i ++) //移动速度设定
- {
- Display(Display_Swap_Buffer);
- }
- Display_Word_Count = Shift_Count/16; //计算当前显示第几个字
- Calc_Shift();
- Shift_Count++;
- if(Shift_Count == (Num_Of_Word+1)*16 ) //移动次数
- {
- Shift_Count = 0;
- }
- }
- //************************************************************
- //清空缓冲区
- //************************************************************
- void Clear_Display()
- {
- unsigned char i,j;
- for(j = 0 ; j < Num_Word; j++)
- {
- for(i = 0 ; i < 32 ;i++)
- {
- Display_Swap_Buffer[j][i] = 0xff; //0=显示 1=不显示
- }
- }
- }
- //************************************************************
- //计算移动数据,存在在缓冲器
- //************************************************************
- void Calc_Shift()
- {
- unsigned char i;
- for(i = 0;i < 16;i++)
- {
- if((Display_Swap_Buffer[0][16+i]&0x80) == 0) //前8位 移位
- {
- Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)&0xfe; //最低位清零
- }
- else
- {
- Display_Swap_Buffer[0][i] = (Display_Swap_Buffer[0][i] << 1)|0x01; //最低位置一
- }
- if(Shift_Count%16 < 8 && Display_Word_Count < Num_Of_Word)
- {
- Shift_Bit = Word[Display_Word_Count][i]&temp;
- }
- else if(Shift_Count%16 < 16 && Display_Word_Count < Num_Of_Word)
- {
- Shift_Bit = Word[Display_Word_Count][16+i]&temp;
- }
- else
- {
- Shift_Bit = 1; //把字移出缓冲区
- }
- if( Shift_Bit == 0) //后8位移位
- {
- Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)&0xfe; //最低位清零
- }
- else
- {
- Shift_Bit = 1;
- Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)|0x01; //最低位置一
- }
-
- }
- temp = (temp>>1)&0x7f;
- if(temp == 0x00)
- {
- temp = 0x80;
- }
- }
- //************************************************************
- //num为字数 dat[][32]为字模的名称
- //*************************************************************
- void Display(unsigned char dat[][32])
- {
- unsigned char i;
- for( i = 0 ; i < 16 ; i++ )
- {
- digitalWrite(LEDARRAY_G, HIGH); //更新数据时候关闭显示。等更新完数据,打开138显示行。防止重影。
-
- Display_Buffer[0] = dat[0][i];
- Display_Buffer[1] = dat[0][i+16];
- Send(Display_Buffer[1]);
- Send(Display_Buffer[0]);
- digitalWrite(LEDARRAY_LAT, HIGH); //锁存数据
- delayMicroseconds(1);
-
- digitalWrite(LEDARRAY_LAT, LOW);
- delayMicroseconds(1);
- Scan_Line(i); //选择第i行
- digitalWrite(LEDARRAY_G, LOW);
-
- delayMicroseconds(300);; //延时一段时间,让LED亮起来。
- }
- }
- //****************************************************
- //扫描某一行
- //****************************************************
- void Scan_Line( unsigned char m)
- {
- switch(m)
- {
- case 0:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 1:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 2:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 3:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 4:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 5:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 6:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 7:
- digitalWrite(LEDARRAY_D, LOW);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 8:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 9:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 10:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 11:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, LOW);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 12:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 13:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, LOW);digitalWrite(LEDARRAY_A, HIGH);
- break;
- case 14:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, LOW);
- break;
- case 15:
- digitalWrite(LEDARRAY_D, HIGH);digitalWrite(LEDARRAY_C, HIGH);digitalWrite(LEDARRAY_B, HIGH);digitalWrite(LEDARRAY_A, HIGH);
- break;
- default : break;
- }
- }
- //****************************************************
- //发送数据
- //****************************************************
- void Send( unsigned char dat)
- {
- unsigned char i;
- digitalWrite(LEDARRAY_CLK, LOW);
- delayMicroseconds(1);;
- digitalWrite(LEDARRAY_LAT, LOW);
- delayMicroseconds(1);;
- for( i = 0 ; i < 8 ; i++ )
- {
- if( dat&0x01 )
- {
- digitalWrite(LEDARRAY_DI, HIGH);
- }
- else
- {
- digitalWrite(LEDARRAY_DI, LOW);
- }
- digitalWrite(LEDARRAY_CLK, HIGH); //上升沿发送数据
- delayMicroseconds(1);;
- digitalWrite(LEDARRAY_CLK, LOW);
- delayMicroseconds(1);;
- dat >>= 1;
-
- }
- }
复制代码 显示效果如下:
|
|