本帖最后由 james_lz 于 2024-11-13 22:36 编辑

分享一个4位数码管的动态显示的模块,也可以用在其他的芯片上。
很简洁的实现了字符串的滚动显示,
a915e29814fb71fec54e03d0318a2bc.jpg

  源代码如下

#ifndef __DIGITRON_H__
#define __DIGITRON_H__

#include <stdio.h>
#include <string.h>
#include "me32f103.h"
#include "me32f103_sys.h"
#include "me32f103_gpio.h"
#include "me32f103_ioconfig.h"
#include "me32f103_iap.h"
#include "typedefs.h"

#define BITA BIT0
#define BITB BIT1
#define BITC BIT2
#define BITD BIT3
#define BITE BIT4
#define BITF BIT5
#define BITG BIT6
#define BITH BIT7


#define DIGIT_0  (BITA|BITB|BITC|BITD|BITE|BITF)
#define DIGIT_1  (BITB|BITC)
#define DIGIT_2  (BITA|BITB|BITG|BITD|BITE)
#define DIGIT_3  (BITA|BITB|BITC|BITD|BITG)
#define DIGIT_4  (BITB|BITC|BITF|BITG)
#define DIGIT_5  (BITA|BITF|BITG|BITC|BITD)
#define DIGIT_6  (BITA|BITG|BITC|BITD|BITE|BITF)
#define DIGIT_7  (BITA|BITB|BITC)
#define DIGIT_8  (BITA|BITB|BITC|BITD|BITE|BITF|BITG)
#define DIGIT_9     (BITA|BITB|BITC|BITD|BITF|BITG)
#define DIGIT_A  (BITA|BITB|BITC|BITE|BITF|BITG)
#define DIGIT_B  (BITC|BITD|BITE|BITF|BITG)
#define DIGIT_C  (BITA|BITD|BITE|BITF)
#define DIGIT_D  (BITB|BITC|BITD|BITE|BITG)
#define DIGIT_E  (BITA|BITD|BITE|BITF|BITG)
#define DIGIT_F  (BITA|BITE|BITF|BITG)
#define DIGIT_G  (BITA|BITC|BITD|BITE|BITF)
#define DIGIT_H  (BITB|BITC|BITE|BITF|BITG)
#define DIGIT_I  (BITA|BITB|BITC|BITD)
#define DIGIT_J  (BITB|BITC|BITD)
#define DIGIT_K  (BITA|BITC|BITE|BITF|BITG)
#define DIGIT_L  (BITD|BITE|BITF)
#define DIGIT_M  (BITA|BITB|BITC|BITE|BITF)
#define DIGIT_N  (BITC|BITE|BITG)
#define DIGIT_O  (BITC|BITD|BITE|BITG)
#define DIGIT_P  (BITA|BITB|BITE|BITF|BITG)
#define DIGIT_Q  (BITA|BITB|BITC|BITF|BITG)
#define DIGIT_R  (BITA|BITE|BITF)
#define DIGIT_S  (BITA|BITD|BITG)
#define DIGIT_T  (BITD|BITE|BITF|BITG)
#define DIGIT_U  (BITB|BITC|BITD|BITE|BITF)
#define DIGIT_V  (BITC|BITD|BITE)
#define DIGIT_W  (BITB|BITC|BITD|BITE|BITF|BITG)
#define DIGIT_X  (BITC|BITF|BITG)
#define DIGIT_Y  (BITB|BITC|BITD|BITF|BITG)
#define DIGIT_Z     (BITB|BITD|BITE|BITG)
#define DIGIT_OFF   0
#define DIGIT_ALL   (BITA|BITB|BITC|BITD|BITE|BITF|BITG|BITH)


typedef struct
{
    char *  string;     //ÐèÒªÏÔʾµÄ×Ö·û´®
    uint8_t coms;       //ÊýÂë¹ÜλÊý
    uint8_t length;     //ÏÔʾ×Ö·û´®³¤¶È
    uint8_t current;    //µ±Ç°²½Êý
    uint8_t levels;     //×ܲ½Êý
    uint8_t rate;       //ÏÔʾ¸üÐÂƵÂÊ
    union               //ÏÔʾË÷Òý»º´æ
    {
        uint8_t  bytes[4];
        uint32_t dat;
    } buffers;
     
} digitron_object_t;


