/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
哪位可以看出 ADC->CR2 中的第20位 EXTTRIG 是如何设置出来的!
请仔细看看!
幸亏我不用STM32的库!^_^!
我写的ADC初始化函数是这样的,使用查询和DMA方式都OK!
STM32_Adc1_Regs->cr1.bit.DUALMOD=0; //0000:独立模式 ADC_Mode_Independent
STM32_Adc1_Regs->cr1.bit.SCAN=0; // * 0:关闭扫描模式 ADC_ScanConvMode = ENABLE 这个0/1好像都可以!?
STM32_Adc1_Regs->cr2.bit.CONTL=1; // * 0:单次转换模式 【1】连续模式
STM32_Adc1_Regs->cr2.bit.EXTSEL=7; // * 7 触发ADC转换的条件 SWSTART软件[7] 0XE=1110
STM32_Adc1_Regs->cr2.bit.EXTTRIG=1; // * 1:使用外部触发信号启动转换 ADC_ExternalTrigConv_None=((u32)0x000E0000)
STM32_Adc1_Regs->cr2.bit.ALIGN=0; // 0:数据右对齐 ADC_DataAlign_Right
STM32_Adc1_Regs->sqr1.bit.L=0; // 规则通道序列长度 0000:1个转换 ADC_NbrOfChannel = 1
寄存器透明是使用库的一个优势
当然,喜欢裸奔或者西服,应该是都有需求吧
是这样,但是有问题始终解决不了
/*---------------------------- ADCx CR2 Configuration -----------------*/
/* Get the ADCx CR2 value */
tmpreg1 = ADCx->CR2;
/* Clear CONT, ALIGN and EXTSEL bits */
tmpreg1 &= CR2_CLEAR_Mask;
/* Configure ADCx: external trigger event and continuous conversion mode */
/* Set ALIGN bit according to ADC_DataAlign value */
/* Set EXTSEL bits according to ADC_ExternalTrigConv value */
/* Set CONT bit according to ADC_ContinuousConvMode value */
tmpreg1 |= (u32)(ADC_InitStruct->ADC_DataAlign | ADC_InitStruct->ADC_ExternalTrigConv |
((u32)ADC_InitStruct->ADC_ContinuousConvMode << 1));
/* Write to ADCx CR2 */
ADCx->CR2 = tmpreg1;
执行该函数后,寄存器的内容确实能正确改变,但是设置为定时器触发,定时器的相应位已经设置了,ADC却触发不了!只好用TIMER作INT,在INT里软件触发ADC,再等待转换后DMA完成,这样也能得到正确的采样频率,但是要浪费部分CPU时间.遇到该问题的高手一起讨论一下.
哈哈!看来你们都不仔细啊!
哪位可以看出 ADC->CR2 中的第20位 EXTTRIG 是如何设置出来的!
请仔细看看!
说实话,我用STM32做了几个案子,还很少研究它的寄存器
用库,可以屏蔽各家芯片的差异
需要快速操作IO口的时候直接访问寄存器还是很快的
比调用库函数少了一个跳转的时间
顶楼上两位!
其实 我的意思不是不去使用STM32库,相反,我使用自己的方法却却更好的了解STM32库!对使用它更有好处。
回归正题吧:
上面那段代码。 根本就没有 设置 EXTTRIG位。也就是【外部触发信号启动转换】
ST库这样是非常不厚道的!做技术的,也不能这样吧!
回复主题:STM32库真让人哭笑不得
这很正常,ST做库的也是常人.BUG有待大家共同努力,要是没有BUG,微软就不要每月公布补丁了.
楼主的严谨是值得我们大家学习的!
ST每月打补丁,你还用么?
他的库,一个版本,兼容所有型号!!
所以,每出一个新芯片,肯定库升级,并且说,老库bug......
新库和老库,结构定义不兼容,程序基本要重写........
ADC_ExternalTrigConv_None
ADC_ExternalTrigConv_None
转换由软件而不是外部触发启动
楼主更是让人哭笑不得
现在弄明白你的意思了,是看一下你在顶楼上的代码如何设置ExternalTrig位的,但是你的代码里没要求设置为ExternalTrig啊,如果库里设置了该位才是错的呢!
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
该行的意思是不使用外部触发,我写的是
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_TIM2_CC2;
调试时清楚的看到执行ADC_Init(ADC1, &ADC_InitStructure);后ExternalTrig位被置1。但是奇怪的是TIM2_CC2置1后不触发ADC,但是一执行
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_TIM2_CC2;就触发ADC一次!
你是不是 跟我开国际玩笑 ?
等你 完全弄懂在跟我说吧!
请你仔细 看看每个 寄存器的操作,也可以 仿真看 寄存器的每位的变化。
一步一步仿真!
还有:ADC_ExternalTrigConv_None =? 它最后是作为那个 寄存器的参数?
拜托你仔细 看看!
re
lz有点问题..老抓着库不放..
ST这点库做的比ATmel的好多了..
我的目的是希望STM32 库 更进步。
我的目的是希望STM32 库 更进步。我现在照样适用STM32 的库。
某些部分,不是全部。它的代码很多不敢恭维!
Swd21ic 同学就看ATMEL的, 为何不看看TI给 dsp28XX的。
可以肯定,STM32 还会不断 升级,每个版本变化可能还会差别很多的呢!
还是跟freefish 同学说。
“代码里没要求设置为ExternalTrig啊,如果库里设置了该位才是错的呢!
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
该行的意思是不使用外部触发”
就拿万利开发板 ADCDEMO 程序来说。
按上面结论:ADC控制寄存器2(ADC_CR2)的第20位 EXTTRIG应该=0,是不是?
我们可以把断点设在ADC_Init(ADC1, &ADC_InitStructure)开始处。
这时看看寄存器: EXTTRIG应该=? 是不是=1?
是谁干了的?
如果把EXTTRIG 位设置为0, 看看这个ADCDEMO还能不能运行?
我的是不能的。就是万利开发板的ADCDEMO 程序。
糊涂了,好像没有问题呀!
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
======》
#define ADC_ExternalTrigConv_None ((u32)0x000E0000)
第20位为零,19,18,17为1,EXTSEL=111,
........
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
=====>
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
{
/* Check the parameters */
assert(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the selected ADC conversion on external event */
/* Starts the selected ADC conversion */
ADCx->CR2 |= CR2_EXTTRIG_SWSTRT_Set;
}
else
{
/* Stops the selected ADC conversion */
/* Disable the selected ADC conversion on external event */
ADCx->CR2 &= CR2_EXTTRIG_SWSTRT_Reset;
}
====>
/* ADC Software start mask */
#define CR2_EXTTRIG_SWSTRT_Set ((u32)0x00500000)
位22 SWSTART:开始转换规则通道
由软件设置该位以启动转换,转换开始后硬件马上清除此位。如果在EXTSEL[2:0]位中选择
了SWSTART为触发事件,该位用于启动一组规则通道的转换,
0:复位状态
1:开始转换规则通道
位20 EXTTRIG:规则通道的外部触发转换模式
该位由软件设置和清除,用于开启或禁止可以启动规则通道组转换的外部触发信号。
0:不用外部触发信号启动转换
1:使用外部触发信号启动转换
====>跟踪完毕!
仿真的结果。
图上 就是=1 ,而且查不多原因!
LZ才是让人哭笑不得~~~
当用软件触发ADC转换时:
(1)ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
===〉EXTSEL=111@ CR2,表示软件触发ADC转换
(2)ADC_SoftwareStartConvCmd(ADC1, ENABLE);
===> SWSTART=1@ CR2,并且EXTTRIG=1@ CR2,这里就同时使能了外部事件触发和软件开启ADC的转换
当使用真正的外部事件触发ADC转换时:例如
(1)ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11;
===〉 EXTSEL= 110@ CR2
(2)ADC_ExternalTrigConvCmd(ADC1, ENABLE);
===> EXTTRIG=1@ CR2,使能外部事件触发
有啥不对么?
LZ自己断章取义~~~