Proteus与Keil联调仿真(STM32F401版)

  西电大二微控制项目个人作业软件部分总结。

  临时通知需要用stm32f401仿真,于是使用cubemx写了HAL库版本,各种问题折磨了我将近两天    本篇总结记录一下遇到的问题。

一. 所需软件:

        Proteus、Keil5、VSPD、串口调试助手(XCOM)、Stm32CubeMX

二.Proteus部分

详细步骤可以参考:
proteus创建工程、芯片选择、元件配置操作方法

1.接线图

         所需元器件:

                

        a)整体图

         

         b)LCD部分

         

          注.红色的是可变电阻,器件名为POT-HG 

         c)串口 

         

         d)温度传感器

        

  注.与单片机连接时需将虚拟串口的RX与单片机的RX连接(TX同理) 

        e)电机

         

         f)单片机部分 

        

 2.各项参数配置

               a)电源均配置为+5V,注意接地

        注. 单片机上的VSSA(VREF+)要接地并且VDDA要接+5V(给ADC提供参考电压,否则ADC读取数据会异常)

               b)双击单片机配置

 

         c)虚拟串口配置如下 

  三.CUBEMX部分

        1. 引脚图

                

         2.GPIO

        3. UART

 

 

        4.ADC

 

 

        5.SYS 

 

                                      SYS如果不设置为Serial Wire串口会接收不到数据

 

        6.时钟 

 

        7.NVIC 

  四.Keil部分

        Keil部分需具备STM32的HAL库基础知识

        1.LCD(HAL库版)

        a)管脚连接

                        #define LCD_E        GPIO_PIN_9
                        #define LCD_RS        GPIO_PIN_8
                        #define LCD_D0        GPIO_PIN_0
                        #define LCD_D1        GPIO_PIN_1
                        #define LCD_D2        GPIO_PIN_2
                        #define LCD_D3        GPIO_PIN_3
                        #define LCD_D4        GPIO_PIN_4
                        #define LCD_D5        GPIO_PIN_5
                        #define LCD_D6        GPIO_PIN_6
                        #define LCD_D7        GPIO_PIN_7

        b)代码.c

#include "lcd.h"

