单片机复习

对STM32单片机进行复习,结合网络中不同的面试题以及基础知识进行复习

1.GPIO

STM32单片机GPIO有着八种工作方式,分别为

  1. (1) GPIO_Mode_AIN 模拟输入
  2. (2) GPIO_Mode_IN_FLOATING 浮空输入
  3. (3) GPIO_Mode_IPD 下拉输入
  4. (4) GPIO_Mode_IPU 上拉输入
  5. (5) GPIO_Mode_Out_OD 开漏输出
  6. (6) GPIO_Mode_Out_PP 推挽输出
  7. (7) GPIO_Mode_AF_OD 复用开漏输出
  8. (8) GPIO_Mode_AF_PP 复用推挽输出

上述八种工作模式,其中的

  1. 1.GPIO_Mode_IN_FLOATING 浮空输入,该模式下GPIO口不连接任何功能,IO口电平信号直接进入数据寄存器,因此该端口的电平是有外设决定的。输出浮空状态,可以用于读取外部开关信号,
  2. 2.GPIO_Mode_IPU 上拉输入,GPIO通过上拉电阻连接电源,IO口默认为高电平,此时的上拉电阻是弱上拉,注意不能带大负载,如果可以用读取外部开关状态获取传感器信号。
  3. 3.GPIO_Mode_IPD 下拉输入 GPIO通过下拉电阻连接到地,IO口默认为低电平,可以用于读取传感器信号,
  4. 4.GPIO_Mode_AIN 模拟输入,GPIO可以作为一个模拟输入口使用,此时信号不经过施密特触发器可用于ADC采集电压。和其他输出的不同在于没有TTL触发器,数据连接的终点不一样,一般输入是直接到寄存器中,而模拟输入是直接到片上外设。
  5. 5.GPIO_Mode_Out_OD 开漏输出,GPIO可以通过控制输出高低电平,此时的IO口端口外部是由上拉或者下拉决定的,如果没有则为悬空状态,并且此时的施密特触发器是打开的,可以通过输入寄存器来读取实际状态。实现线与逻辑,并且可以实现电平的转换,常用于需要线与的逻辑
  6. 6.GPIO_Mode_AF_OD 复用开漏输出,有这上述开漏输出的功能,并且还可以有其他外设扩展功能
  7. 7.GPIO_Mode_Out_PP 推挽输出,该模式可以用于输出高低电平,区别于开漏输出是需要外接上拉电阻,而推挽是可以作为电流型驱动的一般20ma,
  8. 8.GPIO_Mode_AF_PP 复用推挽输出,有着推挽输出的功能,还有其他外设的复用功能。

使用总结:

在STM32 中上拉电阻可以用于检测外部信号,按键这些

模拟输入可用于ADC模拟输入

开漏输出用于IIC、线与功能的总线电路中

推挽输出用于,输出电平为0~3.3V的高速开关中

复用推挽可用于IIC的SCL和SDA

复用开漏可用于USART,SPI

2.SPI    

单片机有许多通信协议,例如SPI,IIC,USART,CAN等介绍比较常见这几种通信协议

SPI通讯优势:全双工串行通信,高速数据传输速率,简单的软件配置,极其灵活的数据传输,简单的硬件结构

缺点:没有硬件从机的应答信号,通常仅支持一个主设备,需要更多的引脚,

SPI是全双工串行通信,有着四条逻辑线,分别为

  1. 1.MOSI master input slave output 主机输出从机输入
  2. 2.MISO master output slave input 主机输入从机输出
  3. 3.SCL serial clock 串行时钟信号线 主机发送时钟信号给从机
  4. 4.SS slave select 片选信号,用于多从机状态来选择控制那个从机,多从机和主机的线束关系式 X+3,X表示为从机数量。

接着就是介绍SPI通讯协议的工作模式

有四种工作模式,先介绍

CKP时钟极性 clock polarity,简单理解就是控制时钟的是高电平触发还是低电平触发,如果CKP=0表示空闲时低电平,CKP=1表示为高电平。

CKE时钟相位clock phase,表示为时钟数据采集的相位是的第几个边沿,如果是CKE=0表示为第一个边沿,反之如CKE=1表示为第二个边沿

就有了下面四种状况

  1. 1.CKP=0.CKE=0:表示为空闲的为低电平,第一个边沿出发信号所以为上升沿因为第一个边沿就是低电平变为高电平
  2. 2.CKP=0.CKE=1:表示为空闲为低电平,第二个边沿为高电平到低电平所以是下降沿。确定的不同的模式需要观看传感器的芯片手册来确定芯片的采集信号是上升沿还是下降沿,确定极性和相位
  3. 3.CKP=1,CKE=1:表示为空闲的时候是高电平,第一个边沿为高电平到低电平,第二个边沿为低电平转为高电平,所以是上升沿
  4. 4.CKP=1,CKE=0:表示为空闲的时候为高电平,第一个边沿发出信号为下下降沿

