////*************************************************************************
////----------------1.开发环境:Arduino IDE or Visual Studio 2010----------------
////----------------2.使用开发板型号:Arduino UNO ----------------
////----------------3.单片机使用晶振:16M ----------------
////----------------4.店铺名称:大学生电子商铺/小强电子设计 ----------------
////----------------5.淘宝网址:Ilovemcu.taobao.com ----------------
////---------------- 52dpj.taobao.com ----------------
////----------------6.作者:神秘藏宝室 ----------------
////***********************************************************************
#include <Arduino.h>
//IO配置
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12
#define led 13
#define Display_Num_Word 2 //液晶能显示的汉字个数
unsigned char Display_Buffer[8];
unsigned char Display_Swap_Buffer[Display_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 33
const unsigned char Word[Num_Of_Word][32] =
{
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x03,0xBD,0xBD,0xBD,0x83,0xB7,0xB7,0xBB,0xBB,0xBD,0x1C,0xFF,0xFF,/*"R",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC1,0xBD,0xBD,0xBF,0xDF,0xE7,0xFB,0xFD,0xBD,0xBD,0x83,0xFF,0xFF,/*"S"*/
0xFF,0xFF,0xFF,0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0x83,0xFF,0xFF,/*"I",0*/
0xFF,0xFF,0xFF,0xC3,0xBB,0xBB,0x7F,0x7F,0x7F,0x71,0x7B,0xBB,0xBB,0xC7,0xFF,0xFF,/*"G",0*/
0xFF,0xFF,0xFF,0xBF,0x83,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xC7,0xBB,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0x7D,0xBB,0xC7,0xFF,0xFF,/*"O"*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBB,0xBB,0x87,0xBB,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"B",0*/
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0x07,0xBB,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBD,0xBB,0x07,0xFF,0xFF,/*"D",0*/
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0xEF,0xEF,0xE7,0xD7,0xD7,0xDB,0xC3,0xBB,0xBD,0xBD,0x18,0xFF,0xFF,/*"A",0*/
0xFF,0xFF,0xFF,0x01,0x6D,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xC7,0xFF,0xFF,/*"T",0*/
0xFF,0xFF,0xFF,0x18,0xBD,0xBD,0xBD,0xBD,0x81,0xBD,0xBD,0xBD,0xBD,0x18,0xFF,0xFF,/*"H",0*/
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" Space",0*/
0xFF,0xFF,0xFF,0xDF,0xD7,0xB7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xBE,0xBD,0xBB,0xB7,0xB7,0xBB,0xBB,0xBD,0xBD,0xBE,0xBE,0xFF,0xFF,
0xFF,0xFF,0xFF,0x83,0xBD,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBD,0x83,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0x81,0xFF,0xFF,
0xFF,0xFF,0xFF,0x81,0xBF,0xBF,0xBF,0x83,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xFF,0xFF,
0xFF,0xFF,0xFF,0x1F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0x01,0xFF,0xFF,
};
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<30;i++)
{
Display(Display_Swap_Buffer);
}
Display_Word_Count = Shift_Count/16; //计算当前显示第几个字
Calc_Shift();
Shift_Count++;
if(Shift_Count == (Num_Of_Word+Display_Num_Word)*16 ) //移动次数
{
Shift_Count = 0;
}
}
//************************************************************
//清空缓冲区
//************************************************************
void Clear_Display()
{
unsigned char i,j;
for(j = 0 ; j < Display_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) //每行第一个字节移位
{
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((Display_Swap_Buffer[1][i]&0x80) == 0) //每行第二个字节移位
{
Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)&0xfe; //最低位清零
}
else
{
Display_Swap_Buffer[0][16+i] = (Display_Swap_Buffer[0][16+i] << 1)|0x01; //最低位置一
}
if((Display_Swap_Buffer[1][16+i]&0x80) == 0) //每行第三个字节移位
{
Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][i] << 1)&0xfe; //最低位清零
}
else
{
Display_Swap_Buffer[1][i] = (Display_Swap_Buffer[1][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[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)&0xfe; //最低位清零
}
else
{
Shift_Bit = 1;
Display_Swap_Buffer[1][16+i] = (Display_Swap_Buffer[1][16+i] << 1)|0x01; //最低位置一
}
}
temp = (temp>>1)&0x7f;
if(temp == 0x00)
{
temp = 0x80;
}
}
//************************************************************
//num为字数 dat[][32]为字模的名称
//*************************************************************
void Display(const 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];
Display_Buffer[2] = dat[1][i];
Display_Buffer[3] = dat[1][i+16];
Display_Buffer[4] = dat[2][i];
Display_Buffer[5] = dat[2][i+16];
Display_Buffer[6] = dat[3][i];
Display_Buffer[7] = dat[3][i+16];
Send(Display_Buffer[7]);
Send(Display_Buffer[6]);
Send(Display_Buffer[5]);
Send(Display_Buffer[4]);
Send(Display_Buffer[3]);
Send(Display_Buffer[2]);
Send(Display_Buffer[1]);
Send(Display_Buffer[0]);
digitalWrite(LEDARRAY_LAT, HIGH); //锁存数据
delayMicroseconds(0.1);
digitalWrite(LEDARRAY_LAT, LOW);
delayMicroseconds(0.1);
Scan_Line(i); //选择第i行
digitalWrite(LEDARRAY_G, LOW);
delayMicroseconds(100);; //延时一段时间,让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(0);;
digitalWrite(LEDARRAY_LAT, LOW);
delayMicroseconds(0);;
for( i = 0 ; i < 8 ; i++ )
{
if( dat&0x01 )
{
digitalWrite(LEDARRAY_DI, HIGH);
}
else
{
digitalWrite(LEDARRAY_DI, LOW);
}
digitalWrite(LEDARRAY_CLK, HIGH); //上升沿发送数据
delayMicroseconds(0);;
digitalWrite(LEDARRAY_CLK, LOW);
delayMicroseconds(0);;
dat >>= 1;
}
}
-
reduce any delays as much as practicable - if you've reduced them as far as you can, then you have achieved the maximum speed your code allows - if this isn't fast enough, then use a faster MCU, or perhaps your code can be written better, but this is unknown as the code is almost unreadable as it standsJaromanda X– Jaromanda X2019-03-07 02:42:37 +00:00Commented Mar 7, 2019 at 2:42
-
Start by measuring the update time (microseconds). After that you may consider optimizations, for instance, faster digitalWrite, direct port access, SPI, etc.Mikael Patel– Mikael Patel2019-03-07 19:48:03 +00:00Commented Mar 7, 2019 at 19:48
2 Answers
You have 30x loop calling Display() that inside a 16X loop calls eight Send() that inside an 8x loop makes three digital writes each taking at least 2us to complete. At a minimum, only digitalWrite takes 180ms in one pass.
Use SPI if possible or search Google for "arduino speed up digitalWrite" , here is a good article on this.
Also unrolling the 8x loop inside Send() like this can spare some ms:
if( dat&0x01 ) digitalWrite(LEDARRAY_DI, HIGH);
else digitalWrite(LEDARRAY_DI, LOW);
digitalWrite(LEDARRAY_CLK, HIGH); //上升沿发送数据
delayMicroseconds(0);;
digitalWrite(LEDARRAY_CLK, LOW);
delayMicroseconds(0);
if( dat&0x02 ) digitalWrite(LEDARRAY_DI, HIGH);
else digitalWrite(LEDARRAY_DI, LOW);
digitalWrite(LEDARRAY_CLK, HIGH); //上升沿发送数据
delayMicroseconds(0);;
digitalWrite(LEDARRAY_CLK, LOW);
delayMicroseconds(0);
........
if( dat&0x80 ) digitalWrite(LEDARRAY_DI, HIGH);
else digitalWrite(LEDARRAY_DI, LOW);
digitalWrite(LEDARRAY_CLK, HIGH); //上升沿发送数据
delayMicroseconds(0);;
digitalWrite(LEDARRAY_CLK, LOW);
delayMicroseconds(0);
These lines
digitalWrite(LEDARRAY_LAT, HIGH); //锁存数据
delayMicroseconds(0.1);
digitalWrite(LEDARRAY_LAT, LOW);
delayMicroseconds(0.1);
Scan_Line(i); //选择第i行
digitalWrite(LEDARRAY_G, LOW);
delayMicroseconds(100);; //延时一段时间,让LED亮起来。
Reduce the time in the last one. I don't think delayMicroseconds(0.1); does anything, nor does delayMicroseconds(0); found elsewhere.
I see individual pins being controlled
#define LEDARRAY_D 5
#define LEDARRAY_C 6
#define LEDARRAY_B 7
#define LEDARRAY_A 8
#define LEDARRAY_G 9
#define LEDARRAY_DI 10
#define LEDARRAY_CLK 11
#define LEDARRAY_LAT 12
You don't say what the hardware is, but I bet you replace writing individual pins with blasting data out serially to a shift register with 8 MHz SPI clock as a way speed things up. Or if you had a '1284P or '2560 board, then you could do port writes also.