最近做項目用到STM32F051的片子,遇到了兩個小坑。
我的一個項目,需要ADC採集。兩路ADC輸入通道。PA0-ADCIn0; PA1-ADCIn1.
一開始想使用最簡單的方式,單次轉換。第一次採In0, 第2次採集In1.
STM32F0 的ADC庫裏面提供了ADC轉換的函數:如下:
ADC_StartOfConversion(ADC1);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
AdcProValRig[AdcLoopId] =ADC_GetConversionValue(ADC1);
ADC_StopOfConversion(ADC1);
解釋:ADC_StartOfConversion 開始連續轉換,也可以配置爲,不是連續轉換。在ADC初始化結構體中配置。
然後等待ADC轉換結束,然後讀取ADC的轉換結果(同時會自動清空EOC標識)。
然後停止轉換。
接下來採集In1 , 理所當然,在採集前配置ADC的通道指向In1.
ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_71_5Cycles);
但是設置完了之後,發現,根本沒有鳥用啊。 採集的數據還是 之前IN0的通道。WHAT???
最後去看了一下原函數:居然是或運算!!!! 我的理解是,STM32 的ADC庫設計,讓你儘量使用規則或者注入模式去使用ADC。如下:
void ADC_ChannelConfig(ADC_TypeDef* ADCx, uint32_t ADC_Channel, uint32_t ADC_SampleTime)
{
uint32_t tmpreg = 0;
/* Check the parameters */
assert_param(IS_ADC_ALL_PERIPH(ADCx));
assert_param(IS_ADC_CHANNEL(ADC_Channel));
assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
/* Configure the ADC Channel */
ADCx->CHSELR |= (uint32_t)ADC_Channel;
/* Clear the Sampling time Selection bits */
tmpreg &= ~ADC_SMPR1_SMPR;
/* Set the ADC Sampling Time register */
tmpreg |= (uint32_t)ADC_SampleTime;
/* Configure the ADC Sample time register */
ADCx->SMPR = tmpreg ;
}
那就直接寫通道到寄存器吧:
ADC1->CHSELR = ADC_CHSELR_CHSEL1;
第2個小坑: 就是在向FLASH 寫入參數的時候,單片機會死機,後來找到問題了,在寫FLASH的時候,要關閉中斷。可能是我寫入到FLASH的內容多,時間長,寫進入後,還要讀出來,校驗。而我的串口通訊,波特率時38400很快,讀寫FLASH期間,頻繁的進入中斷,導致死機。