stm32F4编码器测速并通过串口打印--- 程序源码

发布者:美丽的1号最新更新时间:2018-07-06 来源: eefocus关键字:stm32F4  编码器测速  串口打印 手机看文章 扫描二维码
随时随地手机看文章

一、使用cubeMX软件对程序需要使用的端口和资源进行初始化。
为了保持程序的简洁性,这里仅使用一个串口和一路通用定时器。
(1)引脚的初始化


注:在引脚配置这里,是没有编码器模式的,不知道为什么。高级寄存器是由combined channels选项的。
这里先暂时选择为Input Capture direct mode,后面在针对具体的代码进行修改即可。
(2)时钟的配置



(3)串口资源的配置




(4)定时器的配置



(5)中断的配置
这里不适用串口来接收数据,所以串口的中断也不用打开。这里需要打开定时器的中断,在定时器发生上下计数溢出时,需要对进行记录,保证记录的准确性。

(6)最后生成的定时器初始化代码如下:


static void MX_TIM3_Init(void)

{

 

  TIM_ClockConfigTypeDef sClockSourceConfig;

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_IC_InitTypeDef sConfigIC;

 

  htim3.Instance = TIM3;

  htim3.Init.Prescaler = 0;

  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim3.Init.Period = 65535;

  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

  if (HAL_TIM_IC_Init(&htim3) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;

  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;

  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;

  sConfigIC.ICFilter = 0;

  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

}

去掉Input Capture模式配置的代码,对代码修改如下:


void MX_TIM3_Init(void)

 

{    

 htimx_Encoder.Instance = TIM3; 

htim3.Init.Prescaler = 0; 

htim3.Init.CounterMode = TIM_COUNTERMODE_UP; 

htim3.Init.Period = 65535; 

htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;  

//HAL_TIM_Base_Init(&htimx_Encoder); 

sEncoderConfig.EncoderMode  = TIM_ENCODERMODE_TIx;  

sEncoderConfig.IC1Polarity  = TIM_ICPOLARITY_RISING;      

sEncoderConfig.IC1Selection       = TIM_ICSELECTION_DIRECTTI;   

sEncoderConfig.IC1Prescaler       = TIM_ICPSC_DIV1;    

sEncoderConfig.IC1Filter          = 0;     

sEncoderConfig.IC2Polarity        = TIM_ICPOLARITY_RISING;    

sEncoderConfig.IC2Selection       = TIM_ICSELECTION_DIRECTTI;     

sEncoderConfig.IC2Prescaler       = TIM_ICPSC_DIV1;    

sEncoderConfig.IC2Filter          = 0;   

__HAL_TIM_SET_COUNTER(&htimx_Encoder,0);     

HAL_TIM_Encoder_Init(&htimx_Encoder, &sEncoderConfig);      

__HAL_TIM_CLEAR_IT(&htimx_Encoder, TIM_IT_UPDATE);  //清除更新中断标志位   

__HAL_TIM_URS_ENABLE(&htimx_Encoder);          //仅允许计数器溢出才产生更新中断   

__HAL_TIM_ENABLE_IT(&htimx_Encoder,TIM_IT_UPDATE);  //使能更新中断     

HAL_NVIC_SetPriority(ENCODER_TIM_IRQn, 0, 0);    HAL_NVIC_EnableIRQ(ENCODER_TIM_IRQn); }

主函数代码不多说,直接贴上了。 


#include "main.h"

#include "stm32f4xx_hal.h"

#include "string.h"

#define SAMPLING_PERIOD             20    // 采样周期;单位20ms

 

TIM_HandleTypeDef htim3;

 

UART_HandleTypeDef huart1;

 

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_TIM3_Init(void);

static void MX_USART1_UART_Init(void);

static void MX_NVIC_Init(void);

 

void ENCODER_TIMx_Init(void);

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

/* 私有类型定义 --------------------------------------------------------------*/

 

 

#define SAMPLING                  0x01    // 采样标记

#define TXD                       0x02    // 发送数据标记   

#define MPR                         5     //丝杠单圈距离;单位:mm/r       

#define PSPM           ((600*4)/MPR)      //单位距离输出的脉冲数,根据实际的轮子或连杆计算

 

/* USER CODE END PFP */

#define abs(x)                    ((x)<0?(-x):(x))

 

__IO uint16_t time_count=0;         // 时间计数,每1ms增加一(与滴答定时器频率有关)

__IO int32_t CaptureNumber=0;       // 输入捕获数

__IO int32_t Last_CaptureNumber=0;  // 上一次捕获值

 

__IO static int16_t Speed = 50;     // 换算为丝杠上行进的速度,单位为:0.1mm/s所以实际速度是5mm/s

__IO uint16_t SUM_Pulse = 0;      

__IO int16_t MSF = 0;               // 电机反馈速度

__IO float MMPS = 0;                // mm Per Seconed (mm/s)

__IO uint8_t Time_Flag = 0;         // 标记时间

 

uint8_t aTxBuffer[60];        

int16_t OverflowCount=0;             // 编码器计数溢出 计数器

TIM_HandleTypeDef    htimx_Encoder;

 

/* Timer Encoder Configuration Structure declaration */

TIM_Encoder_InitTypeDef sEncoderConfig;

int main(void)

{

  HAL_Init();

 

  SystemClock_Config();

 

  MX_GPIO_Init();

  //MX_TIM3_Init();

   ENCODER_TIMx_Init();

   HAL_TIM_Encoder_Start(&htimx_Encoder, TIM_CHANNEL_ALL);

  MX_USART1_UART_Init();

 

 

  /* Initialize interrupts */

  MX_NVIC_Init();

 

 

int a=0;

  while (1)

  {

if(Time_Flag & SAMPLING){

MSF = CaptureNumber  - Last_CaptureNumber;

Last_CaptureNumber = CaptureNumber;

MSF = abs(MSF);

MMPS = (float)(MSF*500/PSPM);

CaptureNumber = 65535*OverflowCount+__HAL_TIM_GET_COUNTER(&htimx_Encoder);

     //计算单位之间内脉冲个数。

     Time_Flag &= ~SAMPLING; 

   }

     if(Time_Flag & TXD)

    {

  

sprintf(aTxBuffer,"编码器当前值为: %d   当前速度为:  %.2f mm/s\n",CaptureNumber,MMPS);

    

      HAL_UART_Transmit(&huart1,aTxBuffer,strlen((const char*)aTxBuffer),1000);

  

      Time_Flag &= ~TXD;

    }

  }

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

 

   if(__HAL_TIM_IS_TIM_COUNTING_DOWN(&htimx_Encoder)){

    OverflowCount--;       //向下计数溢出

}

  else

{

    OverflowCount++;       //向上计数溢出

}

 __HAL_TIM_CLEAR_IT(&htimx_Encoder, TIM_IT_UPDATE);//很重要

}

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;

  while(HAL_UART_Receive(&huart1,&ch, 1, 0xffff)!=HAL_OK);

  return ch;

}

