stm32l053r8t6做一个电子秤,编译软件用的IAR,但数码管示数闪烁,且颜色浅

img


当数码管显示物体重量的时候,后面的三位示数一直闪烁,0不会闪烁,而且看起来颜色很浅,几乎看不到,当重量超过1000g时,第一位的数字还是很清晰不会闪烁,求解答



/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2022 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l0xx_hal.h"

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define HX711_GapValue 457.0
//static uint8_t fac_us = 0;      //us延时倍乘数
unsigned long HX711_Real_Weight=0;
unsigned long Weight_Maopi=0;
unsigned long Weight_Shiwu = 0;
unsigned long Weight = 0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/*void DIGITAL_out(unsigned char X) ;
void display(unsigned int n) ;*/
void DIGITAL_out(unsigned char X) ;
void display(unsigned long n);
void delay(void);
//void delay_Init(void) ;
//void delay_us(uint32_t nus);
unsigned long HX711_Read(void);
//void Get_Weight(void);
unsigned long Get_Weight(void);
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  *
  * @retval None
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
   
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
  
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
   
   Weight_Maopi = HX711_Read();
   HAL_Delay(50);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
   
    Weight = Get_Weight();
    display(Weight);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
  

  }
  /* USER CODE END 3 */

}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /**Configure the main internal regulator output voltage 
    */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* USART2 init function */
static void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_7B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(CLK_GPIO_Port, CLK_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, LD2_Pin|DIO_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, SCLK_Pin|RCLK_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : DT_Pin */
  GPIO_InitStruct.Pin = DT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(DT_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : CLK_Pin */
  GPIO_InitStruct.Pin = CLK_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(CLK_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : LD2_Pin DIO_Pin */
  GPIO_InitStruct.Pin = LD2_Pin|DIO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : SCLK_Pin RCLK_Pin */
  GPIO_InitStruct.Pin = SCLK_Pin|RCLK_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
/* Digital OUTPUT function */
void DIGITAL_out(unsigned char X) 
{
  unsigned char i;
  for(i=8;i>=1;i--)
  {
    if (X&0x80) HAL_GPIO_WritePin(GPIOA, DIO_Pin, GPIO_PIN_SET);
    else HAL_GPIO_WritePin(GPIOA,DIO_Pin, GPIO_PIN_RESET);
    X<<=1;
    HAL_GPIO_WritePin(GPIOB, SCLK_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, SCLK_Pin, GPIO_PIN_SET);
  }
}
/* display function */
void display(unsigned long n) 
{
 
  static unsigned int thousand_bit, hundred_bit, ten_bit, single_bit;
  const unsigned char  *led_table;          // 查表指针,指针使用
  unsigned char i;  //定义需要放在LED赋值前
  unsigned char LED_0F[] =
  {
  0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf
  };
  thousand_bit = n / 1000;
  hundred_bit = (n % 1000) / 100;
  ten_bit = n % 1000 % 100 / 10;
  single_bit = n % 10;   //显示千位数
  
  //显示第1位
  led_table = LED_0F + single_bit;      //LED_OF是首地址,LED[0]移动
  i = *led_table;

  DIGITAL_out(i);            
  DIGITAL_out(0x01);         //位选
 
  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_RESET);       //    RCLK = 0;
  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_SET);         //    RCLK = 1;
  //显示第2位
  led_table = LED_0F + ten_bit;
  i = *led_table;

  DIGITAL_out(i);        
  DIGITAL_out(0x02);        

  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_RESET);       //    RCLK = 0;
  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_SET);         //    RCLK = 1;
  //显示第3位
  led_table = LED_0F + hundred_bit;
  i = *led_table;

  DIGITAL_out(i);            
  DIGITAL_out(0x04);    

  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_RESET);       //    RCLK = 0;
  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_SET);         //    RCLK = 1;
  //显示第4位
  led_table = LED_0F + thousand_bit;
  i = *led_table;

  DIGITAL_out(i);            
  DIGITAL_out(0x08);        

  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_RESET);       //    RCLK = 0;
  HAL_GPIO_WritePin(GPIOB, RCLK_Pin, GPIO_PIN_SET);         //    RCLK = 1;
}

void delay(void)
{
  for(int i=0;i<1;i++);
}


/* HX711_Read function */
unsigned long HX711_Read(void)    //增益128
{
  unsigned long count;
  unsigned char i;
  HAL_GPIO_WritePin(GPIOC, DT_Pin, GPIO_PIN_SET); // 拉低时钟引脚
  
  delay();
  HAL_GPIO_WritePin(GPIOC, CLK_Pin, GPIO_PIN_RESET); // 拉低时钟引脚
  
  delay();
  
  while(HAL_GPIO_ReadPin(GPIOC, DT_Pin));
  //while(DT_Pin);
        
  for( i=0;i<24;i++)
  { 
    HAL_GPIO_WritePin(GPIOC, CLK_Pin, GPIO_PIN_SET); // 拉高时钟
    
    delay();
    count=count<<1;
    HAL_GPIO_WritePin(GPIOC, CLK_Pin, GPIO_PIN_RESET);  
    delay();
    
    if(HAL_GPIO_ReadPin(GPIOC, DT_Pin)) count++;
    //if(DT_Pin) count++;
  } 
  HAL_GPIO_WritePin(GPIOC, CLK_Pin, GPIO_PIN_SET); 
  delay();
  
  count=count^0x800000;//第25个脉冲下降沿来时,转换数据
  
  HAL_GPIO_WritePin(GPIOC, CLK_Pin, GPIO_PIN_RESET);   
  delay();
  
  return count;
}



unsigned long Get_Weight(void)
{
  HX711_Real_Weight = HX711_Read();
  if(HX711_Real_Weight > Weight_Maopi)            
  {
          Weight_Shiwu = HX711_Real_Weight;

          Weight_Shiwu = Weight_Shiwu - Weight_Maopi;    
  
          Weight_Shiwu = (unsigned long)((float)Weight_Shiwu/HX711_GapValue);                                                                                                     
  }
  return Weight_Shiwu;
}


void _Error_Handler(char *file, int line)
{
  
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

是不是你测量一次就刷新一次数码管?数码管刷新频率不要太高,可以多测几次取均值再刷新数码管

可以先直接用硬件点亮数码管,确认数码管没有问题。这个大概率是程序问题,具体是控制引脚上下拉是否一致,或者是否持续高电平需要测试下

可能是读取weight的时间太长,而读取重量的这段时间的显示位选的是0号位置,所以0号位置亮度高,其它几位因为被点亮的间隔长,所以就显得暗而且有闪烁感。建议在定时器中断里扫描LED,而不是在读取完后再扫描。

刚才又看了一下,可能不是读取重量花的时间长,而是因为你在各个位之间切换后停留的时间太短,读取重量相当于让0号位停留更长一点时间,所以更亮一些。

试一下main函数这样写会常亮还是闪一下就灭?我怀疑是display里出了问题,led可能是低电平点亮

  Weight = Get_Weight();
  display(Weight);
  while (1)
  {
  }