当前位置:   article > 正文

STM32笔记_stm32 adc 外部触发源

stm32 adc 外部触发源

 

1.VSS、VDD、VCC

VSS代表电源地,通常连接到电路的地线或地点。

VDD代表电源电压,通常连接到电路的正电源或电源电压。

VCC是一种常见的电源引脚命名约定,通常用于表示正电源电压。它与VDD类似,用于提供芯片所需的电源电压。

在某些芯片或电路中,VCC和VDD可能被用来表示相同的电源电压,只是命名上的差异。但在其他情况下,VCC可能用于表示特定的电源引脚,例如用于数字电路的电源引脚,而VDD用于表示模拟电路的电源引脚。

总之,VCC通常用于表示正电源电压,用于为芯片或电路提供所需的电源。

 2.推挽输出 开漏输出

 开漏输出模式,当引脚输出低电平时,引脚会与地连接,因此可以提供较低的电平。但当引脚输出高电平时,引脚处于高阻态,无法提供高电平,需要通过外部上拉电阻连接到电源电压,才能产生高电平信号。

推挽输出模式,当引脚输出低电平时,引脚会与地连接,可以提供较低的电平。而当引脚输出高电平时,引脚与电源电压连接,可以直接提供高电平信号。

两种输出低电平驱动能力强,开漏输出高电平驱动能力弱,推挽输出高电平驱动能力也强。

一般用推挽即可。

3.读写引脚 

14a8b81e69374c899907fde141b051b2.png

a6facf1120654cd992f6dec286b7d013.png

 HAL_Delay(500);单位为ms

4.TIM定时器原理

定时器就是计数。 

通用定时器框图

6e16318e3baf43a4b168f42a8dbf88b8.png

 时基单元

d1a706f0528d4abf84fd32075e90167b.png

STM32F103C8T6有四个定时器:TIM1、TIM2、TIM3、TIM4 b579606cb6df46d4abbe414e85cec39b.png
计时原理:
晶振在一定的电路条件下,产生稳定的机械振动(压电效应)
晶振产生的方波信号经过倍频、分频作为stm32的各种时钟信号,主频即CPU的时钟频率,计算机的操作在时钟信号的控制下分步执行,每个时钟信号周期完成一步操作,时钟频率的高低在很大程度上反映了CPU速度的快慢
 
计数器时钟来源:
内部时钟(CK_INT)
外部时钟模式1:外部输入脚(TIx)
外部时钟模式2:外部触发输入(ETR)
内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器
 
计数模式:
向上计数、向下计数、中央对齐
ARR:AutoReload Register,自动重装载值寄存器,16位,最大值65535
CNT:count,计数值,16位
PSC: Prescaler,预分频系数

5.TIM定时器使用

计算公式:Tout   =  (psc+1)*(ARR+1)/ Tclk        f   =  Tclk  / [ (psc+1)  *  (ARR+1) ]      

01db8b6df921402f9139bfc0f6e2b205.png

 1a2a3f71126e42a7a3d3e514679f43f6.png

 36a588ffea964b5dbc92f433cdc2235d.png

 

开启定时器(注意带IT的才有中断)

  1. /* Initialize all configured peripherals */
  2. MX_GPIO_Init();
  3. MX_TIM2_Init();
  4. /* USER CODE BEGIN 2 */
  5. HAL_TIM_Base_Start_IT(&htim2);
  6. /* USER CODE END 2 */

 

重写回调函数

  1. /* USER CODE BEGIN 4 */
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  3. {
  4. if(htim==&htim2)
  5. {
  6. HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
  7. }
  8. }
  9. /* USER CODE END 4 */

 


 总结:

        1 选择定时器几

        2 使能内部时钟

        3 设置预分频系数

        4 自动重装载值

        5 使能定时器中断

        6 开启定时器

        7 重写回调函数


 6.PWM

决定占空比的寄存器:CCR

捕获/比较寄存器:capture comparison register

占空比 = CCR / ARR   或  占空比 = 1  -  CCR / ARRe5b28458238f4f058b7fd6e73d2dc987.pngaeea2a8d849046f39509e8b4314d015c.png开启PWM的定时器

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

修改占空比,可直接操作寄存器

