zoukankan      html  css  js  c++  java
  • 基于HAL库STM32的FSMC驱动8位TFTLCD屏

    先上代码。

    main.c:

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under BSD 3-Clause license,
      * the "License"; You may not use this file except in compliance with the
      * License. You may obtain a copy of the License at:
      *                        opensource.org/licenses/BSD-3-Clause
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "stdio.h"
    #include "ili9341.h"
    #include "ctype.h"
    #include "stdlib.h"
    #include "INA226.h"
    #include "INA3221.h"
    /* USER CODE END Includes */
    
    /* Private typedef -----------------------------------------------------------*/
    /* USER CODE BEGIN PTD */
    
    /* USER CODE END PTD */
    
    /* Private define ------------------------------------------------------------*/
    /* USER CODE BEGIN PD */
    
    /* USER CODE END PD */
    
    /* Private macro -------------------------------------------------------------*/
    /* USER CODE BEGIN PM */
    
    /* USER CODE END PM */
    
    /* Private variables ---------------------------------------------------------*/
    ADC_HandleTypeDef hadc1;
    DMA_HandleTypeDef hdma_adc1;
    
    TIM_HandleTypeDef htim2;
    
    UART_HandleTypeDef huart1;
    
    SRAM_HandleTypeDef hsram1;
    
    /* USER CODE BEGIN PV */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_DMA_Init(void);
    static void MX_USART1_UART_Init(void);
    static void MX_FSMC_Init(void);
    static void MX_ADC1_Init(void);
    static void MX_TIM2_Init(void);
    /* USER CODE BEGIN PFP */
    
    /* USER CODE END PFP */
    
    /* Private user code ---------------------------------------------------------*/
    /* USER CODE BEGIN 0 */
        float adc0,adc1,adc2,adc3,adc4,adc5,adc6,
                        adc7,adc8,adc9,adc10,adc11,adc12,adc13,adc14,adc15,adc16,adc17,adc18,adc19,adc13a,adc14a,adc15a,adc16a,adc17a,adc18a,adc19a;
        uint32_t adc_0,adc_1,adc_2,adc_3,adc_4,adc_5,adc_6,
                  adc_7,adc_8,adc_9,adc_10,adc_11,adc_12,adc_13,adc_14,adc_15,adc_16,adc_17,adc_18,adc_19,adc_13a,adc_14a,adc_15a,adc_16a,adc_17a,adc_18a,adc_19a;
            uint32_t AD_DMA[13];
        
        char SStr[10];
        char SStr_A[10];
        uint8_t x = 0;
    /* USER CODE END 0 */
    
    /**
      * @brief  The application entry point.
      * @retval int
      */
    int main(void)
    {
      /* USER CODE BEGIN 1 */
        uint8_t key = 0;
      /* 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_DMA_Init();
      MX_USART1_UART_Init();
      MX_FSMC_Init();
      MX_ADC1_Init();
      MX_TIM2_Init();
      /* USER CODE BEGIN 2 */
        INA226_Init();
        INA3221_Init();
        
        //HAL_Delay(20);
        
        
        LCD_REG_Config();
        Lcd_data_start();  
    
        for(long z=0; z<76800; z++)                 
        {
            LCD_WR_Data(WHITE); 
        }
    //    printf("主函数测试 
    ");
        LCD_Str_O_BK(2,5,80,16,"LEDA_1 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,21,80,16,"LEDA_1A VOL =        V",RED,WHITE,20);
            LCD_Str_O_BK(2,37,80,16,"LEDA_2 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,53,80,16,"LEDA_2A VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,69,80,16,"LEDK_1 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,85,80,16,"LEDK_2 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,101,80,16,"LEDK_3 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,117,80,16,"LEDK_4 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,133,80,16,"OUT_VSN VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,146,80,16,"CURRENT_LEDK1 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,159,80,16,"CURRENT_LEDK2 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,172,80,16,"CURRENT_LEDK3 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,185,80,16,"CURRENT_LEDK4 VOL =       V",RED,WHITE,20);
            LCD_Str_O_BK(2,201,80,16,"226_VSN V =        V       A",RED,WHITE,20);
        LCD_Str_O_BK(2,217,80,16,"3221_VSPA =       V        A",RED,WHITE,20);
        LCD_Str_O_BK(2,233,80,16,"3221_VCIA =       V        A",RED,WHITE,20);
        LCD_Str_O_BK(2,249,80,16,"3221_3VA =       V         A",RED,WHITE,20);
        LCD_Str_O_BK(2,265,80,16,"3221_1V8A =       V        A",RED,WHITE,20);
        LCD_Str_O_BK(2,281,80,16,"3221_5VA =       V         A",RED,WHITE,20);
        LCD_Str_O_BK(2,297,80,16,"3221_VDDA =       V        A",RED,WHITE,20);
        //    LCD_Str_O_BK(2,5,80,16,"LEDA_1 VOL =      V",RED,WHITE,20);
        //    LCD_Num_6x12_P(88,319-8-16,key,RED);
        
        char cStr[10];
        
    //    sprintf(cStr,"%d", key);
    //                LCD_Str_O_BK(188,75,80,16,cStr,RED,WHITE,20);
        
            HAL_TIM_Base_Start_IT(&htim2);
            //HAL_ADCEx_Calibration_Start(&hadc1);
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
             HAL_ADC_Start_DMA(&hadc1, AD_DMA, 13);
            
            adc0 = (float)AD_DMA[0];
            adc1 = (float)AD_DMA[1];
            adc2 = (float)AD_DMA[2];
            adc3 = (float)AD_DMA[3];
            adc4 = (float)AD_DMA[4];
            adc5 = (float)AD_DMA[5];
            adc6 = (float)AD_DMA[6];
            adc7 = (float)AD_DMA[7];
            adc8 = (float)AD_DMA[8];
            adc9 = (float)AD_DMA[9];
            adc10 = (float)AD_DMA[10];
            adc11 = (float)AD_DMA[11];
            adc12 = (float)AD_DMA[12];
            
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
            key = KEY_Scan(0);
            sprintf(cStr,"%d", key);
            //    LCD_Str_O_BK(2,181,80,16,cStr,RED,WHITE,20);
                //LCD_Num_6x12_P(88,319-8-16,atoi(),RED);
                switch(key)
            {            
                case KEY1_PRES:
    //                    sprintf(cStr,"%d", key);
    //                LCD_Str_O_BK(168,75,80,16,cStr,RED,WHITE,20);
                HAL_GPIO_TogglePin(O_LEDA_1_POWER_ON_GPIO_Port, O_LEDA_1_POWER_ON_Pin);//测试MOS开关
                    //printf("LCD屏幕第一个按键, LEDA_1电压 = %.3f V 
    ", (adc0 * 3.3)/4096);
                break;    
            case KEY2_PRES:
    //                sprintf(cStr,"%d", key);
    //                LCD_Str_O_BK(168,75,80,16,cStr,RED,WHITE,20);
                    //printf("LCD屏幕第二个按键
    ");
            HAL_GPIO_TogglePin(O_OUT_VSN_POWER_ON_GPIO_Port, O_OUT_VSN_POWER_ON_Pin);//测试MOS开关
                    break;    
                case KEY3_PRES:
    //                    sprintf(cStr,"%d", key);
    //                LCD_Str_O_BK(168,75,80,16,cStr,RED,WHITE,20);
                    //printf("LCD屏幕第三个按键
    ");
                HAL_GPIO_TogglePin(O_OUT_VSP_POWER_ON_GPIO_Port, O_OUT_VSP_POWER_ON_Pin);//测试MOS开关
                HAL_GPIO_TogglePin(O_VCI_3_8V_OUT_POWER_ON_GPIO_Port, O_VCI_3_8V_OUT_POWER_ON_Pin);//测试MOS开关
                HAL_GPIO_TogglePin(O__3_0V_OUT_POWER_ON_GPIO_Port, O__3_0V_OUT_POWER_ON_Pin);//测试MOS开关
                    //    LCD_Rectangle(217,109,12,40,WHITE);//3221_vsp
    
    
                break;    
            case KEY4_PRES:
    //                sprintf(cStr,"%d", key);
    //                LCD_Str_O_BK(168,295,80,16,cStr,RED,WHITE,20);
                    //printf("LCD屏幕第四个按键
    ");
                HAL_GPIO_TogglePin(O_IOVCC_1_8V_OUT_POWER_ON_GPIO_Port, O_IOVCC_1_8V_OUT_POWER_ON_Pin);//测试MOS开关
            HAL_GPIO_TogglePin(O__5V_POWER_ON_GPIO_Port, O__5V_POWER_ON_Pin);//测试MOS开关
            HAL_GPIO_TogglePin(O_AVDD_POWER_ON_GPIO_Port, O_AVDD_POWER_ON_Pin);//测试MOS开关
            //    HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_11);            //喇叭
                break;    
                default:
                    HAL_Delay(10);    
            } 
      }
      /* USER CODE END 3 */
    }
    
    /**
      * @brief System Clock Configuration
      * @retval None
      */
    void SystemClock_Config(void)
    {
      RCC_OscInitTypeDef RCC_OscInitStruct = {0};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
      RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    
      /** Initializes the CPU, AHB and APB busses clocks 
      */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
      RCC_OscInitStruct.HSIState = RCC_HSI_ON;
      RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
      /** 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_HSI;
      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();
      }
      PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
      PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2;
      if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    /**
      * @brief ADC1 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_ADC1_Init(void)
    {
    
      /* USER CODE BEGIN ADC1_Init 0 */
    
      /* USER CODE END ADC1_Init 0 */
    
      ADC_ChannelConfTypeDef sConfig = {0};
    
      /* USER CODE BEGIN ADC1_Init 1 */
    
      /* USER CODE END ADC1_Init 1 */
      /** Common config 
      */
      hadc1.Instance = ADC1;
      hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
      hadc1.Init.ContinuousConvMode = DISABLE;
      hadc1.Init.DiscontinuousConvMode = DISABLE;
      hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
      hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
      hadc1.Init.NbrOfConversion = 13;
      if (HAL_ADC_Init(&hadc1) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_0;
      sConfig.Rank = ADC_REGULAR_RANK_1;
      sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_1;
      sConfig.Rank = ADC_REGULAR_RANK_2;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_2;
      sConfig.Rank = ADC_REGULAR_RANK_3;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_3;
      sConfig.Rank = ADC_REGULAR_RANK_4;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_4;
      sConfig.Rank = ADC_REGULAR_RANK_5;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_5;
      sConfig.Rank = ADC_REGULAR_RANK_6;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_6;
      sConfig.Rank = ADC_REGULAR_RANK_7;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_7;
      sConfig.Rank = ADC_REGULAR_RANK_8;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_8;
      sConfig.Rank = ADC_REGULAR_RANK_9;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_10;
      sConfig.Rank = ADC_REGULAR_RANK_10;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_11;
      sConfig.Rank = ADC_REGULAR_RANK_11;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_12;
      sConfig.Rank = ADC_REGULAR_RANK_12;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel 
      */
      sConfig.Channel = ADC_CHANNEL_13;
      sConfig.Rank = ADC_REGULAR_RANK_13;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN ADC1_Init 2 */
    
      /* USER CODE END ADC1_Init 2 */
    
    }
    
    /**
      * @brief TIM2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_TIM2_Init(void)
    {
    
      /* USER CODE BEGIN TIM2_Init 0 */
    
      /* USER CODE END TIM2_Init 0 */
    
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
    
      /* USER CODE BEGIN TIM2_Init 1 */
    
      /* USER CODE END TIM2_Init 1 */
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 10000-1;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 800-1;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN TIM2_Init 2 */
    
      /* USER CODE END TIM2_Init 2 */
    
    }
    
    /**
      * @brief USART1 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_USART1_UART_Init(void)
    {
    
      /* USER CODE BEGIN USART1_Init 0 */
    
      /* USER CODE END USART1_Init 0 */
    
      /* USER CODE BEGIN USART1_Init 1 */
    
      /* USER CODE END USART1_Init 1 */
      huart1.Instance = USART1;
      huart1.Init.BaudRate = 9600;
      huart1.Init.WordLength = UART_WORDLENGTH_8B;
      huart1.Init.StopBits = UART_STOPBITS_1;
      huart1.Init.Parity = UART_PARITY_NONE;
      huart1.Init.Mode = UART_MODE_TX_RX;
      huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart1.Init.OverSampling = UART_OVERSAMPLING_16;
      if (HAL_UART_Init(&huart1) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN USART1_Init 2 */
    
      /* USER CODE END USART1_Init 2 */
    
    }
    
    /** 
      * Enable DMA controller clock
      */
    static void MX_DMA_Init(void) 
    {
    
      /* DMA controller clock enable */
      __HAL_RCC_DMA1_CLK_ENABLE();
    
      /* DMA interrupt init */
      /* DMA1_Channel1_IRQn interrupt configuration */
      HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
    
    }
    
    /**
      * @brief GPIO Initialization Function
      * @param None
      * @retval None
      */
    static void MX_GPIO_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOE_CLK_ENABLE();
      __HAL_RCC_GPIOF_CLK_ENABLE();
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOG_CLK_ENABLE();
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOF, O_OUT_VSP_POWER_ON_Pin|O_VCI_3_8V_OUT_POWER_ON_Pin|O__3_0V_OUT_POWER_ON_Pin|O_IOVCC_1_8V_OUT_POWER_ON_Pin 
                              |O__5V_POWER_ON_Pin|O_AVDD_POWER_ON_Pin|O_OUT_VSN_POWER_ON_Pin|O_LEDA_1_POWER_ON_Pin 
                              |O_LEDA_2_POWER_ON_Pin, GPIO_PIN_RESET);
    
      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(PF11_SPEAKER_GPIO_Port, PF11_SPEAKER_Pin, GPIO_PIN_SET);
    
      /*Configure GPIO pins : KEY3_Pin KEY4_Pin KEY1_Pin KEY2_Pin */
      GPIO_InitStruct.Pin = KEY3_Pin|KEY4_Pin|KEY1_Pin|KEY2_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_PULLUP;
      HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    
      /*Configure GPIO pins : O_OUT_VSP_POWER_ON_Pin O_VCI_3_8V_OUT_POWER_ON_Pin O__3_0V_OUT_POWER_ON_Pin O_IOVCC_1_8V_OUT_POWER_ON_Pin 
                               O__5V_POWER_ON_Pin O_AVDD_POWER_ON_Pin O_OUT_VSN_POWER_ON_Pin O_LEDA_1_POWER_ON_Pin 
                               O_LEDA_2_POWER_ON_Pin */
      GPIO_InitStruct.Pin = O_OUT_VSP_POWER_ON_Pin|O_VCI_3_8V_OUT_POWER_ON_Pin|O__3_0V_OUT_POWER_ON_Pin|O_IOVCC_1_8V_OUT_POWER_ON_Pin 
                              |O__5V_POWER_ON_Pin|O_AVDD_POWER_ON_Pin|O_OUT_VSN_POWER_ON_Pin|O_LEDA_1_POWER_ON_Pin 
                              |O_LEDA_2_POWER_ON_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_PULLDOWN;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
    
      /*Configure GPIO pin : PF11_SPEAKER_Pin */
      GPIO_InitStruct.Pin = PF11_SPEAKER_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_PULLUP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(PF11_SPEAKER_GPIO_Port, &GPIO_InitStruct);
    
    }
    
    /* FSMC initialization function */
    static void MX_FSMC_Init(void)
    {
    
      /* USER CODE BEGIN FSMC_Init 0 */
    
      /* USER CODE END FSMC_Init 0 */
    
      FSMC_NORSRAM_TimingTypeDef Timing = {0};
      FSMC_NORSRAM_TimingTypeDef ExtTiming = {0};
    
      /* USER CODE BEGIN FSMC_Init 1 */
    
      /* USER CODE END FSMC_Init 1 */
    
      /** Perform the SRAM1 memory initialization sequence
      */
      hsram1.Instance = FSMC_NORSRAM_DEVICE;
      hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
      /* hsram1.Init */
      hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;
      hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
      hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
      hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
      hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
      hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
      hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
      hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
      hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
      hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
      hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE;
      hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
      hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
      /* Timing */
      Timing.AddressSetupTime = 15;
      Timing.AddressHoldTime = 15;
      Timing.DataSetupTime = 24;
      Timing.BusTurnAroundDuration = 0;
      Timing.CLKDivision = 16;
      Timing.DataLatency = 17;
      Timing.AccessMode = FSMC_ACCESS_MODE_A;
      /* ExtTiming */
      ExtTiming.AddressSetupTime = 8;
      ExtTiming.AddressHoldTime = 15;
      ExtTiming.DataSetupTime = 8;
      ExtTiming.BusTurnAroundDuration = 0;
      ExtTiming.CLKDivision = 16;
      ExtTiming.DataLatency = 17;
      ExtTiming.AccessMode = FSMC_ACCESS_MODE_A;
    
      if (HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming) != HAL_OK)
      {
        Error_Handler( );
      }
    
      /** Disconnect NADV
      */
    
      __HAL_AFIO_FSMCNADV_DISCONNECTED();
    
      /* USER CODE BEGIN FSMC_Init 2 */
    
      /* USER CODE END FSMC_Init 2 */
    }
    
    /* USER CODE BEGIN 4 */
    struct __FILE 
    { 
    int handle;
    
    };
    
    FILE __stdout; 
    //定义_sys_exit()以避免使用半主机模式 
    void _sys_exit(int x) 
    { 
    x = x; 
    } 
    //重定义fputc函数 
    int fputc(int ch, FILE *f)
    { 
    while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 
    USART1->DR = (uint8_t) ch; 
    return ch;
    }
    
    uint8_t KEY_Scan(uint8_t mode)
    {
         static uint8_t key_up=1;     //按键松开标志
        if(mode==1)key_up=1;    //支持连按
        if(key_up&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
        {
            HAL_Delay(10);
            key_up=0;
                 if(KEY1==0)       return KEY1_PRES;
                else if(KEY2==0)       return KEY2_PRES;
                else if(KEY3==0)       return KEY3_PRES;
                else if(KEY4==0)       return KEY4_PRES;
                       
        }
            else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
                key_up=1;
            
        return 0;   //无按键按下
    }
    
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
     {
         if(x == 0)
         {
             LCD_Str_O_BK(180,30,80,16,"....",BLUE,WHITE,20);
             x = 1;
         }
         else if(x == 1)
         {
              LCD_Str_O_BK(180,30,80,16,"     ",BLUE,WHITE,20);
            x = 0;
         }
            
         //LEDA_1
         adc0 = (adc0 * 3.3)/4096;     
            sprintf(SStr, "%.4f", adc0);
         LCD_Str_O_BK(100,5,80,16,SStr,BLUE,WHITE,20);
             
         //LEDA_1A
          adc1 = (adc1 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc1);
                 LCD_Str_O_BK(107,21,80,16,SStr,BLUE,WHITE,20);
             
         
                 //LEDA_2
         adc2 = (adc2 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc2);
             LCD_Str_O_BK(100,37,80,16,SStr,BLUE,WHITE,20);
        
                
                     //LEDA_2A
          adc3 = (adc3 * 3.3)/4096;
    
             sprintf(SStr,"%.4f", adc3);
                 LCD_Str_O_BK(107,53,80,16,SStr,BLUE,WHITE,20);
    
                
                     //LEDK_1
          adc4 = (adc4 * 3.3)/4096;
    
             sprintf(SStr,"%.4f", adc4);
                 LCD_Str_O_BK(100,69,80,16,SStr,BLUE,WHITE,20);
    
                
                     //LEDK_2
          adc5 = (adc5 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc5);
                 LCD_Str_O_BK(100,85,80,16,SStr,BLUE,WHITE,20);
    
                
                     //LEDK_3
          adc6 = (adc6 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc6);
                 LCD_Str_O_BK(100,101,80,16,SStr,BLUE,WHITE,20);
    
                
                     //LEDK_4
          adc7 = (adc7 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc7);
                 LCD_Str_O_BK(100,117,80,16,SStr,BLUE,WHITE,20);
    
                
                     //O_OUT_VSN
             //printf("adc8 = %.2f
    ",adc8);
          adc8 = (adc8 * 3.3)/4096;
    
             sprintf(SStr,"%.4f", adc8);
                 LCD_Str_O_BK(107,133,80,16,SStr,BLUE,WHITE,20);
    
                     //CURRENT_LEDK1_ADC
          adc9 = (adc9 * 3.3)/4096;
    
             sprintf(SStr,"%.4f", adc_9);
                 LCD_Str_O_BK(157,146,80,16,SStr,BLUE,WHITE,20);
    
                
                     //CURRENT_LEDK2_ADC
          adc10 = (adc10 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc_10);
                 LCD_Str_O_BK(157,159,80,16,SStr,BLUE,WHITE,20);
    
                
                     //CURRENT_LEDK3_ADC
          adc11 = (adc11 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc_11);
                 LCD_Str_O_BK(157,172,80,16,SStr,BLUE,WHITE,20);
    
                
                     //CURRENT_LEDK4_ADC
          adc12 = (adc12 * 3.3)/4096;
             sprintf(SStr,"%.4f", adc_12);
                 LCD_Str_O_BK(157,185,80,16,SStr,BLUE,WHITE,20);
    
                
                             //226_VSN_V
          adc13 = (((float)INA226_GetVoltage(0x80)*1.25) / 1000) - 8.948;     
             sprintf(SStr,"%.4f", adc13);
             LCD_Str_O_BK(94,201,80,16,SStr,BLUE,WHITE,20);
    
                    
                     adc13a = ((float)(INA226_GetShunt_Current(0x80)  * 2.5)) * 0.001f ;  //A    
                    if(adc13a < 0){adc13a = -adc13a;}
                 sprintf(SStr_A, "%.4f", adc13a);
                     LCD_Str_O_BK(167,201,80,16,SStr_A,BLUE,WHITE,20);
    
             
    //3221_VSP_V
          adc14 = ((float)(INA3221_GetVoltage(0x82, 1)  * 0.001f));    
             sprintf(SStr,"%.4f", adc14);        
                 LCD_Str_O_BK(92,217,80,16,SStr,BLUE,WHITE,20);
    
                
                adc14a = ((float)(INA3221_GetShuntVoltage(0x82, 1)  * 1)) * 5 * 10 * 0.000001f;  //A
                 sprintf(SStr_A, "%.4f", adc14a);
                     LCD_Str_O_BK(165,217,80,16,SStr_A,BLUE,WHITE,20);
    
                
         //3221_VCI_V
          adc15 = ((float)(INA3221_GetVoltage(0x82, 2)  * 0.001f));        
             sprintf(SStr,"%.4f", adc15);
                 LCD_Str_O_BK(92,233,80,16,SStr,BLUE,WHITE,20);
    
                
            adc15a = ((float)(INA3221_GetShuntVoltage(0x82, 2)  * 1)) * 5 * 10 * 0.000001f;  //A
                 sprintf(SStr_A, "%.4f", adc15a);
                     LCD_Str_O_BK(165,233,80,16,SStr_A,BLUE,WHITE,20);
    
                
                                 //3221_3V_V
          adc16 = ((float)(INA3221_GetVoltage(0x82, 3)  * 0.001f));    
             sprintf(SStr,"%.4f", adc16);
                 LCD_Str_O_BK(84,249,80,16,SStr,BLUE,WHITE,20);
    
                
                adc16a = ((float)(INA3221_GetShuntVoltage(0x82, 3)  * 1)) * 5 * 10 * 0.000001f;  //A
                 sprintf(SStr_A, "%.4f", adc16a);
                     LCD_Str_O_BK(165,249,80,16,SStr_A,BLUE,WHITE,20);
    
                
                                 //3221_1.8_V
          adc17 = ((float)(INA3221_GetVoltage(0x84, 1)  * 0.001f));
             sprintf(SStr,"%.4f", adc17);
                 LCD_Str_O_BK(92,265,80,16,SStr,BLUE,WHITE,20);
    
                
                adc17a = ((float)(INA3221_GetShuntVoltage(0x84, 1)  * 1)) * 5 * 10 * 0.000001f;  //A
                 sprintf(SStr_A, "%.4f", adc17a);
                    LCD_Str_O_BK(165,265,80,16,SStr_A,BLUE,WHITE,20);
    
                
                                 //3221_5_V
          adc18 = ((float)(INA3221_GetVoltage(0x84, 2)  * 0.001f));
             sprintf(SStr,"%.4f", adc18);
                 LCD_Str_O_BK(84,281,80,16,SStr,BLUE,WHITE,20);
    
                
                        adc18a = ((float)(INA3221_GetShuntVoltage(0x84, 2)  * 1)) * 5 * 10 * 0.000001f;  //A
                 sprintf(SStr_A, "%.4f", adc18a);
                     LCD_Str_O_BK(165,281,80,16,SStr_A,BLUE,WHITE,20);
    
                
                                 //3221_VDD_V
          adc19 = ((float)(INA3221_GetVoltage(0x84, 3)  * 1));
             sprintf(SStr,"%.4f", adc19);
                 LCD_Str_O_BK(92,297,80,16,SStr,BLUE,WHITE,20);
    
                
                adc19a = ((float)(INA3221_GetShuntVoltage(0x84, 3)  * 1)) * 5 * 10 * 0.000001f;  //A
                 sprintf(SStr_A, "%.4f", adc19a);
                     LCD_Str_O_BK(165,297,80,16,SStr_A,BLUE,WHITE,20);
    
                //
    }
         
    /* USER CODE END 4 */
    
    /**
      * @brief  This function is executed in case of error occurrence.
      * @retval None
      */
    void Error_Handler(void)
    {
      /* USER CODE BEGIN Error_Handler_Debug */
      /* User can add his own implementation to report the HAL error return state */
    
      /* 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
    ", file, line) */
      /* USER CODE END 6 */
    }
    #endif /* USE_FULL_ASSERT */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    View Code

    ili9341.c:

    #include "ili9341.h"
    #include "stm32f1xx_hal_sram.h"
    #include "asc_font.h"
    uint8_t display_direction = 1;
    
      //写寄存器函数
    //regval:寄存器值
    void LCD_WR_REG(vu16 regval)
    {   
        regval=regval;        //使用-O2优化的时候,必须插入的延时
        LCD->LCD_REG=regval;//写入要写的寄存器序号     
    }                                                
    //写LCD数据
    //data:要写入的值
    void LCD_WR_DATA(vu16 data)
    {      
        data=data;            //使用-O2优化的时候,必须插入的延时
        LCD->LCD_RAM=data;         
    }
    
    void LCD_WR_Data(uint16_t u16Date)
    {
        LCD_WR_DATA(u16Date>>8);
        LCD_WR_DATA(u16Date);
    }                                                                                                    
    
    
    void Lcd_data_start(void)
    {
        LCD_WR_REG(0x2C);//开始写
    }
    
    /**
     * @brief  配置lcd初始化寄存器
     * @param  无
     * @retval 无
     */
    void LCD_REG_Config(void)
    {  
        LCD_WR_REG(0x01);
        HAL_Delay(100);
        
        LCD_WR_REG(0x11);     
    
        LCD_WR_REG(0x36);     
        LCD_WR_DATA(0x00);   
    
        LCD_WR_REG(0x3A);     
        LCD_WR_DATA(0x05);   
    
        LCD_WR_REG(0xB2);     
        LCD_WR_DATA(0x0C);   
        LCD_WR_DATA(0x0C);   
        LCD_WR_DATA(0x00);   
        LCD_WR_DATA(0x33);   
        LCD_WR_DATA(0x33);   
    
        LCD_WR_REG(0xB7);     
        LCD_WR_DATA(0x75);   //VGH=14.97V, VGL=-10.43V  
    
        LCD_WR_REG(0xBB);   //VCOM  
        LCD_WR_DATA(0x19);   
    
        LCD_WR_REG(0xC0);     
        LCD_WR_DATA(0x0C); // D5----RGB/BGR  
    
        LCD_WR_REG(0xC2);     
        LCD_WR_DATA(0x01);   
    
        LCD_WR_REG(0xC3);   //GVDD    VRH
        LCD_WR_DATA(0x1D);   //GVDD=5V   
    
        LCD_WR_REG(0xC4);     
        LCD_WR_DATA(0x20);   
    
        LCD_WR_REG(0xC6);  //??   
        LCD_WR_DATA(0x0F);   
    
        LCD_WR_REG(0xD0);     
        LCD_WR_DATA(0xA4);   
        LCD_WR_DATA(0xA1);   
    
        LCD_WR_REG(0xE0);     
        LCD_WR_DATA(0xD0);   
        LCD_WR_DATA(0x03);   
        LCD_WR_DATA(0x0B);   
        LCD_WR_DATA(0x14);   
        LCD_WR_DATA(0x17);   
        LCD_WR_DATA(0x1D);   
        LCD_WR_DATA(0x3F);   
        LCD_WR_DATA(0x44);   
        LCD_WR_DATA(0x4E);   
        LCD_WR_DATA(0x0A);   
        LCD_WR_DATA(0x13);   
        LCD_WR_DATA(0x13);   
        LCD_WR_DATA(0x1E);   
        LCD_WR_DATA(0x20);   
    
        LCD_WR_REG(0xE1);     
        LCD_WR_DATA(0xD0);   
        LCD_WR_DATA(0x03);   
        LCD_WR_DATA(0x0B);   
        LCD_WR_DATA(0x12);   
        LCD_WR_DATA(0x14);   
        LCD_WR_DATA(0x1C);   
        LCD_WR_DATA(0x3F);   
        LCD_WR_DATA(0x44);   
        LCD_WR_DATA(0x4E);   
        LCD_WR_DATA(0x0B);   
        LCD_WR_DATA(0x17);   
        LCD_WR_DATA(0x15);   
        LCD_WR_DATA(0x1E);   
        LCD_WR_DATA(0x21);   
    
        LCD_WR_REG(0x29);  
    }
    
    /**********************************
     * 函数名:Set_direction
     * 描述  :设置ILI9341GRAM指针扫描方向
     * 输入  : 0: 横向扫描
                1: 纵向扫描
     * 输出  :无
     * 举例  :无
     * 注意  :无
    *************************************/
    void Set_direction(uint8_t option)
    {
        switch(option)
        {
        case 0:
        /*横屏*/
            LCD_WR_REG(0x36); 
            LCD_WR_DATA(0x68);    //横屏
            LCD_WR_REG(0X2A); 
            LCD_WR_DATA(0x00);    //start  00
            LCD_WR_DATA(0x00);
            LCD_WR_DATA(0x01);    //end  319
            LCD_WR_DATA(0x3F);
    
            LCD_WR_REG(0X2B); 
            LCD_WR_DATA(0x00);   //start  00
            LCD_WR_DATA(0x00);
            LCD_WR_DATA(0x00);   //end    239
            LCD_WR_DATA(0xEF);
            display_direction = 0;        
            break;
        case 1:
            /*竖屏*/
            LCD_WR_REG(0x36); 
            LCD_WR_DATA(0x08);    //竖屏 
            LCD_WR_REG(0X2A); 
            LCD_WR_DATA(0x00);    //00
            LCD_WR_DATA(0x00);
            LCD_WR_DATA(0x00);
            LCD_WR_DATA(0xEF);    //239
    
            LCD_WR_REG(0X2B); 
            LCD_WR_DATA(0x00);    //00
            LCD_WR_DATA(0x00);
            LCD_WR_DATA(0x01);
            LCD_WR_DATA(0x3F);    //319
            display_direction = 1;
            break;
        }
    }
    
    /**********************************
     * 函数名:LCD_open_windows
     * 描述  :开窗(以x,y为坐标起点,长为len,高为wid)
     * 输入  : -x    窗户起点
               -y       窗户起点
               -len  窗户长 
               -wid 窗户宽
     * 输出  :无
     * 举例  :无
     * 注意  :无
    *************************************/
    void LCD_open_windows(uint16_t x,uint16_t y,uint16_t len,uint16_t wid)
    {                    
        if(display_direction == 0)        /*如果是横屏选项*/
        {
            LCD_WR_REG(0X2A); 
            LCD_WR_DATA(x>>8);    //start 
            LCD_WR_DATA(x-((x>>8)<<8));
            LCD_WR_DATA((x+len-1)>>8);    //end
            LCD_WR_DATA((x+len-1)-(((x+len-1)>>8)<<8));
            
            LCD_WR_REG(0X2B); 
            LCD_WR_DATA(y>>8);   //start
            LCD_WR_DATA(y-((y>>8)<<8));
            LCD_WR_DATA((y+wid-1)>>8);   //end
            LCD_WR_DATA((y+wid-1)-(((y+wid-1)>>8)<<8));
        }
        else
        {
            LCD_WR_REG(0X2A); 
            LCD_WR_DATA(x>>8);
            LCD_WR_DATA(x-((x>>8)<<8));
            LCD_WR_DATA((x+len-1)>>8);
            LCD_WR_DATA((x+len-1)-(((x+len-1)>>8)<<8));
    
            LCD_WR_REG(0X2B); 
            LCD_WR_DATA(y>>8);
            LCD_WR_DATA(y-((y>>8)<<8));
            LCD_WR_DATA((y+wid-1)>>8);
            LCD_WR_DATA((y+wid-1)-(((y+wid-1)>>8)<<8));    
        }
        LCD_WR_REG(0x2c);     
    }
    
    void LCD_Redraw(uint16_t Color)
    {
        unsigned long i;            
        Lcd_data_start();   
        for(i=0; i<(240*320); i++)                 
        {
            LCD_WR_Data(Color);                         
        }   
    }
    
    
    
    /***************************************/
    void LCD_Str_O_BK(uint16_t x, uint16_t y,uint16_t w,uint16_t h,const uint8_t *str,uint16_t Color,uint16_t BkColor,uint8_t u8StrSize)
    {
        uint16_t u16x,u16y,u16w,u16h;
        
           Set_direction(1);     
        
            u16w=u8StrSize*8;
        //u16w=5*8;
        
        if(u16w<w)
        {
            u16x=x+(w-u16w)/2;
        }
        else
        {
            u16x=x;
        }
        
        u16h=16;
        
        if(u16h<h)
        {
            u16y=y+(h-u16h)/2;
        }
        else
        {
            u16y=y;
        }
        
    
        while(*str != '')
        {       
                if(u16x > (240-8)) 
                {    
                    //换行
                     u16x = 0;
                     u16y += 16;
                }
                if(u16y > (320-16)) 
                {    
                    //一屏
                     u16x = u16y = 0;
                }
                
                LCD_Char_O_BK(u16x ,u16y, *str,Color,BkColor); // LCD_Char_O
                u16x += 8;
                str ++ ;
        }
            
    }
    
    void LCD_Char_O_BK(uint16_t x, uint16_t y, uint8_t acsii,uint16_t Color,uint16_t BkColor)
    {       
    #define MAX_CHAR_POSX (240-8)
    #define MAX_CHAR_POSY (320-16)
        uint8_t temp, t, pos;     
        if(x > MAX_CHAR_POSX || y > MAX_CHAR_POSY)
            return;
           
        LCD_open_windows(x,y,8,16); 
        
        for (pos=0;pos<16;pos++)
        {
            temp=ascii_8x16[((acsii-0x20)*16)+pos];
            
            for(t=0; t<8; t++)
            {
                if(temp & 0x80)
                {
                                if(t==0)                                       /*如果是一行起点--则重新开启一个矩形*/
                                {
                                    LCD_open_windows(x,y+pos,8,16-pos);
                                    LCD_WR_Data(Color);
                                }
                                else
                                {
                                    LCD_WR_Data(Color);    
                                }
                }
                            else     
                {
                                if(t==7)                                    /*如果是末尾点--则直接开启下一个矩形*/
                                {    
                                        LCD_WR_Data(BkColor);    
                                        LCD_open_windows(x,y+pos+1,8,16-pos-1);         
                                }
                                else
                                {
                                        LCD_WR_Data(BkColor);    
                                        LCD_open_windows(x+t+1,y+pos,8-t,1);/*前进一位 开启一行线*/    
                                }
                } 
                
                temp <<= 1;    
            }        
        }
    #undef MAX_CHAR_POSX
    #undef MAX_CHAR_POSY   
    }
    void LCD_Rectangle(uint16_t x,uint16_t y,uint16_t len,uint16_t wid,uint16_t rgb565)
    {                    
       uint32_t n, temp;
         Set_direction(0);                             /*设定方向为横向*/
       LCD_open_windows(x,y,len,wid);   
       temp = (uint32_t)len*wid;    
       for(n=0; n<temp; n++)
         {
            LCD_WR_Data( rgb565 );
         }
    }
    void LCD_Num_6x12_P(uint16_t x,uint16_t y,uint32_t num, uint16_t Color)      
    {      
        uint32_t res=num;          
        uint8_t t=0;
    
            Set_direction(1);  
          if( num == 0 )
            {
                LCD_Char_6x12_O(x, y, '0',Color);
                        return;
            }    
           while( res )  /*得到数字长度t*/
        {
            res/=10;
            t++;
        }
    
            while(num)
            {
                 LCD_Char_6x12_O(x+(6*(t--)-6), y, (num%10)+'0',Color);/*先显示低位在显示高位*/
                 num /= 10 ;
            }                 
    } 
    
    void LCD_Char_6x12_O(uint16_t x, uint16_t y, uint8_t acsii, uint16_t Color)    
    {       
    #define MAX_CHAR_POSX (240-6)
    #define MAX_CHAR_POSY (320-12)
        uint8_t temp, t, pos;  
     
         if(x > MAX_CHAR_POSX || y > MAX_CHAR_POSY)
         {
                 return;
             }
    
        LCD_open_windows(x,y,6,12);
       
        acsii = acsii - ' ';                                             /*得到偏移后的值*/
        for(pos=0; pos<12; pos++)
        {
            temp = asc2_1206[acsii][pos];
            for(t=0; t<6; t++)                                            /* 低位开始,丢弃高两位*/
            {                 
                if(temp & 0x01)
                 {
                    if(t==0)
                    {
                        LCD_open_windows(x,y+pos,6,12-pos);
                        LCD_WR_Data(Color);
                    }
                    else
                    {
                        LCD_WR_Data(Color);    
                    }
                 }
                else     
                {
                    if(t==5)                                            /*如果是末尾点--开启剩下窗户*/
                    {
                            LCD_open_windows(x,y+pos+1,6,12-pos-1);         
                    }
                    else
                    {
                            LCD_open_windows(x+t+1,y+pos,6-t,1);          /*前进一位 开启一行线*/    
                    }                
                }   
                temp >>= 1; 
            }
        }
        
    #undef MAX_CHAR_POSX
    #undef MAX_CHAR_POSY   
    }
    View Code

    ili9341.h:

    #ifndef __ILI9341_H
    #define __ILI9341_H
    
    #include "stm32f1xx_hal.h"
    
    typedef struct
    {
        __IO uint16_t LCD_REG;
        __IO uint16_t LCD_RAM;
    } LCD_TypeDef;
    
    //使用NOR/SRAM的 Bank1.sector4,地址位HADDR[27,26]=11 A23作为数据命令区分线 
    //注意设置时STM32内部会右移一位对其!                 
    #define LCD_BASE        ((uint32_t)(0x6C000000 | 0x007FFFFE))
    #define LCD             ((LCD_TypeDef *) LCD_BASE)
    #define vu16                         __IO uint16_t
    
    /******常用颜色*****/
    #define RED      0XF800
    #define GREEN 0X07E0
    #define BLUE  0X001F  
    #define BRED  0XF81F
    #define GRED  0XFFE0
    #define GBLUE 0X07FF
    #define BLACK 0X0000
    #define WHITE 0XFFFF
    #define YELLOW 0XFFE0
    #define BK_COLOR 0XFFFF//0xC618
    #define Navy            0x000F      /*   0,   0, 128 */
    #define DarkGreen       0x03E0      /*   0, 128,   0 */
    #define DarkCyan        0x03EF      /*   0, 128, 128 */
    #define Maroon          0x7800      /* 128,   0,   0 */
    #define Purple          0x780F      /* 128,   0, 128 */
    #define Olive           0x7BE0      /* 128, 128,   0 */
    #define LightGrey       0xC618      /* 192, 192, 192 */
    #define DarkGrey        0x7BEF      /* 128, 128, 128 */
    #define Cyan            0x07FF      /*   0, 255, 255 */
    #define Red             0xF800      /* 255,   0,   0 */
    #define Magenta         0xF81F      /* 255,   0, 255 */
    #define Orange          0xFD20      /* 255, 165,   0 */
    #define GreenYellow     0xAFE5      /* 173, 255,  47 */
    #define Pink            0xF81F
    
    void LCD_WR_REG(vu16 regval);
    void LCD_WR_DATA(vu16 data);
    void LCD_WR_Data(uint16_t u16Date);
    void Lcd_data_start(void);
    void LCD_REG_Config(void);
        
        
        
    void LCD_Rectangle(uint16_t x,uint16_t y,uint16_t len,uint16_t wid,uint16_t rgb565);    
    void LCD_Char_O_BK(uint16_t x, uint16_t y, uint8_t acsii,uint16_t Color,uint16_t BkColor);
    void LCD_Str_O_BK(uint16_t x, uint16_t y,uint16_t w,uint16_t h,const uint8_t *str,uint16_t Color,uint16_t BkColor,uint8_t u8StrSize);
    void LCD_Char_6x12_O(uint16_t x, uint16_t y, uint8_t acsii, uint16_t Color);
    void LCD_Num_6x12_P(uint16_t x,uint16_t y,uint32_t num, uint16_t Color);      
    #endif
    View Code

    在使用FSMC之前,要看看使用芯片的规格是否支持到到16位的fsmc总线,少Pin脚的IC应该是没有的。

    然后就是了解FSMC大概情况,我们使用FSMC驱动LCD,相比8080驱动,速度更快,我对它的理解其实就是一个外部总线,且是一个可以自己定义时序的总线并且速度不慢,当驱动8080接口的器件是时,由于STM32没有自带硬件8080接口的控制器,如果只是使用GPIO来实现此时序的话,会占用大量的CPU资源,所以这个时候就可以考虑采用FSMC功能。

    当设置好FSMC接口后,不用手动设置时序,方便快捷。

    参考:https://blog.csdn.net/jxnu_xiaobing/article/details/8719897?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

    CubeMX中的设置:

    根据自己项目原理图接口,选择了A22作为RS口。

    cubemx设置后有:

    static void MX_FSMC_Init(void)
    {
    
      /* USER CODE BEGIN FSMC_Init 0 */
    
      /* USER CODE END FSMC_Init 0 */
    
      FSMC_NORSRAM_TimingTypeDef Timing = {0};
      FSMC_NORSRAM_TimingTypeDef ExtTiming = {0};
    
      /* USER CODE BEGIN FSMC_Init 1 */
    
      /* USER CODE END FSMC_Init 1 */
    
      /** Perform the SRAM1 memory initialization sequence
      */
      hsram1.Instance = FSMC_NORSRAM_DEVICE;
      hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
      /* hsram1.Init */
      hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;
      hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
      hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
      hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
      hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
      hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
      hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
      hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
      hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
      hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
      hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_ENABLE;
      hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
      hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
      /* Timing */
      Timing.AddressSetupTime = 15;
      Timing.AddressHoldTime = 15;
      Timing.DataSetupTime = 24;
      Timing.BusTurnAroundDuration = 0;
      Timing.CLKDivision = 16;
      Timing.DataLatency = 17;
      Timing.AccessMode = FSMC_ACCESS_MODE_A;
      /* ExtTiming */
      ExtTiming.AddressSetupTime = 8;
      ExtTiming.AddressHoldTime = 15;
      ExtTiming.DataSetupTime = 8;
      ExtTiming.BusTurnAroundDuration = 0;
      ExtTiming.CLKDivision = 16;
      ExtTiming.DataLatency = 17;
      ExtTiming.AccessMode = FSMC_ACCESS_MODE_A;
    
      if (HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming) != HAL_OK)
      {
        Error_Handler( );
      }
    
      /** Disconnect NADV
      */
    
      __HAL_AFIO_FSMCNADV_DISCONNECTED();
    
      /* USER CODE BEGIN FSMC_Init 2 */
    
      /* USER CODE END FSMC_Init 2 */
    }

    LCD_BASE,须根据外部电路的连接来确定,如Bank1.sector4就是从地址0x6C000000开始,而0x000007FE,则是A10的偏移量。以A10为例,7FE换成二进制位为:111 1111 1110,而16位数据时,地址右移一位对齐,对应到地址引脚,就是:A10:A0 = 011 1111 1111,此时A10是0,但是如果16位地址再加1,那么A10:A0 = 100 0000 0000,此时A10就是1了,即实现了对RS的0和1的控制。

    这里是A22作为RS口,有上面同理算得,

    #define LCD_BASE        ((uint32_t)(0x6C000000 | 0x007FFFFE))
    #define LCD             ((LCD_TypeDef *) LCD_BASE)

    在ili9341.h中定义结构体

    typedef struct
    {
        __IO uint16_t LCD_REG;
        __IO uint16_t LCD_RAM;
    } LCD_TypeDef;

    写数据和寄存器的函数:

      //写寄存器函数
    //regval:寄存器值
    void LCD_WR_REG(vu16 regval)
    {   
        regval=regval;        //使用-O2优化的时候,必须插入的延时
        LCD->LCD_REG=regval;//写入要写的寄存器序号     
    }                                                
    //写LCD数据
    //data:要写入的值
    void LCD_WR_DATA(vu16 data)
    {      
        data=data;            //使用-O2优化的时候,必须插入的延时
        LCD->LCD_RAM=data;         
    }

    剩下参考上面代码即可。

  • 相关阅读:
    go.js:画布内容导出为图片
    go.js:拖拽创建流程图
    vue+go.js:实现流程图
    前端:go.js去水印
    screenfull错误
    VUE:axios接收后端文件流并下载文件
    CSS:unset 属性
    上传文件小工具
    个人技能总结2--MyBaties框架
    个人技能总结1:Shiro框架
  • 原文地址:https://www.cnblogs.com/zjx123/p/12874647.html
Copyright © 2011-2022 走看看