[STM32F7]

【NUCLEO-F767ZI评测】USART与ADC实验

[复制链接]
1226|4
手机看帖
扫描二维码
随时随地手机跟帖
shlll|  楼主 | 2016-8-25 19:07 | 显示全部楼层 |阅读模式
一、NUCLEO-F767ZI简介  NUCLEO-F767ZI使用了一块STM32F767ZIT6作为主控制芯片,同时集成了一块ST-Link V2.1仿真器,极大的方便了开发与调试。STM32F767ZIT6是基于ARM Cortex-M7核心的主频最高可达216MHz,是市面上性能最强的单片机之一。而此次由于拿到板子的时间比较短,同时又有电子设计竞赛的比赛,因此没有详细的试用过这块板子。因此这里就简单的使用下STM32F7的GPIO USART和ADC等模块,并在今后详细的使用,移植uCOS等软件。
二、开发工具简介
  在这里,本人使用Keil MDK作为开发工具使用,Keil作为ARm公司开发的专为ARM旗下面向嵌入式方向内核设计的开发软件,有非常强大的功能。软件中集成了代码编辑、编译、下载仿真等一系列功能。极大的方便了开发。
  同时使用ST公司的STM32F7 HAL驱动库为底层进行开发,这样避免了直接使用寄存器开发需要对照芯片手册一个个配置寄存器的烦恼。
三、USART的使用
USART.png
      上图为USART串口功能框图,可以看到有RX TX数据输入输出脚,也有RTS CTS硬件控制流脚;这里采用异步通讯方式,不使用硬件控制流。外接数据通过Rx脚输入到移位寄存器中,再从移位寄存器传输到RDR接收数据寄存器中,最后传输到数据总线中。发送数据的流程也是类似。
       以下是USART的配置代码:
/* Includes ------------------------------------------------------------------*/
#include "sys_usart.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* UART handler declaration */
UART_HandleTypeDef       UartHandle;
       
/* Private function prototypes -----------------------------------------------*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

/* Private functions ---------------------------------------------------------*/

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART3 and Loop until the end of transmission */
  HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);

  return ch;
}

/**
  * @brief UART MSP Initialization
  *        This function configures the hardware resources used in this example:
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration
  * @param huart: UART handle pointer
  * @retval None
  */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

  RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /* Select SysClk as source of USART1 clocks */
  RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  RCC_PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;
  HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);

  /* Enable USARTx clock */
  __HAL_RCC_USART3_CLK_ENABLE();

  /*##-2- Configure peripheral GPIO ##########################################*/
  /* UART TX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = GPIO_PIN_8;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;

  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* UART RX GPIO pin configuration  */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;

  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

/**
  * @brief UART MSP De-Initialization
  *        This function frees the hardware resources used in this example:
  *          - Disable the Peripheral's clock
  *          - Revert GPIO and NVIC configuration to their default state
  * @param huart: UART handle pointer
  * @retval None
  */
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{
  /*##-1- Reset peripherals ##################################################*/
  __HAL_RCC_USART3_FORCE_RESET();
  __HAL_RCC_USART3_RELEASE_RESET();

  /*##-2- Disable peripherals and GPIO Clocks #################################*/
  /* Configure UART Tx as alternate function  */
  HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8);
  /* Configure UART Rx as alternate function  */
  HAL_GPIO_DeInit(GPIOD, GPIO_PIN_9);

}

/* Public functions ----------------------------------------------------------*/
/**
  * @brief  USART3 initialize function
  * @param  None
  * @retval None
  */
HAL_StatusTypeDef SYS_USART3_Init(void)
{
        /*##-1- Configure the UART peripheral ######################################*/
  /* Put the USART peripheral in the Asynchronous mode (UART Mode) */
  /* UART configured as follows:
      - Word Length = 8 Bits (7 data bit + 1 parity bit) :
                          BE CAREFUL : Program 7 data bits + 1 parity bit in PC HyperTerminal
      - Stop Bit    = One Stop bit
      - Parity      = ODD parity
      - BaudRate    = 9600 baud
      - Hardware flow control disabled (RTS and CTS signals) */
        UartHandle.Instance        = USART3;

  UartHandle.Init.BaudRate   = 9600;
  UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  UartHandle.Init.StopBits   = UART_STOPBITS_1;
  UartHandle.Init.Parity     = UART_PARITY_ODD;
  UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  UartHandle.Init.Mode       = UART_MODE_TX_RX;
  UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
       
  return HAL_UART_Init(&UartHandle);
}
四、ADC的使用
ADC.png
以上是ADC模块的功能框图,可以通过配置选择不同的ADC通道,进行模数转换。
一下为ADC的配置代码
/* Includes ------------------------------------------------------------------*/
#include "sys_adc.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* ADC handler declaration */
ADC_HandleTypeDef    AdcHandle;

