跟着铁头山羊取经


Day 01     GPIO


引脚:NRST(复位引脚)

          BOOT(启动模式选择引脚)

          VBAT(备用电源)


通用和复用:

      通用就是芯片直接控制引脚,复用则是通过外设控制引脚


GPIO的工作模式:
        开漏输出:Output push-pull            输出要么是低电压,要么是悬空的高阻抗状态

        推挽输出: output open-drain         输出要么是高电压,要么是低电压


输入模式:

        上拉输入:当引脚悬空时,提供默认的高电压(相当于一个电压表去读取电位,改变时读取去读取输入的信号)

        下拉输入:当引脚悬空时,提供默认的低电压

库函数:HAL_GPIO_WritePin(GPIOx,GPIO_Pin,PinState)

                                                                              GPIO_PIN_SET(RESET)

库函数:HAL_Delay(uint32_t Delay)

函数库: HAL_GPIO_ReadPin(GPIOx,GPIO_Pin)


Day 02     UART


串口的数据帧的格式:

校准分为奇数校准和偶数校准:奇校验也就是发送方在原有数据的1的个数上令1为奇数个,如果为偶数个1校验位为0,反之则为1


关于波特率


串口有许多模式:

配置好UART后需要发送数据,调用库函数

库函数:HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *date,uint16_t size,uint32_t Timeout)

库函数:HAL_UART_Receive(UART_HandleTypeDef *huart,uint8_t *date,uint16_t size,uint32_t Timeout)


Day 03     I2C


一共就俩条总线,SCL和SDA,一个负责传输的时钟信号,一个负责传输数据

这俩条总线都使用开漏输出(开漏模式下引脚写一是高阻抗),且都接一个上拉电阻


I2C的通信组成部分

        起始位:在SCL高电平时,拉低SDA

        寻址:主机向总线发送从机的地址(一般有七位或者十位的),并指定是读还是写,然后等                       待应答(应答(Ack),未响应(NAk))

        数据传输:每传输完一次数据就询问一次主机是读还是写(R&W)

        停止位:在SCL高电平时,拉高SDA


I2C的传输速度模式:

函数库:HAL_I2C_Master_Transmit(I2C_HAndTypeDef*hi2c,unit16_t DevAdress,uint8_t *pDate,uint16_t Size,uint32_t Timeout)

函数库:HAL_I2C_Master_Receive(I2C_HAndTypeDef*hi2c,unit16_t DevAdress,uint8_t *pDate,uint16_t Size,uint32_t Timeout)                 延时一般就是最大: HAL_MAX_DELAY


Day 04     CLK SYSTEM



组合逻辑电路和时序逻辑电路

        组合逻辑电路 (Combinational Logic Circuit):没有记忆。它的输出只取决于当前的输入。就像一个简单的计算器,你按什么键(输入),它就立刻显示什么结果(输出),它不记得你之前按过什么


        时序逻辑电路 (Sequential Logic Circuit):有记忆。它的输出不仅取决于当前的输入,还取决于电路之前的状态(也就是“记忆”)。就像一个计数器,它显示的数字不仅和你当前按的“+1”键有关,更和它之前显示的数字是多少有关


关于时钟树

        树根:有俩颗时钟树,一个是高速,一个是低速的(用于实时时间(RTC)和独立看门狗(IWDT))。还内分                       为外接和内接(内接成本低,外接精度高)

        锁相环:对时钟数产生的信号进行倍频处理,最高16倍数

        分频器:对时钟信号做除法

使用外部时钟需要接一个外部晶振,然后设置RCC为C....


Day 05     SPI


适用场景:高速双向的数据传输


引脚:

        SCK:时钟线

        MOSI:主机输出

        MISO:主机接受

        NSS:主机想和哪个从机对话就向NSS发送低电压


SPI的五个参数

        波特率:通信速度

        比特位传输顺序:MSB 先发高位 和 LSB先发低位

        数据帧的长度:有8字节和16位的整数

        时钟的极性:当SCK高电位时,下降沿为第一边沿,反之同理

        时钟的相位:控制SPI的不同模式,也就是控制时钟的第一边沿采集还是第二边沿采集


函数库:HAL_SPI_Transmit()

库函数:HAL_SPI_Receive()


SPI串口发送数据的代码逻辑

设置一个输出口为推挽输出默认电压高电平

注意:这里需要给接受缓冲区赋初始值


拓展:关于FLASH数据写入过程

        基本流程(擦除的最小单元是扇,写入的最小单元是页)


Day 06     EXIT NVIC


中断的基本知识

        中断优先级分组:就是给抢占优先级和子优先级分位置,一共有五种分法

        中断排队:优先级高的排队靠前。相同优先级的,遵循先来后到原则

        中断嵌套:中断进程中的中断


案例之串口发送数据控制LED点灯

        库函数:HAL_UART_Receive_IT()

代码逻辑


Day 07     Timer


定时器的基本框图:

        从模式控制器

        输入捕获

        输出比较:其中的CCR寄存器决定了占空比

        时计单元的基本结构

   


关于时计单元


注意:预分频系数实际是输入的数字加一,重复计数器同理

           自动重装寄存器的作用是设定计数器的计数范围,可向上也可向下也可中心对称


寄存器预加载(影子寄存器):

        为了能在计数器计数过程中修改下一次计数的自动重装,是安全方面的考量


库函数:HAL_TIM_Base_Start_IT(句柄)

 控制逻辑:设定一个定时器,他的作用是每过一段可以设定的时间就是产生一次更新,然后触发中断,调用回调函数执行设定的功能,循环往复


关于输出比较


不同的输出模式

库函数:HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim,uint32_t Channel)

库函数:这里前面是俩下划线,get函数传参是句柄,set函数是句柄,通道和具体数值


关于输入捕获


概念:捕捉信号变化的时间点,并保存到CCR


输入捕获的阶段

        第一阶段:过滤掉毛刺信号,得到一个纯净的方波信号

·       第二阶段:每检测到一个沿信号就发送一个脉冲(就是TI1FP1或者TI2FP1)

库函数:启动输入捕获:HAL_TIM_IC_Start(句柄,通道)

              关闭输入捕获:HAL_TIM_IC_Stop(句柄,通道)

库函数:CCR读取数据后会产生一个标志位,清除标志位


关于从模式控制器


基本框图:

从模式控制器有俩类,这俩类互不影响,可以同时工作

        作为从机时有以下模式                                                 作为主机时的模式

              

        复位模式:使用TRGI的上升沿复位CNT,同时产生Update事件

        门模式:当输入高电压时时计单元计数运作,低电压时保持高电压的计数状态并暂停计数

        触发模式:使用TRGI的上升沿来启动定时器

        外部时钟源:顾名思义

        

        使能:通过TRGO把时计单元的开关状态输出出去

        更新:每产生一个Update事件就向TRGO输出一个脉冲

        编码器的三个模式分别是:在A相变化时计数,在B相计数和        在AB相都计数


Day 08     ENCODER


编码器的介绍:用于检测旋转的角度和转速,基本内部图:

这样旋转时会对外输出俩个波形图(a相和b相),结合定时器的输入捕获就可捕获旋转的动作并进一步操作

编码器和计时器合作的工作流

当编码器产生时钟信号作为时钟源控制计时器时,PSC如果等于0,表示没拧一次编码器CNT就计数一次,如果PSC等于1,则每拧俩次计数一次

注:

        当输入捕获都设置为上升(下降)沿时,那么顺时针转A相在前,B相在后

        当输入捕获AB相设置不一样时,那么顺时针转B相在前,A相在后

编码器的参数设置

库函数:HAL_TIM_Encoder_Start(TIM_HAndleTypeDef *tim,Uint32_t Channel)

启动编码器

库函数:HAL_TIM_Encoder_Stop(TIM_HAndleTypeDef *tim,Uint32_t Channel)

关闭编码器

库函数:__HAL_TM_GET_COUNTER(&htimx)

读取计数器的值

旋转编码器计数的整个控制逻辑:

        编码器通过旋转产生波形图,顺时针和逆时针转向决定AB相位差,波形图被输入捕获后经过          滤波分频输入到计时器的从模式控制器的编码器接口,编码器接口读取处理后的信号转换成            时钟信号给时计单元然后计数


Day 09     ADC


介绍:

        本质:将模拟信号转化为数字信号

        采样深度:用多少位二进制数来表示一个采样点

        ADC的类型:逐次逼近型SAR(逻辑就是:用电容采集电压后和电压比较器另一端的“砝码电                                                             压比较”)

ADC的内部结构 :

             

从单片机外到单片机内的开关由常规序列或者注入序列触发控制,每收到一个脉冲就转换一次数据

ADC的采样时间和转换时间:(输入到APB总线分支下的ADC1和2的时钟频率不能超过14mhz)

        注:采样时间和转换时间都需要设置成时钟周期的倍数,例子:

                转换时间 :和采样深度有关,如果是12位的采样深度,每个深度都会消耗掉一个时钟周                     期 外加0.5的周期总共就是12.5个时钟周期

                采样时间就是:电容充电的时间,采样精度和采样时间有关

                补充:如何平衡采样时间和采样精度

                当采样的误差源小于转换的最小单位时就可以忽略

最佳采样时间的计算公式(只和时钟源的内阻有关)

计算出来的结果必须时时钟周期的倍数,也就是采样时间必须时时钟周期的倍数

库函数:HAL_ADC_Start(ADC_HandleTypeDef *hADC)

        启动常规序列        

库函数:HAL_ADC_PollForConversion(ADC_HandleTypeDef *hADC,uint32_t Timeout)

        以轮询标志位的方式等待常规序列的转换完成

库函数:HAL_ADC_GetValue(ADC_HandleTypeDef *hADC)

        获取结果存储器的转化结果

实用函数:sprintf(数组名,字符串,其他了类型的字符),在stdio库里

实用函数:strlen(数组):               计算数组元素的长度

此致

致敬我的暑假

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