单片机项目中使用新IC芯片调试方法


前两天,一位小伙伴咨询我一款新IC芯片怎么使用,借此机会我顺便把我日常工作中经常用到的一种调试方法介绍给小伙伴们,希望对对大家有所帮助。准备仓促,文中难免有技术性错误,欢迎大家给予指正,并给出好的建议...🤝🤝


前言:

我们在单片机的项目开发过程中经常会遇到使用新IC芯片的情况,某宝卖家有个时候也提供不了对应开发程序,到网上找资料也找不到;很多初学者面对这样的问题往往束手无策,这里我给大家介绍我经常用的其中一种新IC调试的方法。

因为这个芯片比较简单我这里采用下面步骤进行:
第一步:先用arduino+面包板快速搭建电路验证芯片功能
第二步:使用STM32CubeIDE快速搭建工程验证在STM32上工作是否正常
Tips:由于我手头没有万用表,这里我使用arduino的模拟电压采集功能通过串口打印出来作为电位计的电压监控用。


首先,我们先快速浏览芯片数据手册,获取重要信息
IC型号:TPL0501
电压范围:2.7~5.5V
温度范围:-40~125℃
通信方式:SPI
阻值:100KΩ
阻值偏差:±20%
该芯片是某州仪器的一款单通道数字电位计,通信方式是SPI总线,单方向的,即只能控制芯片,不能读取输入数据,下面是数据手册的具体介绍。
环境参数:主要包括温度使用范围、电压使用范围、误差、温度漂移以及实物引脚对应关系都在这里
环境参数

功能框图:主要介绍该芯片的内部组成和工作原理
功能框图

引脚定义:每个引脚的功能介绍
引脚定义

SPI通信说明:主要介绍芯片的通信方式,这个芯片因为没有设置模式功能,只需要对芯片直接写数据即可,通信方式与我们所使用的74HC595的方式类似
SPI通信说明

真值对照表:也就是数字量对应的实际电阻值,我这里只截取了一部分,剩下的大家可以自行去参考详细手册
真值对照表

对于要调通这个芯片这些介绍基本满足我们的需求了

芯片模块的快速制作
在芯片商城上买了两片回来调试,芯片购买的费用小伙伴给付了

准备好芯片+转接板



焊接两块是为了防止在使用过程中意外弄坏另一块可以立马补上,确保调试正常进行而不耽误太多时间



焊接好排针,并在供电端加上0.1uF的滤波电容,降低高频供电干扰

这样我们的模块就制作完成了


arduino快速搭建工程

电路原理图

引脚对应关系:
arduino uno 引脚4 -> CLK
arduino uno 引脚5 -> DIN
arduino uno 引脚6 -> CS
arduino uno 引脚5v -> VCC、VREF
arduino uno 引脚GND -> GND、L
arduino uno 引脚A0 -> VRES_OUT
首先用面包板+杜邦线搭好电路
说明:我在这里使用的供电电压和数字电位计参考电压都是使用的5V,相应的输出结果也是在0~5V范围

然后使用arduino自带的库,编写代码,再变动阻值参数,看下输出的实际结果和真值表是否对应的上
数值为0x00时对应的模拟电压输出

数值为0x88时对应的模拟电压输出

数值为0xFF时对应的模拟电压输出

经过验证,在arduino上跑没有问题,接下来我们准备在STM32上去运行
arduino代码部分:

/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

int CS_Pin = 6;
int CLK_Pin = 4;
int DIN_Pin = 5; //这里定义了那三个脚

// the setup routine runs once when you press reset:
void setup() {
  
  pinMode(CS_Pin,OUTPUT);
  pinMode(CLK_Pin,OUTPUT);
  pinMode(DIN_Pin,OUTPUT); //让三个脚都是输出状态
  
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  digitalWrite(CS_Pin,LOW); 
  shiftOut(DIN_Pin,CLK_Pin,MSBFIRST,0xFF);
  digitalWrite(CS_Pin,HIGH);
}

// the loop routine runs over and over again forever:
void loop() {
    
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  float voltage= sensorValue * (5.0 / 1023.0);   //换算成电压
  // print out the value you read:
  Serial.println(voltage,DEC);
  delay(100);        // delay in between reads for stability
}

STM32搭建工程验证

说明:STM32使用的供电电压和数字电位计参考电压都是3V3,相应的输出结果也是在0~3V3范围

电路原理图

引脚对应关系:
PA4 -> CLK
PA5 -> DIN
PA6 -> CS
3V3 -> VCC、VREF
arduino uno 引脚GND -> GND、L
arduino uno 引脚A0 -> VRES-OUT
开发板+面包板搭建电路

用STM32CubeIDE建立一个工程

配置好PA4、PA5、PA6引脚为输出

生成代码,并添加TPL0501的驱动代码

编译看运行的效果,输入值为0x55

更改输入的数值为0x22,验证是否正确

main函数代码部分:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 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 */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#define TLP0501_DIN_H()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)
#define TLP0501_DIN_L()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)

#define TLP0501_CS_H()     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET)
#define TLP0501_CS_L()     HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET)

#define TLP0501_CLK_H()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)
#define TLP0501_CLK_L()    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)


/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

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

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void TLP0501_WriteByte( uint8_t data )
{
    uint8_t j;
    for ( j=8; j>=1; j--)
    {
        TLP0501_CLK_L();
        __NOP();
        if(data & 0x80 ){   TLP0501_DIN_H();    }
        else            {   TLP0501_DIN_L();    }
        data <<= 1;
        TLP0501_CLK_H();
    }
}


/* 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();
  /* USER CODE BEGIN 2 */

  TLP0501_CS_L();
  TLP0501_WriteByte(0x22);
  TLP0501_CS_H();


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* 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};

  /** 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();
  }
}

/**
  * @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_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6, GPIO_PIN_RESET);

  /*Configure GPIO pins : PA4 PA5 PA6 */
  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

/* 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 */

  /* 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\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

总结:

1、这里介绍了众多新IC芯片调试方式中的一种,后期有机会再陆续介绍其他IC或新模块的调试方法。
2、文中只是简单的对芯片进行功能测试,实际项目中还会有移植、驱动的可靠性、稳定性等测试工作 。
3、我们要善于运用手头的工具、arduino等快速验证开发环境;模块的快速验证,特别是在项目开发过程中,时间就是金钱,对每一种工具的熟练掌握也是单片机开发过程中不可或缺的重要技能。
4、硬件调试与软件调试有很大的区别,很多时候是一次性,不可逆转的,不像软件Ctl+Z可以撤销;硬件在使用过程中出现意外损坏情况很正常:焊接不当、意外插错,静电防护不到位等等;我们要善于运用一些项目技巧,权衡时间或花费;这里之所以选择焊接两个芯片模块也是为了防止这种意外的发生而对调试造成不必要的时间耽搁。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容