个人成就
- 发布了50篇内容
- 获得了4次赞同
- 获得了3次收藏
个人简介
擅长领域
暂时没有设置哦~
-
STM32中SystTick是个啥?咋用?
Cortex-Mx内核内部包含了一个SysTick定时器, SysTick 是一个24 位的倒计数定时器, 当计到0 时, 将从RELOAD寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。SysTick 在《STM32xx 中文参考手册》里面基本没有介绍,其详细介绍,内核编程手册中。 在工程中我们将以STM32F373为例,为SysTick配置1ms,利用1ms中断处理系统任务。下面我们介绍下寄存器:
下图是SysTick定时器的4个寄存器概括,我们介绍部分使用的寄存器:
SysTick控制和状态寄存器
这个寄存器的EBNALE(0位)为SysTick的使能位,TICKINT(1位)为设置是否产生中断,CLKSOURCE(2位)为时钟选择,当为1 时AHB时钟不分频,为0时AHB时钟8分频。当然我们选择使能定时器,产生中断,并选择AHB 8分频。假如系统时钟为72M,即可获得 72/8 = 9M的SysTick时钟频率。使能SysTick并产生中断,8分频时钟,代码如下:
SysTick->CTRL = (0<<2) | (1<<1) | (1<<0);
SysTick重装载值寄存器
该图来自数据手册中断和事件章节
图5为SysTick重载计数值寄存器RELOAD([23:0]),从该介绍我们可以得出结论,SysTick的计数方式为向下计数,也就是从RELOAD([23:0])值向下递减,当减到0的时候产生标志位,这个时候会重新装载该寄存器值,循环执行上面的步骤。那麽我们可以利用这个功能做一个1ms的定时器,我们已经配置系统时钟为72M,使用系统时钟的8分频(9M)作为SysTick定时器的时钟,也就是说时钟周期T = 1/9M(ns),即SysTick减1需要1/9M(ns),我们定时1ms那麽重载寄存器的值为 1ms/(1/9M(ns))-1 = 8999(注意这里要进行单位换算),这也就是我们的重装载值,下面给出具体代码配置,其中使能等操作包含在SysTick_Config();函数里面。配置代码如下:
SysTick->LOAD = 8999;
单个寄存器讲完了我们总结一下综合起来让SysTick工作起来,我们把SySTick的配置单独做成一个函数如下:
Void SysTick_Init(void)
{
/*
第一步:装载值
第二步:使能SysTick并允许中断,8分频时钟
第三步:设置SysTick优先级
*/
SysTick->LOAD = 8999;
SysTick->CTRL = (0<<2) | (1<<1) | (1<<0);
NVIC_SetPriority (SysTick_IRQn, (1<<4) - 1);
}
我们用库函数表示为:
对于官方库函数的查找我们可以使用《stm32f37x_dsp_stdperiph_lib_um.chm》这个文档,想要找某一方面的函数在里面直接搜索就可以,具体的使用方法我们下面再仔细介绍。
-
STM32学习USART之基础篇
今天分享USART设计前的基础知识。
下面我们先来了解一下有关通信的基本概念:
通信:两个设备之间进行数据交换时,称这个过程为两个设备间的通信。
并行通信:设备之间的数据是以一位一位的二进制数进行传输的,并行通信的方式就是传输的二进制数同时从主机发送,然后同时到达从机,其优点就是传输速度快、效率高,但当需要传输很多位数据时,就需要很多根数据线,造成成本偏高,还有就是其传输距离不远。
早期的打印机就使用并口来传输数据。下图为并口数据线:
串行通信:两设备之间的数据是一位一位的从主机发送,然后一位一位的到达从机,数据传送可在一根线上进行传输,其传输速度相对并行通信较慢,但其优点是成本低,可以远距离传输。下图为9针串口数据线。
串行通信的分类:当在串行通信方式下,发送数据是在时钟的控制下进行的,当主机和从机都用同一时钟(时钟的相位和幅值均相同)来进行数据传输时,称这种方式为同步串行通信。当主机和从机不使用同一时钟来进行数据传输时,称这种方式为异步串行通信方式。
主机:两个设备进行通信时,对另一个设备发送数据的设备称为主机。
从机:两个设备进行通信时,接收数据的设备称为从机。
我们已经知道并行通信方式虽然传输速度快,但传输数据位数多时,其所需要的数据线就很多,成本偏高,传输距离远,然而串行通信因其成本低,需要数据线少,传输距离远,而且随着技术的发展串行通信的数据传输速度也变得很快了,有些甚至比并行通信传输速度更快了,所以基于这些优点,串行通信的方式被广泛的使用。下面我们重点介绍串行通信。
串行通信
串行通信因其优势突出,被广泛运用,因此产生了一些串行通信的接口标准,如RS-232标准、RS-485标准、RS-422标准等,各个标准在使用过程中又衍生出了一些子标准,如RS-232标准下又有RS-232C类型等,因其各个标准特点不同,所以使用场合也就不同了,但相对于其他标准,RS-232使用较广泛(如大家的台式电脑主机后都有一个RS-232接口),所以下面我们就以RS-232为例给大家进行介绍。
RS-232是串行通信的一种标准,在RS-232标准中主要规定了其通信接口、信号的电平标准、信号的用途。下图描述了基于RS-232标准的两设备之间的通信原理图:
从上图我们可以了解两个串口设备1和设备2之间使用RS-232标准进行通信的原理,因为控制器1/2使用TTL电平标准(正逻辑标准,逻辑“0”为0V,逻辑“1”为5V),但RS-232标准使用的是电平标准是负逻辑标准(逻辑“0”为+3至+15V,逻辑“1”为-3至-15V),所以当使用RS-232标准对这两个串行设备进行数据传输时,就需要在RS-232接口与控制器之间接一个电平转换芯片,两设备之间通过RS-232接口线连接(有25针或9针接口),这样才能确保两设备正常通信。下面我们分别介绍一下RS-232标准的接口标准和电平标准。
1. 接口标准
RS-232标准有两种接口定义,一种为DB25接口,一种为DB9接口,DB25接口现已很少使用,大多数都使用DB9接口,下面我们对这两种接口进行介绍:
DB25接口
接口的各个引脚含义如上图所示,其中第2脚和第3脚分别为数据发送和接收脚,第7脚为信号地,其他脚为一些状态标志引脚,在使用时,将接口线对应接在两个设备上,即可正常通信。
DB9接口
从上图可以看出,DB9接口对DB25接口进行了简化,同样也能传输数据,且DB9被广泛使用,下面我们对DB9的各个引脚功能进行简要说明。
第一脚(DCD):
该引脚为接收线路信号检测,该信号是从发送设备->接收设备,用于告知接收设备是否收到载波信号。
第二脚(RXD):
数据接收引脚,用于接收数据。
第三脚(TXD):
数据发送引脚,用于发送数据。
第四脚(DTR):
数据终端准备就绪引脚,用于告知接收设备,发送设备是否准备就绪。
第五脚(SG):
信号地,用于给两个设备共地,因为两个设备之间地电位可能不一致,不一致就会影响数据收发的电平信号,所以必须给两设备进行共地,保证数据的正确传输。
第六脚(DSR):
数据准备好引脚,该信号用于接收设备告知发送设备数据发送准备就绪,随时可以发送数据。
第七脚(RTS):
请求发送引脚,该信号用于发送设备请求向接收设备发送数据。
第八脚(CTS):
清除发送引脚,该信号用于接收设备告知发送设备是否可以发送数据。
第九脚(RT):
振铃提示,表示接收端与线路已经接通。
在两个设备通信时,发送设备的TXD应该接接收设备的RXD,发送设备的RXD应该接接收设备的TXD,SG接SG,在现在的串口通信中,一般就使用这三根线来传输数据信号,具体接线图如下所示:
按上图对应接线正确,两设备就可正常通信。
2. 电平标准
前已提及,RS-232采用的是负逻辑电平标准,所以两设备(使用TTL电平)之间进行串口通信时,必须外加一个电平转换芯片(如MAX232),才能保证通信成功,下面我们介绍RS-232的电平标准。
RS-232标准规定:
逻辑“1”电平为:-5—-15V或-3—-12V
逻辑“0”电平为:+5—+15V或+3—+12V
TTL电平规定(5V):
逻辑“1”电平为:+2.4—+5V
逻辑“0”电平为:0—0.5V
当用不同电平表示同一逻辑信号时,可用下图对比:
上面讲了两个设备进行串口通信的硬件支持部分,那么两个设备间传输数据应该遵守一些规定,如开始和停止条件、传输数据的位数、传输数据的快慢(波特率)、数据校验等等,只有双方都遵循这些规定,才能使传输数据不容易出错,更加能保证通信过程的顺利进行。因此我们需要对这些规定有一定的了解。
3. 串行通信的分类
1) 同步通信
这种通信方式要求发送设备和接收设备的工作时钟频率一致,发送数据时一般要有一至两个同步字符,保证两设备时钟频率一致后然后开始传输数据,最后为校验位。该种方式可用下图表示:
2) 异步通信
这种通信方式不要求发送设备和接收设备的工作时钟频率一致,发送数据要有一个开始位,然后为数据位,后面有一个校验位和停止位,相邻两个数据之间常会有空闲位,其方式可用下图描述:
4.串行通信的方式
1) 单工通信:
两个设备之间数据传输时,数据只能从一个设备发送到另一个设备,收发固定,不能互换。可用下图表示上述传输过程:
2) 半双工通信:
两个设备之间数据传输时,两个设备都可以作为发送方或接收方,但同一时刻数据只能从一个设备发送到另一个设备。其数据传输线可以是一条或者两条。可用下图表示上述传输过程:
3)全双工通信:
两个设备之间进行数据传输时,双方都可以作为发送方或接收方,双方可同时双向传输数据,有两条数据传输线。可用下图表示上述传输过程:
5.数据传输协议
因串行同步通信方式对时钟要求很高,若两个设备间时钟频率稍有不一致,则会造成数据错误,所以我们一般都使用串行异步通信,这样对时钟要求就没那么严格,可以为我们使用,前已提及,两个设备间进行数据传输时,需要遵守一些约定,这样能保证数据正确发送,那么下面我们就来介绍一下这个约定。
1) 波特率
波特率为每秒钟传送二进制数码的位数,也称为比特率,单位为b/s,位/秒,它反映了数据传输的速度,波特率越高,数据传送越快,两设备进行数据传输时,需要把发送设备波特率和接收设备波特率设为一致,这样才能保证发送数据的速度和接收数据的速度一致,从而保证通信的正确进行。
我们常用的波特率为300b/s、600b/s、1200b/s、2400b/s、4800b/s、9600b/s、115200b/s。
2) 起始位
两设备要传输数据时,发送方要先发一个起始位告知对方我要发数据了,这样接收方才知道发送方要发数据了,就准备接收数据。起始位为一位二进制位,规定逻辑“0”为起始位。
3) 数据位
当发送一个起始位之后,接收方知道发送方要发送数据了,准备好之后,发送方就开始发数据了,数据位可以是5个二进制位或者6/7/8个二进制位,我们常取8个二进制位作为数据位,发送数据时,先发送低位后发送高位。
4) 校验位
数据发送完之后,需要判断数据是否和发送方发送的一致,用一个二进制位表示校验位,常用的校验方式有奇校验、偶校验等,奇校验要求数据位和校验位“1”的个数为奇数,偶校验要求数据位和校验位“1”的个数为偶数,校验位可一定程度解决数据出错问题,但也会有误差,当然也可以不设定校验位。
5) 结束位
当一次数据发送完毕后,发送方需要告知接收方这一次数据发送完毕,常用1位或2位二进制位表示,用逻辑“1”表示停止位。
当双方达成约定后,两个设备就可以进行数据传输了。
-
单片机学习之基础篇
①寄存器
寄存器,是集成电路中非常重要的一种存储单元,在集成电路设计中,寄存器可分为电路内部使用的寄存器和充当内外部接口的寄存器这两类。内部寄存器不能被外部电路或软件访问,只是为内部电路的实现存储功能或满足电路的时序要求。而接口寄存器可以同时被内部电路和外部电路或软件访问,CPU中的寄存器就是其中一种,作为软硬件的接口,为广泛的通用编程用户所熟知。
我们举例STM32的一个寄存器:
1. 关于学习资料
对于学习一款单片机而言,资料不需要很多,最主要的还是芯片的手册,手册里面会体现出你想要的,有的人忽视手册,想要通过某种捷径直接去跳过这一步,在这里我想说,除非你有一定的了解,有信心前面的过程不会出现问题,否则还是老老实实的去啃手册,下面我们来介绍下学习STM32F373CCT6这款单片机我们用到的文档:
1.《STM32F373_Reference_Manual》是 ST 出的官方资料,有 STM32F3的详细介绍,包括了STM32F3 的各种寄存器定义以及功能等,是学习 STM32F3 的必备资料之一。
2.《STM32F373xx》也是 ST 出的官方资料,有关于芯片引脚定义,模块功能概括,以及芯片的电气属性等介绍,是学习 STM32F3 的必备资料之一。
3. 《STM32F3 与F4 系列 Cortex M4 内核编程手册》 则是对 上述资料的补充, 很多关于 CortexM4 内核的介绍(寄存器等) ,都可以在这个文档找到答案,该文档同样是 ST 的官方资料,专门针对 ST 的 Cortex M4 产品。4. 《Cortex M3 与 M4 权威指南》则针对 Cortex M4 内核进行了详细介绍,并配有简单实例,对于想深入了解 Cortex M4 内核的朋友,此文档是非常好的参考资料。
2. 关于学习方法
首先你要有个实验平台,不管资料再多这些资料的来源依据还是数据手册,一定要自己去对着数据手册仔细研读,自己独立动手配置,在平台上去做实验。只有不断的实验你才能理解。当遇到问题时不要在第一时间去网上搜索答案,再去研读数据手册,解决不了的时候,再试图去网上参考借鉴一下其他朋友的案例。
3. MDK5软件的使用
3.1 STM32 官方 标准 固件库简介
ST(意法半导体)为了方便用户开发, 提供了一套丰富的 STM32 固件库。 到底什么是固件库?它与操作寄存器有什么区别?这一节,我们将讲解 STM32 固件库相关的基础知识, 希望能够让大家对 STM32固件库有一个初步的了解。
3.1.1 库开发与寄存器开发的关系
固件库就是函数的集合,固件库函数的作用是向下负责与寄存器直接打交道,向上提供用户函数调用的接口(API) ,最终操作的还是寄存器。
在 51 的开发中我们常常的做法是直接操作寄存器,比如要控制某些 IO 口的状态,我们直接操作寄存器:
我们写成十六进表示:P0 = 0xAA;
而在 STM32 的开发中,我们同样可以操作寄存器:
GPIOA->BSRR=0x0001;
为了省却麻烦, ST(意法半导体)推出了官方固件库, 固件库将这些寄存器底层操作都封装起来, 提供一整套接口 (API)。
比如上面的控制 BSRR 寄存器实现对某一引脚的电平控制,官方库封装了一个函数:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
GPIOx->BSRR = GPIO_Pin;
}
②位操作
C 语言位操作相信学过 C 语言的人都不陌生了,简而言之, 就是对基本类型变量可以在位级别进行操作。这里简单再复习一下。我们讲解几种位操作符,然后讲解位操作使用技巧。
运算符
含义
运算符
含义
&
按位与
~
取反
|
按位或
<<
左移
^
按位异或
>>
右移
1. 不改变其他位的值的情况下,对某几个位进行清0
GPIOA-> BSRR = GPIOA-> BSRR & 0XFF0F; //将第 4-7 位清 0
不改变其他位的值的状况下,对某几个位进行置1
GPIOA-> BSRRL = GPIOA-> BSRRL | 0X0040; //设置相应位第6位的值,不改变其他位的
2. 移位操作
GPIOx->ODR = 1 << 2; //1<<2 = 4 相当于把4赋给了ODR寄存器
GPIOx->ODR = 4 >> 2; //4<<2 = 1 相当于把1赋给了ODR寄存器
~取反操作 //用来对一个二进制数按位取反,即0变1,1变0。
GPIOx->ODR = ~GPIOx->ODR;
3. ^按位异或 //若参加运算的两个二进制位值相同则为0,否则为1.
GPIOx->ODR = 0x05^GPIOx->ODR;
以上就是做单片机控制的基础知识,踏实学了可以节省时间和精力去做应用模块的逻辑和算法了。基础扎实了会让产品更稳定,不能模棱两可的设计,否则故障会意想不到的出现。
-
白话文讲解STM32时钟树
时钟就像是单片机的“心脏”,单片机正常工作离不开时钟的支持,下图是我们单片机的时钟树 ,它反映了单片机的时钟关系。我们来详细描述一下时钟树的工作原理。
寄存器上电后有一个复位值,大家看我画红线的这个,这个是单片机上电默认使用时钟的配置线路,默认使用的是内部默认的8M RC振荡器,有两条路可以选,我们先看上面红色的第一条,到多路选择器SW的时候,我们可以通过配置寄存器中的SW位来决定HSI/PLLCLK/HSE哪一个输入信号从多路选择器通过,在默认的状态下SW选择的是HSI8M从多路选择器通过。
通过了SW这个选择开关后,第一个是SYSCLK 一路朝上可以供I2C1选择时钟,另外一个就是继续向后,通过AHB 这个方框,在这里我们可以配置寄存器选择这个8M是否分频,默认是不分频 也就是经过这个方框后出来往后的还是8M,如果这里配置为2分频,方框出来后就是 4M 了,经过AHB分频出来后还是8M ,这个8M 提供给了很多路大家可以从上面的图中看出来,那么继续向后是 APB 分频
这里分了两个箭头指向,一个是朝上的给AHB总线 、内核、Memory 、DMA、内核定时器和FCLK。从这里我们可以看到 内核是8M时钟(这个频率决定了单片机指令的执行时间,频率越小,指令执行速度越慢),一路是向后给了APB分频器,这里可以配置你想要的分频系数,如果这里还是不分频出来的PCLK 还依然是8M,那么PCLK又给了 APB外设 ,还给了定时器、串口等外设。通过这个关系,我们可以清楚的知道,每个外设的工作频率,那可能就会有人问了,这有什么用呢?每个外设都需要时钟来提供振荡源来帮助完成工作,举个例子讲,比如说串口配置一个波特率,那么波特率(通信速率,表示每秒钟传送的数据的位数,即bit/s)是如何来配置呢,就是根据这个时钟频率来配置的,知道了时钟频率,厂家有一个计算公式,就能很容易的算出某一个波特率对应的寄存器值是多少。
默认的我们知道了,M0支持最大48M,内部RC振荡器只有8M,这个咋整呢?不要慌,我们继续往下看。
既然HSI直接给SW多路选择器,不能到48M,那我不直接给通过SW了行不行,请看图中箭头处,HSI绕一下从 PLLSRC 多路选择器通过,那么PLLSRC多路选择器也有两个选择可以通过寄存器配置,假设配置寄存器选择 HSI作为输入,多路选择器输出后经过PREDIV分频器,假设 PREDIV 我们配置不分频,这个分频器出来输入到PLL模块的时候还是8M
PLL模块起到 一个倍频的作用,大家可以看到方框里面是乘2 3...,如果这个时候我们配置寄存器设置PLLMUL为6,那么出来的PLLCLK是 48M,那么这个时候 SW多路开关选择 PLLCLK作为输入,后面出来的时钟就是48M了,再往后面就跟上面讲的情况一样了,可以自由去配置分频
使用内部RC振荡器我们理解了,但是内部的振荡器往往会因为,精度低,受温度影响比较大等情况,不会被选择,这个时候工程师们就会选择使用外部晶振,外部晶振也是一样的配置方式,大家是否能根据上面讲的思路,配置出来呢? -
看完这篇,SPI其实也很简单嘛
首先我们来简单介绍一下SPI,SPI是串行外设接口(Serial Peripheral Interface),简单来讲就是它一种高速的,全双工,同步的通信总线。
那么被各种总线搞的晕头转向的人来说就会问了,为什么要弄那么多种总线?太难了。一会I2C,一会SPI;一会内部总线,一会外部总线。
碰到总线这样的字眼,千万别急,通过接触你会发现都有各自的特点,通过实践了你才会真正理解这些总线的用途,那么我们今天就来聊一聊SPI。
下面我们来看一下SPI的框图,我们从框图上来介绍SPI通信的原理
1. SPI传输需要有一个时钟,因为他是同步通信,所以连接引脚有串行时钟SCK
2. SPI以主从方式工作,通常有一个或者多个从设备连接。所以MOSI,M是主机,S就是从机,从机输入,所以叫MOSI,I就是input输入的意思,那么MISO也是一样的原理。
3. NSS就是片选,是SPI从设备是否被选中的,只有片选信号为预先规定的使能信号时(高电位或低电位),对此 SPI 从设备的操作才有效。如果从机没有被选中,主机发送数据从机是不会接收的。
4. Rx FIFO,Tx FIFO:发送缓冲和接收缓冲,当高速通信的时候,数据来不及处理就可以放在缓冲区里面,可以节省一定的时间去处理其他事情。
5. CRC controller:CRC校验,是一种数据检测方式。
6. Communication controller:SPI的主控模块,从框图中我们得到一些重点信息,就是关于寄存器的配置信息。时钟输出波特率受BR[2:0],这3个位来控制。
以上就是单片机整个的SPI通信的架构,只有这些配合工作才能实现SPI通信。单片机SPI一般作为主机工作,那么参数配置就需要从机的一些信息了。那么看到这里大家可能觉得这不算讲了SPI啊,我还不懂怎么应用啊,没关系,上面只是简单介绍,知道基本信息了再去实现不就容易多了嘛。
首先既然有时钟,那么就存在时钟极性的问题,既然有从机,那么可以根据从机的时钟极性来设置主机的,保持一致就好了,相当于相约好规则。
SPI的时钟极性(哪种电平状态是有效的):
CPOL为0的时候,空闲状态(不传输数据的时候)是低电平,CPOL为1的时候,空闲状态是高电平;两种时钟极性是相反的
其次时钟频率,波特率表示每秒钟发送多少位数据,可以根据波特率计算发送一位需要的时间。波特率由主机决定。
接着就是时钟相位,也就是时钟信号SCK的第一个边沿出现对应位置在数据传输周期的开始位置还是中央位置。是不是有点绕,那看图说话,直接理解了。
上面是开始位置,下面是中间位置,注意是第一个时钟信号的边沿啊。
这里还要注意就是时钟极性和相位主从机必须设置一致(如果从机是不可编程的,那么要根据从机时序决定)
那么对于从机来说是不是还要看个时序图,那什么是时序图?
就是根据时间做不同的动作,就是时序图会把大家搞晕吧。我们来看一个时序图:
根据上面对单片机SPI的分析,拿到这个从机的时序图你能分析出一些什么呢?
如果根据这个时序图让你来做模拟SPI通信,你是否可以实现呢?(平时设计项目或产品碍于各种问题不得不用普通管脚实现SPI通信,这是很常见的)