MAX7219点阵屏四合一—基于CH32V307的应用

发布时间 2023-11-03 15:04:11作者: ZaiLi

参考链接:https://blog.csdn.net/weixin_46957846/article/details/127352759

本篇文章为基于CH32V307MAX7219级联应用,代码是基于上参考链接代码基础上修改,若有侵权请联系及时删除。该应用测试所用模块为一个四级级联模块,参考链接代码下载应用4个点阵模块均显示均显示同一个字符。该应用在此基础上进行了修改,可以使4个点阵模块显示不同的字符。具体代码会附在下文章介绍中。

关于MAX7219介绍

MAX7219 是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。其上包括一个片上的BBCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。只有一个外部寄存器用来设置各个LED的段电流。《以上信息来自MAX7219手册》

关于代码介绍

程序代码中,片选引脚CS采用软件控制的方式。CH32V307不支持使用位操作进行写0或写1,因此程序中调用GPIO_WriteBit函数对对应引脚进行写0或写1操作。相关程序代码如下:

max7219.h文件

#ifndef __MAX7219_H
#define __MAX7219_H

#include "ch32v30x.h"

#define number          4  //级联个数
#define brl             6  //亮度级别

#define SPI_IS_HARDWARE 1  //1:硬件SPI;0:软件模拟SPI

#define Max7219_pinDIN_GPIO GPIO_Pin_7
#define Max7219_pinCS_GPIO  GPIO_Pin_3
#define Max7219_pinCLK_GPIO GPIO_Pin_5

#define Max7219_pinDIN(i)  GPIO_WriteBit(GPIOA,GPIO_Pin_7,i)
#define Max7219_pinCS(i)   GPIO_WriteBit(GPIOA,GPIO_Pin_3,i)
#define Max7219_pinCLK(i)  GPIO_WriteBit(GPIOA,GPIO_Pin_5,i)

void Max7219_GPIO_Init(void);
void Write_Max7219_byte(u8 data);
void Write_Max7219(u8 addr,u8 dat);
void Init_MAX7219(void);

#endif

 

max7219.c文件

#include "max7219.h"
#include "debug.h"

u8 code_disp1[39][8]=
{
{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//0
{0x08,0x18,0x28,0x08,0x08,0x08,0x08,0x3E},//1
{0x7E,0x02,0x02,0x7E,0x40,0x40,0x40,0x7E},//2
{0x3E,0x02,0x02,0x3E,0x02,0x02,0x3E,0x00},//3
{0x08,0x18,0x28,0x48,0xFE,0x08,0x08,0x08},//4
{0x3C,0x20,0x20,0x3C,0x04,0x04,0x3C,0x00},//5
{0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x00},//6
{0x3E,0x22,0x04,0x08,0x08,0x08,0x08,0x08},//7
{0x00,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E},//8
{0x3E,0x22,0x22,0x3E,0x02,0x02,0x02,0x3E},//9
{0x08,0x14,0x22,0x3E,0x22,0x22,0x22,0x22},//A
{0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C,0x00},//B
{0x3C,0x40,0x40,0x40,0x40,0x40,0x3C,0x00},//C
{0x7C,0x42,0x42,0x42,0x42,0x42,0x7C,0x00},//D
{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C},//E
{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40},//F
{0x3C,0x40,0x40,0x40,0x40,0x44,0x44,0x3C},//G
{0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44},//H
{0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x7C},//I
{0x3C,0x08,0x08,0x08,0x08,0x08,0x48,0x30},//J
{0x00,0x24,0x28,0x30,0x20,0x30,0x28,0x24},//K
{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C},//L
{0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81},//M
{0x00,0x42,0x62,0x52,0x4A,0x46,0x42,0x00},//N
{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//O
{0x3C,0x22,0x22,0x22,0x3C,0x20,0x20,0x20},//P
{0x1C,0x22,0x22,0x22,0x22,0x26,0x22,0x1D},//Q
{0x3C,0x22,0x22,0x22,0x3C,0x24,0x22,0x21},//R
{0x00,0x1E,0x20,0x20,0x3E,0x02,0x02,0x3C},//S
{0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08},//T
{0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1C},//U
{0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18},//V
{0x00,0x49,0x49,0x49,0x49,0x2A,0x1C,0x00},//W
{0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81},//X
{0x41,0x22,0x14,0x08,0x08,0x08,0x08,0x08},//Y
{0x00,0x7F,0x02,0x04,0x08,0x10,0x20,0x7F},//Z
{0x08,0x7F,0x49,0x49,0x7F,0x08,0x08,0x08},//
{0xFE,0xBA,0x92,0xBA,0x92,0x9A,0xBA,0xFE},//
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08},//.
};


#if SPI_IS_HARDWARE  //判断SPI方式

void Max7219_GPIO_Init(void)    //硬件SPI
{
    GPIO_InitTypeDef GPIO_InitStructure={0};
    SPI_InitTypeDef  SPI1_InitStructure={0};

    //配置SPI1管脚
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);

    GPIO_InitStructure.GPIO_Pin=Max7219_pinCS_GPIO;//CS/LOAD
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=Max7219_pinCLK_GPIO|Max7219_pinDIN_GPIO;//CLK MISO MOSI
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    SPI_I2S_DeInit(SPI1);
    SPI1_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
    SPI1_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_64;
    SPI1_InitStructure.SPI_DataSize=SPI_DataSize_8b;
    SPI1_InitStructure.SPI_Mode=SPI_Mode_Master;
    SPI1_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB; //高位在先
    SPI1_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI1_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI1_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI1_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI1_InitStructure);

    SPI_Cmd(SPI1, ENABLE);
}