extern digitron_object_t digitron_object;
extern const uint8_t alphanumeric_array_size ;

extern char *convert_value2str(uint16_t val, uint8_t radix);
extern void digitron_gpio_init(void);
extern void digitron_strings_set(digitron_object_t *object, char *str);
extern void digitron_update(digitron_object_t *object);
extern void digitron_scan(digitron_object_t *object);

#endif



#include "digitron.h"

digitron_object_t digitron_object;

const uint8_t alphanumeric_array[] =
{
    DIGIT_OFF ,
    DIGIT_0 ,
    DIGIT_1 ,
    DIGIT_2 ,
    DIGIT_3 ,
    DIGIT_4 ,
    DIGIT_5 ,
    DIGIT_6 ,
    DIGIT_7 ,
    DIGIT_8 ,
    DIGIT_9 ,
    DIGIT_A ,
    DIGIT_B ,
    DIGIT_C ,
    DIGIT_D ,
    DIGIT_E ,
    DIGIT_F ,
    DIGIT_G ,
    DIGIT_H ,
    DIGIT_I ,
    DIGIT_J ,
    DIGIT_K ,
    DIGIT_L ,
    DIGIT_M ,
    DIGIT_N ,
    DIGIT_O ,
    DIGIT_P ,
    DIGIT_Q ,
    DIGIT_R ,
    DIGIT_S ,
    DIGIT_T ,
    DIGIT_U ,
    DIGIT_V ,
    DIGIT_W ,
    DIGIT_X ,
    DIGIT_Y ,
    DIGIT_Z ,
    DIGIT_ALL ,
};
const uint8_t alphanumeric_array_size = ARR_SIZE(alphanumeric_array);

/**
* @method digitron_gpio_init
* @brief   ÊýÂë¹ÜGPIO³õʼ»¯
* @details 4λ¹²Òõ
* @param   ;
* @retval  ;
*/
void digitron_gpio_init(void)
{
    //com0~com3
    PA9_INIT(PA9_GPIO);
    PA10_INIT(PA10_GPIO);
    PA11_INIT(PA11_GPIO);
    PA12_INIT(PA12_GPIO);

    //seg1~8
    PB3_INIT(PB3_GPIO);
    PB4_INIT(PB4_GPIO);
    PB5_INIT(PB5_GPIO);
    PB6_INIT(PB6_GPIO);
    PA4_INIT(PA4_GPIO);
    PA5_INIT(PA5_GPIO);
    PA6_INIT(PA6_GPIO);
    PA7_INIT(PA7_GPIO);


    PB_INIT_AS_OUTPUT(IO_PIN3);
    PB_INIT_AS_OUTPUT(IO_PIN4);
    PB_INIT_AS_OUTPUT(IO_PIN5);
    PB_INIT_AS_OUTPUT(IO_PIN6);

    PA_INIT_AS_OUTPUT(IO_PIN9);
    PA_INIT_AS_OUTPUT(IO_PIN10);
    PA_INIT_AS_OUTPUT(IO_PIN11);
    PA_INIT_AS_OUTPUT(IO_PIN12);

    PA_INIT_AS_OUTPUT(IO_PIN4);
    PA_INIT_AS_OUTPUT(IO_PIN5);
    PA_INIT_AS_OUTPUT(IO_PIN6);
    PA_INIT_AS_OUTPUT(IO_PIN7);
}




/**
* @method convert_value2str
* @brief   ½«Ò»¸öÎÞ·ûºÅÕûÐÍֵת»»Îª×Ö·û´®
* @details ;
* @param   uint16_t val ÐèÒª±»×ª»»µÄÖµ
* @param   uint8_t radix ת»»½øÖÆ 2£º¶þ½øÖÆ£¬8£º°Ë½øÖÆ£¬10£ºÊ®½øÖÆ£¬16£ºÊ®Áù½øÖÆ
* @retval  ;
*/
char * convert_value2str(uint16_t val, uint8_t radix)
{
    uint8_t i = 0, left = 0, right = 0;
    static char str[17] = "";
    if(radix == 2)
    {
        while(val != 0)
        {
            str = (val % radix) + '0' ;
            val /= radix;
            i++;
        }
        if(i > 0) right = i - 1;
        while (left < right)
        {
            char temp = str[left];
            str[left] = str[right];
            str[right] = temp;
            left++;
            right--;
        }
    }
    else if(radix == 8) sprintf(str, "%o", val);
    else if(radix == 10) sprintf(str, "%u", val);
    else if(radix == 16) sprintf(str, "%x", val);
    return (char *)(&str);
}


/**
* @method digitron_drive
* @brief   ;
* @details ;
* @param   ;
* @retval  ;
*/
static void digitron_drive(uint8_t dat)
{
    ubit8_t temp;
    temp.byte = dat;
    (temp.bits.bit0 != 0) ? (PB->DOSET = IO_BIT_PIN3) : (PB->DOCLR = IO_BIT_PIN3);
    (temp.bits.bit1 != 0) ? (PB->DOSET = IO_BIT_PIN4) : (PB->DOCLR = IO_BIT_PIN4);
    (temp.bits.bit2 != 0) ? (PB->DOSET = IO_BIT_PIN5) : (PB->DOCLR = IO_BIT_PIN5);
    (temp.bits.bit3 != 0) ? (PB->DOSET = IO_BIT_PIN6) : (PB->DOCLR = IO_BIT_PIN6);
    (temp.bits.bit4 != 0) ? (PA->DOSET = IO_BIT_PIN4) : (PA->DOCLR = IO_BIT_PIN4);
    (temp.bits.bit5 != 0) ? (PA->DOSET = IO_BIT_PIN5) : (PA->DOCLR = IO_BIT_PIN5);
    (temp.bits.bit6 != 0) ? (PA->DOSET = IO_BIT_PIN6) : (PA->DOCLR = IO_BIT_PIN6);
    (temp.bits.bit7 != 0) ? (PA->DOSET = IO_BIT_PIN7) : (PA->DOCLR = IO_BIT_PIN7);
}


/**
* @method digitron_scan
* @brief   ÊýÂë¹ÜɨÃè
* @details ;
* @param   ;
* @retval  ;
*/
void digitron_scan(digitron_object_t *object)
{
    static uint8_t steps = 0;
    ubit8_t coms = {0xff};


    PA->DOSET = IO_BIT_PIN9;
    PA->DOSET = IO_BIT_PIN10;
    PA->DOSET = IO_BIT_PIN11;
    PA->DOSET = IO_BIT_PIN12;

    coms.byte &= ~(0x01 << steps);

    digitron_drive(alphanumeric_array[(object->buffers).bytes[steps]]);

    (coms.bits.bit3 != 0) ? (PA->DOSET = IO_BIT_PIN9) : (PA->DOCLR = IO_BIT_PIN9);
    (coms.bits.bit2 != 0) ? (PA->DOSET = IO_BIT_PIN10) : (PA->DOCLR = IO_BIT_PIN10);
    (coms.bits.bit1 != 0) ? (PA->DOSET = IO_BIT_PIN11) : (PA->DOCLR = IO_BIT_PIN11);
    (coms.bits.bit0 != 0) ? (PA->DOSET = IO_BIT_PIN12) : (PA->DOCLR = IO_BIT_PIN12);

    if(++steps >= object->coms) steps = 0;
}


