四合一点阵显示模块采用MAX7219作为控制,它是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。只有一个外部寄存器用来设置各个LED的段电流。它可以连接所有通用的微处理器。每个数据可以寻址在更新时不需要改写所有的显示。MAX7219同样允许用户对每一个数据选择编码或者不编码。
整个设备包含一个150μA的低功耗关闭模式,模拟和数字亮度控制,一个扫描限制寄存器允许用户显示1-8位数据,还有一个让所有LED发光的检测模式。
只需要3个IO口即可驱动1个点阵!点阵显示时无闪烁!支持级联!
一、二、 模块来源?
采购链接:
资料下载链接: https://pan.baidu.com/s/19WdOd8D2QlPi1Q_EWlb3fQ
资料提取码:b822
产品实物展示
2、规格参数?
工作电压:4-5.5V
工作电流:8-330MA
扫描速率:500-1300Hz
通信协议:串行通信
以上信息见厂家资料文件
三、移植过程?
我们的目标是将例程移植至MSPM0G3507开发板上。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。
3.1. 查看资料?
3.1.1. 时序讲解?
无论数据输入或输出CS端必须为低电平。然后数据在CS端的上升沿被载入数据寄存器或控制寄存器。CS端在第 16个时钟的上升沿之后,下个时钟上升沿之前变为高电平,否则数据将会丢失。
对 MAX7219 来说,串行数据在 DIN 输入 16 位数据包,在CLK的上升沿数据均移入到内部 16 位移位寄存器。即DIN不能在CLK的上升沿时进行数据变换。
3.1.2. 数据位讲解?
DIN传输的16位数据包说明,见表格000。其中D8-D11 为寄存器地址位。D0-D7 为数据位。D12-D15 为无效位。
根据以上的时序说明和传输格式,实现的数据传输代码。
//向MAX7219写入字节 //dat写入的数据 void Write_Max7219_byte(uint8_t dat) { uint8_t i; MAX7219_CS(0);//确认CS拉低 for(i=8;i>=1;i--)//传输8位 { MAX7219_CLK(0);//拉低CLK //当前数据位是否为1 if( dat&0x80 ) { MAX7219_DIN(1); } else { MAX7219_DIN(0); } dat=dat<1;//准备下一位数据 //CLK拉高将数据载入寄存器 MAX7219_CLK(1); } }
//向MAX7219写入数据 //address写入地址 dat写入数据 void Write_Max7219(uint8_t address,uint8_t dat) { //CS拉低 MAX7219_CS(0); //传输高8位数据(寄存器地址) Write_Max7219_byte(address); //传输低8位数据(数据) Write_Max7219_byte(dat); //CS拉高 MAX7219_CS(1); }
3.1.3. 关键寄存器讲解?
相关寄存器地址,见下表。这里先讲解0X09译码方式寄存器。
我们发送的数据位是16位,而进入译码方式寄存器只使用到了D15-D8数据位(0x09),还有D7到D0没有设置。而根据数据手册的说明,关于译码方式寄存器的D7-D0的设置在数据手册的表格4.
按照图中所示,如果要设置译码方式为全部数码管都进行译码,那么要发送:
//高8位=0x09(寄存器地址), 低8位=0x00(数据) Write_Max7219(0x09,0x00);
点阵是通过一个个像素点显示,要在8x8点阵上显示个字符,需要以下两步:
占据屏幕上的一块地方,大小由字体大小说了算;
在占据的地方上依次控制每个像素点是否显示。
比如一个8x8字体大小的字符,表示水平方向需要8个像素点,垂直方向需要8个像素点。在这块8x8的地盘上,每个像素点是否显示由字模说了算,字模中的每1位数据表示一个像素点,如果该位为0则表示此处像素点不显示、为1则表示显示(阴码规则)。 以下为 逐行式,顺向(高位在前),阴码格式输出的字模数据。在程序中逐位读取字模,如果该位为0则该点点亮,如果该位为1则灭。
字模例子
0x7C,第一行显示 0111 1100 0x42,第二行显示 0100 0010 0x02,第三行显示 0000 0010 0x04,第四行显示 0000 0100 0x08,第五行显示 0000 1000 0x30,第六行显示 0011 0000 0x42,第七行显示 0100 0010 0x7E 第八行显示 0111 1110 (一共8行)
如果想要第0行显示一条直线,应如何操作?
先在数据手册中找到关于第0个行的寄存器地址。根据右图显示得知,第0个数码管的地址是0X01知道地址后,根据数据手册提示找到数据位设置表,因为全部没有进行译码,那么只需要发送:
//高8位=0x01(寄存器地址), 低8位=0xff(数据) Write_Max7219(0x01,0xff);//第0行显示一条直线
3.2. 引脚选择?
该模块有10个引脚,其中有5个是接入下一个级联的点阵。如果不接入下一个级联的点阵,则只要接5个引脚,具体引脚连接见下表。
数码管模块 | 开发板 |
---|---|
VCC | 5V |
GND | GND |
DIN | PB10 |
CS | PB13 |
CLK | PB15 |
3.3. 移植至工程?
我们新建两个文件分别是 bsp_DotMatrix.c 和 bsp_DotMatrix.h ,然后将C文件添加至工程中,将h文件路径添加到工程中。
在文件bsp_DotMatrix.c中,编写如下代码。
/* * Change Logs: * Date Author Notes * 2024-06-18 LCKFB-LP first version */ #include "bsp_DotMatrix.h" #include "stdio.h" /****************************************************************** * 函 数 名 称:MAX7219_GPIO_Init * 函 数 说 明:初始化MAX7219引脚 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void MAX7219_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体 RCC_MAX7219_ENABLE(); // 使能GPIO时钟 GPIO_InitStruct.Pins = GPIO_MAX7219_CLK| // GPIO引脚 GPIO_MAX7219_DIN| GPIO_MAX7219_CS; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 输出速度高 GPIO_Init(PORT_MAX7219, &GPIO_InitStruct); // 初始化 } /****************************************************************** * 函 数 名 称:Write_Max7219_byte * 函 数 说 明:向MAX7219写入字节 * 函 数 形 参:dat写入的数据 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void Write_Max7219_byte(uint8_t dat) { uint8_t i; MAX7219_CS(0); for(i=8;i>=1;i--) { MAX7219_CLK(0); if( dat&0x80 ) { MAX7219_DIN(1); } else { MAX7219_DIN(0); } dat=dat<1; MAX7219_CLK(1); } } /****************************************************************** * 函 数 名 称:Write_Max7219 * 函 数 说 明:向MAX7219写入数据 * 函 数 形 参:address写入地址 dat写入数据 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void Write_Max7219(uint8_t address,uint8_t dat) { Write_Max7219_byte(address); //写入地址,即点阵行号1-8 Write_Max7219_byte(dat); //写入数据,即该行显示内容 } /****************************************************************** * 函 数 名 称:Max7219_Lock * 函 数 说 明:将更新的数据写入芯片 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void Max7219_Lock(void) { MAX7219_CS(1); MAX7219_CS(0); } /****************************************************************** * 函 数 名 称:Max7219_display * 函 数 说 明:4个点阵显示 * 函 数 形 参:show1第一个点阵显示内容 show2第二个 show3第三个 show4第四个 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void Max7219_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行 进行更新 { Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(show1[i-1]); //第一个点阵 Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(show2[i-1]); //第二个点阵 Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(show3[i-1]); //第三个点阵 Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(show4[i-1]); //第四个点阵 Max7219_Lock();//锁存显示数据 } } /****************************************************************** * 函 数 名 称:Write_Max7219_AllOff * 函 数 说 明:控制第一片MAX7219的全部数码管全灭 * 函 数 形 参:address写入地址 dat写入数据 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void Write_Max7219_AllOff(void) { int i = 0; for( i = 1; i < 9; i++ )//1~8行 进行更新 { Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(0x00); //全灭 Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(0x00); //全灭 Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(0x00); //全灭 Write_Max7219_byte(i); //写入地址,即行编号1-8 Write_Max7219_byte(0x00); //全灭 Max7219_Lock();//更新内容 } } /****************************************************************** * 函 数 名 称:MAX7219_Init * 函 数 说 明:MAX7219初始化 * 函 数 形 参:无 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void MAX7219_Init(void) { unsigned int i = 0; MAX7219_GPIO_Init();//引脚初始化 for( i = 0; i < 4; i++ )//设置4个点阵 { Write_Max7219(0x09, 0x00); //译码方式:不进行译码 } Max7219_Lock();//更新设置 for( i = 0; i < 4; i++ )//设置4个点阵 { Write_Max7219(0x0a, 0x01); //亮度 } Max7219_Lock();//更新设置 for( i = 0; i < 4; i++ )//设置4个点阵 { Write_Max7219(0x0b, 0x07); //扫描界限;8个数码管显示 } Max7219_Lock();//更新设置 for( i = 0; i < 4; i++ )//设置4个点阵 { Write_Max7219(0x0c, 0x01); //掉电模式:0,普通模式:1 } Max7219_Lock();//更新设置 for( i = 0; i < 4; i++ )//设置4个点阵 { Write_Max7219(0x0f, 0x00); //显示测试:1;测试结束,正常显示:0 } Max7219_Lock();//更新设置 }
在文件bsp_DotMatrix.h中,编写如下代码。
/* * Change Logs: * Date Author Notes * 2024-06-18 LCKFB-LP first version */ #ifndef _BSP_DOTMATRIX_H_ #define _BSP_DOTMATRIX_H_ #include "board.h" #define RCC_MAX7219_ENABLE() __RCC_GPIOB_CLK_ENABLE() #define PORT_MAX7219 CW_GPIOB #define GPIO_MAX7219_CLK GPIO_PIN_15 #define GPIO_MAX7219_DIN GPIO_PIN_10 #define GPIO_MAX7219_CS GPIO_PIN_13 #define MAX7219_CLK(X) GPIO_WritePin(PORT_MAX7219, GPIO_MAX7219_CLK, X?GPIO_Pin_SET:GPIO_Pin_RESET) #define MAX7219_DIN(X) GPIO_WritePin(PORT_MAX7219, GPIO_MAX7219_DIN, X?GPIO_Pin_SET:GPIO_Pin_RESET) #define MAX7219_CS(X) GPIO_WritePin(PORT_MAX7219, GPIO_MAX7219_CS, X?GPIO_Pin_SET:GPIO_Pin_RESET) void Write_Max7219(uint8_t address,uint8_t dat); void Write_Max7219_2(unsigned char address,unsigned char dat); void Write_Max7219_AllOff(void); void MAX7219_Init(void); void Max7219_display(uint8_t* show1, uint8_t* show2, uint8_t* show3, uint8_t* show4); #endi
四、移植验证?
在自己工程中的main主函数中,编写如下。
/* * Change Logs: * Date Author Notes * 2024-06-18 LCKFB-LP first version */ #include "board.h" #include "stdio.h" #include "bsp_uart.h" #include "bsp_DotMatrix.h" unsigned char disp1[12][8]={//一共12行 {0x3C,0x42,0x42,0x42,0x42,0x42,0x66,0x38},/*"0",0*/ {0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x18},/*"1",1*/ {0x7C,0x42,0x02,0x04,0x08,0x30,0x42,0x7E},/*"2",2*/ {0x7C,0x46,0x04,0x18,0x06,0x02,0x42,0x3C},/*"3",3*/ {0x0C,0x14,0x14,0x24,0x44,0x3C,0x04,0x0C},/*"4",4*/ {0x3E,0x40,0x58,0x64,0x02,0x02,0x42,0x3C},/*"5",5*/ {0x3E,0x40,0x48,0x76,0x42,0x42,0x42,0x3C},/*"6",6*/ {0x7E,0x04,0x04,0x08,0x10,0x10,0x10,0x10},/*"7",7*/ {0x7C,0x42,0x62,0x3C,0x44,0x42,0x42,0x3C},/*"8",8*/ {0x7C,0x42,0x42,0x46,0x3A,0x02,0x44,0x38},/*"9",9*/ {0x3A,0x04,0x04,0x24,0x24,0x18,0x08,0x7E},/*"立",10*/ {0x52,0x4E,0x76,0xD6,0x56,0x76,0x4A,0x4E},/*"创",11*/ }; int main(void) { board_init(); uart1_init(115200); MAX7219_Init(); Write_Max7219_AllOff(); printf("MAX7219 demo startrn"); while(1) { //第一个点阵显示disp1数组的第10行内容 //第二个点阵显示disp1数组的第11行内容 //第三个点阵显示disp1数组的第7行内容 //第四个点阵显示disp1数组的第6行内容 Max7219_display(disp1[10],disp1[11], disp1[7], disp1[6]); delay_ms(1000); } }
上电效果:显示“立创76”
移植成功案例代码:
链接:https://pan.baidu.com/s/1xXCdgOcDR8lY7poyH9vayA?pwd=LCKF 提取码:LCKF
审核编辑 黄宇
-
寄存器
+关注
关注
31文章
5440浏览量
124967 -
CW32
+关注
关注
1文章
256浏览量
1286
发布评论请先 登录
锦浪科技四合一混合储能逆变器助力迎峰度夏
用Wi-Fi蓝牙模组Ai-M62-CBS做一个电子沙漏

CW32模块使用 0.91寸彩屏

5050 RGBW 四合一全彩 LED 灯珠
【CW32模块使用】1.8寸彩色触摸屏

代码+案例+生态:武汉芯源半导体CW32嵌入式开发实战正式出版
CW32模块使用 红外接收模块

CW32模块使用 EC-01G NBIOT+GPS模块

CW32模块使用 NEO-6M GPS模块

CW32模块使用 HC05蓝牙模块

CW32模块使用 红外解码编码模块

CW32模块使用 BMP180气压传感器

评论