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

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

因为这个芯片比较简单我这里采用下面步骤进行:

第一步:先用arduino+面包板快速搭建电路验证芯片功能

第二步:使用STM32CubeIDE快速搭建工程验证在STM32上工作是否正常

Tips:由于我手头没有万用表,这里我使用arduino的模拟电压采集功能通过串口打印出来作为电位计的电压监控用。

首先,我们先快速浏览芯片数据手册,获取重要信息

IC型号:TPL0501

电压范围:2.7~5.5V

温度范围:-40~125℃

通信方式:SPI

阻值:100KΩ

阻值偏差:±20%

该芯片是某州仪器的一款单通道数字电位计,通信方式是SPI总线,单方向的,即只能控制芯片,不能读取输入数据,下面是数据手册的具体介绍。

环境参数:主要包括温度使用范围、电压使用范围、误差、温度漂移以及实物引脚对应关系都在这里

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

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

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

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



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

芯片模块的快速制作

在芯片商城上买了两片回来调试,芯片购买的费用小伙伴给付了



准备好芯片+转接板



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



焊接好排针,并在供电端加上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可以撤销;硬件在使用过程中出现意外损坏情况很正常:焊接不当、意外插错,静电防护不到位等等;我们要善于运用一些项目技巧,权衡时间或花费;这里之所以选择焊接两个芯片模块也是为了防止这种意外的发生而对调试造成不必要的时间耽搁。

单片机项目中使用新IC芯片的调试方法的更多相关文章

  1. Web项目中JSP页面的一种调试方法与出现的问题 -- SpringMVC架构测试

    在前端开发中,尤其是MVC架构多人开发,负责前端的童鞋总是需要做静态页面,再和后台连接前无法使用变量如EL表达式等测试功能,所以本人引入了一个模板jsp数据测试专用文件,专门配置所有的变量,然后在待测 ...

  2. GDB中应该知道的几个调试方法 来自陈皓

    GDB中应该知道的几个调试方法 2011年2月10日陈皓发表评论阅读评论62,325 人阅读   七.八年前写过一篇<用GDB调试程序>,于是,从那以后,很多朋友在MSN上以及给我发邮件询 ...

  3. 【转】GDB中应该知道的几个调试方法

    文章来源:http://coolshell.cn/articles/3643.html GDB中应该知道的几个调试方法 2011年02月10日 陈皓 评论 40 条评论  70,776 人阅读 七.八 ...

  4. 项目中解决实际问题的代码片段-javascript方法,Vue方法(长期更新)

    总结项目用到的一些处理方法,用来解决数据处理的一些实际问题,所有方法都可以放在一个公共工具方法里面,实现不限ES5,ES6还有些Vue处理的方法. 都是项目中来的,有代码跟图片展示,长期更新. 1.获 ...

  5. .NET项目中实现多工程文件共用的方法

    一处开发,多处同步编辑使用,并且发布时各个项目均可独立 一.直接编辑项目工程文件 .csproj 具体实现为:编辑 .csproj 文件,在<ItemGroup>中添加新的 <Con ...

  6. Junit4中的新断言assertThat的使用方法

    如果需要是用assertThat需要在项目中引入junit4的jar包.(匹配器和断言方法在junit4的jar包中都能找到,引入就可以了) 下面是常用断言的代码 1 import static or ...

  7. windows系统下,express构建的node项目中,如何用debug控制调试日志

    debug是一款控制日志输出的库,可以在开发调试环境下打开日志输出,生产环境下关闭日志输出.这样比console.log方便多了,console.log只有注释掉才能不输出. debug库还可以根据d ...

  8. js 自己项目中几种打开或弹出页面的方法

    自己项目中,几种打开或弹出页面的方法(部分需要特定环境下) var blnTop = false;//是否在顶层显示 ///动态生成模态窗体(通过字符串生成) ///strModalId:模态窗体ID ...

  9. x86项目中读取注册表Register数据项的方法

    x86项目中使用Registry读取key/value的时候,会出现重定向的问题,解决方法如下: public static string GetMachineGuid() { string guid ...

随机推荐

  1. X Sever —— Xorg

    X Sever -- Xorg  发表于 2020-03-20 分类于 系统服务 , Xorg 阅读次数:39 阅读次数:48 本文字数: 7k 阅读时长 ≈ 6 分钟 Xorg:基于X11协议的服务 ...

  2. python从hello world开始(3)

    """# !usr/bin/env python# -*- coding:utf-8 _*-""""""@Au ...

  3. 系统区域设置 本地语言的支持依赖于 /etc/locale.conf,/etc/locale.conf 包含不少于此相关的环境变量

    https://linux.cn/lfs/LFS-BOOK-7.7-systemd/chapter07/locale.html 7.7. 系统区域设置 本地语言的支持依赖于 /etc/locale.c ...

  4. 攻防世界(十二)upload1

    攻防世界系列 :upload1 1.打开题目,文件上传. 2.立即上传shell 1.php <?php @eval($_POST[root]); ?> 提示只能上传图片 3.burp改报 ...

  5. zabbix官方源替换为阿里云的zabbix源,一键脚本。(安装zabbix报错curl#18 - "transfer closed with 2988713 bytes remaining to read":15 ETA Trying other mirro)

    最近突然安装zabbix总是报错,比如 (24/27): t1lib-5.1.2-14.el7.x86_64.rpm | 166 kB 00:00:00 zabbix-web-4.4.6-1.el7. ...

  6. cgic: CGI的C函数库-(转自COS)

    下载回源码包以后,就3个文件:cgic.c      函数库capture.c   一个很简单的CGI例子,仅仅输出两行提示文字cgictest.c  一个演示读取form表单数据的CGI例子 首先在 ...

  7. 10.10 traceroute:追踪数据传输路由状况

    traceroute命令 用于显示网络数据包传输到指定主机的路径信息,追踪数据传输路由状况.默认数据包大小是60字节(IPv4)或80字节(IPv6),用户可另行设置.它与Windows下的trace ...

  8. go, iris , nuxt, 服务端渲染等技术在helloworld开发者社区中的应用与实践

    大家好,helloworld.net 上线已经有近半年的时间了,转眼过的好快,在这半年的时间里,迭代了近10多个版本,优化了很多的体验,交互上的不足之处,同时也上线了我们的安卓 app, 苹果的因为还 ...

  9. 路由信息相关 route 网卡

    目录 route命令 1.查看路由表 2.管理路由 基本网络配置 添加网卡地址 修改网卡UUID route命令 路由表管理命令,路由表主要构成: Destination: 目标网络ID,表示可以到达 ...

  10. 日常Bug排查-消息不消费

    日常Bug排查-消息不消费 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 某天下午,在笔者研究某个问题正high的时候.开 ...