一、STM32时钟系统详解
1 STM32的时钟源主要有:
- 内部时钟
- 外部时钟
- 锁相环倍频输出时钟
1.1 详细介绍
HSI(内部高速时钟)
- 它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入
HSE(外部高速时钟)
- 接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。
LSI(内部低速时钟)
- 它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源
LSE(外部低速时钟)
- 通常外接32.768MHZ晶振提供给RTC
PLL(锁相环)
- 用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。
MCO(时钟输出管脚)
- 通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源
2 标准库的时钟配置
2.1 STM32启动文件
首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。
2.2 SystemInit函数详解
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
打开内部8M时钟:
RCC->CR |= (uint32_t)0x00000001
通过查看寄存器手册可知,这段代码为打开内部8M时钟。
设置时钟配置寄存器:
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
2.3 SetSysClock()函数详解
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
}
system_stm32f10x.c文件中会根据芯片的型号定义对应的宏:
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000
#endif
3 时钟配置函数
3.1 时钟初始化配置函数
void SystemInit(void);
SYSCLK(系统时钟)=72MHZ;
AHB总线时钟(HCLK=SYSCLK)=72MHZ;
APB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;
APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;
PLL主时钟=72MHZ;
3.2 外设时钟使能配置函数
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
3.3 时钟源使能函数
void RCC_HSICmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_RTCCLKCmd(FunctionalState NewState);
3.4 时钟源和倍频因子配置函数
void RCC_HSEConfig(uint32_t RCC_HSE);
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);
void RCC_PCLK2Config(uint32_t RCC_HCLK);
3.5 外设时钟复位函数
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
3.6 自定义系统时钟
void RCC_HSE_Config(u32 div,u32 pllm)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
if(RCC_WaitForHSEStartUp()==SUCCESS)
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PLLConfig(div,pllm);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)
while(RCC_GetSCLKSource()!=0x08);
}
}
二、无刷直流电机的基本工作原理
无刷直流电机简介
无刷直流电机,英语缩写为BLDC(Brushless Direct Current Motor)。电机的定子是线圈,或者叫绕组。转子是永磁体,就是磁铁 。根据转子的位置,利用单片机来控制每个线圈的通电,使线圈产生的磁场变化,从而不断在前面勾引转子让转子转动,这就是无刷直流电机的转动原理。下面深入一下。
无刷直流电机的结构
首先先从最基本的线圈说起。如下图。可以将线圈理解成长得像弹簧一样的东西。根据初中学过的右手螺旋法则可知,当电流从该线圈的上到下流过的时候,线圈上面的极性为N,下面的极性为S。
现在再弄一根这样的线圈。然后摆弄一下位置。这样如果电流通过的话,就能像有两个电磁铁一样。
再弄一根,就可以构成电机的三相绕组。
再加上永磁体做成的转子,就是一个无刷直流电动机了。
无刷直流电机的电流换向电路
无刷直流电机之所以既只用直流电,又不用电刷,是因为外部有个电路来专门控制它各线圈的通电。这个电流换向电路最主要的部件是FET(场效应晶体管,Field-Effect Transitor)。可以把FET看作是开关。下图将FET标为AT(A相Top),AB(A相Bottom),BT,BB,CT,CB。FET的“开合”是由单片机控制的。
用霍尔传感器确认转子位置
霍尔传感器通过霍尔效应(Hall Effect),能检测出磁场强度的变化。根据高中物理所学的左手定则(用来判断带电导体在磁场中的受力方向),在霍尔传感器所在的回路中,磁场使带电粒子的运动发生偏转,带电粒子“撞到”霍尔传感器的两边,产生电位差。这时就可以用电压计接到霍尔传感器的两边,检测出这种电压变化,从而检测出磁场强度的变化,原理如下图所示。
电气角度和机械角度关系
虽然在这里插入这么个小知识有点怪,但我还是觉得有必要的,因为我觉得当时学的时候不太好理解。在这里配合霍尔传感器的实例说可能好懂一点。机械角度就是电动机转子实际转过的角度。电气角度和机械角度的关系与转子的极对数有关。
电气角度 = 极对数 x 机械角度
因为实际上线圈生成的磁场要吸引的是转子的磁极。所以对于电机的转动控制来说,我们只关心电气角度就好。
怎样控制无刷直流电机的转速?
线圈两端的电压越大,通过线圈的电流越大,生成磁场越强,转子转动得就越快。因为接的电源是直流的,所以我们通常用PWM(Pulse Width Modulation,脉冲宽度调制)来控制线圈两端电压的大小。PWM的简单原理如下。
所以给无刷直流电机通电的时候,用单片机产生的PWM不断地控制FET的开合,能使线圈反复处于通电断电,通电断电的状态。通电时间长(Duty大),线圈两端的等效电压就大,产生的磁场强度就强,转子转动就快;通电时间短(Duty小),线圈两端的等效电压就小,产生的磁场强度就弱,转子转动就慢。
PWM波形接到FET的Gate(门极)上,控制FET的开合。假设Gate上的电压为高时,FET闭合导通;Gate上的电压为低时,FET断开不通电。
而且同一相上的上下两个FET须由反相的PWM波形控制,以防止上下两个FET同时导通,造成电流不通过电机而上下相同,造成短路。
无刷直流电机的关键有三点:
- 线圈绕组电流的换向顺序。电流的换向顺序决定了由线圈产生的磁场的旋转方向,从而决定了转子的转动方向
- 霍尔传感器或其它手段来估计永磁体转子所处的位置,用于决定电流什么时候换向
- 使用单片机产生的PWM波形来控制电机绕组的通电时间,来控制转子转动的速度
三、零欧姆电阻的使用技巧
零欧姆电阻又称为跨接电阻器,是一种特殊用途的电阻,0欧姆电阻的并非真正的阻值为零,欧姆电阻实际是电阻值很小的电阻。
电路板设计中两点不能用印刷电路连接,常在正面用跨线连接,这在普通板中经常看到,为了让自动贴片机和自动插件机正常工作,用零电阻代替跨线。
上图是用在单面PCB板上做跨线的0欧姆电阻。
零欧姆电阻的作用总结可以包括以下作用:
- 在电路中没有任何功能,只是在PCB上为了调试方便或兼容设计等原因。
- 可作跳线使用,避免用跳针造成的高频干扰(成为天线)
- 在匹配电路参数不确定的时候,以0欧姆代替,实际调试的时候,确定参数,再以具体数值的元件代替。
- 0欧姆电阻实际是电阻值很小的电阻,想测某部分电路的耗电流的时候,接0欧姆电阻,接上电流表,这样方便测耗电流,可用于测量大电流。
上图是用在单面PCB板上做跨线的0欧姆电阻。
- 在布线时,如果实在布不过去了,也可以加一个0欧的电阻。
- 在高频信号下,充当电感或电容。(与外部电路特性有关)电感用,主要是解决EMC问题。如地与地,电源和IC Pin间。
- 单点接地(指保护接地、工作接地、直流接地在设备上相互分开,各自成为独立系统。)
做电路保护,充当低成本熔丝(圈圈USB电路中以0欧0603电阻充当USB过流保护)由于PCB上走线的熔断电流较大,如果发生短路过流等故障时,很难熔断,可能会带来更大的事故。由于0欧电阻电流承受能力比较弱(其实0欧电阻也是有一定的电阻的,只是很小而已),过流时就先将0欧电阻熔断了,从而将电路断开,防止了更大事故的发生。有时也会用一些阻值为零点几或者几欧的小电阻来做保险丝。不过不太推荐这样来用,但有些厂商为了节约成本,就用此将就了。
在数字和模拟等混合电路中,往往要求两个地分开,并且单点连接,相关文章:认识地弹(地噪声)。我们可以用一个0欧的电阻来连接这两个地,而不是直接连在一起。这样做的好处就是,地线被分成了两个网络,在大面积铺铜等处理时,就会方便得多。附带提示一下,这样的场合,有时也会用电感或者磁珠等来连接。
配置电路,一般产品上不要出现跳线和拨码开关。有时用户会乱动设置,易引起误会,为了减少维护费用,应用0欧电阻代替跳线等焊在板子上,相关文章:0欧电阻在电路中有妙用。
零欧姆电阻可以承受多少电流?
设计电路经常要用零欧姆电容,一般根据线路电流来选择电阻额定功率,那0欧姆一般选多少合适?
一般的0欧姆电阻的实际阻值在50毫欧左右+-5%的偏差。所以根据额定功率,你就可以计算出来,它的额定电流了。
- 0402 1/16W:1/16=I*I*0.05 即I=1.118A;
- 0603 1/8W:1/8=I*I*0.05 即I=1.58A;
- 0805 1/4W:1/4=I*I*0.05 即I=2.236A;
对于每种封装的O欧姆电阻具体可以通过多大的电流,还需要根据电阻在PCB板上的散热情况来决定。
下面分别测试了0603, 0805, 1206三种封装下,通过的电流和电阻两端之间的电压的关系。可以看到三种封装的电阻都在电流实际超过6A之后,电压开始快速上升。
上图是在测试0欧姆电阻最大流经电流。
这说明电阻的温度也急剧增加,导致功耗也大幅度增加。0603电阻在电流增加到11.5A时烧毁,0805电阻在电流增加到12A时烧断,1206的电阻在12A时没有烧毁。
上图是0603封装0欧姆电阻电流与电压之间的曲线。
上图是0805封装0欧姆电阻电流与电压之间的曲线。
上图是1206封装0姆电阻电流与电压之间的曲线。
四、射频中的非线性
在我们常规的认识里面,射频无源器件都是线性器件,耦合器的耦合度,滤波器的损耗和衰减,天线的增益等等,我们仅需在功率的dBm格式中加或者减去这些器件的相应dB 值就可以。
在时分双工TDD系统中,收发靠时间来分开,发射链路的互调也没有以往在频分双工FDD中那么受人关注。
安逸久了,以至于慢慢淡忘了曾经受到的痛苦。尤其是在FDD滤波器生产中无源互调的那些磨难,痛苦到只能用玄学来解释这些PIM的来源,以至于有一些无神论不是那么坚定的人有了烧香拜佛求助的念头。
现在的射频工程师确实比以往幸福了很多。
在《无源互调干扰导论》这本书中,介绍了在卫星通信中因PIM产物影响而发生故障的例子:
美国舰队通信卫星FLTSTCOM的3阶,美国海事卫星MARISAR的13阶,欧洲国际通信卫星V号IS-V的27阶,甚至欧洲海事卫星MARECS的43阶 PIM 产物落在了接收通带引起干扰,一度影响了一些国外卫星系统的研发进展和使用。
3阶,5阶,7阶的影响比较大,我们比较容易理解,27阶和43阶都要考虑到是不是有点过头了?
所以,在射频设计中,任何时候的掉以轻心都有可能带来意想不到的损失。
那么无源互调的来源是什么?又该如何解决呢?我们今天一起来探讨一下。
互调产物的数学解释
在我们学习《信号与系统》这本书的时候,有一个比较重要的概念——线性时不变系统 LTI。
线性时不变系统要求一个信号通过这个系统时,可以放大,缩小,延时,但是信号的基本特征不变,从数学上要满足齐次性,叠加性和时不变性,下图给了比较生动的解释。
这个构成了我们通信的数学基础,也是所有通信人梦寐以求能达到的效果——所有信息能够无失真的传输。
说的再简单一点就是这个系统的输出y是输入x的一次函数,用高等数学来解释就是函数的一阶导数为常数。
在线性时不变这个假设的舞台上,我们肆意狂舞,忘却了这一切都想贾宝玉的太虚幻境一般虚无缥缈,非线性才是这个世界的常态。
任何的变化都具有不确定性,量与量之间的关系都不是简单的线性关系。
来,补交数学作业了!
同时呢,假设输入信号为最简单的两个不同频率的余弦信号的线性组合
简直惨不忍睹啊,进去两个频率的信号,出来了一堆,而且还是简略版的非线性。那要是标准非线性不是出来的更多。
心情稍微平复一下,我们捋一下这个产物都有什么?
1,靠近直流的频率: w1-w2, DC
2,靠近输入信号的频率:w1,w2,2w1-w2,2w2-w1,
3,二阶谐波的频率:2w1,2w2
4,三阶谐波附近的频率:3w1,3w2,2w1+w2,2w2+w1
放到频域里面如下图所示:
通常情况下,2w1-w2和2w2-w1这两个互调信号距离主信号交近,会造成带内临近信道干扰,是射频设计中常常会注意到的项,其他项距离主信号比较远,对于有源部分产生的互调产物,可在后端加滤波器进行滤除,但是如果是无源滤波器和天线产生的互调产物,就无能为力了。
互调产物的物理机理
对于有源电路部分,非线性的解释比较充分,研究的也比较透彻。比如混合器,本身就是利用了电路的非线性完成调制信号和载波信号混频的功能;而对于功率放大器,为了追求更高的效率,常常工作在晶体管的饱和区,非线性带来的增益的一点点压缩,也就导致了输出信号和输入信号的非线性关系。
而无源器件的非线性就更加奇妙了,以至于有些时候,人们只能求助于玄学了。但是随着人们研究的深入,无源非线性的物理机理也慢慢呈现在我们的眼前。无源器件的非线性主要可分为材料非线性和接触非线性。
材料的非线性现象包括以下几个方面:
1,电介质薄层的电子隧道效应:比如在铝材料表面的氧化铝薄层就有这种电子隧道效应。
2,铁磁效应:铁磁材料有很高的磁导率,并且随着磁场做非线性变化,具有磁滞效应;常见的铁磁材料包括铁,有磁钢,钴,镍等,都是在射频无源器件设计中应该避免用到的;
3,电致伸缩,即电场的非线性变化,比如产生于聚四氟乙烯PTFE电介质中的电致伸缩会对同轴电缆中的PIM有所贡献;
4,磁阻,磁场引起金属导体电阻的变化;
5,微放电效应,由于强电场产生的离子气体而引起二次电子倍增,如在微狭缝之间和跨越金属中砂眼的微放电;
6,电介质击穿等。
当然还有空间电荷效应,离子导电,热离子发射效应,内部肖特基效应等,都会引起无源器件的非线性,进而产生互调信号。
接触非线性
接触非线性主要包括材料结构和老化引起的非线性
1,材料结构引起的非线性主要包括:不同零部件的安装,比如,谐振器,连接器,调谐螺钉等,还有材料结构折弯产生的微裂缝等。其产生机理主要包括接触面不良接触引起的机械效应和电子效应。
2,老化引起的非线性,主要是指随着时间的增加,接触面的松动或者滑动都会引起接触的不良,另外金属氧化物的产生,会导致更多的非线性产生。
总 结
在射频设计中,非线性才是常态,如何处理非线性导致的问题,是考究射频工程师设计功底的一道压轴题。但是常态并不意味着一定会有影响,尽可能的去减小它的影响才是我们应该做的。
有果必有因,遇到问题,先尝试着找到问题的根,然后解决方法就应运而生了。