void HAL_SYSTICK_Callback(void)

{

  // 每1ms自动增一

  time_count++;         

  if(time_count%(20) == 0)// 20ms读取一次编码器数值

  {

    Time_Flag |= SAMPLING;

  }

  else if(time_count>=1000)        //1s发送一次数据

  {

    Time_Flag |= TXD;

    time_count=0;

  }

}

 

/** System Clock Configuration

*/

void SystemClock_Config(void)

{

  RCC_OscInitTypeDef RCC_OscInitStruct;

  RCC_ClkInitTypeDef RCC_ClkInitStruct;

 /**Configure the main internal regulator output voltage 

    */

  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

  RCC_OscInitStruct.HSEState = RCC_HSE_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  RCC_OscInitStruct.PLL.PLLM = 8;

  RCC_OscInitStruct.PLL.PLLN = 336;

  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

  RCC_OscInitStruct.PLL.PLLQ = 4;

  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_PLLCLK;

  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

 

 

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != 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);

}

 

/**

  * 函数功能: 通用定时器初始化并配置通道PWM输出

  * 输入参数: 无

  * 返 回 值: 无

  * 说    明: 无

  */

void ENCODER_TIMx_Init(void)

{    

  htimx_Encoder.Instance = TIM3;

  htimx_Encoder.Init.Prescaler = 0;

  htimx_Encoder.Init.CounterMode = TIM_COUNTERMODE_UP;

  htimx_Encoder.Init.Period = 0xFFFF;

  htimx_Encoder.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;

  HAL_TIM_Base_Init(&htimx_Encoder);

  

  sEncoderConfig.EncoderMode        = TIM_ENCODERMODE_TI12;  

  

  sEncoderConfig.IC1Polarity        = TIM_ICPOLARITY_RISING;   

  sEncoderConfig.IC1Selection       = TIM_ICSELECTION_DIRECTTI;  

  sEncoderConfig.IC1Prescaler       = TIM_ICPSC_DIV1; 

  sEncoderConfig.IC1Filter          = 0;

  

  sEncoderConfig.IC2Polarity        = TIM_ICPOLARITY_RISING;   

  sEncoderConfig.IC2Selection       = TIM_ICSELECTION_DIRECTTI;  

  sEncoderConfig.IC2Prescaler       = TIM_ICPSC_DIV1; 

  sEncoderConfig.IC2Filter          = 0;

 

 

  

  HAL_TIM_Encoder_Init(&htimx_Encoder, &sEncoderConfig);

 

 

  //

  __HAL_TIM_CLEAR_IT(&htimx_Encoder, TIM_IT_UPDATE);  //清除更新中断标志位

  __HAL_TIM_URS_ENABLE(&htimx_Encoder);               //仅允许计数器溢出才产生更新中断

  __HAL_TIM_ENABLE_IT(&htimx_Encoder,TIM_IT_UPDATE);  //使能更新中断

  

  HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);    //这里只是设置一个总的中断。其他的中断还需要另外设置。

  HAL_NVIC_EnableIRQ(TIM3_IRQn);           //不像外部按键中断,外部中断比较简单只有一个。

}

 