TIM3->CCR1=TIM3->ARR*0.2;  //CCR1为通道1的比较值

TIM3->CCR2=TIM3->ARR*0.8;  //CCR2为通道2的比较值

或者        __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, 20);  //最后一个参数为CCR

修改频率        TIM3->ARR=

  1. /* USER CODE BEGIN 2 */
  2. HAL_TIM_Base_Start_IT(&htim2);
  3. HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
  4. HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
  5. /* USER CODE END 2 */

 

7.输入捕获模式

输入捕获模式可以用来测量脉冲宽度或者测量频率,原理是输入引脚触发两次中断,分别获得计数器的计数值,相减即是时间间隔 

52ff6b46b6f7474499144d6dddad32f7.png

ecf3f88154234cbe9908c3b57dc73949.png

8431d143338342bdb6f121ea7da43029.png

2d942f4c42d14d06af913ee23998a4aa.png

d334f02a4680485f83181c714dd96cbf.png

8.UART(同步)和USART(异步)

波特率(BaudRate):在信息传输通道中,携带数据信息的信号单元叫码元,单位时间内通过信道传输的码元数称为码元传输速率,简称波特率。

         数字通信中常常用时间间隔相同的符号来表示一个二进制数字,这样的时间间隔内的信号称为(二进制)码元。我们可以将码元看作为一段携带信息(二进制数)的脉冲信号,也就是把码元看作是信息的载体,码元(脉冲信号)本身的振幅、相位等特征即是对所携带信息的反映。例如:将一段脉冲信号的振幅规定为低(00)、中(01)、高(10)、极高(11)四种,那么当我们接收到一个码元发现它的振幅是低的时候,我们就接受到了它所负载的信息-00。那么由此可见一个二进制码元可以承载1byte(2bit)的信息,由于波特率是码元传输速率(传符号率/传码元率),而比特率是信息传输速率(传信号率),那么此时波特率==1/2比特率。

数据帧字长(WordLength):描述的是串口通信时一帧数据的真实长度

从下图可以更直观地看出串口通信的协议格式 :        

起始位(1bit)+数据位(8bit)+校验位(1bit)+停止位(1bit)9b477ac9b4ae4eae9e1c0325cef00131.png 

停止位(StopBits):是串口通信结束的标志,当接收端接收到逻辑1时表明这一帧数据接受结束 

 

9ad1f1e1f9d846ca92a48a8d10569207.png

串行:通讯效率较低,但是对信号线路要求低,抗干扰能力强,同时成本也相对较低,一般用于与计算机与外部设备,或者长距离的数据传输。

并行:通讯效率高,但是对信号线路要求也很高,一般应用于快速设备之间采用并行通信,譬如CPU 与存储设备、存储器与存储器、主机与打印机等都采用并行通讯。

 根据串行通信中实现数据的同步收发方式的不同,串行通信方式又分为同步串行异步串行。

异步串行

采用固定的通信格式,数据以相同的帧格式传送。每一帧由起始位数据位奇偶校验位停止位组成。
当设备开始发送数据时,设备先发一个逻辑0的信号作为数据发送即将开始的标志,当接收端接收到0时即会打开相应的通道进行数据的接收,在逻辑0信号后的则是所要传输的数据,当传输完毕后发送端将发送一个逻辑1信号,当接收端接收到逻辑1信号时将停止接收数据,这样一帧数据的发送与接收便已经完成。ps:若一帧数据发送完毕后并没有紧接着再发送一帧数据,那么信号线上逻辑1信号则会保持,表示这个线路正处于空闲状态,这里对空闲的理解将会有助于后续空闲中断的理解)

同步串行(SPII2C

同步通信时,通信双方共用一个时钟,这是同步通信区分于异步通信的最显著的特点。

在异步通信中,每个字符要用起始位和停止位作为字符开始和结束的标志,以致占用了时间。所以在数据块传送时,为提高通信速度,常去掉这些标志,而采用同步通信。同步通信中,数据开始传送前用同步字符来指示(常约定12 个),并由时钟来实现发送端和接收端的同步,即检测到规定的同步字符后,下面就连续按顺序传送数据,直到一块数据传送完毕。同步传送时,字符之间没有间隙,也不要起始位和停止位,仅在数据开始时用同步字符SYNC来指示。

单工:数据传输只支持数据在一个方向上传输

半双工:允许数据传输在两个方向传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信。

全双工:允许数据同时在两个方向上传输,它要求发送设备和接收设备都有独立的接收和发送能力;在同一时间可以同时接受和发送信息,实现双向通信。

USART:通用同步和异步收发器
UART:通用异步收发器
当进行异步通信时,这两者是没有区别的。区别在于USART比UART多了同步通信功能。
这个同步通信功能可以把USART当做SPI来用,比如用USART来驱动SPI设备

UART_HandleTypeDef huart1;

对于定时器(TIMER)、串口(UART)和模数转换器(ADC)等功能较为复杂的外设,HAL库设计了一个名为外设句柄的数据类型PPP_HandleTypeDefPPP表示外设名称)。外设句柄作为外设的一个标识符,一般采用结构体类型实现,结构体的成员变量对应外设的工作参数。

串口发送/接收函数

HAL_UART_Transmit();串口发送数据,使用超时管理机制 
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送  
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送

HAL_UART_Transmit_DMA();串口DMA模式接收

发送

什么是重定向?重定向是指fputc里面的输出指向目标设备。因printf函数调用了fputc,而fputc输出有默认指向的目标,且不同库中的fputc输出指向不同,所以需要重写fputc 

  1. /**
  2. *函数功能:重定向c库函数printf到DEBUG_USARTx
  3. *输入参数:无
  4. *返 回 值:无
  5. *说 明:无
  6. **/
  7. int fputc(int ch, FILE *f)
  8. {
  9. HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  10. return ch;
  11. }
  12. /**
  13. *函数功能:重定向c库函数getchar,scanf到DEBUG_USARTx
  14. *输入参数:无
  15. *返 回 值:无
  16. *说 明:无
  17. **/
  18. int fgetc(FILE *f)
  19. {
  20. uint8_t ch=0;
  21. HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  22. return ch;
  23. }

4ff85d603620456e88f814a366bed292.png

 接收

一般来说我们使用中断来接收数据

具体流程:

1、初始化串口

2、在main中第一次调用接收中断函数

3、进入接收中断,接收完数据  进入中断回调函数

4、修改HAL_UART_RxCpltCallback中断回调函数,处理接收的数据,

5  回调函数中要调用一次HAL_UART_Receive_IT函数,使得程序可以重新触发接收中断

中断接收数据:

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

功能:使串口中断接收,以中断方式接收指定长度数据。

大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断。再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断) 

Uart中断如何接收信号

RXNE为接收缓冲器Rx非空标志,置1表明接收到了数据(1个字节),产生中断;

IDLE为空闲标志,置1表明当前数据接收完毕(1帧数据),产生中断。

接收不定长信息:

例如发送0XAA 0XEE 0XCC,在接收到0XAA时候1==RXNE,它产生了3次中段去接收

而IDLE等到0XCC接收完毕后才1==IDLE。

 fe6d062df0fa4b18afda37537c7a038b.png

 

总结:

1.用CUBEMX配置完毕后,需要开启HAL_UART_Receive_IT
2.需要重新写void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart),并在这个里面处理接收的数据
3.在HAL_UART_RxCpltCallback函数结束的时候要再次开启HAL_UART_Receive_IT

 9.USART实际操作

一、设置RCC

设置高速外部时钟HSE 选择外部时钟源 84b1e8afc00b40338b1465ac08253475.png

二、设置串口

•1点击USATR1   
•2设置MODE为 异步通信 (Asynchronous)       
3基础参数 :波特率为 115200 Bits/s 。传输数据长度为 8 Bit 。奇偶检验无,停止位 1      接收和发送都使能 
•4GPIO引脚设置 USART1_RX/USART_TX 205fa0c87ccb4493b72fd24fe06848f4.png

三、设置时钟树

 NVIC Settings 一栏使能接收中断3204ab14c5f84609aeb68d17d3a364e7.png

 四、在main.c下方添加中断回调函数(原回调函数:stm32f1xx_hal_uart.c 2616行)

  1. /* Private includes ----------------------------------------------------------*/
  2. /* USER CODE BEGIN Includes */
  3. #include "stdio.h"
  4. #include "string.h"
  5. /* USER CODE END Includes */
  1. /* USER CODE BEGIN PV */
  2. uint8_t RxBuffer[9];
  3. uint8_t aRxBuffer;
  4. uint8_t Uart1_Rx_Cnt=0;
  5. /* USER CODE END PV */
  1. /* USER CODE BEGIN 4 */
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  3. {
  4. /* Prevent unused argument(s) compilation warning */
  5. UNUSED(huart);
  6. /* NOTE: This function should not be modified, when the callback is needed,
  7. the HAL_UART_RxCpltCallback could be implemented in the user file
  8. */
  9. if(Uart1_Rx_Cnt>=255)//溢出函数
  10. {
  11. Uart1_Rx_Cnt=0;
  12. memset(RxBuffer,0x00,sizeof(RxBuffer));
  13. HAL_UART_Transmit(&huart1,(uint8_t *)"数据溢出",10,0xFFFF);
  14. }
  15. else
  16. {
  17. RxBuffer[Uart1_Rx_Cnt++]=aRxBuffer;//接收数据转存
  18. if((RxBuffer[Uart1_Rx_Cnt-1]==0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2]==0x0D))//判断结束位
  19. {
  20. HAL_UART_Transmit(&huart1,(uint8_t *)&RxBuffer,Uart1_Rx_Cnt,0xFFFF);//将收到的信息发送出去
  21. while(HAL_UART_GetState(&huart1)==HAL_UART_STATE_BUSY_TX);//检测UART发送结束
  22. Uart1_Rx_Cnt=0;
  23. memset(RxBuffer,0x00,sizeof(RxBuffer));//清空数组
  24. }
  25. }
  26. HAL_UART_Receive_IT(&huart1,(uint8_t *)&aRxBuffer,1);//再开启接收中断
  27. }
  28. /* USER CODE END 4 */

 

10.堵塞、中断和DMA 

一、阻塞式发送

printf():需要fputc重定向,相当于是HAL_UART_Transmit()的封装版,实质还是HAL_UART_Transmit()

HAL_UART_Transmit() 注意:一次发送一个字节。

缺点:在进行一个I/O操作的时候,要一直占用着CPU,这样就会浪费CPU的时间。

二、中断式发送

是写在while函数之外的,不影响正常while中其他函数运行

HAL_UART_Transmit_IT();此函数为发送中断函数,每一个字节都会进入一次中断,无需字节编写回调函数,HAL库会自己处理知道完全发送。

此发送方式不需要等待发送结束才退出函数,而是直接开启中断,在中断里发送。

在接收全部数据后会有一个回调函数:HAL_UART_TxCpltCallback();

HAL_UART_Receive_IT().(注意在定义接收数组的时候要将数组定义为全局变量,以防局部变量被销毁)

DMA,全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 

三、DMA发送

【函数】

HAL_UART_Transmit_DMA();

HAL_UART_Receive_DMA();

【区别】

中断发送是每个字节都会触发一次中断而DMA只触发一次。比起中断不占cpu资源

(了解)DMA串口的工作顺序

1 在中断服务函数里判断是否为空闲中断:if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET)

2:再写清空标志位函数 __HAL_UART_CLEAR_IDLEFLAG(&huart1)

3:判断已经接收的个数:uint8_t len=3-__HAL_DMA_GET_COUNTER( huart1.hdmarx);

其中3为Receive中规定的接收字节数;

__HAL_DMA_GET_COUNTER( huart1.hdmarx)为计数器,每接收一个字节就减一,初始值为Transmit中规定的接收字节数。

4:发送剩下字节。HAL_UART_Transmit(&huart1,buffer,len)

5:开启下次接收(相当于回调函数):HAL_UART_Receive

11.ADC (Analog-to-Digital Converter)

指模/数转换器或者模拟/数字转换器, 即将连续变量的模拟信号转换为离散的数字信号的器件。

典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号

简单地说就是将模拟电压值,转换成对应的肉眼可读数值

ADC的转换模式 (重要,请务必看懂)

1 单次转换模式:ADC只执行一次转换;

2 连续转换模式:转换结束之后马上开始新的转换;

3 扫描模式:ADC扫描被规则通道和注入通道选中的所有通道,在每个组的每个通道上执行单次转换。在每个转换结束时,这一组的下一个通道被自动转换。如果设置了CONT位(开启了连续 转换模式),转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。

4 间断模式:触发一次,转换一个通道,在触发,在转换。在所选转换通道循环,由触发信号启动新一轮的转换,直到转换完成为止。

扫描模式简单的说是一次对所有所选中的通道进行转换,比如开了ch0,ch1,ch4,ch5。  ch0转换完以后就会自动转换通道1,4,5直到转换完这个过程不能被打断。如果开启了连续转换模式,则会在转换完ch5之后开始新一轮的转换。

这就引入了间断模式,可以说是对扫描模式的一种补充。它可以把0,1,4,5这四个通道进行分组。可以分成0,1一组,4,5一组。也可以每个通道单独配置为一组。这样每一组转换之前都需要先触发一次。

配置

ADC单通道:

只进行一次ADC转换:配置为“单次转换模式”,扫描模式关闭。ADC通道转换一次后,就停止转换。等待再次使能后才会重新转换

进行连续ADC转换:配置为“连续转换模式”,扫描模式关闭。ADC通道转换一次后,接着进行下一次转换,不断连续。

ADC多通道:

只进行一次ADC转换:配置为“单次转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,就停止转换。等待再次使能后才会重新转换

进行连续ADC转换:配置为“连续转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,接着进行下一次转换,不断连续。

也就是:多通道必须使能扫描模式 

ADC一般用于采集小电压,其输入值不能超过VDDA

一般把VSSA和VREF- 接地, VREF+ 和 VDDA接3V3,那么ADC的输入范围是0~3.3V

 ADC输入范围:VREF- ≤ VIN ≤ VREF+1e8abb416b19402280046fe1589f7b0e.png

12.ADC实际操作

1.设置RCC              设置高速外部时钟HSE 选择外部时钟源

2.设置ADC引脚       只有设置了ADC的引脚,才能够设置ADC的时钟分频

3.设置时钟树

 640a0e584aec45b080cbef12112b36f8.png

ADCs_Common_Settings  ADC模式设置

Mode  ADC_Mode_Independent

这里设置为独立模式

独立模式模式下,双ADC不能同步,每个ADC接口独立工作。所以如果不需要ADC同步或者只是用了一个ADC的时候,应该设成独立模式,多个ADC同时使用时会有其他模式,如双重ADC同步模式,两个ADC同时采集一个或多个通道,可以提高采样率

Data Alignment (数据对齐方式): 右对齐/左对齐

Scan Conversion Mode( 扫描模式 ) :DISABLE

如果只是用了一个通道的话,DISABLE就可以了(也只能DISABLE),如果使用了多个通道的话,会自动设置为ENABLE。 就是是否开启扫描模式

 

Continuous Conversion Mode(连续转换模式)   ENABLE

设置为ENABLE,即连续转换。如果设置为DISABLE,则是单次转换。两者的区别在于连续转换直到所有的数据转换完成后才停止转换,而单次转换则只转换一次数据就停止,要再次触发转换才可以进行转换

Discontinuous Conversion Mode(间断模式)    DISABLE

因为我们只用到了1个ADC,所以这个直接不使能即可

规则通道设置

Enable Regular Conversions (启用常规转换模式)    ENABLE

使能 否则无发进行下方配置

Number OF Conversion(转换通道数) 
用到几个通道就设置为几
多个通道自动使能扫描模式

96cf848448de44bf98ca77fc3050a1de.png

Extenal Trigger Conversion Source (外部触发转换源)  设定ADC的触发方式

Regular Conversion launched by software 规则的软件触发 调用函数触发即可

Timer X Capture Compare X event 外部引脚触发

Timer X Trigger Out event 定时器通道输出触发 需要设置相应的定时器设置1698a25eaf10490089c9febac02c9c2f.png

 83f3f820f4b443a4be497f403944d78e.png

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/805846
推荐阅读
相关标签
  

闽ICP备14008679号