#define LCD_E		GPIO_PIN_9
#define LCD_RS		GPIO_PIN_8
#define LCD_D0		GPIO_PIN_0
#define LCD_D1		GPIO_PIN_1
#define LCD_D2		GPIO_PIN_2
#define LCD_D3		GPIO_PIN_3
#define LCD_D4		GPIO_PIN_4
#define LCD_D5		GPIO_PIN_5
#define LCD_D6		GPIO_PIN_6
#define LCD_D7		GPIO_PIN_7

 void LCD_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

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

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
                          |GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6
                          |GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);

  /*Configure GPIO pins : PB0 PB1 PB2 PB10
                           PB3 PB4 PB5 PB6
                           PB7 PB8 PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
                          |GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6
                          |GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
  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);

}
void Lcd_ready(){
	Lcd_write_cmd(0x38);
	Lcd_write_cmd(0x0C);//开显不显示光标
	Lcd_write_cmd(0x06);//写一个指针加一
	Lcd_clear();//清屏
	Lcd_write_cmd(0x80);//设置数据指针起点
}

void Lcd_write(uint8_t data){
	HAL_GPIO_WritePin(GPIOB, LCD_D7 , (GPIO_PinState)((data & 0x80) >>7));//取出数据第8位并向右移7位
	HAL_GPIO_WritePin(GPIOB, LCD_D6 , (GPIO_PinState)((data & 0x40) >>6));//其余同理
	HAL_GPIO_WritePin(GPIOB, LCD_D5 , (GPIO_PinState)((data & 0x20) >>5));
	HAL_GPIO_WritePin(GPIOB, LCD_D4 , (GPIO_PinState)((data & 0x10) >>4));
	HAL_GPIO_WritePin(GPIOB, LCD_D3 , (GPIO_PinState)((data & 0x08) >>3));
	HAL_GPIO_WritePin(GPIOB, LCD_D2 , (GPIO_PinState)((data & 0x04) >>2));
	HAL_GPIO_WritePin(GPIOB, LCD_D1 , (GPIO_PinState)((data & 0x02) >>1));
	HAL_GPIO_WritePin(GPIOB, LCD_D0 , (GPIO_PinState)((data & 0x01)));
}

void Lcd_clear(){
     Lcd_write_cmd(0x01);
}

void Lcd_set_coord(uint8_t x, uint8_t y){
	 uint8_t x_show;
	if(y==0){
		x_show = x;//如果是第一行则x坐标为x
	}else{
		x_show = x + 0x40;//如果为第二行则x坐标需要加0x40
	}
	Lcd_write_cmd(x_show | 0x80);//取得最终坐标
}

void Lcd_write_cmd(uint8_t cmd){
	HAL_GPIO_WritePin(GPIOB,LCD_RS,GPIO_PIN_RESET);//RS置低电平
	Lcd_write(cmd);//写指令
	
	Delay_us(5);
	HAL_GPIO_WritePin(GPIOB,LCD_E,GPIO_PIN_SET);//使能
	Delay_us(5);
	HAL_GPIO_WritePin(GPIOB,LCD_E,GPIO_PIN_RESET);//失能
	Delay_ms(5);
}

void Lcd_write_data(uint8_t data){
	HAL_GPIO_WritePin(GPIOB,LCD_RS,GPIO_PIN_SET);//RS置高电平
	Lcd_write(data);//写数据
	
	Delay_us(5);
	HAL_GPIO_WritePin(GPIOB, LCD_E,GPIO_PIN_SET);
	Delay_us(5);
	HAL_GPIO_WritePin(GPIOB, LCD_E,GPIO_PIN_RESET);
	Delay_ms(5);
}

void Lcd_write_ch(uint8_t x, uint8_t y, uint8_t ch){
	Lcd_set_coord(x, y);//写坐标
	Lcd_write_data(ch);//在坐标上写入字符
}
	
void Lcd_write_str(uint8_t x, uint8_t y, uint8_t *str){
	Lcd_set_coord(x, y);//写入坐标
	while(*str != '\0'){
		Lcd_write_ch(x , y, *str);//取出数组中的首地址,数组本质是指针
		x += 1;//每写一个字符x坐标右移一位
		str++;//字符指针右移一位
	}
}
uint32_t Lcd_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y--)
	{
		Result *= X;
	}
	return Result;
}

void Lcd_write_num(uint8_t x, uint8_t y, uint32_t num, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		Lcd_write_ch(x + i, y, num/ Lcd_Pow(10, Length - i - 1) % 10 + '0');
	}
}

        c)代码.h

#ifndef __LCD_H
#define __LCD_H
#include "main.h"

#ifdef __cplusplus
extern "C" {
#endif
void LCD_init(void);
void Lcd_ready(void);
void Lcd_write(uint8_t data);
void Lcd_clear(void);
void Lcd_set_coord(uint8_t x, uint8_t y);
void Lcd_write_cmd(uint8_t cmd);
void Lcd_write_data(uint8_t data);
void Lcd_write_ch(uint8_t x, uint8_t y, uint8_t ch);
void Lcd_write_str(uint8_t x, uint8_t y, uint8_t *str);
void Lcd_write_num(uint8_t x, uint8_t y, uint32_t num, uint8_t Length);
void LCD_Init(void);


#ifdef __cplusplus
}
#endif

#endif 

            2.main.c 

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 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"
#include "adc.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include "stdio.h"
#include "lcd.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 ---------------------------------------------------------*/

/* USER CODE BEGIN PV */;
  char *strx,*extstrx,*Readystrx; 
  char RxBuffer[200],Rxcouter; //存放接收的数据
  extern char RxBuffer[200],Rxcouter;
  char *strstr(const char *, const char *);//比较字符是否一样,判断是否接收到运行命令
  uint8_t Res;//存放接收数据
  float tem = 0;//存放温度数据
  uint16_t ADC_Value = 0;//接收ADC原始数据
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */


/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#include "stm32f4xx.h"                  // Device header
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

/**
  * 函数功能: 比较温度值若大于等于24则电机正转,小于24则停止
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void Compare()
{
	if((int)tem>=24)
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);
	}

}

 /**
  * 函数功能: UART中断回调函数
  * 输入参数: uart结构体
  * 返 回 值: 无
  * 说    明:无
  */
void HAL_UART_RxCpltCallback (UART_HandleTypeDef *huart){
	
	UNUSED (huart);
	if(huart->Instance ==USART1)
		{
		RxBuffer[Rxcouter++]= Res ;
		HAL_UART_Receive_IT(&huart1,(uint8_t *)&Res, 1);
		}
}

 /**
  * 函数功能: ADC中断回调函数
  * 输入参数: adc结构体
  * 返 回 值: 无
  * 说    明:无
  */
 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
 {
	if(hadc->Instance == ADC1)
	{
		ADC_Value = HAL_ADC_GetValue(&hadc1);
		tem = ADC_Value*500/4096.0;
		
	}
	HAL_ADC_Stop_IT(&hadc1);
 }
 
 /**
  * 函数功能: 清除中断寄存器缓存
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */

void Clear_Buffer(void) {
	uint8_t i;
	for(i=0;i<Rxcouter;i++) 
	RxBuffer[i]=0; 
	Rxcouter=0;
}

  int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
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_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1,&Res,1);		//uart接收数据
  LCD_Init();		//lcd屏幕时钟初始化
  Lcd_ready();		//lcd屏幕显示参数初始化
  Lcd_write_str(0,0,(uint8_t *)"TEMPERATURE:");		//lcd第一行显示TEMPERATURE:
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	    strx=strstr((const char*)RxBuffer,(const char*)"运行");		//判断串口是否接收到运行命令
		      
        if(strx!=NULL) 		//如果接收到
			{	
				Clear_Buffer();		//清除缓存,用于下一次接收
				printf("OK\r\n");			//串口打印OK
				while(1)
				{
					HAL_ADC_Start_IT(&hadc1);		//开始ADC转换
					Compare();		//比较温度,判断是否开启电机
					printf("%d\r\n",(int)tem);		//串口打印温度
					Lcd_write_num(0,1,tem,2);		//lcd显示温度
				}
			}
    /* 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 = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

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

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  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 buses 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();
  }
}

/* USER CODE BEGIN 4 */

/* 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 */
  __disable_irq();
  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,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

    由于lcd用到了Delay函数,所以将Delay函数写在了main.c里。因此需要在main.h里声明函数 

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 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 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */

/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

/* USER CODE BEGIN EFP */
//声明Delay函数
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */

     3.main.c中所添加的代码

        

        a)uart

 /**
  * 函数功能: UART中断回调函数
  * 输入参数: uart结构体
  * 返 回 值: 无
  * 说    明:无
  */
void HAL_UART_RxCpltCallback (UART_HandleTypeDef *huart){
	
	UNUSED (huart);
	if(huart->Instance ==USART1)
		{
		RxBuffer[Rxcouter++]= Res ;
		HAL_UART_Receive_IT(&huart1,(uint8_t *)&Res, 1);
		}
}


 /**
  * 函数功能: 清除中断寄存器缓存
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */

void Clear_Buffer(void) {
	uint8_t i;
	for(i=0;i<Rxcouter;i++) 
	RxBuffer[i]=0; 
	Rxcouter=0;
}

 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

  int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

 

        b)ADC 

 /**
  * 函数功能: ADC中断回调函数
  * 输入参数: adc结构体
  * 返 回 值: 无
  * 说    明:无
  */
 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
 {
	if(hadc->Instance == ADC1)
	{
		ADC_Value = HAL_ADC_GetValue(&hadc1);
		tem = ADC_Value*500/4096.0;
		
	}
	HAL_ADC_Stop_IT(&hadc1);
 }

         c)比较温度函数

/**
  * 函数功能: 比较温度值若大于等于24则电机正转,小于24则停止
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void Compare()
{
	if((int)tem>=24)
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);
	}

}

        d)Delay函数

void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

 

 五.VSPD

        第一次使用点击Add Pair即可(添加的串口对要和虚拟串口里设置的对应

六 .XCOM串口助手

        波特率设置要与虚拟串口、STM32的设置保持一致

        直接发送 运行 即可。

七 .Proteus导入HEX文件

        Keil程序需要生成HEX文件


        1.点击KEIL魔法棒
        2.点击output
        3.点击生成HEX文件
        4.进入proteus双击单片机并选择程序路径,选择刚刚生成的HEX文件进行仿真即可

八.实验现象

        

九.问题总结

        1.串口接收不到数据或接收到乱码

                解决方法:a)调整波特率让单片机、虚拟串口、cubemx里的设置一致

                                  b)cubeMX里SYS调整至Serial Wire

                                  c)接收到乱码可能是由于Keil与串口调试助手编码格式不同导致的

                                        将二者编码格式调为一至后解决问题

        2.串口无法判断是否接收到运行命令

                解决办法:main函数里加入以下代码

strx=strstr((const char*)RxBuffer,(const char*)"运行");

        3.ADC无法收到数据 

                解决办法:a)注意ADC所涉及到的变量要定义为全局变量,不能在写函数时定义一次

                                        主函数里再定义一次,这样会导致变量取值错误。

                                  b)注意自己的代码要写在/* USER CODE BEGIN x */到

                                        /* USER CODE END 2 */之间

                                        不能写在

                                         /* USER CODE BEGIN Init */

                                         /* USER CODE END Init */间。

                                         否则会导致初始化失败。

                                  c) 转换公式数据类型不匹配.ADC_Voltage = ADC_Value / 4096 * 3.3,

                                      把4096更换为4096.0后解决问题,因为输出电压ADC_Voltage

                                      为浮点型数据。

                                  d)也可能是未设置参考电压,解决办法为

                                        单片机上的VSSA要接地并且VDDA要接+5V。

        4.Printf有关

                问题描述:使用 printf(”%f“,tem);打印温度到串口时,串口一直显示0.00000。

                解决办法:a)printf只能打印整形数据,把%f改为%d后问题解决。

        5. Keil使用cubeMX生成代码时的.c和.h文件存放问题

                解决办法:.c文件存在Core的Inc下、.h文件存在Core的Src下。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值