/**
* @method get_character_index
* @brief   »ñÈ¡Ò»¸ö×Ö·ûµÄË÷ÒýÖµ
* @details »ñÈ¡×Ö·û´®ÖÐÆ«ÒÆnλµÄ×Ö·ûÔÚÊý×éalphanumeric_arrayÖеÄË÷ÒýÖµ
* @param   char *chr ÐèÒª²éÕÒ×Ö·ûËùÔÚµÄ×Ö·û´®
* @param   uint8_t n Æ«ÒÆλÊý
* @retval  uint8_t ·µ»ØË÷ÒýÖµ ÈôÊÇÕÒ²»µ½Ëù²éÕÒ×Ö·û»òÆ«ÒÆλÊýn´óÓÚ×Ö·û´®³¤¶È·µ»Ø 0£»
*/
static uint8_t get_character_index(char *chr, uint8_t n)
{
    uint8_t i, len;
    const char * string = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    if( n >= strlen(chr) ) return 0;
    len = strlen(string);
    chr += n;
    if( (*chr) >= 'a' && (*chr) <= 'z') *chr = (*chr) - 32; //ÈôÊÇСд×ÖĸÔòת»»Îª´óд×Öĸ
    for(i = 0; i < len ; i++)
    {
        if(*string == *chr)
        {
            return i;
        }
        string++;
    }
    return 0;
}


/**
* @method digitron_buffer_lshift
* @brief   ÊýÂë¹Ü»º´æÊý¾Ý×óÒÆ
* @details ÓÃÓÚ×Ö·û´®´óÓÚÊýÂë¹ÜλÊýµÄÇé¿öÏÂÉèÖûº´æ£¬ÊµÏÖ¶¯Ì¬ÏÔʾ
* @param   ;
* @retval  ;
*/
static void digitron_buffer_lshift(digitron_object_t *object)
{
    (object->buffers).dat <<= 8;
    if(object->current < object->length)
    {
        (object->buffers).bytes[0] = get_character_index(object->string, object->current);
    }

    if((++(object->current)) >= object->levels)
    {
        object->current = 0;
    }
}

/**
* @method digitron_buffer_set
* @brief   ÊýÂë¹Ü»º´æÊý¾ÝÉèÖÃ
* @details ÓÃÓÚ×Ö·û´®Ð¡ÓÚ»òµÈÓÚÊýÂë¹ÜλÊýµÄÇé¿öÏÂÉèÖûº´æ£¬ÊµÏÖ¾²Ì¬ÏÔʾ
* @param   ;
* @retval  ;
*/
static void digitron_buffer_set(digitron_object_t *object)
{
    uint8_t i;
    for(i = 0; i < 4; i++)
    {
        (object->buffers).bytes = get_character_index(object->string, i);
    }
}


/**
* @method ;
* @brief   ;
* @details ;
* @param   ;
* @retval  ;
*/
void digitron_strings_set(digitron_object_t *object, char *str)
{
    object->string          = str;
    object->length          = strlen(object->string);     //ÏÔʾ×Ö·û´®³¤¶È
    object->coms            = 4;
    //×Ö·û´®³¤¶ÈСÓÚµÈÓÚÊýÂë¹ÜλÊýʱ£¬¹ö¶¯ÏÔʾ»ò¾²Ö¹ÏÔʾ
//    object->levels          = object->length + object->coms -1 ;
    object->levels          = (object->length > object->coms) ? (object->length + object->coms - 1 ) : (0);
    (object->buffers).dat   = 0;
    object->current         = 0;
    object->rate            = 0;
}


/**
* @method ;
* @brief   ;
* @details ;
* @param   ;
* @retval  ;
*/
void digitron_update(digitron_object_t *object)
{
    (object->levels > 0) ? (digitron_buffer_lshift(object)) : (digitron_buffer_set(object));


//    (object->length > object->coms) ? (digitron_buffer_lshift(object)) : (digitron_buffer_set(object));
}


// main 文件
#include "me32f103.h"
#include "me32f103_sys.h"
#include "me32f103_gpio.h"
#include "me32f103_ioconfig.h"
#include "me32f103_iap.h"
#include "digitron.h"
uint16_t cnt = 0;

int main(void)
{
    digitron_gpio_init();
    digitron_strings_set(&digitron_object, "HELLO MIAN BAO BAN");
    while(1)
    {

        digitron_scan(&digitron_object);
        if(++cnt >= 4000)
        {
            digitron_update(&digitron_object);
            cnt = 0;
        }
    }

}