一、硬件原理图及PCB
项目完整的原理图
理论上只要给高电平,灯就亮。
二、软件(keil程序)
main.c
//stm32f303cbt6
//32kb ram
//128kb flash
//本实验,LED常亮
/* Includes ------------------------------------------------------------------*/
#include <stm32f30x.h>
#include <stdio.h>
#include "led.h"
int main()
{
// Sysclk = 72 MHz
hardware_init_all();
while(1)
{
}
}
led.c
/* Includes ------------------------------------------------------------------*/
#include "led.h"
void hardware_init_all(void)
{
//时钟频率结构体变量存放不同片上时钟的频率
RCC_ClocksTypeDef RCC_Clocks;
/*!< 4 bits for pre-emption priority //四位抢占优先级
0 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
hardware_init_rcc();
//获取时钟频率
RCC_GetClocksFreq (&RCC_Clocks);
//HCLK :提供给AHB总线的时钟,由系统时钟SYSCLK 分频得到,一般不分频,等于系统时钟
SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000);//1ms中断一次
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
hardware_init_led();
}
//Initialize main clock system
void hardware_init_rcc(void)
{
//0 wait state if 0MHz < SYSCLK <= 24MHz
//1wait state if 24MHz < SYSCLK <= 48MHz
//2 wait state if 48MHz < SYSCLK <= 72MHz
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(ENABLE);//选择FLASH预取指缓存的模式,预取指缓存使能
//switch to HSI
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
while (RCC_GetSYSCLKSource() != 0x00) {}//等待HSE成为SYSCLK时钟源
RCC_DeInit();//RCC寄存器恢复初始化值
//enable HSE
RCC_HSEConfig(RCC_HSE_ON);//使能外部高速时钟
RCC_WaitForHSEStartUp();
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {} //等待外部高速时钟使能就绪
RCC_PLLConfig(RCC_PLLSource_PREDIV1,RCC_PLLMul_9); // PLL config 8*9=72 MHz RCC_PLLMul_x(枚举2~16)是倍频值
RCC_PLLCmd(ENABLE);//使能PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} //等待PLL输出稳定
//switch to HSE
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//选择SYSCLK时钟源为PLL
while (RCC_GetSYSCLKSource() != 0x08) {} //等待PLL成为SYSCLK时钟源
}
void hardware_init_led(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//没有上拉也没有下拉
GPIO_Init(LED_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = TEST_PIN;
GPIO_Init(TEST_GPIO, &GPIO_InitStructure);
GPIO_SetBits(LED_GPIO, LED_PIN); //PA3常亮
}
led.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __LED_H
#define __LED_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f30x.h"
//#include "config.h"
// test ***********************************************************
#define TEST_GPIO GPIOA
#define TEST_PIN GPIO_Pin_2
#define LED_GPIO GPIOA
#define LED_PIN GPIO_Pin_3
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void hardware_init_all(void);
void hardware_init_rcc(void);
void hardware_init_led(void);
#endif /* __LED_H */
完整的程序可私信我
三、调试过程
同时焊了两块板子,一块称为板L(有一个激光器和一个APD),一块称为板Z(没有激光器和APD),焊好所有器件后,向板L烧录点灯程序,verify ok后发现冒烟,立即断电,同时有闻到臭味,手触摸感觉激光器最烫,但是并没有对激光器的引脚做任何程序操作。
(一)测试板Z
1、将同样的程序烧录进板Z,看现象如何
用正点原子stm32f103精英板的5v输出给板Z供电,发现按下精英板的电源开关后,板子上的电源指示灯不亮。断开板Z和精英板的连接后按下精英板的电源开关,电源指示灯亮了。那说板Z的VIN和GND之间可能短路。
万用表调至欧姆档,VIN和GND之间的电阻只有3Ω左右,明显短路。
整个板子上VIN的网络只有这一块,我的第一反应是从VIN焊盘引线出来的时候,用焊笔刮的比较使劲,难道焊盘被刮坏了,顶层和信号层发生了串扰?
2、接下来检查了整个板Z上的焊接情况
发现一个虚焊的电阻,TDC芯片有引脚焊在一起的情况。
修改之后再次检查VIN GND之间的电阻,仍然只有几欧。
3、板Z上除了VIN还有VCC,把VCC的后续网络断掉
猜测可能是VCC和GND之间短路
拆掉5V转3.3V的芯片,再次测试,还是短路现象。
拆掉L10 R25 L9 L7 R28 L1,再次测试,还是短路现象。
4、板L和板Z对比的时候,发现栅极驱动器UCC27511的引脚焊接顺序不一样
怀疑板Z可能焊错了,拆掉这块芯片,再次测试板Z,VINGND之间仍然是短路的状态,我没辙了。
有请万能的男朋友隆重出场!
5、检查VIN附近的电路,把VIN的后续网络断掉,只留输入的部分
也就是断掉L4 C3,测试VINGND正常,阻值在千欧,电压为5v。
6、接上C3和LD1117,测试VCC
C7两端电压为3.3V
7、看MIC2288输出是否正常
万用表测试C9两端电压确实为13V左右。
8、再次向板L中烧录点灯程序
灯不亮,测试输出电压的大小,发现高电平只有0.7V。
9、测试单片机最小系统的供电是否正常
C27两端的电压为3.3V,供电正常
10、测其它引脚的电平
如PA0 PA1,也是0.几V左右,说明程序根本没起作用
11、断掉和最小系统连接的一切电路
L6 R2 R32
虽然没有对这些器件有程序上的操作,但这些器件每部的二极管三极管等数字器件可能会灌电流,拉低灯的电平。
但是!灯还是不亮,电压还是零点几伏,
12、猜测有可能是单片机的晶振出了问题
测试无源贴片晶振,逻辑分析仪观察到的波形很乱,示波器观察到的波形也不对。
一般情况下,无源晶振起振的波形为优雅的正弦波,通过示波器可以看到正弦波形,测量其频率应和晶振的起振频率一致。
更换新的晶振,波形仍然不对。
男朋友开始怀疑人生了,总不能一包晶振都是坏的吧!
测试精英板上的晶振波形,是正弦波没错,那可以排除示波器的问题。
13、不是晶振出了问题,是晶振附近的电路出了问题?
重新焊接 C25 C28,晶振波形终于对了。不过灯还是不亮,测灯的电压,3.3v,没问题啊
14、灯焊反了
有横线的这边是负极
灯终于亮了!
(二)测试板L
1、先拆掉板L上的激光器和APD,首先测试电源模块是否正常
正常
2、灯也不亮
按照板Z的处理方法,重新焊接了晶振附近的 两个电容,灯也亮了!
结语
结束一切工作回到宿舍已经是00:40,回顾这一天的工作,从下午三点开始到凌晨,就 点亮了个灯?!但是换个角度想想这些解决问题的思路和经验才是最宝贵的东西。
很感谢男朋友的温柔
祝大家都能有充实的生活,遇到温柔的人!