因此上述模式选择是SPI初始化的重要步骤.

SPI通信流程,就是当SPI主机先将CS拉低来来告诉从机准备通信,主机通过发送SCK时钟信号,来告诉从机上升沿接受下降沿发送,这个时候主机需要将要写入的数据发送到数据缓存区,缓存区经过移位寄存器,移位寄存器通过MOSI信号线将字节一位一位的发送给从机,同时从机的MISO接口接受到的数据经过移位寄存器一位一位的移到缓存区。

从机发送也是利用串行移位寄存器,通过MISO信号线将数据发送给主机,主机也通过MOSI接收到从机发来的数据,这样数据就通过同时交换完成。

通过两个移位寄存器的数据移位然后将数据发送给从机,通过移位寄存器的移动数据就可以将主机要发送的数据和从机要发送的数据发送成功,这个是主机发送从机也发送同时发送

也可以当主机发送,从机不发送,这样就需要配置从机发送,从机发送的数据不看他就行,

同理也可以主机不发送,从机发送,这样就需要主机设置0x00或者0xff来给从机发送数据,而从机正常发送数据,然后将数据存入缓存区内

总结

就是SPI的通信原理其实就是两个移位寄存器,同时发送数据给对方,然后通过移位寄存器,相互将数据移位到对方,表示为发送一个字节接受一个字节。并将这个字节放入缓存区内

3.IIC

IIC通信协议是市面上比较常用的协议,主要是由两根通信线,一根是SCL、一根是SDA,分别表示串行时钟线和串行数据线。可支持总线挂载多个设备,是一个同步半双工的

然后iic是不允许从机控制SCL线,所以在主机对从机有着绝对的控制权。在设备线路上SDA和SCL添加一个上拉电阻是为了防止总线的SDA没协调好主机和从机的时间,因此设备需要配置位开漏输出模式。

时序基本单元

为了能识别不同发送的信息和主机从机之间的通信,在两条线之间设置了时序来,来识别。

起始条件:在SCL高电平期间SDA从高电平转到低电平,这句话表示在SCL位高电平时SDA如果从高电平转位低电平就是表示启动后续的时序。

终止条件:在SCL高电平期间SDA从低电平转为高电平。同上面起始条件原理类似,就是将SDA从高电平转换为低电平引发终止条件。

发送字节:SCL低电平期间,主机将数据位依次放在SDA线上,然后释放SCL,从机在SCL高电平期间读取数据位,期间SDA不允许有数据变化,,一直循环8次一个字节发送完毕。

表示SCL为低电平期间主机发送数据在SDA,接着SCL拉高从机开始读主机发送的数据,所以在SCL为低电平期间主机发送的SDA 不允许数据发生变化,不然会导致后面的从机读取数据错误

接受字节:SCL低电平期间,从机将数据放在SDA 上,然后在释放SCL,主机在SCL高电平期间读取从机发送SDA数据,然后释放SDA

表示为SCL低电平期间,从机发送数据在SDA上,然后SCL拉高,主机开始在SCL高电平期间读取SDA 数据。

发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答数据1表示非应答

接受应答:主机发发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答,数据在接收之前需要释放SDA

总结

从机或主机发送完字节,主机来应答SCL高电平,来判断SDA1或0来确认发送和接收

4.中断

中断是单片机中重要的操作步骤,涉及到很多有外部中断,定时器中断,等不同的中断事件。

 中断就是指,在主系统运行中,出现了特定的中断触发条件,使得CPU暂停当前正在运行的程序,转移到处理中断程序,处理完中断程序后返回原来的被暂停的程序

中断有这优先级,当有多种中断同时申请中断时,就会按中断的优先级进行判断。

中断嵌套,当一个中断程序正在运行时,又有新的更高的优先级的中断申请中断,此时CPU再次暂停当前中断程序,转而去处理新的中断程序,处理完成后依次进行返回。

STM32使用NVIC统一中断,管理,每一个中断通道都拥有16个可编程的优先等级, 相当于分配当前使用中断的顺序。

NVIC的中断优先级是由优先级寄存器的4位决定,这4位可以进行切分,分为高n位的抢占优先级和低4-n位的响应优先级,抢占优先级高的可以中断嵌套,响应优先级高的可以优先派对,抢占优先级和响应优先级均相同的按中断号排队。