static void MX_NVIC_Init(void)

{

  /* TIM3_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(TIM3_IRQn);

}

 

 

/* TIM3 init function */

static void MX_TIM3_Init(void)

{

 

 

  TIM_ClockConfigTypeDef sClockSourceConfig;

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_IC_InitTypeDef sConfigIC;

 

 

  htim3.Instance = TIM3;

  htim3.Init.Prescaler = 0;

  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim3.Init.Period = 65535;

  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

 

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

 

  if (HAL_TIM_IC_Init(&htim3) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

 

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

 

  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;

  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;

  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;

  sConfigIC.ICFilter = 0;

  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

 

  if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

 

}

/* USART1 init function */

static void MX_USART1_UART_Init(void)

{

 

 

  huart1.Instance = USART1;

  huart1.Init.BaudRate = 115200;

  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(__FILE__, __LINE__);

  }

}

 

static void MX_GPIO_Init(void)

{

 

 

  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOH_CLK_ENABLE();

  __HAL_RCC_GPIOC_CLK_ENABLE();

  __HAL_RCC_GPIOB_CLK_ENABLE();

}

 

/**

  * @brief  This function is executed in case of error occurrence.

  * @param  None

  * @retval None

  */

void _Error_Handler(char * file, int line)

{

  /* USER CODE BEGIN Error_Handler_Debug */

  /* User can add his own implementation to report the HAL error return state */

  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


关键字:stm32F4  编码器测速  串口打印 引用地址:stm32F4编码器测速并通过串口打印--- 程序源码

上一篇:STM32F10X PWM配置例程详解,测试无误
下一篇:STM32+MS5611测气压温度例程详解,测试无误

推荐阅读最新更新时间:2024-03-16 16:07

USB Audio设计与实现
1 前言 本文将基于STM32F4 Discovery板,从零开始设计并实现一个USB Audio的例子。 2 设计构思 所谓的USB AUDIO就是制作一个盒子,这个盒子可以通过USB连接到PC,PC端将其识别为Audio设备,然后在PC端播放音乐的时候,声音可以通过盒子播放出来。 2.1 从原理框图开始 图1 如上图所示,我们大概构思一下,为了实现USB AUDIO功能,我们使用一个MCU的USB外设连接PC端,整个流程是这样: PC端播放音乐时,代表音乐的数据流从PC端通过USB传输到MCU端,MCU端然后将其转发给一个外部Codec,最后通过Codec上连接的扬声器或耳机播放音乐。 2.2 硬件支撑 这里选择ST官
[单片机]
USB Audio设计与实现
STM32F4工程模板建立与时钟的设置方法
当你使用ST官网的STD标准库或者HAL库的时候,首先解决的就是时钟的配置问题,时钟就像一个人的心脏,心脏不好更别谈其他的工作了,闲话少说,关于STM32的时钟设置我们先从搭建Keil的工程模板开始。我们这次使用的是最新版的F4的STM32F4xx_StdPeriph_Driver库,版本1.8。具体请继续往下看。 1. 新建立Keil工程命名STM32F4_STD_Template,在Select Device for Target 对话框中,选择STM32F427VITx,这里一定要根据自己使用的芯片具体进行选择,当然官网的外设库也要与之匹配才行,如果没有安装支持包请转至: http://www.keil.com/dd2/pa
[单片机]
基于STM32F407主控芯片的发动机转速/相位发生器设计方法分享
摘要 STM32F407包含Cortex-M4内核,共有14路TIM资源,其中TIM2和TIM5具有32位计数功能,其他为16位计数功能。本文将以TIM2实现发动机转速/相位发生器的设计,并通过串口屏幕显示。文章给出了具体的电路的硬件设计及软件设计流程,并给出设计说明。经实践证明,该发生器据有可靠、稳定、精确的特性。 发动机转速传感器是一种感应式传感器,获取发动机转速和曲轴准确角度位置(输入系统)。在飞轮上安装有一个单独用于发动机转速传感器的信号轮。 信号轮被设计成一个带有很多齿段的轮,共分成60个齿段.每当信号轮转过传感器,就会产生一个交流电压,其频率随看转速而变化。频率即是转速的高低.为了识别曲轴位置,信轮在两个齿段之
[单片机]
基于<font color='red'>STM32F4</font>07主控芯片的发动机转速/相位发生器设计方法分享
STM32F4XXGPIO知识点总结<2>——GPIO寄存器介绍
在使用库函数编写STM32单片机GPIO程序时,一般都是通过配置相应的寄存器来实现具体的功能。下面将根据《STM32参考手册》对各个寄存器进行梳理。 每个通用I/O端口包括4个32位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR和GPIOx_PUPDR)、2个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)、一个32位置位/复位寄存器(GPIOx_BSRR)、1个32位锁存寄存器(GPIOx_LCKR)和2个32位复用功能选择寄存器(GPIOx_AFRH和GPIOx_AFRL)。 GPIO按照功能分类: (1)I/O端口控制寄存器 每个GPIO有4个32位存储器映射的控制
[单片机]
<font color='red'>STM32F4</font>XXGPIO知识点总结<2>——GPIO寄存器介绍
STM32 在PC端串口助手上打印中文字符----printf()函数重定向
前言 本博文基于STM32F103ZET6和MDK5.2.6和库函数V3.5.0开发; 本博文采用七星虫德飞莱开发板,USB-TTL电路,USART1和串口调试助手; 如有不足,多指教; 针对STM32CubeIDE环境的重定向请看https://blog.csdn.net/qq_45172156/article/details/108249811 串口通信作为拓展单片机功能的一个外设,其本身还有一个常用的功能就是用于调试使用,通过对一个值的输出从而观察所要的值是否正确,比较形象,但是自己在写串口的时候写出来的程序不能像当初VC++里的C语言一样利用printf()函数还输出汉字,而是一堆乱码的东西或者16进制数字,看着很难受,于
[单片机]
STM32 在PC端<font color='red'>串口</font>助手上<font color='red'>打印</font>中文字符----printf()函数重定向
stm32f4在液晶上画圆及填充圆的几种方法
先说下画圆,根据圆的对称性将圆8等分,求出其中一份,其他可以通过坐标变换得到。得到过程可以百度中点画圆法。 程序: void LCD_Draw_Circle(uint16_t Xpos,uint16_t Ypos,uint16_t Radius) { int16_t mx=Xpos,my=Ypos,x=0,y=Radius; int16_t d=1-Radius; while(y x) { putpixel(x+mx,y+my); putpixel(-x+mx,y+my); putpixel(-x+mx,-y+my); putpixel(x+mx,-y+my); putpixel(y+mx,x+my); putpixel(-y+m
[单片机]
<font color='red'>stm32f4</font>在液晶上画圆及填充圆的几种方法
通过stm32cubemax配置与mpu6050通信兵读取数据,将数据串口打印
通过stm32cubemax完成配置,与mpu6050通信并读取数据,将数据通过串口打印出来 单片机源程序如下: /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include main.h #include i2c.h #include stm32f4xx_hal.h #include usart.h #include gpio.h #include stdio.h /* Private includes -----------------
[单片机]
如何使用STM32F4的DSP库
  我们平常所使用的CPU为定点CPU,意思是进行整点数值运算的CPU。当遇到形如1.1+1.1的浮点数运算时,定点CPU就遇到大难题了。对于32位单片机,利用Q化处理能发挥他本身的性能,但是精度和速度仍然不会提高很多。   现在设计出了一个新的CPU,叫做FPU,这个芯片专门处理浮点数的运算,这样处理器就将整点数和浮点数分开来处理,整点数交由定点CPU处理而浮点数交由FPU处理。我们见到过TI的DSP,还有STM32F4系列的带有DSP功能的微控制器。前者笔者没有用过,不作评论,而后者如果需要用到FPU的浮点运算功能,必须要进行一些必要的设置。   首先,由于浮点运算在FPU中进行,所以首先应该使能FPU运行。在syst
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved