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.mzph.cn/news/684423.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

备战蓝桥杯---图论之最短路Bellman-Ford算法及优化

目录 上次我们讲到复杂度为&#xff08;nm)logm(m为边&#xff0c;n为点&#xff09;的迪杰斯特拉算法&#xff0c;其中有一个明显的不足就是它无法解决包含负权边的图。 于是我们引进Bellman-Ford算法。 核心&#xff1a;枚举所有的点&#xff0c;能松弛就松弛&#xff0c;直…

利用修改邻接变量

资源下载 【免费】突破密码认证程序&#xff08;修改邻接变量&#xff09;资源-CSDN文库 资源内容 源码 /*****************************************************************************To be the apostrophe which changed "Impossible" into "Im possib…

【AI绘画】硬核解读Stable Diffusion(完整版) 小白必收藏!!!

手把手教你入门绘图超强的AI绘画&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。给大家带来了全新保姆级教程资料包 &#xff08;文末可获取&#xff09; 2022年可谓是AIGC&#xff08;AI Generated Content&#xff09;元年&#xff0c;上半年…

爱上JVM——常见问题:JVM组成(一)

1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&…

Spring AOP的实现方式

AOP基本概念 Spring框架的两大核心&#xff1a;IoC和AOP AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程&#xff09; AOP是一种思想&#xff0c;是对某一类事情的集中处理 面向切面编程&#xff1a;切面就是指某一类特定的问题&#xff0c;所以AOP可…

ChatGPT高效提问—prompt实践(白领助手)

ChatGPT高效提问—prompt实践&#xff08;白领助手&#xff09; ​ 随着社会的不断发展&#xff0c;白领的比例越来越高。白领的工作通常较为繁忙&#xff0c;需要管理复杂的项目。工作量大、要求高、任务紧急&#xff0c;时间分配不当部分可能导致工作效率低下&#xff0c;任…

问题:人的安全知识和技能是天生的。() #媒体#知识分享#学习方法

问题&#xff1a;人的安全知识和技能是天生的。&#xff08;) 人的安全知识和技能是天生的。() 参考答案如图所示 问题&#xff1a;&#xff08;&#xff09;是党和国家的根本所在、命脉所在&#xff0c;是全国各族人民的利益所在、幸福所在。 A.人民当家作主 B.坚持和完善…

OpenAI突然发布首款文生视频模型——Sora;谷歌发布Gemini 1.5,迈向多模态大模型新时代

&#x1f989; AI新闻 &#x1f680; OpenAI突然发布首款文生视频模型——Sora 摘要&#xff1a;OpenAI发布了首个AI视频模型Sora&#xff0c;可以根据文字指令生成神级效果的长视频&#xff0c;引发了广泛关注和震惊。 Sora模型通过深入理解语言和图像&#xff0c;能够创造出…

代码随想录算法训练营第二十七天|贪心算法理论基础,455.分发饼干,376. 摆动序列,53. 最大子序和

系列文章目录 代码随想录算法训练营第一天|数组理论基础&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代码随想录算法训练营第二天|977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II 代码随想录算法训练营第三天|链表理论基础&#xff…

中国电子学会2023年12月份青少年软件编程Scratch图形化等级考试试卷三级真题(含答案)

2023-12 Scratch三级真题 分数&#xff1a;100 题数&#xff1a;31 测试时长&#xff1a;60min 一、单选题(共18题&#xff0c;共50分) 1.运行左图程序&#xff0c;想得到右图中的效果&#xff0c;红色框应填写的数值是&#xff1f;&#xff08;D&#xff09;(3分) A.12 …

《合成孔径雷达成像算法与实现》Figure6.18

% rho_r c/(2*Fr)而不是rho_r c/(2*Bw) % Hsrcf exp函数里忘记乘pi了 clc clear close all参数设置 距离向参数设置 R_eta_c 20e3; % 景中心斜距 Tr 2.5e-6; % 发射脉冲时宽 Kr 20e12; % 距离向调频率 alpha_os_r 1.2; …

【题解】—— LeetCode一周小结6

【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结5 5.跳跃游戏 VI 题目链接&#xff1a;1696. 跳跃游戏 VI 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 一开始你在下标 0 处。每一步&#xff0c;你最多可以往前跳 k 步&#xff0c;…

蓝桥杯电子类单片机提升三——NE555

目录 单片机资源数据包_2023 一、NE555和定时器工作模式 1.NE555的介绍 2.定时器的计数模式 二、NE555频率读取代码的实现 1.定时器0初始化 2.通过读取TH0和TL0来读取频率 3.通过中断读取频率 三、完整代码演示 通过读取TH0和TL0来读取频率 main.c 通过中断读取频…

qml中解决Page控件头部元素Margin不生效的问题

0、想要的效果 1、问题描述 经测试&#xff1a;Page的头部无法完美的进行左右边距设置&#xff0c;leftMargin可以&#xff0c;rightMargin不可以。。。。 Page {// ...header: Frame {id: headerheight: 70// 必须首先锚定位&#xff0c;然后设置边距才生效padding: 0anchor…

QlikSense: 通过 Insight Advisor 创建可视化

通过 Insight Advisor 创建可视化 探索你的数据&#xff0c;并通过 Insight Advisor 分析类型 和 Insight Advisor 搜索创建可视化。Insight Advisor 使用 Qlik cognitive engine 和应用程序的逻辑模型为您创建可视化。单击工作表中的 Insight Advisor 以使用 Insight Advisor…

构建智慧交通平台:架构设计与实现

随着城市交通的不断发展和智能化技术的迅速进步&#xff0c;智慧交通平台作为提升城市交通管理效率和水平的重要手段备受关注。本文将探讨如何设计和实现智慧交通平台的系统架构&#xff0c;以应对日益增长的城市交通需求&#xff0c;并提高交通管理的智能化水平。 ### 1. 智慧…

【电路笔记】-LR串联电路

LR串联电路 文章目录 LR串联电路1、概述2、示例1所有线圈、电感器、扼流圈和变压器都会在其周围产生磁场,由电感与电阻串联组成,形成 LR 串联电路。 1、概述 在本节有关电感器的第一个文章中,我们简要介绍了电感器的时间常数,指出流过电感器的电流不会瞬时变化,而是会以恒…

Covalent Network(CQT)与卡尔加里大学建立合作,共同推动区块链技术创新

Covalent Network&#xff08;CQT&#xff09;作为领先的 Web3 数据索引器和提供者&#xff0c;宣布已经与卡尔加里大学达成了具备开创性意义的合作&#xff0c;此次合作标志着推动区块链数据研究和可访问性的重要里程碑。卡尔加里大学是首个以验证者的身份加入 Covalent Netwo…

如何在30天内使用python制作一个卡牌游戏

如何在30天内使用python制作一个卡牌游戏 第1-5天&#xff1a;规划和设计第6-10天&#xff1a;搭建游戏框架第11-20天&#xff1a;核心游戏机制开发第21-25天&#xff1a;游戏界面和用户体验第26-30天&#xff1a;测试和发布附加建议游戏类型游戏规则设计界面设计技术选型第6-…

【Qt】环境安装与初识

目录 一、Qt背景介绍 二、搭建Qt开发环境 三、新建工程 四、Qt中的命名规范 五、Qt Creator中的快捷键 六、QWidget基础项目文件详解 6.1 .pro文件解析 6.2 widget.h文件解析 6.3 widget.cpp文件解析 6.4 widget.ui文件解析 6.5 main.cpp文件解析 七、对象树 八、…