天天看点

4位数码管,带小数显示方法说明代码

说明

4位数码管,带小数点,最大显示整数为9999;最多显示3位小数,例:0.123。

#define HAL_DIGITAL_TUBE_MUTIPLE   (1000) //可以改为10的整数倍倍数, 放大倍数, 要显示1.234,请输入1234
#define HAL_DIGITAL_TUBE_DISPLAY_HZ   (5) //自动刷新频率,可以关闭
           

代码

/**************************************************************************/
#ifdef PRINT_HEADER
#undef PRINT_HEADER
#endif
#define PRINT_HEADERx  "DT> "


#ifdef PRINT_HEADER
#ifndef print
#undef print
#endif
#define print(...)        do{Debug(PRINT_HEADER);Debug(__VA_ARGS__);}while(0)

#ifndef println
#undef println
#endif
#define println(...)      do{Debug(PRINT_HEADER);Debugln(__VA_ARGS__);}while(0)


#ifndef print_hex
#undef print_hex
#endif
#define print_hex(_x,_y)  do{DebugHex(_x, _y);}while(0)
#else
#ifndef print
#undef print
#endif
#define print(...)

#ifndef println
#undef println
#endif
#define println(...)


#ifndef print_hex
#undef print_hex
#endif
#define print_hex(_x,_y)
#endif
/**************************************************************************/
#define HAL_DIGITAL_TUBE_MUTIPLE   (1000)
#define HAL_DIGITAL_TUBE_DISPLAY_HZ   (5)
/**************************************************************************/

uint16_t hal_digital_tube_timer = 0;
//uint16_t hal_digital_tube_display_hz = HAL_DIGITAL_TUBE_DISPLAY_HZ;
uint32_t hal_digital_tube_display_new_num = 0;
uint32_t hal_digital_tube_display_last_num = 0;
uint8_t 	decimal_dispaly_digits = 0;
/**************************************************************************/
void hal_digital_tube_write_num(uint8_t dig, char num, bool dot);
/**************************************************************************/
void hal_digital_tube_init(void)
{
    aip650_init();
    aip650_write_cmd(AIP650_ADDR_SETING, AIP650_CMD_SYSON_3_8SEG_ON);
    decimal_dispaly_digits = math_get_digits(HAL_DIGITAL_TUBE_MUTIPLE - 1) ;
    //hal_digital_tube_timer = 1000;// HAL_DIGITAL_TUBE_DISPLAY_HZ + 1;
    hal_digital_tube_decimal(0);
}
/**************************************************************************************************
 * @fn      hal_digital_tube_update
 *
 * @brief   just update, display in poll
 *
 * @param   uint32_t num
 *
 * @return  None
 **************************************************************************************************/
void hal_digital_tube_update(uint32_t num)
{
    hal_digital_tube_display_new_num = num;
}
/**************************************************************************************************
 * @fn      hal_digital_tube_integer
 *
 * @brief   display at once
 *
 * @param   uint32_t num
 *
 * @return  None
 **************************************************************************************************/
void hal_digital_tube_integer(uint32_t num)
{
    char n = 0;

    char display_buff[AIP_DIGITAL_TUBE_DIGITS] = {AIP650_NUM_NULL};

    hal_digital_tube_display_new_num = num;

    if(hal_digital_tube_display_new_num != hal_digital_tube_display_last_num)
    {
        hal_digital_tube_display_last_num = hal_digital_tube_display_new_num;

        uint16_t integer = hal_digital_tube_display_last_num;

        for(n = 0; n < AIP_DIGITAL_TUBE_DIGITS; n++)
        {
            display_buff[n] = AIP650_NUM_NULL;
        }
				
        if(num)
        {
            uint8_t digits = math_get_digits(integer) ;

            digits = digits > AIP_DIGITAL_TUBE_DIGITS?AIP_DIGITAL_TUBE_DIGITS:digits;

            println("digits %d", digits);
            for(n = 0; n < digits; n++)
            {
                display_buff[AIP_DIGITAL_TUBE_DIGITS - 1 - n] = (integer % 10);

                integer /=  10;
            }
        }
        else
        {
            display_buff[AIP_DIGITAL_TUBE_DIGITS-1] = AIP650_NUM_0;
        }

        print_hex(display_buff, AIP_DIGITAL_TUBE_DIGITS);
        for(n = 0; n < AIP_DIGITAL_TUBE_DIGITS; n++)
        {
            hal_digital_tube_write_num(n, display_buff[n], false);
        }
    }
}
/**************************************************************************************************
 * @fn      hal_digital_tube_decimal
 *
 * @brief   display at once
 *
 * @param   uint32_t dec
 *
 * @return  None
 **************************************************************************************************/