void Write_Max7219_byte(u8 data)
{
    Max7219_pinCS(0);
    SPI_I2S_SendData(SPI1, data);        //写入数据
}

//功能:向MAX7219内部寄存器写入数据
//参数:addr、dat
void Write_Max7219(u8 addr,u8 dat)
{
    Max7219_pinCS(0);
    SPI_I2S_SendData(SPI1, addr);       //写入地址
    Delay_Us(10);//必须,点阵不显示时可以延长此延时调试
    SPI_I2S_SendData(SPI1, dat);        //写入数据
    Delay_Us(10);//必须,点阵不显示时可以延长此延时调试
    //Max7219_pinCS(1)该函数若不注释掉,会导致级联的模块全部显示同一个字符,无法进行单独控制,若要使级联模块全部显示一样时,可取消该注释
//    Max7219_pinCS(1);
}

#else

void Max7219_GPIO_Init(void)//软件模拟SPI
{
     GPIO_InitTypeDef GPIO_InitStructure={0};

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

     GPIO_InitStructure.GPIO_Pin  = Max7219_pinCS_GPIO | Max7219_pinDIN_GPIO | Max7219_pinCLK_GPIO;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA,&GPIO_InitStructure);
}

//功能:向MAX7219写入字节
//入口参数:data
void Write_Max7219_byte(u8 data)
{
    u8 i;
    Max7219_pinCS(0);
    for(i = 0;i<8;i++)
    {
        Max7219_pinCLK(0);
        Max7219_pinDIN((data & 0x80));
        data = data<<1;
        Max7219_pinCLK(1);
    }
}

//功能:向MAX7219内部寄存器写入数据
//参数:addr、dat
void Write_Max7219(u8 addr,u8 dat)
{
    Max7219_pinCS(0);
    Write_Max7219_byte(addr);              //写入地址
    Delay_Us(10);
    Write_Max7219_byte(dat);               //写入数据
    Delay_Us(10);
//    Max7219_pinCS(1);
}
#endif

/*
关于MAX7219的初始化,当需要级联模块全部显示一样,或者只有一个显示模块时,在初始化配置时,对下列函数配置一次即可
     Write_Max7219(0x09, 0x00);       //译码方式:无
     Write_Max7219(0x0a, 0x03);       //亮度
     Write_Max7219(0x0b, 0x07);       //扫描界限;8个数码管显示
     Write_Max7219(0x0c, 0x01);       //掉电模式:0,普通模式:1
     Write_Max7219(0x0f, 0x00);       //显示测试:1;测试结束,正常显示:0
若需要对每个模块进行控制,则需要根据级联数量进行初始化,如下,初始化过程中需要对片选引脚进行相应的拉高拉低

*/
void Init_MAX7219(void)
{
    u8 i,j;
    for(i=0;i<5;i++)
    {
        for(j=0;j<number;j++)
        {
            switch(i)
            {
            case 0:Write_Max7219(0x09, 0x00); break; //译码方式:BCD码 不译码
            case 1:Write_Max7219(0x0A, brl);  break; //亮度 0-15 共16级
            case 2:Write_Max7219(0x0B, 0x07); break; //扫描界限;8位显示
            case 3:Write_Max7219(0x0C, 0x01); break; //掉电模式:0,普通模式:1
            case 4:Write_Max7219(0x0F, 0x00); break; //显示测试:1;测试结束,正常显示:0
            }
            Max7219_pinCS(1);
            Delay_Us(1);
            Max7219_pinCS(0);

        }
    }

}

main.c文件

/********************************** (C) COPYRIGHT *******************************
* File Name          : main.c
* Author             : WCH
* Version            : V1.0.0
* Date               : 2021/06/06
* Description        : Main program body.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/

/*
 *@Note

*/

#include "debug.h"
#include "ch32v30x.h"
#include "max7219.h"
/* Global typedef */

/* Global define */

/* Global Variable */
extern u8 code_disp1[39][8];

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    u8 i,j;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    USART_Printf_Init(115200);

    printf("SystemClk:%d\r\n",SystemCoreClock);
    printf("This is printf example\r\n");

    Max7219_GPIO_Init();
    Delay_Ms(500);
    Init_MAX7219();


    while(1)
    {
//        //以下方式可用于控制级联模块显示相同的字符
//        Max7219_pinCS(1);
//        Delay_Ms(1);
//        for(j=0;j<38;j++)
//        {
//            for(i=1;i<9;i++)
//            {
//                Write_Max7219(i,code_disp1[j][i-1]);
//            }
//            Delay_Ms(500);
//        }

        //以下方式可单独控制每个模块显示不同的字符
        for(j=0;j<8;j++)
        {
            for(i=0;i<number;i++)
            {
                if(i==0)
                {
                    Write_Max7219(j+1,code_disp1[i][j]);
                }
                else if(i==1)
                {
                    Write_Max7219(j+1,code_disp1[i][j]);
                }
                else if(i==2)
                {
                    Write_Max7219(j+1,code_disp1[10][j]);
                }
                else if(i==3)
                {
                    Write_Max7219(j+1,code_disp1[12][j]);
                }
                else
                {
                    Write_Max7219(j+1,0x00);
                }
            }
            Max7219_pinCS(1);
            Delay_Us(1);
            Max7219_pinCS(0);
        }

    }
}

 编译下载,显示结果如下: