SPI控制8_8点阵屏

协议与硬件概述

SPI

SPI是串行外设接口(Serial Peripheral Interface)的缩写。是一种高速的(10Mbps)的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线。
image.png

引脚介绍

  • SCLK:串行时钟线,用于数据的同步。
  • MOSI(Master Output Slave Input):主机输出数据,从机输入数据。
  • MISO(Master Input Slave Output):主机输入数据,从机输出数据。
  • CS:(芯)片选(择)引脚,引脚低电平,从机工作有效;引脚高电平,从机工作无效。

全双工通信的数据输出和数据输入是用同一个时钟信号同步的。时钟信号由主设备通过SCK脚提供。
主机不能同时与多个从机通信。多机通信时,从机之间共用SCLK、MOSI、MISO三个引脚,主机选定与哪一从机通信是拉低该从机的CS片选信号引脚。
在之前的“读取红外键码”中,需要通过设置GPIO初始为高电平,下降沿触发,通过中断处理函数获取有效数据。
在本文中,不需要配置具体的读取过程,只需要同GPIO_Init一样,创建一个结构体,通过Init方法初始化即可。
只是因为,这款开发板配备了相关的硬件。读写操作由硬件自动完成。
同样情况的还有之前出现的USART,开发板也配备了相关的硬件。写操作是直接通过USART_SendData(USART1,Byte);发送一个字节数据。手动实现的字节流和字符串输出函数,也是在调用这个方法。并没有像“显示红外键码”时那样按位操作。
红外键码中需要实现的操作比较多,是因为开发板没有相关协议的设备和寄存器,那个接收器只是用来接收38K滤波,判断0和1的。所以在读取时,可以用1MHz的TIM频率进行输入捕获,而无需关注信号在空中的38KHz,这一部分由硬件已经完成了。

MAX7219

LED点阵屏配备了MAX7219驱动电路。
通过SPI发送的数据就需要这一部分解释到点阵屏上。
硬件对外只暴露了5根线:VCC、GND、DIN、CS、CLK。
只有DIN没有提过:串行数据输入端。
其实就是MOSI,点阵屏没必要向主机发送数据,所以就省掉了MISO这根线。
image.png

  • 在SPI通信中,SDI通常是输出,SDO是输入。

接线时需要将点阵屏的DIN连接到SPISPI_SDI引脚,SPISPI_SDO引脚闲置即可,因为用不到读入数据。

MAX7219和单片计算机连接有三条引线(DIN、CLK、LOAD),采用16位数据串行移位接收方式。即单片机将16位二进制数逐位发送到DIN端,在CLK上升沿到来前准备就绪,CLK的每个上升沿将一位数据移入MAX7219内移位寄存器,当16位数据移入完,在LOAD引脚信号上升沿将16位数据装入MAX7219内的相应位置,在MAX7219内部硬件动态扫描显示控制电路作用下实现动态显示。

文字中的LOAD指的就是原理图中的CS。
image.png
MAX7219是高位先行。先发送的第一个字节会作为地址,将第二个字节的数据写入到地址指向的寄存器。
接下来要做的,就是通过SPI协议,发送两个字节数据,第一个字节是地址,第二个字节是数据。

实现SPI控制LED点阵

SPI部分

SPI并没有直接控制灯的高低电平,而是告诉从机,让从机去实现。

初始化GPIO

先在原理图中找到对应引脚的接口:
image.png

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1,ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;

//MISO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);

//SCK MOSI
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7);

需要注意的就是:

  • 原理图的SPO对应SPI协议的MISO,而非MOSI。

配置SPI

前面提到了,SPI已经被集成到这款开发板中,我们不需要手动去实现具体的位操作过程。
只需要创建一个SPI_InitTypeDef类型的结构体,把结构体的配置项都给填上就可以。

SPI_InitTypeDef	SPI_InitStructure;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA  = SPI_CPHA_1Edge; 
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_Init(SPI1,&SPI_InitStructure);

SPI_Cmd(SPI1,ENABLE);

上面的配置项需要在主机和从机之间提前约定好,才能有效地通信。
对于从机部分,已经焊死了。
我们需要对照从机的文档,对主机进行配置。
通过时钟极性CPOL和时钟相位CPHA来控制主设备的通信模式。
时钟极性CPOL定义时钟空闲状态的电平:

  • CPOL=0:表示SCLK为0时处于空闲态,高电平时为有效态。
  • CPOL=1:表示SCLK为1时处于空闲态,低电平时为有效态。

时钟相位CPHA定义数据的采集时间:

  • CPHA=0:在时钟的第1个跳变沿进行数据采样,第2个边沿发送数据。
  • CPHA=1:在时钟的第2个跳变沿进行数据采样,第1个边沿发送数据。

这两个选项需要对照从机的手册进行配置。
SPI_BaudRatePrescaler:波特率预分频器。SPI挂载在APB2上,为32MHz,需要调整到10Mhz以下。256分频也可以,因为用不到那么快的速度。
image.png
时序图中,空闲状态下,CLK是低电平,第一个上升沿将D15读入:

  • SPI_CPOL_LowSPI_CPHA_1Edge

在时序图中,先到达的是D15,也就是高位。
主机数据的发送顺序也应是先发送高位,配置为SPI_FirstBit_MSB
SPI_CRCPolynomial填写的是CRC校验公示的因子,设置为随机正数。
SPI_NSS设置由硬件控制还是软件控制。在此设置为软件(据课程老师说更常用)。

发送数据

这是SPI部分,看上去跟之前写的USART没有什么区别。

void SPI1_WriteByte(uint8_t TxData)
{
	while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);
	SPI_I2S_SendData(SPI1,TxData);
}

MAX7219部分

上面只是SPI方面的配置和使用。SPI是通信协议,我们要通过这个协议来告诉从机改干什么。
最开始有提到过,但从未使用的CS,现在有用了:在需要通信时拉低,告诉从机,传输要开始了。
需要先初始化相关的引脚:

void MAX7219_CS_Init()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    GPIO_InitTypeDef	GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_SetBits(GPIOA,GPIO_Pin_4);
}

利用位带修改引脚的值。

void Write_MAX7219(uint8_t addr,uint8_t data)
{
	PAout(4) = 0;
    SPI1_WriteByte(addr);
	SPI1_WriteByte(data);
	Delay_ms(1);
	PAout(4) = 1;
}

写完数据,从机未必成功读完,需要给从机一点时间响应。
写成发送两次8字节,是因为这样更加直观。

设置显示选项

点阵屏的亮度、开关也可以设置。
在板载的硬件中,可以通过stm32提供的库函数修改。
在这种外设条件下,主机和从机之间的联系方式只有目前的SPI。
通过SPI发送2字节数据,第一个字节指定地址,第二个字节指定该地址填入的数据。
各内部功能寄存器含义如下:

  • 停机寄存器(地址0CH):当D0=0时,MAX721处于停机状态;当D0=1时,处于正常工作状态。
  • 显示测试寄存器(地址0FH):当D0=0时,MAX7219按设定模式正常工作;当D0=1时,处于测试状态。在该状态下,不管MAX7219处于什么模式,全部LED将按最大亮度显示。
  • 亮度寄存器(地址0AH):亮度可以用硬件和软件两种方法调节。亮度寄存器中的D0~D3位可以控制LED显示器的亮度。
  • 扫描界限寄存器(地址0BH):该寄存器中D0~D3位数据设定值为0~7H,设定值表示显示器动态扫描个数位1~8。
  • 译码方式寄存器(地址09H):该寄存器的8位二进制数的各位分别控制8个LED显示器的译码方式。当高电平时,选择BCD-B译码模式,当低电平时选择不译码模式(即送来数据为字型码)。
  • 内部RAM地址01~08H分别对应于DIG0~DIG7。

也就是说,通过SPI协议向指定的位置写值,实现修改设置和数据。

void MAX7219_Init()
{
	SPI1_Init();
	MAX7219_CS_Init();
	Write_MAX7219(0x0C,0x01);
	Write_MAX7219(0x0F,0x00);
	Write_MAX7219(0x0A,0x0f);
	Write_MAX7219(0x0B,0x07);
	Write_MAX7219(0x09,0x00);
}

对照上面的寄存器含义,该代码的含义为:

  • 停机寄存器:正常工作状态
  • 测试寄存器:按设定正常工作
  • 亮度寄存器:最大亮度显示
  • 扫描界限寄存器:显示到第8列,即全部显示
  • 译码方式寄存器:不译码,送来什么就显示什么

主函数显示笑脸

不同于点亮数码管。点亮数码管需要快速刷新,在一个瞬间只能点亮一个数字。停止刷新就不再显示。
该点阵屏的点亮是通过往寄存器写值,刷新显示操作交由外设硬件。只要寄存器值不变,现实的内容就不变 。我们只需要写一次数据即可。

uint8_t smile[8] = {0x3C,0x42,0xA5,0x81,0xA5,0x99,0x42,0x3C};
int main(void)
{
	MAX7219_Init();
	uint8_t i = 0;
	for(i = 1; i <=8; i++)
	{
		Write_MAX7219(i,smile[i-1]);
	}
	while(1)
	{
	}
}

IMG_20240215_221253.HEIC

参考

  • MAX7219点阵原理图.pdf
  • MAX7219中文.pdf
  • MAX7219原理及其应用.pdf
  • stm32 使用说明+笔记(必读).pdf
  • 32版开发板原理图.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/388444.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年【安徽省安全员C证】考试题库及安徽省安全员C证免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安徽省安全员C证考试题库根据新安徽省安全员C证考试大纲要求&#xff0c;安全生产模拟考试一点通将安徽省安全员C证模拟考试试题进行汇编&#xff0c;组成一套安徽省安全员C证全真模拟考试试题&#xff0c;学员可通过…

ChatGPT高效提问—prompt实践(教师助手)

ChatGPT高效提问—prompt实践&#xff08;教师助手&#xff09; 下面来看看ChatGPT在教育领域有什么用途。 首先设定ChatGPT的角色为高中教师助手。 输入prompt: ChatGPT输出&#xff1a; ​ 教师助手的角色已经设置完成。下面通过几种不同的情景演示如何使用。 1.1.1 制定…

专业130+总分420+厦门大学847信号与系统考研经验厦大信息系统与通信工程,真题,大纲,参考书。

今年很幸运被厦门大学录取&#xff0c;考研专业课847信号与系统130&#xff0c;数二130&#xff0c;总分420&#xff0c;回头看这将近一年的复习&#xff0c;还是有不少经验和大家分享&#xff0c;希望对大家复习有帮助。专业课&#xff1a; 厦门大学847信号与系统在全国各高校…

comfyui换脸学习笔记

目录 Portrait Maker ComfyUI_Lam 人脸融合方案&#xff1a; 圣诞写真工作流 IPadapter faceID/faceID plus/faceID plusV2/Reactor换脸效果对比来 Portrait Maker 核心用的是 EasyPhoto ComfyUI_Lam 人脸融合方案&#xff1a; demo效果还可以&#xff0c;真实效果不是很稳…

Linux操作系统基础(十四):集群服务器搭建

文章目录 集群服务器搭建 一、新增Linux服务器 1、克隆虚拟机 2、修改虚拟机的硬件配置 3、修改虚拟机的网络配置 二、关闭防火墙 1、关闭firewalld 2、关闭SElinux 三、修改主机名 四、修改hosts映射 五、SSH免密登录 六、时钟同步 七、远程文件拷贝 1、从本机拷…

网红铁头因涉黄经历遭全网封杀

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 铁头根本没意识到自己是公众人物了。 知名网红“铁头惩恶扬善”帐号被全网封禁&#xff0c;原因是因为遭到别人举报&#xff0c;1月12日凌晨“铁头”在直播的时候呢&#xff0c;自爆其涉黄经历。 铁头居然自己在直…

二维数组及函数的非函数实现

2024年2月14日 1.请编程实现二维数组的杨慧三角 #include<stdio.h> #include<stdlib.h> #include<string.h> void Yanghui(int n,int (*p)[n]) {for(int i0;i<n;i){for(int j0;j<i;j){if(j0||ij){*(*(pi)j)1;}else{*(*(pi)j)*(*(pi-1)j-1)*(*(pi-1)j)…

HTML快速入门教程

HTML&#xff1a;超文本标记语言&#xff08;Hyper Text Markup Language&#xff09;&#xff0c;是通过标签的形式将内容组织起来然后共享到网络之上供其他电脑访问查看。 大家可以思考一下&#xff0c;怎么将自己电脑上的文件或图片共享给其他电脑&#xff1f; 这时候会说通…

计算机的历史以及原理

一、计算机发展历史 计算机的历史可以追溯到几个世纪前,但现代计算机的起源和发展主要经历了以下几个重要阶段: 1. 机械计算设备:早在17世纪,人们就开始尝试制造可以进行基本数学运算的设备。例如,法国哲学家兼数学家Blaise Pascal在1642年发明了Pascalene,这是一种用于…

洛谷_P1059 [NOIP2006 普及组] 明明的随机数_python写法

这道题的关键在于去重和排序&#xff0c;去重可以联想到集合&#xff0c;那排序直接使用sort方法。 n int(input()) data set(map(int,input().split( ))) data list(data) data.sort() print(len(data)) for i in data:print(i,end )

深度理解实分析:超越公式与算法的学习方法

在数学的学习旅程中&#xff0c;微积分和线性代数为许多学生提供了直观且具体的入门体验。它们通常依赖于明确的公式、算法以及解题步骤&#xff0c;而这些元素往往可以通过记忆和机械练习来掌握。然而&#xff0c;当我们迈入实分析的领域时&#xff0c;我们面临着一种全新的挑…

Nginx实战:日志按天分割

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、方式1&#xff1a;定时任务执行分割脚本 1.分割日志脚本 2.添加定时任务 二、方式2&#xff1a;logrotate配置分割 1.logrotate简单介绍 2.新增切割ngi…

steam搬砖项目赚钱吗?3年亲身经历告诉你真相

csgo饰品交易市场由来已久&#xff0c;且玩家众多&#xff0c;绝对蓝海。而steam搬砖项目就是基于csgo游戏的交易。在steam用美金买入道具、装备和饰品&#xff0c;然后搬砖到国内的网易buff售卖&#xff0c;从中赚取一定的差价和汇率差额。 steam搬砖怎么赚钱&#xff1f;在s…

shumei 滑块 qd参数仿写记录

在对qd参数进行仿写的过程中&#xff0c;由于缺失很多js的基础知识&#xff0c;导致进展一度非常的缓慢&#xff0c;并且不知道自己的方向是不是正确的方向。在不知道自己的方向是否正确的时候&#xff0c;这个时候自己的投入的努力都是畏首畏尾。大概是一种&#xff0c;不知道…

【网站项目】229企业员工薪酬关系系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

在线Windows鼠标主题转换器(ani动态鼠标改为Xcur)

文章目录 前言在哪访问如何使用惨淡的界面简单粗暴的使用方法目前的bug 前言 在这篇文章中&#xff0c;我使用一些方法把转换脚本包装成了在线服务&#xff0c;现在我将说明如何使用服务。 在哪访问 还是说明一下&#xff0c;访问链是这个&#xff1a;https://www.sakebow.c…

51单片机编程基础(C语言):LED点阵屏

点阵屏介绍 类似于数码管&#xff0c;要用到肉眼视觉效应。扫描&#xff0c;才能把每一个LED都能选中&#xff0c;从而显示我们想要的图形&#xff0c;否则&#xff0c; 只能一次点亮一个LED&#xff0c; LED使用 51单片机点阵屏电路图&#xff1a; 实际连接顺序如下图&#…

(06)Hive——正则表达式

Hive版本&#xff1a;hive-3.1.2 一、Hive的正则表达式概述 正则表达式是一种用于匹配和操作文本的强大工具&#xff0c;它是由一系列字符和特殊字符组成的模式&#xff0c;用于描述要匹配的文本模式。 Hive的正则表达式灵活使用解决HQL开发过程中的很多问题&#xff0c;本篇文…

Python dict函数

Python中的字典&#xff08;dict&#xff09;是一种非常重要且灵活的数据结构&#xff0c;它提供了键值对的存储和访问机制。字典函数&#xff08;dict()&#xff09;作为创建字典的工具之一&#xff0c;可以从多种数据结构中创建字典对象。在本文中&#xff0c;将深入探讨dict…

统一数据返回格式 及 可能遇到的问题;统一异常处理

统一数据返回格式 统一数据返回格式就像我们寄快递一样&#xff0c;不管你需要寄的东西具体是什么都需要将它打包到统一的快递箱中。 此时我们需要一个“快递箱”用来将返回的数据“装”在里面。这个类是根据业务情况来自行定义的。 Data public class Resp<T> {//200…