表示当前中断号的顺序,当抢占优先级和响应优先级均相同,就按照表中的数字顺序,数值小的优先响应。

上面表,是当前的分组方式

接下来就是外部中断,EXTI,可以用于监测GPIO的电平信号,当有变化的时候,就可以让EXTI立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使得CPU执行EXTI对应的中断程序,支持触发方式有,上升沿,下降沿,双边沿,软件触发,支持的GPIO口,但相同的pin不能同时触发中断,

通道数:16个GPIO外加PVD,RTC闹钟,USB唤醒,以太网唤醒,触发响应方式,中断响应,事件响应

相同的pin不能同时触发中断

AFIO主要用于引脚复用功能的选择和重定义,在STM32中AFIO主要完成两个任务,复用功能引脚重映射,中断引脚选择

总结

在STM32使用中断函数配置初始化

  1. 配置RCC将涉及到的外设时钟都打开
  2. 配置GPIO,选择我们的端口
  3. 配置AFIO,选择我们用的一路GPIO连接到后面的EXTI
  4. .配置EXTI,选择边沿触发方式,例如上升沿下降沿,或者双边沿,触发响应方式,可以选择中断响应和事件响应
  5. 配置NVIC当前的中断优先等级

5.DMA

DMA直接数据存储器存取,

用来提供外设和存储器之间或者存储器和存储器之间的告诉数据传输,无须CPU干预,数据可以通过DMA快速移动,节省CPU资源

DMA配置参数包括:通道地址、优先级、数据传输方向、存储器/外设数据宽度、存储器/外设地址是否增量、循环模式、数据传输量

DMA传输方式,有着DMA_Mode_Circular 循环模式,DMA_Mode_Normal 正常缓存模式
应用场景:ADC,GPS、蓝牙,都是用的循环采集,DMA_Mode_Circular模式。

总结DMA初始化配置

  1. 使能DMA时钟
  2. 初始化DMA通道,确定当前外设的寄存器地址以及要传输内存的地址
  3. 使能外设DMA
  4. 使能DAM通道传输
  5. 查询DAM传输状态
  6. 获取数据量
  7. void AD_Init(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIO时钟
    	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
    	
    	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    	
    	GPIO_InitTypeDef GPIO_InitStructure;//初始化
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1|GPIO_Pin_2;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA, &GPIO_InitStructure);//设置三个数据
    	
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
    	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
    
    		
    	ADC_InitTypeDef ADC_InitStructure;//ADC配置
    	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    	ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    	ADC_InitStructure.ADC_NbrOfChannel = 3;
    	ADC_Init(ADC1, &ADC_InitStructure);
    	
    	DMA_InitTypeDef DMA_InitStructure;//DMA配置
    	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//ADC数据寄存器,通过移位来实现不同ADC数据转运
    	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//设置DMA内存长度
    	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//内存自增地址设置为失能
    	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;//内存地址传输变量
    	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//设置内存数据长度
    	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//打开内存地址的自增,用来循环三种ADC数据
    	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//从外设到内存
    	DMA_InitStructure.DMA_BufferSize = 3;//传输数据大小
    	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循环发送
    	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止内存到内存的传输
    	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//优先级高
    	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    	
    	DMA_Cmd(DMA1_Channel1, ENABLE);//DMA使能
    	ADC_DMACmd(ADC1, ENABLE);
    	ADC_Cmd(ADC1, ENABLE);
    	
    	ADC_ResetCalibration(ADC1);
    	while (ADC_GetResetCalibrationStatus(ADC1) == SET);//查询ADC
    	ADC_StartCalibration(ADC1);
    	while (ADC_GetCalibrationStatus(ADC1) == SET);
    	
    	ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    }
    

    通关观看上述代码理解。

详情原理看江科大DMA讲解很详细。

6.USART

在STM32串口通信是连接蓝牙和WiFi的重要连接方式,所以介绍串口在STM32一些基础信息

USART和UART分别为异步和同步,在STM32中常用语第一个中异步全双工,采用点对点的方式进行传输,引脚有两条 分别为RX和TX接受和发送。

串口还有比较重要的发送参数,需要在使用前配置好相关的参数

  1. 波特率:串口通信的速率,为了匹配双方设备的通信速度
  2. 起始位:标志一个数据帧的开始,固定为低电平
  3. 数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
  4. 校验位:用于数据验证,根据数据位计算得来
  5. 停止位:用于数据帧间隔,固定为高电平

