[其他ST产品] STM32模拟SPI协议控制数字电位器MCP41010电阻值

[复制链接]
1098|10
 楼主| 原来是wjc 发表于 2023-7-8 15:05 | 显示全部楼层 |阅读模式
STM32模拟SPI协议控制数字电位器MCP41010电阻值
MCP41010是单路8位分辨率数字电位器,通过SPI接口可控制电位器阻值分配,相当于PW0端在PA0和PB0之间滑动。

如下图所示:



2040964a90a8fd99f1.png

MCP41010是10K欧姆规格的数字电位器,即PA0和PB0之间的阻值恒定为10K,PW0与PA0或PW0与PB0之间的阻值互补可配。
另外有相关型号不同阻值规格和集成双路的MCP系列数字电位器,其控制原理相同:
850064a90ab2c732d.png

这里介绍STM32模拟SPI协议控制数字电位器MCP41010的代码范例。采用STM32CUBEIDE开发平台,以STM32F401RCT6为例。



 楼主| 原来是wjc 发表于 2023-7-8 15:05 | 显示全部楼层
STM32工程配置
首先建立基本工程并设置时钟:
1608164a90acc076f0.png
 楼主| 原来是wjc 发表于 2023-7-8 15:06 | 显示全部楼层
采用内部时钟源即可:
3593164a90ae640a23.png
 楼主| 原来是wjc 发表于 2023-7-8 15:06 | 显示全部楼层
配置3个GPIO作为模拟SPI的管脚:

1706364a90af33ac6a.png
 楼主| 原来是wjc 发表于 2023-7-8 15:06 | 显示全部楼层
保存并生成初始工程代码: 2161764a90b12088fd.png
 楼主| 原来是wjc 发表于 2023-7-8 15:07 | 显示全部楼层
STM32工程代码
代码里用到的微秒延时函数参考: STM32 HAL us delay(微秒延时)的指令延时实现方式及优化

代码的实现功能为每隔5秒将阻值从低值,中值和高值进行转变,用万用表即可测试阻值验证。
 楼主| 原来是wjc 发表于 2023-7-8 15:07 | 显示全部楼层
建立MCP41010.h头文件:
  1. #ifndef INC_MCP41010_H_
  2. #define INC_MCP41010_H_

  3. #include "main.h"
  4. void PY_Delay_us_t(uint32_t Delay);

  5. void MCP41010_Init(void);
  6. void MCP41010_SHUTDONW(void);
  7. void MCP41010_Write(uint8_t data);

  8. #endif /* INC_MCP41010_H_ */


 楼主| 原来是wjc 发表于 2023-7-8 15:08 | 显示全部楼层
建立MCP41010.c源文件:



  1. #include "MCP41010.h"

  2. #define   MCP41010_CS_L             HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET)
  3. #define   MCP4101_CS_H              HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET)

  4. #define   MCP4101_SCK_L             HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET)
  5. #define   MCP4101_SCK_H             HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET)

  6. #define   MCP4101_SI_L              HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET)
  7. #define   MCP4101_SI_H              HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET)


  8. #define SPI_Delay_us 2

  9. void MCP41010_Init(void)
  10. {
  11.         MCP4101_CS_H;
  12. }


  13. void MCP41010_SHUTDONW(void)
  14. {
  15.          uint16_t MD=0x2100;

  16.             MCP41010_CS_L;PY_Delay_us_t(SPI_Delay_us);
  17.             for(uint8_t i=0;i<16;i++)
  18.                 {
  19.                     MCP4101_SCK_L;
  20.                         if(MD&0x8000){MCP4101_SI_H;}
  21.                         else {MCP4101_SI_L;}
  22.                         PY_Delay_us_t(SPI_Delay_us);
  23.                         MCP4101_SCK_H;
  24.                         MD<<=1;
  25.                         PY_Delay_us_t(SPI_Delay_us);
  26.                 }
  27.             MCP4101_SCK_L;
  28.             PY_Delay_us_t(SPI_Delay_us);

  29.             MCP4101_CS_H ;

  30. }

  31. void MCP41010_Write(uint8_t data)
  32. {
  33.     uint16_t MD=0x1100;
  34.     MD |= data;
  35.     MCP41010_CS_L;PY_Delay_us_t(SPI_Delay_us);
  36.     for(uint8_t i=0;i<16;i++)
  37.         {
  38.             MCP4101_SCK_L;
  39.                 if(MD&0x8000){MCP4101_SI_H;}
  40.                 else {MCP4101_SI_L;}
  41.                 PY_Delay_us_t(SPI_Delay_us);
  42.                 MCP4101_SCK_H;
  43.                 MD<<=1;
  44.                 PY_Delay_us_t(SPI_Delay_us);
  45.         }
  46.     MCP4101_SCK_L;
  47.     PY_Delay_us_t(SPI_Delay_us);

  48.     MCP4101_CS_H ;
  49. }




 楼主| 原来是wjc 发表于 2023-7-8 15:08 | 显示全部楼层
