野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16465|回复: 25

【F1-ADC】STM32 ADC 规则序列寄存器SQR和注入序列寄存器JSQR的使用方法

[复制链接]
发表于 2015-9-20 19:01:26 | 显示全部楼层 |阅读模式
参考资料:《STM32中文参考手册》——  11 模拟/数字转换(ADC)

SQR: 规则序列寄存器
JSQR: 注入序列寄存器

1.jpg SQR和JSQR寄存器说明.xls (11.5 KB, 下载次数: 29)


STM32 的ADC 在转换的时候有规则通道和注入通道,无论使用这两种模式都必须操作相对应的规则序列寄存器SQR和注入序列寄存器JSQR。

SQR有3个,分别为SQR1、SQR2、SQR3,这三个寄存器决定规则转换的顺序。
第一次转换的是SQR3寄存器的SQ1[4:0],第二次转换的是SQ2[4:0],第x次转换的是SQx[4:0],以此类推。
SQR3寄存器决定的是SQ1~SQ6,SQR2寄存器决定的是SQ7~SQ12,SRQ1寄存器决定的是SQ13~SQ16。


ADC支持最多16个通道,具体要使用多少个通道,在SQR1的L[3:0]设置。当我们设置好要使用
多少个通道之后,就面临着这些通道的转换顺序,我们先讲解SQR。这个转换顺序由SQR决定,
SQR就好像做了16个蹲位,每个蹲位按照1~16标号,标号1表示第一次转换,以此类推,标号16表示最后一次转换。
剩下的就是要转换的通道往相应的蹲位跳即可,如果是通道16(CH16)想第一次转换,那么CH16往SQ1这个蹲位跳即可,
我们只要在SQR3这个寄存器的SQ1[4:0]位设置0X10(即16)就可以了,如果第二次转换的是通道1(CH1)那么只要在SQR3寄存器的SQ2[4:0]位设置0X01即可,


而JSQR则跟SQR不一样,JSQR最多只支持4个通道,这个由JSQR的JL[2:0]决定。
JSQR跟SQR决定转换顺序的时候也不一样,第一次转换的不是JSQR1[4:0],而是JCQRx[4:0] ,x = (4-JL),更SQR刚好是反过来的。
如果JL=00(1个转换),那么转换的顺序是从JSQR4[4:0]开始,而不是从JSQR1[4:0]开始,这个要注意,编程的时候不要搞错了。


有关规则序列寄存器:SQR的库函数应用
该库函数的功能是:设定ADC某个通道的转换顺序,并设定该通道的采样时间。
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);

举例:如果我们在项目中需要使用 ADC1的通道10、通道11、通道12、通道13这四个通道,那么在转换的时候就需要设置这四个通道的转换顺序,
我们设置通道13第一个转换,通道10第二个转换,通道11第三个转换,通道12第四个转换,这时候我们就需要操作SQR寄存器了,具体是怎么操作的我们可以看该库函数的底层,现在我告诉大家该库函数的使用方法,怎么样来设置通道的转换顺序。

每个通道的采样时间我们都统一设置成1.5个周期(这个周期是ADC_CLK)
通道13第一个转换:
  1. ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_1Cycles5);
复制代码
通道10第二个转换:
  1. ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 2, ADC_SampleTime_1Cycles5);
复制代码
通道11第三个转换:
  1. ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 3, ADC_SampleTime_1Cycles5);
复制代码
通道12第四个转换:
  1. ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 4, ADC_SampleTime_1Cycles5);
复制代码
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
规则通道配置函数的原型如下:
  1. void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
  2. {
  3.   uint32_t tmpreg1 = 0, tmpreg2 = 0;
  4.   /* Check the parameters */
  5.   assert_param(IS_ADC_ALL_PERIPH(ADCx));
  6.   assert_param(IS_ADC_CHANNEL(ADC_Channel));
  7.   assert_param(IS_ADC_REGULAR_RANK(Rank));
  8.   assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
  9.   /* if ADC_Channel_10 ... ADC_Channel_17 is selected */
  10.   if (ADC_Channel > ADC_Channel_9)
  11.   {
  12.     /* Get the old register value */
  13.     tmpreg1 = ADCx->SMPR1;
  14.     /* Calculate the mask to clear */
  15.     tmpreg2 = SMPR1_SMP_Set << (3 * (ADC_Channel - 10));
  16.     /* Clear the old channel sample time */
  17.     tmpreg1 &= ~tmpreg2;
  18.     /* Calculate the mask to set */
  19.     tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10));
  20.     /* Set the new channel sample time */
  21.     tmpreg1 |= tmpreg2;
  22.     /* Store the new register value */
  23.     ADCx->SMPR1 = tmpreg1;
  24.   }
  25.   else /* ADC_Channel include in ADC_Channel_[0..9] */
  26.   {
  27.     /* Get the old register value */
  28.     tmpreg1 = ADCx->SMPR2;
  29.     /* Calculate the mask to clear */
  30.     tmpreg2 = SMPR2_SMP_Set << (3 * ADC_Channel);
  31.     /* Clear the old channel sample time */
  32.     tmpreg1 &= ~tmpreg2;
  33.     /* Calculate the mask to set */
  34.     tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
  35.     /* Set the new channel sample time */
  36.     tmpreg1 |= tmpreg2;
  37.     /* Store the new register value */
  38.     ADCx->SMPR2 = tmpreg1;
  39.   }
  40.   /* For Rank 1 to 6 */
  41.   if (Rank < 7)
  42.   {
  43.     /* Get the old register value */
  44.     tmpreg1 = ADCx->SQR3;
  45.     /* Calculate the mask to clear */
  46.     tmpreg2 = SQR3_SQ_Set << (5 * (Rank - 1));
  47.     /* Clear the old SQx bits for the selected rank */
  48.     tmpreg1 &= ~tmpreg2;
  49.     /* Calculate the mask to set */
  50.     tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1));
  51.     /* Set the SQx bits for the selected rank */
  52.     tmpreg1 |= tmpreg2;
  53.     /* Store the new register value */
  54.     ADCx->SQR3 = tmpreg1;
  55.   }
  56.   /* For Rank 7 to 12 */
  57.   else if (Rank < 13)
  58.   {
  59.     /* Get the old register value */
  60.     tmpreg1 = ADCx->SQR2;
  61.     /* Calculate the mask to clear */
  62.     tmpreg2 = SQR2_SQ_Set << (5 * (Rank - 7));
  63.     /* Clear the old SQx bits for the selected rank */
  64.     tmpreg1 &= ~tmpreg2;
  65.     /* Calculate the mask to set */
  66.     tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7));
  67.     /* Set the SQx bits for the selected rank */
  68.     tmpreg1 |= tmpreg2;
  69.     /* Store the new register value */
  70.     ADCx->SQR2 = tmpreg1;
  71.   }
  72.   /* For Rank 13 to 16 */
  73.   else
  74.   {
  75.     /* Get the old register value */
  76.     tmpreg1 = ADCx->SQR1;
  77.     /* Calculate the mask to clear */
  78.     tmpreg2 = SQR1_SQ_Set << (5 * (Rank - 13));
  79.     /* Clear the old SQx bits for the selected rank */
  80.     tmpreg1 &= ~tmpreg2;
  81.     /* Calculate the mask to set */
  82.     tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13));
  83.     /* Set the SQx bits for the selected rank */
  84.     tmpreg1 |= tmpreg2;
  85.     /* Store the new register value */
  86.     ADCx->SQR1 = tmpreg1;
  87.   }
  88. }
复制代码


回复

使用道具 举报

发表于 2015-9-21 08:47:38 | 显示全部楼层
规则通道和注入通道之间有什么区别呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-9-21 08:53:15 | 显示全部楼层
飞鱼流星 发表于 2015-9-21 08:47
规则通道和注入通道之间有什么区别呢?

参考资料:《STM32中文参考手册》——  11 模拟/数字转换(ADC)

STM32的ADC支持规则通道和注入通道,那这两种通道有什么区别?

1、规格通道:我们一般使用的是规则通道,规则通道的使用方法很好理解,就是按照顺序依次转换而已。

2、注入通道:注入的意思我们可以理解成插入,插队的意思,就是属于一种紧急的转换通道,它只有在外部信号触发的时候才会启动,就跟中断一样。
当有触发信号来的时候,注入通道就会打断规则通道的转换,去执行注入通道,等注入通道转换完毕之后又回到规则通道转换的执行流。


要注意的是:注入通道是只有在规则通道存在时才会有的,所有才叫注入。
回复 支持 反对

使用道具 举报

发表于 2015-9-21 22:21:43 | 显示全部楼层
除了讲解支持点外,建议火哥可以在这个模块下经常上传一些经典的stm32题目,特别是企业项目里面经常用到的知识以题目的形式提出来,大家可以在这里一起做一起讨论,共同提高。
回复 支持 反对

使用道具 举报

发表于 2015-10-31 11:52:07 | 显示全部楼层
支持野火!!!支持每日一题!!!
回复 支持 反对

使用道具 举报

发表于 2015-10-31 18:04:41 | 显示全部楼层
ddddddddddddddddddddddddddddddd
回复 支持 反对

使用道具 举报

发表于 2015-11-2 23:41:43 来自手机 | 显示全部楼层
v2咋没有电位计,跟视频不一样
回复 支持 反对

使用道具 举报

发表于 2015-11-20 13:17:33 | 显示全部楼层
HAOHAOHAOHAO
回复 支持 反对

使用道具 举报

发表于 2015-11-29 10:28:23 | 显示全部楼层
仔细研究,好好学习
回复 支持 反对

使用道具 举报

发表于 2016-1-8 11:44:24 | 显示全部楼层
看看看看看看看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-1-8 12:00:06 | 显示全部楼层
china 发表于 2015-11-2 23:41
v2咋没有电位计,跟视频不一样

在板子的右上角 有电位器      
回复 支持 反对

使用道具 举报

发表于 2016-1-24 22:55:29 | 显示全部楼层
最近对于 ADC实验,我怎么改都是1.6V,醉了
回复 支持 反对

使用道具 举报

发表于 2016-2-27 17:23:20 | 显示全部楼层
谢谢火哥!!!
回复

使用道具 举报

发表于 2016-2-29 20:49:51 | 显示全部楼层
寄存器。。。。。。。。。。。。。。。。
回复

使用道具 举报

发表于 2016-3-3 09:49:22 | 显示全部楼层
【F1-ADC】单通道(NO DMA DMA)+ 6通道(DMA)采集例程
回复 支持 反对

使用道具 举报

发表于 2016-3-7 17:29:35 | 显示全部楼层
火哥真厉害,加油,小弟佩服你。。
回复 支持 反对

使用道具 举报

发表于 2016-3-17 22:50:00 | 显示全部楼层
STM32 ADC 规则序列寄存器SQR和注入序列寄存器JSQR的使用方法 [修改]  
学习,谢谢!
回复 支持 反对

使用道具 举报

发表于 2016-3-21 09:28:08 | 显示全部楼层
搜嘎,火哥威武
回复 支持 反对

使用道具 举报

发表于 2016-3-21 10:34:25 | 显示全部楼层
支持野火,支持火哥!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-3-21 10:34:51 | 显示全部楼层
时光隐匿 发表于 2016-1-24 22:55
最近对于 ADC实验,我怎么改都是1.6V,醉了

当没有成功采集到外部信号的时候,默认都是1.6V左右,比如 悬空的时候
回复 支持 反对

使用道具 举报

发表于 2016-3-21 11:39:56 | 显示全部楼层
新手学习STM32F103ZET6,希望火哥多多关照
回复 支持 反对

使用道具 举报

发表于 2016-3-21 16:07:31 | 显示全部楼层
学习,困无止境
回复 支持 反对

使用道具 举报

发表于 2016-4-28 20:54:01 | 显示全部楼层
哈哈哈,看看
回复 支持 反对

使用道具 举报

发表于 2016-4-30 12:14:23 | 显示全部楼层
5555555555555555555555555555555555555555555555
回复 支持 反对

使用道具 举报

发表于 2016-5-10 13:09:49 | 显示全部楼层
谢谢。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

发表于 2016-5-22 14:53:11 | 显示全部楼层
look啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-12-26 19:17 , Processed in 0.067761 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表