个人做电子商务网站创意网红蛋糕
个人做电子商务网站,创意网红蛋糕,二维码生成器小程序,传奇霸业官网下载基于MAX7219的四合一点阵模块驱动移植与显示实战#xff1a;以MSPM0G3507开发板为例
最近在做一个需要显示信息的小项目#xff0c;手头正好有块TI的MSPM0G3507开发板和一个基于MAX7219的四合一点阵模块。网上找了一圈#xff0c;发现针对这个具体组合的教程不多#xff0c…基于MAX7219的四合一点阵模块驱动移植与显示实战以MSPM0G3507开发板为例最近在做一个需要显示信息的小项目手头正好有块TI的MSPM0G3507开发板和一个基于MAX7219的四合一点阵模块。网上找了一圈发现针对这个具体组合的教程不多自己摸索着移植了一遍过程还挺有意思的。今天就把这个完整的驱动移植和显示过程分享出来如果你也在用MSPM0系列芯片想驱动LED点阵屏跟着这篇教程一步步来应该能少走不少弯路。咱们的目标很明确让MSPM0G3507成功驱动这个四合一点阵模块并且能显示我们想要的数字和汉字。整个过程我会拆解成几个部分先搞清楚MAX7219是个啥、怎么通信然后进行硬件连接和引脚配置接着编写完整的驱动代码最后用实际显示效果来验证。放心我会尽量把每个步骤都讲透包括我踩过的一些坑。1. 认识我们的“演员”MAX7219与四合一点阵模块在动手写代码之前咱们得先了解要驱动的对象。这个点阵模块的核心是MAX7219芯片它是个“多面手”。MAX7219是什么你可以把它理解为一个专为LED显示服务的“大管家”。它采用串行通信只需要3根线能直接连接微处理器和最多8位7段数码管或者像我们用的这种8x8点阵屏一个芯片管一个点阵。它内部自带扫描电路、驱动电路还有一个8x8的小内存静态RAM用来存放要显示的数据。最方便的是它支持多个芯片级联所以一个模块上四片MAX7219级联起来就能控制四个8x8点阵组成一个更大的显示区域。这个芯片功耗很低有关闭模式亮度可以调节还能设置扫描的位数1-8位。对我们来说最大的好处就是只用MCU的3个IO口就能驱动起整个四合一模块而且显示稳定无闪烁。模块关键参数干活前先看说明书工作电压4 - 5.5V 接开发板的5V引脚正合适工作电流8 - 330mA 动态变化亮度越高电流越大扫描速率500 - 1300Hz 人眼完全感觉不到闪烁通信协议串行通信SPI类似但需要自己控制时序接口5Pin 排针2.54mm间距模块的资料和驱动例程可以在提供的链接里下载里面包含了数据手册和参考代码是我们移植的重要依据。2. 核心原理MAX7219如何“听令行事”要让MAX7219干活我们必须按照它规定的“语言”通信时序和“指令集”寄存器配置来。这部分稍微有点枯燥但理解了后面写代码就一马平川了。2.1 通信时序三个IO口的舞蹈MAX7219通过DIN数据输入、CLK时钟、CS片选三根线与MCU对话。它的通信规则是这样的片选CS是总开关任何时候发送或接收数据都必须先把CS引脚拉低置0。数据传输完成后在特定的时刻再拉高。数据锁存靠上升沿数据是在CLK时钟的上升沿从低到高跳变那一刻被MAX7219读进去的。所以我们要保证在CLK上升沿到来时DIN上的数据已经是稳定且正确的。完整的发送流程拉低CS。在CLK为低电平时准备好1位数据放到DIN上。然后将CLK拉高产生上升沿MAX7219读取该位数据。重复以上步骤发送完16位数据。在第16个CLK上升沿之后再将CS拉高。这个拉高的动作就像盖个章告诉芯片“刚才发的16位数据有效请执行吧”如果CS拉高得太早或太晚数据都可能丢失。注意DIN上的数据必须在CLK上升沿之前就准备好并保持稳定不能在上升沿发生的瞬间变化。2.2 数据格式16位“指令包”每次通信我们都要发送一个16位的数据包。这16位不是胡乱填的它有固定的结构位域 (Bit)D15-D12D11-D8D7-D0含义无效位寄存器地址数据简单来说高4位没用中间4位告诉MAX7219“我要设置哪个寄存器”低8位是“我要给这个寄存器设置什么值”。例如我们要设置“译码方式寄存器”地址是0x09并且希望所有数码管都不使用BCD译码对于点阵屏我们通常选择不译码直接控制每个LED那么发送的16位数据就是0x09地址 0x00数据。2.3 关键寄存器简介MAX7219内部有好几个寄存器我们驱动点阵屏主要用到下面几个译码方式寄存器 (地址: 0x09)决定是否对数据进行BCD译码把数字0-9转成7段码。对于点阵屏我们不需要译码直接发送控制每个点的数据所以通常设置为0x00所有位不译码。亮度寄存器 (地址: 0x0A)控制LED的亮度值从0x00到0x0F0x00最暗0x0F最亮。扫描界限寄存器 (地址: 0x0B)设置扫描显示多少位行。我们用的是8x8点阵所以设置为0x07表示扫描0-7行共8行。关机模式寄存器 (地址: 0x0C)0x00进入关机低功耗模式0x01进入正常操作模式。上电后需要设置为0x01。显示测试寄存器 (地址: 0x0F)0x01会让所有LED以最大亮度点亮用于测试模块好坏。正常显示时应设置为0x00。点阵显示的本质8x8点阵可以看成8行Rowx 8列Column。MAX7219内部有8个寄存器地址从0x01到0x08分别对应第1行到第8行。向地址0x01写入一个字节8位这个字节的每一位就控制着第1行上8个列LED的亮灭1亮/0灭取决于共阴/共阳和驱动逻辑。通过快速扫描这8行就能显示出图形或字符。3. 硬件连接与工程配置理论准备就绪现在开始动手。我使用的是TI MSPM0G3507开发板。3.1 引脚连接模块需要连接5根线如果不级联更多模块只需要接5个引脚点阵模块引脚MSPM0G3507开发板引脚说明VCC5V电源正极GNDGND电源地DINPA27串行数据输入CSPA26片选低电平有效CLKPA25串行时钟提示引脚选择不是固定的你可以根据自己板子的空闲IO口来调整只要在代码里对应修改即可。我选择PA25-PA27只是因为它们挨在一起布线方便。3.2 使用SysConfig图形化配置引脚MSPM0的SDK提供了SysConfig工具图形化配置引脚非常方便能自动生成初始化代码。在CCS或你的IDE工程中找到并双击empty.syscfg文件或其他你项目中的.syscfg文件。在打开的界面中点击ADD按钮添加GPIO配置。我们需要添加3个GPIO配置分别对应DIN、CS、CLK三个引脚。对每个配置进行设置Pin选择对应的引脚号例如PA25。Direction选择Output输出。Initial Output Value初始输出电平可以设为Low。Drive Strength驱动强度默认即可。其他引脚如PA26、PA27也按同样方法配置按下Ctrl S保存配置文件。点击编译按钮。这里可能会弹出一些警告通常可以忽略只要配置保存成功就行。保存编译后SysConfig会自动在ti_msp_dl_config.h文件中生成这些引脚的宏定义。我们的工程已经包含了board.h而board.h又包含了ti_msp_dl_config.h所以后续我们直接在代码里#include “board.h”就能使用这些定义好的引脚了。4. 手把手编写驱动代码BSP层理解了原理配置好了硬件最核心的代码部分来了。我们在工程里新建一个BSP板级支持包文件夹专门放这些外设驱动。4.1 头文件定义 (bsp_DotMatrix.h)头文件主要完成宏定义和函数声明。#ifndef _BSP_DOTMATRIX_H_ #define _BSP_DOTMATRIX_H_ #include board.h // 引脚操作宏定义方便读写 // 这些宏依赖于SysConfig生成的宏如DotMatrix_PORT, DotMatrix_CLK_PIN等 #define DotMatrix_CLK(X) ( X ? DL_GPIO_setPins(DotMatrix_PORT,DotMatrix_CLK_PIN) : DL_GPIO_clearPins(DotMatrix_PORT,DotMatrix_CLK_PIN) ) #define DotMatrix_DIN(X) ( X ? DL_GPIO_setPins(DotMatrix_PORT,DotMatrix_DIN_PIN) : DL_GPIO_clearPins(DotMatrix_PORT,DotMatrix_DIN_PIN) ) #define DotMatrix_CS(X) ( X ? DL_GPIO_setPins(DotMatrix_PORT,DotMatrix_CS_PIN) : DL_GPIO_clearPins(DotMatrix_PORT,DotMatrix_CS_PIN) ) // 函数声明 void Write_DotMatrix(uint8_t address,uint8_t dat); void Write_DotMatrix_AllOff(void); void DotMatrix_Init(void); void DotMatrix_display(uint8_t* show1, uint8_t* show2, uint8_t* show3, uint8_t* show4); #endif4.2 核心驱动实现 (bsp_DotMatrix.c)这是重头戏我们一步步来写。第一步实现最基本的字节写入函数这个函数严格按照我们前面讲的时序向MAX7219写入一个字节8位数据。void Write_DotMatrix_byte(uint8_t dat) { uint8_t i; // 1. 拉低CS开始通信 DotMatrix_CS(0); // 2. 循环发送8位数据从最高位(MSB)开始 for(i8; i1; i--) { // 2.1 先将CLK拉低为产生上升沿做准备 DotMatrix_CLK(0); // 2.2 根据当前要发送的位最高位设置DIN电平 if( dat 0x80 ) // 检查最高位是否为1 { DotMatrix_DIN(1); } else { DotMatrix_DIN(0); } // 2.3 将数据左移一位为发送下一位做准备 dat dat 1; // 2.4 将CLK拉高产生上升沿MAX7219在此时采样DIN数据 DotMatrix_CLK(1); // 注意这里没有延时因为GPIO操作本身很快符合MAX7219时序要求。 // 如果芯片速度差异大可能需要插入微小延时nop。 } // 3. 注意这个函数里没有拉高CS因为一次完整的16位命令需要两个字节。 // CS的拉高操作会在上层函数控制。 }第二步实现16位命令写入函数MAX7219需要16位数据其中高8位是地址低8位是数据。void Write_DotMatrix(uint8_t address, uint8_t dat) { // 拉低CS开始一次完整的命令传输 DotMatrix_CS(0); // 先发送地址高8位 Write_DotMatrix_byte(address); // 再发送数据低8位 Write_DotMatrix_byte(dat); // 发送完毕拉高CS锁存数据并执行命令 DotMatrix_CS(1); }第三步实现数据锁存函数用于级联当多个MAX7219级联时我们需要发送完所有芯片的数据后再统一锁存更新显示避免显示错乱。这个函数通过一个CS的跳变高-低来实现。void DotMatrix_Lock(void) { DotMatrix_CS(1); DotMatrix_CS(0); }第四步实现四片点阵的显示函数这是应用层最常用的函数。我们有一个四合一模块即4个级联的MAX7219。要显示一个画面需要分别给4个芯片的1-8行发送数据。void DotMatrix_display(uint8_t* show1, uint8_t* show2, uint8_t* show3, uint8_t* show4) { uint8_t i 0; for(i 1; i 9; i) // 循环1~8行 { // 给第1个芯片的第i行发送数据 show1[i-1] Write_DotMatrix_byte(i); // 发送行地址 Write_DotMatrix_byte(show1[i-1]); // 发送该行数据 // 给第2个芯片的第i行发送数据 show2[i-1] Write_DotMatrix_byte(i); Write_DotMatrix_byte(show2[i-1]); // 给第3个芯片的第i行发送数据 show3[i-1] Write_DotMatrix_byte(i); Write_DotMatrix_byte(show3[i-1]); // 给第4个芯片的第i行发送数据 show4[i-1] Write_DotMatrix_byte(i); Write_DotMatrix_byte(show4[i-1]); // 一行数据发送给四个芯片后统一锁存更新 DotMatrix_Lock(); } }注意show1到show4是四个数组每个数组有8个元素分别对应一个8x8点阵的8行数据。show1[0]是第一个点阵第一行的数据以此类推。第五步初始化函数上电后必须对MAX7219进行正确的初始化设置它才能正常工作。void DotMatrix_Init(void) { unsigned int i 0; // 1. 设置译码方式不译码 (0x00) for(i 0; i 4; i) // 对4个芯片进行相同设置 { Write_DotMatrix(0x09, 0x00); } DotMatrix_Lock(); // 更新设置 // 2. 设置亮度 (0x01 为较低亮度范围0x00~0x0F) for(i 0; i 4; i) { Write_DotMatrix(0x0a, 0x01); } DotMatrix_Lock(); // 3. 设置扫描界限扫描所有8行 (0x07) for(i 0; i 4; i) { Write_DotMatrix(0x0b, 0x07); } DotMatrix_Lock(); // 4. 设置正常工作模式 (0x01)退出关机模式 for(i 0; i 4; i) { Write_DotMatrix(0x0c, 0x01); } DotMatrix_Lock(); // 5. 关闭显示测试模式 (0x00)进入正常显示 for(i 0; i 4; i) { Write_DotMatrix(0x0f, 0x00); } DotMatrix_Lock(); }第六步清屏函数在初始化或切换显示内容前清空屏幕是个好习惯。void Write_DotMatrix_AllOff(void) { int i 0; for(i 1; i 9; i) // 遍历1~8行 { // 将四个芯片的当前行都设置为0x00全灭 Write_DotMatrix_byte(i); Write_DotMatrix_byte(0x00); Write_DotMatrix_byte(i); Write_DotMatrix_byte(0x00); Write_DotMatrix_byte(i); Write_DotMatrix_byte(0x00); Write_DotMatrix_byte(i); Write_DotMatrix_byte(0x00); DotMatrix_Lock(); // 更新 } }5. 实战验证让点阵“说话”驱动写好了得跑起来看看效果。我们在主文件例如main.c或empty.c里调用它们。5.1 准备字模数据点阵显示字符需要字模数据。字模可以用专门的软件生成。这里我直接用一个现成的数组里面包含了数字0-9和“立”、“创”两个汉字的8x8点阵字模逐行式阴码。unsigned char disp1[12][8]{ {0x3C,0x42,0x42,0x42,0x42,0x42,0x66,0x38}, //0 {0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x18}, //1 {0x7C,0x42,0x02,0x04,0x08,0x30,0x42,0x7E}, //2 {0x7C,0x46,0x04,0x18,0x06,0x02,0x42,0x3C}, //3 {0x0C,0x14,0x14,0x24,0x44,0x3C,0x04,0x0C}, //4 {0x3E,0x40,0x58,0x64,0x02,0x02,0x42,0x3C}, //5 {0x3E,0x40,0x48,0x76,0x42,0x42,0x42,0x3C}, //6 {0x7E,0x04,0x04,0x08,0x10,0x10,0x10,0x10}, //7 {0x7C,0x42,0x62,0x3C,0x44,0x42,0x42,0x3C}, //8 {0x7C,0x42,0x42,0x46,0x3A,0x02,0x44,0x38}, //9 {0x3A,0x04,0x04,0x24,0x24,0x18,0x08,0x7E}, //立 {0x52,0x4E,0x76,0xD6,0x56,0x76,0x4A,0x4E}, //创 };5.2 主函数调用#include ti_msp_dl_config.h #include board.h #include bsp_DotMatrix.h int main(void) { // 系统初始化 SYSCFG_DL_init(); // 点阵模块初始化 DotMatrix_Init(); // 清屏 Write_DotMatrix_AllOff(); printf(DotMatrix demo start\r\n); while(1) { // 让四个点阵分别显示“立”、“创”、“7”、“6” // disp1[10] 对应 “立” // disp1[11] 对应 “创” // disp1[7] 对应 “7” // disp1[6] 对应 “6” DotMatrix_display(disp1[10], disp1[11], disp1[7], disp1[6]); // 延时1秒 delay_ms(1000); // 这里可以添加其他显示逻辑比如滚动、切换等 } }编译、下载程序到MSPM0G3507开发板上电后你应该能看到四个点阵屏分别稳定地显示“立”、“创”、“7”、“6”四个字符。如果显示不正常首先检查硬件连接是否牢固尤其是5V和GND然后检查SysConfig的引脚配置是否与代码中的宏定义一致最后用逻辑分析仪或示波器抓一下DIN、CLK、CS的波形看看时序是否符合MAX7219数据手册的要求。这个驱动框架就搭建好了。基于这个框架你可以轻松地扩展显示其他字符、图形甚至实现动画效果。关键就是准备好正确的8x8字模数组然后调用DotMatrix_display函数。希望这篇教程能帮你顺利点亮手中的点阵屏。