main.c文件里实现测试功能:
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * [url=home.php?mod=space&uid=288409]@file[/url]           : main.c
  5.   * [url=home.php?mod=space&uid=247401]@brief[/url]          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * Copyright (c) 2023 STMicroelectronics.
  10.   * All rights reserved.
  11.   *
  12.   * This software is licensed under terms that can be found in the LICENSE file
  13.   * in the root directory of this software component.
  14.   * If no LICENSE file comes with this software, it is provided AS-IS.
  15.   *
  16.   ******************************************************************************
  17.   */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"

  21. /* Private includes ----------------------------------------------------------*/
  22. /* USER CODE BEGIN Includes */
  23. #include "MCP41010.h"
  24. /* USER CODE END Includes */

  25. /* Private typedef -----------------------------------------------------------*/
  26. /* USER CODE BEGIN PTD */
  27. __IO float usDelayBase;
  28. void PY_usDelayTest(void)
  29. {
  30.   __IO uint32_t firstms, secondms;
  31.   __IO uint32_t counter = 0;

  32.   firstms = HAL_GetTick()+1;
  33.   secondms = firstms+1;

  34.   while(uwTick!=firstms) ;

  35.   while(uwTick!=secondms) counter++;

  36.   usDelayBase = ((float)counter)/1000;
  37. }

  38. void PY_Delay_us_t(uint32_t Delay)
  39. {
  40.   __IO uint32_t delayReg;
  41.   __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  42.   delayReg = 0;
  43.   while(delayReg!=usNum) delayReg++;
  44. }

  45. void PY_usDelayOptimize(void)
  46. {
  47.   __IO uint32_t firstms, secondms;
  48.   __IO float coe = 1.0;

  49.   firstms = HAL_GetTick();
  50.   PY_Delay_us_t(1000000) ;
  51.   secondms = HAL_GetTick();

  52.   coe = ((float)1000)/(secondms-firstms);
  53.   usDelayBase = coe*usDelayBase;
  54. }

  55. void PY_Delay_us(uint32_t Delay)
  56. {
  57.   __IO uint32_t delayReg;

  58.   __IO uint32_t msNum = Delay/1000;
  59.   __IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);

  60.   if(msNum>0) HAL_Delay(msNum);

  61.   delayReg = 0;
  62.   while(delayReg!=usNum) delayReg++;
  63. }



  64. /* USER CODE END PTD */

  65. /* Private define ------------------------------------------------------------*/
  66. /* USER CODE BEGIN PD */

  67. /* USER CODE END PD */

  68. /* Private macro -------------------------------------------------------------*/
  69. /* USER CODE BEGIN PM */

  70. /* USER CODE END PM */

  71. /* Private variables ---------------------------------------------------------*/

  72. /* USER CODE BEGIN PV */

  73. /* USER CODE END PV */

  74. /* Private function prototypes -----------------------------------------------*/
  75. void SystemClock_Config(void);
  76. static void MX_GPIO_Init(void);
  77. /* USER CODE BEGIN PFP */

  78. /* USER CODE END PFP */

  79. /* Private user code ---------------------------------------------------------*/
  80. /* USER CODE BEGIN 0 */

  81. /* USER CODE END 0 */

  82. /**
  83.   * @brief  The application entry point.
  84.   * @retval int
  85.   */
  86. int main(void)
  87. {
  88.   /* USER CODE BEGIN 1 */

  89.   /* USER CODE END 1 */

  90.   /* MCU Configuration--------------------------------------------------------*/

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

  93.   /* USER CODE BEGIN Init */

  94.   /* USER CODE END Init */

  95.   /* Configure the system clock */
  96.   SystemClock_Config();

  97.   /* USER CODE BEGIN SysInit */

  98.   /* USER CODE END SysInit */

  99.   /* Initialize all configured peripherals */
  100.   MX_GPIO_Init();
  101.   /* USER CODE BEGIN 2 */
  102.   PY_usDelayTest();
  103.   PY_usDelayOptimize();

  104.   MCP41010_Init();
  105.   /* USER CODE END 2 */

  106.   /* Infinite loop */
  107.   /* USER CODE BEGIN WHILE */
  108.   while (1)
  109.   {

  110.           MCP41010_Write(0x01);
  111.           PY_Delay_us_t(5000000);

  112.           MCP41010_Write(0x80);
  113.           PY_Delay_us_t(5000000);

  114.           MCP41010_Write(0xFF);
  115.           PY_Delay_us_t(5000000);

  116.     /* USER CODE END WHILE */

  117.     /* USER CODE BEGIN 3 */
  118.   }
  119.   /* USER CODE END 3 */
  120. }

  121. /**
  122.   * @brief System Clock Configuration
  123.   * @retval None
  124.   */
  125. void SystemClock_Config(void)
  126. {
  127.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  128.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  129.   /** Configure the main internal regulator output voltage
  130.   */
  131.   __HAL_RCC_PWR_CLK_ENABLE();
  132.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  133.   /** Initializes the RCC Oscillators according to the specified parameters
  134.   * in the RCC_OscInitTypeDef structure.
  135.   */
  136.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  137.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  138.   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  139.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  140.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  141.   RCC_OscInitStruct.PLL.PLLM = 16;
  142.   RCC_OscInitStruct.PLL.PLLN = 336;
  143.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  144.   RCC_OscInitStruct.PLL.PLLQ = 7;
  145.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  146.   {
  147.     Error_Handler();
  148.   }

  149.   /** Initializes the CPU, AHB and APB buses clocks
  150.   */
  151.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  152.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  153.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  154.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  155.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  156.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  157.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  158.   {
  159.     Error_Handler();
  160.   }
  161. }

  162. /**
  163.   * @brief GPIO Initialization Function
  164.   * @param None
  165.   * @retval None
  166.   */
  167. static void MX_GPIO_Init(void)
  168. {
  169.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  170. /* USER CODE BEGIN MX_GPIO_Init_1 */
  171. /* USER CODE END MX_GPIO_Init_1 */

  172.   /* GPIO Ports Clock Enable */
  173.   __HAL_RCC_GPIOB_CLK_ENABLE();

  174.   /*Configure GPIO pin Output Level */
  175.   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);

  176.   /*Configure GPIO pin Output Level */
  177.   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET);

  178.   /*Configure GPIO pins : PB0 PB1 PB2 */
  179.   GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
  180.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  181.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  182.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  183.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  184. /* USER CODE BEGIN MX_GPIO_Init_2 */
  185. /* USER CODE END MX_GPIO_Init_2 */
  186. }

  187. /* USER CODE BEGIN 4 */

  188. /* USER CODE END 4 */

  189. /**
  190.   * @brief  This function is executed in case of error occurrence.
  191.   * @retval None
  192.   */
  193. void Error_Handler(void)
  194. {
  195.   /* USER CODE BEGIN Error_Handler_Debug */
  196.   /* User can add his own implementation to report the HAL error return state */
  197.   __disable_irq();
  198.   while (1)
  199.   {
  200.   }
  201.   /* USER CODE END Error_Handler_Debug */
  202. }

  203. #ifdef  USE_FULL_ASSERT
  204. /**
  205.   * @brief  Reports the name of the source file and the source line number
  206.   *         where the assert_param error has occurred.
  207.   * @param  file: pointer to the source file name
  208.   * @param  line: assert_param error line source number
  209.   * @retval None
  210.   */
  211. void assert_failed(uint8_t *file, uint32_t line)
  212. {
  213.   /* USER CODE BEGIN 6 */
  214.   /* User can add his own implementation to report the file name and line number,
  215.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  216.   /* USER CODE END 6 */
  217. }
  218. #endif /* USE_FULL_ASSERT */

MessageRing 发表于 2023-7-9 23:25 | 显示全部楼层
程序是怎么控制阻值变化的啊?
Undshing 发表于 2023-7-10 22:57 | 显示全部楼层
数字电位器阻值变化是连续的吗?
万图 发表于 2024-1-16 08:20 | 显示全部楼层

模信号是幅度相等且相位相同的信号
Uriah 发表于 2024-1-16 09:23 | 显示全部楼层

在完成测试后,需要分析测试结果并进行评估
Clyde011 发表于 2024-1-16 19:23 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

87

主题

1250

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部