以32*64点阵屏为例,详解LED点阵屏驱动全过程
首先要了解LED点阵屏幕的显示原理。
一般LED点阵屏在某一时间段内只能点亮某一行或者某一列,因为人的眼睛只有24帧速度,只要屏幕速度超过这个值,我们看到的是一个连续完整的画面。一般拿手机的高频率拍摄模式照LED点阵屏能很明显的发现屏幕是在一行一行的显示。
我用的这个屏幕32*64的单色点阵屏。
LED点阵屏的行是由行驱动芯片控制,我用的这个屏幕上有两个行驱动芯片,行驱动芯片一般是三八译码器的形式控制。两个行驱动芯片级联,通过HUB75-B接口上A,B,C,D引脚控制,通过这几个引脚的电平高低表示二进制,四个引脚最多能表示16种状态。但是我这个屏幕是32行的,怎么办呢?屏幕的行是两两接在一起的,也就是说当第0行低电平的时候,第16行也是低电平,当第一行接低电平的时候,第17行也是低电平。
LED点阵屏的列是由列驱动芯片控制,也就是真正输出数据的是这些列驱动芯片,我用的屏幕上的列驱动芯片是16输出,单色屏,所以有8个列驱动芯片,4个控制上面16行,剩下四个控制下面16行。如果是双色屏,他的数量会翻倍。
HUB75-B接口
//定义一个数组存放取模后的数据
uint8_t spi_send_buf[32][8] //屏幕是32*64,一共有32行,每一行64个点,8个字节
程序运行逻辑
将这个函数在循环里或者在任务里面调用就好了
//下面是LED屏幕刷新的大概流程,只要把下面的函数在循环里面调用就好了
//如果用RTOS的话,在任务里面调用就好了,延时500us
uint8_t Line =0; //行变量,遍历32行
void LED_SCAN_Func(void)
{
SPI_send_line(spi_send_buf[Line][0]); //往屏幕传数据
data_lock_out(Line); //数据锁存并输出
Line ++; //行自增
if(Line==32)Line =0; //一共32行,扫描一遍,重新开始
}
//该函数的作用是数锁存
//具体要看屏幕列驱动芯片的时序
void data_lock_out(uint16_t LINE)
{
GPIO_SetBits(GPIOB, LED_LAT); //HUB75-B 的 LAT拉高 ,数据传入锁存
GPIO_ResetBits(GPIOB, LED_LAT); //LAT拉低
GPIO_SetBits(GPIOB, LED_OE); //OE拉高 ,不输出
if (LINE > 15)
{
LINE -=16;
}
LED_line_ctrl (LINE); //换行
GPIO_ResetBits(GPIOB, LED_OE); //OE拉低 输出
}
//每次发送需要发一整行的内容,每一行8个字节,通过spi发送
void SPI_send_line(uint8_t *data)
{
int i =0;
for(i=0;i<8 ; i++) //循环8次,发送8个字节
{
SPI_WriteByte(data[i]); //发送数据
}
}
下面的函数是控制HUB75-B的A,B,C,D引脚,实现换行
void LED_line_ctrl(uint8_t Num)
{
switch(Num)
{
case 0: //控制引脚A、B、C、D状态:0000
GPIO_ResetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 1: //控制引脚A、B、C、D状态:0001
GPIO_SetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 2: //控制引脚A、B、C、D状态:0010
GPIO_ResetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 3: //控制引脚A、B、C、D状态:0011
GPIO_SetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 4: //控制引脚A、B、C、D状态:0100
GPIO_ResetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 5: //控制引脚A、B、C、D状态:0101
GPIO_SetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 6: //控制引脚A、B、C、D状态:0110
GPIO_ResetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 7: //控制引脚A、B、C、D状态:0111
GPIO_SetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_ResetBits(GPIOB, LED_D);
break;
case 8: //控制引脚A、B、C、D状态:1000
GPIO_ResetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 9: //控制引脚A、B、C、D状态:1001
GPIO_SetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 10: //控制引脚A、B、C、D状态:1010
GPIO_ResetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 11: //控制引脚A、B、C、D状态:1011
GPIO_SetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_ResetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 12: //控制引脚A、B、C、D状态:1100
GPIO_ResetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 13: //控制引脚A、B、C、D状态:1101
GPIO_SetBits(GPIOC, LED_A);
GPIO_ResetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 14: //控制引脚A、B、C、D状态:1110
GPIO_ResetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
case 15: //控制引脚A、B、C、D状态:1111
GPIO_SetBits(GPIOC, LED_A);
GPIO_SetBits(GPIOC, LED_B);
GPIO_SetBits(GPIOC, LED_C);
GPIO_SetBits(GPIOB, LED_D);
break;
default:
break;
}
}
头文件里的一些定义放在下面这一段
/******HUB75-B公头接口引脚定义***********/
//A-->单片机PC13
#define LED_A GPIO_Pin_13 //HUB75-B:行电源控制信号A (9号引脚)
//B-->单片机PC14
#define LED_B GPIO_Pin_14 //HUB75-B:行电源控制信号B (10号引脚)
//C-->单片机PC15
#define LED_C GPIO_Pin_15 //HUB75-B:行电源控制信号C (11号引脚)
//D--》单片机PB9
#define LED_D GPIO_Pin_9 //HUB75-B:行电源控制信号D (12号引脚)
//LED_LAT-->单片机PB8
#define LED_LAT GPIO_Pin_8 //HUB75-B:数据锁存信号 (14号引脚)
//LED_OE-->单片机PB5
#define LED_OE GPIO_Pin_5 //HUB75-B:使能信号 (15号引脚)
//LED_CLEK-->单片机PA5
#define LED_CLK GPIO_Pin_5 //HUB75-B:时钟信号 (13号引脚)
我觉得我这个方法是全网最简单,效率最高的
本来写了几千个字的文章忘记保存全没了,第二次就不想写了,后面再补吧,不知道有没有人看这个,如果有人想要的话,私信我把源码发你。内容后期再补