串口中,每一个字节都装载在一个数据帧里面,一个数据帧包含起始位,数据位,停止位和校验位组成。串口的空闲状态是高电平,在没有数据传输的时候,就不会相应,在发送数据的时候就必须要发送一个起始位,起始位必须为低电平,让串口的空闲状况变化,接着发送完一节数据必须要有停止位,停止位表示为高电平,接着就是校验,校验和选择无校验,奇校验,偶校验,奇校验就是在方式数据位的时候根据发送的数据有多少个1来选择校验位是0或者是1,例如要发送01110001就有四个1于是奇校验位就需要为1于是011100011就是奇校验位,偶校验位同理

接着就是数据存储的,在单片机累不有着发送数据寄存器(TDR)和接受数据寄存器(RDR),发送移位寄存器接受移位寄存器。

简单理解就是发送数据寄存器发送数据给移位寄存器这个时候是有一个标志位来判断当前的数据寄存器内是否有数据的来确定什么时候写入数据给发送数据寄存器,而移位寄存器是接受到发送寄存器的数据通过发送控制器来发送数据到TX引脚上面。

接着就是配置单片机的波特率,一般USART都挂载在APB1,所以是PCLK1的时钟,一般是36M,之后这个时钟进行一个分频,除一个USARTDIV的分频系数,里面分为整数部分和小数部分,防止波特率除不尽有误差,支持小数点后六位,分频完之后在除16,得到发送器时钟和接收器时钟,如果TE标志位为1表示发送的波特率有效,如果RX为1表示接收器使能,有效

这个图就是表示当前串口通信的基本结构

通过时钟发送给波特率发生器,

然后波特率发送器发送对应的波特信号给发送控制器和接受控制器,接着就是发送数据寄存器和发送移位寄存器发送出数据,接受端同理。需要注意的是发送数据寄存器会在转移数据给移位寄存器时有一个标志位TXE。当TXE=1就表示当前数据已经发送给移位寄存器,我们可以通过判断这个标志位来确定是否可以发送下个数据

接受数据寄存器也有一个标志位RXNE,当RXNE=1就表示当前有一个字节发送到接受数据寄存器,就可以读取数据了

USART主要特点

  1. (1)全双工操作(相互独立的接收数据和发送数据);
  2. (2)同步操作时,可主机时钟同步,也可从机时钟同步;
  3. (3)独立的高精度波特率发生器,不占用定时/计数器;
  4. (4)支持5、6、7、8和9位数据位,1或2位停止位的串行数据帧结构;
  5. (5)由硬件支持的奇偶校验位发生和检验;
  6. (6)数据溢出检测;
  7. (7)帧错误检测;
  8. (8)包括错误起始位的检测噪声滤波器和数字低通滤波器;
  9. (9)三个完全独立的中断,TX发送完成、TX发送数据寄存器空、RX接收完成;
  10. (10)支持多机通信模式;
  11. (11)支持倍速异步通信模式

总结为如下几个步骤:

  1. (1)串口时钟使能,GPIO时钟使能
  2. (2)串口复位
  3. (3)GPIO端口模式设置
  4. TX的GPIO工作模式为:GPIO_Mode_AF_PP;//复用推挽输出
  5. RX的GPIO工作模式为:GPIO_Mode_IN_FLOATING;//浮空输入
  6. (4)串口参数初始化:
  7. 主要包含:波特率设置(115200)、8个数据位、1个停止位、无奇偶校验位、无硬件数据流控制、收发模式。
  8. (5)开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
  9. (6)使能串口
  10. (7)编写中断处理函数

7.ADC

ADC全程为数模转换器,(analog to digital converter)所以数据就是从模拟信号到数字信号的转换,通过ADC将模拟信号转换为抗干扰能力强的数字信号。

STMF103系列中ADC的精度为12位,每个ADC最多有16个外部通道对应不同的GPIO口,查询不同芯片的引脚图就可以发现那些GPIO口支持ADC功能。

ADC所能测量的电压范围就是VEREF-<VIN<VREF+,一般是0~3.3V

转换顺序,通过三个寄存器控制,SQR1,SQR2,SQR3,详细寄存器配置流程可以看江科大视频

电压转换,因为转换后的数据是一个12位的二进制,所以需要用二进制将采集到的AC数据用数据表示出来,测量电压是3.3V,

y=3.3*x/4096,其中4096是2^12,y表示为转换的数据,x就是采集的数据,

百分比就是将3.3V电压换为99y=99*x/4096

总结

ADC配置函数步骤为,ADC时钟使能,ADC结构体初始化,ADC使能

ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//选择模式只用一个ADC
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换结果向右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发转换
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换模式开启
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;//多通道开启
	ADC_InitStructure.ADC_NbrOfChannel = 3;三个转换通道
	ADC_Init(ADC1, &ADC_InitStructure);

  • 21
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值