void hal_digital_tube_decimal(uint32_t dec)
{
    char n = 0;

    char display_buff[AIP_DIGITAL_TUBE_DIGITS] = {AIP650_NUM_NULL};

    hal_digital_tube_display_new_num = dec;

    if(hal_digital_tube_display_new_num != hal_digital_tube_display_last_num)
    {
        hal_digital_tube_display_last_num = hal_digital_tube_display_new_num;

        uint16_t decimal = hal_digital_tube_display_last_num % HAL_DIGITAL_TUBE_MUTIPLE;
        uint16_t integer = hal_digital_tube_display_last_num / HAL_DIGITAL_TUBE_MUTIPLE;
        uint8_t digits = math_get_digits(integer) ;
        uint8_t dec_digits, i = 0, base = 0;

        println("num %d, digits %d, integer %d", hal_digital_tube_display_last_num, digits, integer);
        digits = digits > AIP_DIGITAL_TUBE_DIGITS?AIP_DIGITAL_TUBE_DIGITS:digits;

        //integer

        if(!digits)
        {

            display_buff[0] = AIP650_NUM_0 | AIP650_DOT;
            digits = 1; //at least 1 digit
            n = 1;
            println("no integer");

        } else
        {
            for(n = 0; n < digits; n++)
            {
                base =  math_pow(10, digits - 1 - n);
                if(n == (digits - 1))
                    display_buff[n] = (integer / base) | AIP650_DOT;
                else
                    display_buff[n] =  integer / base;

                integer %= base;
            }
        }
        //decimal
        dec_digits = AIP_DIGITAL_TUBE_DIGITS - digits;
        println("dec_digits %d, decimal %d", dec_digits, decimal);

        for(i = 0; i < dec_digits; i++, n++)
        {
            base = math_pow(10, decimal_dispaly_digits - 1 - i);
            display_buff[n] = decimal / base;
            println("i %d, decimal %d, base %d", i, decimal, base);
            decimal %= base;

        }
        print_hex(display_buff, AIP_DIGITAL_TUBE_DIGITS);
        for(n = 0; n < AIP_DIGITAL_TUBE_DIGITS; n++)
        {
            hal_digital_tube_write_num(n, display_buff[n] & (~ AIP650_DOT), display_buff[n] & AIP650_DOT? true:false);

        }
    }
}
void hal_digital_tube_write_num(uint8_t dig, char num, bool dot)
{
    switch(dig)
    {
    case 0:
        aip650_write_number(AIP650_ADDR_DIG0, (Aip650Num_e)(num), dot);
        break;
    case 1:
        aip650_write_number(AIP650_ADDR_DIG1, (Aip650Num_e)(num), dot);
        break;
    case 2:
        aip650_write_number(AIP650_ADDR_DIG2, (Aip650Num_e)(num), dot);
        break;
    case 3:
        aip650_write_number(AIP650_ADDR_DIG3, (Aip650Num_e)(num), dot);
        break;
    default:
        break;
    }
}
void hal_digital_tube_loop(void)
{
    if(hal_digital_tube_timer == 1)
    {
        hal_digital_tube_timer = 1000 / HAL_DIGITAL_TUBE_DISPLAY_HZ + 1;

        hal_digital_tube_decimal(hal_digital_tube_display_new_num);

    }

}


uint8_t math_get_digits(uint32_t arg)
{
		uint8_t n = 0;
	  
	while(arg != 0){
	
		  arg /= 10;
			n++;
	}
	
	return n;
	  
}


uint32_t math_pow(uint8_t base, uint8_t exponent)
{
	uint32_t value = 1;
	uint8_t n = 1;
  
	if(exponent){
	
		while(n++ <= exponent)
		{
				value *= base;
		}
	
	}
		
	return value;
	  
}