STM32F103C8T6驱动MAX7219点阵屏

一、说明

刚刚好在学习这个板子,总结了其他几篇文章,其中一些坑踩的我很难受,特别是一些时序的软件实现,想想都已经踩坑了,写下来一起交流学习吧。

参考文章:

STM32使用MAX7219控制点阵屏和点阵屏级联_stm32 max7219-CSDN博客

使用STM32的硬件SPI及软件模拟SPI的方式驱动MAX7219点阵_stm32 max7219-CSDN博客

stm32之点阵模式_stm32点阵-CSDN博客

51单片机LED8*8点阵显示坤坤跳舞打篮球画面_51单片机哥哥跳舞-CSDN博客 

二、硬件结构

1、引脚结构

  • V+:正电源
  • GND:地
  • CLK:移位脉冲输入端
  • DIN:串行数据输入端
  • CS:片选

我们使用的是共阴极的点阵屏,因为有芯片控制,我们只要配置对应的寄存器即可

下面是一些引脚说明,这个支持SPI通信,不过没有主机接收的线路,只有主机发送,如下图MOSI

2、内部结构

看这个图,移位寄存器16位的,所以我写代码的时候,也是写够16位才把cs切换为高电平(低电平有效)。

  • 高位无所谓,给0吧。反正无效。然后发送的数据帧大概就是无效位+地址位+数据位
  • 其实每一行对应一个寄存器存储数据,存着8位数据,寄存器具体大小手册没有说,不用在意,知道8位就好。因为数据帧里面也规定了,数据位8位
  • 所以,我都是每次发送8位,到第16位之后,CS切换为高电平,这个点比较重要。不单是使能和失能,还会存储对应数据。

3、寄存器分布

这个的理解就是,8个REG_x,对应8行,然后每个寄存器存储8位数据,根据我的实验,比如第一行是1111 1111 那么第一行就全亮,0不亮,1亮的意思。

然后剩下的一些就是配置寄存器的内容了。

4、时序图

看蓝色部分就行,CS低电平的时候才工作,时钟上升沿发数据,下降沿变化数据。

5、板子引脚的配置

都配置普通推挽模式就行,其实CS也可以配置上拉,我是为了简单。

三、代码

LatticeLed_Ins.h

#ifndef __LARRICELED_INS_H
#define __LARRICELED_INS_H


#define CLK_PIN GPIO_Pin_3
#define CS_PIN GPIO_Pin_4
#define DIN_PIN GPIO_Pin_5


#define DECODEMODE 		0X09	//编码模式
#define INTENSITY  		0X0a	//亮度
#define SCANLIMT		0x0b	//扫描寄存器个数
#define SHUTDOWN   		0X0c	//关闭寄存器
#define DISPLAYTEST		0X0f	//显示测试


#define CLK(x)			GPIO_WriteBit(GPIOA , CLK_PIN, (BitAction)(x));
#define CS(x)			GPIO_WriteBit(GPIOA , CS_PIN, (BitAction)(x));
#define DIN(x)			GPIO_WriteBit(GPIOA , DIN_PIN, (BitAction)(x));


#endif

LatticeLed.h

#ifndef __LatticeLed_H
#define __LatticeLed_H

void LatticeLedInit(void);
void LatticeLedWrite_byte(uint8_t data);
void LatticeLed_Write_Command(uint8_t addr,uint8_t data);
void StartWrite(void);
void StopWrite(void);
void LatticeLedCLS(void);


#endif

LatticeLed.c

#include "stm32f10x.h"                  // Device header
#include "LatticeLed_Ins.h"


void StartWrite(void)
{
	CS(0);   
}

void StopWrite(void)
{
	CS(1);   
}
void LatticeLedWrite_byte(uint8_t data)//单字节写入
{
	uint8_t i=0;
	for(i=8;i>0;i--)
	{
		if(data&0x80)//高位先行
		{
			DIN(1);
			
		}
		else
		{
			DIN(0);
		}
		CLK(1);
		CLK(0);
		data=data<<1;//最高位左移以为 次高位变最高位
		
		
	}
	
}


void LatticeLed_Write_Command(uint8_t addr,uint8_t data)//写命令
{
	CLK(0);
	StartWrite(); //确保CS处于低电平
	LatticeLedWrite_byte(addr);//寄存器地址
	LatticeLedWrite_byte(data);//需要写入的数据
	StopWrite();
	
	
}


void LatticeLedInit(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = CLK_PIN | CS_PIN| DIN_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//初始化电平确保一下时序
	StopWrite();
	CLK(0);
	
	
	
	LatticeLed_Write_Command(DECODEMODE,0X00);   //译码方式:无
	
	LatticeLed_Write_Command(INTENSITY,0X01);    //亮度 
	
	LatticeLed_Write_Command(SCANLIMT,0X07);     //扫描界限;8个数码管显示
	
	LatticeLed_Write_Command(SHUTDOWN,0X01);    //掉电模式:0,普通模式:1
   
	LatticeLed_Write_Command(DISPLAYTEST,0X00);  //显示测试:1;测试结束,正常显示:0
   
	
	
	
}
void LatticeLedCLS(void)
{
	
	uint8_t i;
 
    for(i=8;i>=1;i--)
	{
		LatticeLed_Write_Command(i,0x00);
	}

}
 


Delay.h 

#ifndef __DELAY_H
#define __DELAY_H

void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

#endif

Delay.c

#include "stm32f10x.h"

/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

坤坤爱篮球

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LatticeLed.h"

const uint8_t  myarray[4][8]={//38行,8列
{0x00,0x00,0x1B,0x3C,0xF8,0xFC,0x3B,0x00},{0x00,0x1B,0x3C,0xFC,0xFF,0x3A,0x00,0x00},
{0x00,0x00,0x0B,0x1C,0x7C,0x7E,0x1B,0x00},{0x00,0x1B,0x3C,0xFC,0xFF,0x3A,0x00,0x00}
};
void show_number(uint8_t j)
{ 
	uint8_t i;
    for(i=1;i<9;i++)//1到8行
	{
		LatticeLed_Write_Command(i,myarray[j][i-1]);  //行1-8地址   列数据
		
	}

  
}



int main(void) {
	
    LatticeLedInit();
    LatticeLedCLS();

   
	uint8_t i;
	
    while (1) 
	{
        for(i=0;i<4;i++)
		{
			show_number(i);
			Delay_ms(100);
		}
    }
	
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的宾哥哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值