/* Variable used to get converted value */
__IO uint16_t uhADCxConvertedValue = 0;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
  * @brief ADC MSP Initialization
  *        This function configures the hardware resources used in this example:
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration
  * @param hadc: ADC handle pointer
  * @retval None
  */
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  GPIO_InitTypeDef          GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* ADC1 Periph clock enable */
  __HAL_RCC_ADC1_CLK_ENABLE();
  /* Enable GPIO clock ****************************************/
  __HAL_RCC_GPIOC_CLK_ENABLE();
  /* Enable DMA2 clock */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /*##-2- Configure peripheral GPIO ##########################################*/
  /* ADC Channel GPIO pin configuration */
  GPIO_InitStruct.Pin =  GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*##-3- Configure the NVIC #################################################*/
  /* NVIC configuration for ADC interrupt */
  HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(ADC_IRQn);
}

/**
  * @brief ADC MSP De-Initialization
  *        This function frees the hardware resources used in this example:
  *          - Disable the Peripheral's clock
  *          - Revert GPIO to their default state
  * @param hadc: ADC handle pointer
  * @retval None
  */
void HAL_ADC_MspDeInit(ADC_HandleTypeDef *hadc)
{
  /*##-1- Reset peripherals ##################################################*/
  __HAL_RCC_ADC_FORCE_RESET();
  __HAL_RCC_ADC_RELEASE_RESET();

  /*##-2- Disable peripherals and GPIO Clocks ################################*/
  /* De-initialize the ADC Channel GPIO pin */
  HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
}

/* Public functions ----------------------------------------------------------*/
/**
  * @brief ADC1 module initialize
  * @param None.
  * @retval HAL_StatusTypeDef
  */
HAL_StatusTypeDef SYS_ADC1_Init(void)
{
        HAL_StatusTypeDef      HAL_Status;
        ADC_ChannelConfTypeDef sConfig;
       
  /*##-1- Configure the ADC peripheral #######################################*/
  AdcHandle.Instance          = ADC1;
  
        HAL_Status = HAL_ADC_DeInit(&AdcHandle);
        if(HAL_Status != HAL_OK)
  {
    /* ADC de-initialization Error */
    return HAL_Status;
  }
       
  AdcHandle.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV4;
  AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;
  AdcHandle.Init.ScanConvMode          = DISABLE;                       /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
  AdcHandle.Init.ContinuousConvMode    = ENABLE;                        /* Continuous mode disabled to have only 1 conversion at each conversion trig */
  AdcHandle.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
  AdcHandle.Init.NbrOfDiscConversion   = 0;
  AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;        /* Conversion start trigged at each external event */
  AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_CC1;
  AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.NbrOfConversion       = 1;
  AdcHandle.Init.DMAContinuousRequests = ENABLE;
  AdcHandle.Init.EOCSelection          = DISABLE;

  HAL_Status = HAL_ADC_Init(&AdcHandle);
        if(HAL_Status != HAL_OK)
        {
//          return HAL_Status;
        }
       
        /*##-2- Configure ADC regular channel ######################################*/
  sConfig.Channel      = ADC_CHANNEL_10;
  sConfig.Rank         = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  sConfig.Offset       = 0;

  HAL_Status = HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
        if(HAL_Status != HAL_OK)
        {
          return HAL_Status;
        }
       
        /*##-3- Start the conversion process #######################################*/
        return HAL_ADC_Start_IT(&AdcHandle);
}
/**
  * @brief  Conversion complete callback in non blocking mode
  * @param  AdcHandle : AdcHandle handle
  * [url=home.php?mod=space&uid=536309]@NOTE[/url]   This example shows a simple way to report end of conversion, and
  *         you can add your own implementation.
  * @retval None
  */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
  /* Get the converted value of regular channel */
  uhADCxConvertedValue = HAL_ADC_GetValue(AdcHandle);
}
五、程序运行效果
STM32首先将对应通道的数据通过AD转换,转换成相应的数字量,在通过USART模块将数据传输到电脑当中,并在显示在串口助手上。调节AD转换通道对应的引脚上的电压就能通过串口助手观察的数据的变化。
结果.png
3_ADC_Interrupt.rar (923.6 KB)
neeringstu| | 2016-8-25 21:04 | 显示全部楼层
adc是不是特别容易受到外部电磁系统的干扰?

使用特权

评论回复
mmuuss586| | 2016-8-25 21:45 | 显示全部楼层

谢谢分享;

使用特权

评论回复
merry_zsp| | 2016-8-28 18:20 | 显示全部楼层
怎么HAL库看着好别扭呢?感觉没以前的库看着舒服了

使用特权

评论回复
队长shiwo| | 2017-7-26 10:32 | 显示全部楼层
数据变化有点大啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

8

帖子

0

粉丝