詳しい話は、また別の機会に。
とりあえず、ポートの制限がなくなった。
さて本題。情報としては知っていたのだけれど、STM32のAD変換で、はまった。
STM32の12bitAD変換は変換結果を左詰にするか、右詰にするかを選べるのだけれど、右詰に設定しても、それが有効化されないのだ。
花岡ちゃんに花束を(STM32F4のAD変換トラブル(その2))
このページで、ADCの初期化でADC_DeInit();を実行すれば良いとされているが、それだけでは解決されなかった。
試行錯誤の結果、ADCの初期化処理の最後にウェイト処理を追加することで解決したので、ADCの初期化が完了する前に、ADCを使い始めてしまったのだろうか?
おそらく、データシートには書いてあるのだろうけれど、詳しく見てないので分からない。
ソースコードは以下。
#include "stm32f4xx.h" #include "uart1.h" #include "stm32f4dis.h" /* -------------------------------------- time : 約1uSec,1000000=1sec -------------------------------------- */ void delay(uint32_t time){ uint32_t t; volatile uint8_t i; for(i=0;i<24;i++){ t = time; while(t--); } } // ------------------------------------------------------------------- // systick 割込み(1msec毎に設定してある) // stm32f4xx_it.c で呼び出している // ------------------------------------------------------------------- volatile uint16_t time_sec=0; volatile uint16_t time_msec=0; void systick_1msec(void){ static uint16_t cnt=0; cnt++; time_msec++; if(cnt>1000){ time_msec=0; cnt=0; time_sec++; } } void Delay_ms(uint16_t msec){ uint16_t cnt=0; cnt = time_msec; while(msec){ if(cnt!=time_msec){ cnt = time_msec; msec--; } } } // ------------------------------------------------------------------- // ADC3 初期化 // ------------------------------------------------------------------- void adc3_init(void){ ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; //必要なペリフェラルにクロック供給開始 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); //GPIO-Cの指定の入力をアナログに設定 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //PC[13:10]をアナログ入力に設定 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); ADC_DeInit(); // AD変換器のリセット //ADC3の変換モード設定。 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // ↓ ENABLE(スキャンモード)、DISABLE(分割スキャンモード) ADC_InitStructure.ADC_ScanConvMode = DISABLE; // ↓ ENABLE(連続変換モード)、DISABLE(シングル変換モード) ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // ↓ AD変換開始トリガなし ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // ↓ AD変換後のデータ右詰 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // ↓ 入力を4本(チャネルを増やしたらここを変える) ADC_InitStructure.ADC_NbrOfConversion = 4; ADC_Init(ADC3, &ADC_InitStructure); ADC_Cmd(ADC3, ENABLE); // ADC3を有効化 delay(10000); // 大切! } // ------------------------------------------------------- // // ------------------------------------------------------- int main(void) { volatile uint16_t time_tmp=0; uint16_t adc1_data=0; // ADC変換後のデータを格納 uint16_t adc2_data=0; // ADC変換後のデータを格納 uint16_t adc3_data=0; // ADC変換後のデータを格納 uint16_t adc4_data=0; // ADC変換後のデータを格納 SystemInit(); stm32f4_init(); set_led(0x01); delay(10000); adc3_init(); set_led(0x02); uart1_init(9600); usart1_printf(\"\\r\\n\"); usart1_printf(\"micro mouse ver0.0.1\\r\\n\"); // systick 設定(1msec) SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); if(SysTick_Config(SystemCoreClock/1000)){ while(1); // error } while(1){ // SW処理 if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13)){ //ボタンが押されて1になっていたら以下を実行 GPIO_ResetBits(GPIOB,GPIO_Pin_7); // 点灯 while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13)); // ボタンを放したら以下を実行 }else{ GPIO_SetBits(GPIOB,GPIO_Pin_7); // 消灯 } // 1秒処理 if(time_tmp!=time_sec){ set_led(0x04); time_tmp = time_sec; ADC_RegularChannelConfig( ADC3, ADC_Channel_10, 1, ADC_SampleTime_56Cycles); ADC_SoftwareStartConv( ADC3 ); // AD変換開始 while(ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) == RESET); adc1_data = ADC_GetConversionValue(ADC3); // AD変換データの取り込み adc1_data = adc1_data *3300/0xFFF; // 電圧に変換 ADC_RegularChannelConfig( ADC3, ADC_Channel_11, 1, ADC_SampleTime_56Cycles); ADC_SoftwareStartConv( ADC3 ); // AD変換開始 while(ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) == RESET); adc2_data = ADC_GetConversionValue(ADC3); // AD変換データの取り込み // adc2_data = adc2_data *3300/0xFFF; // 電圧に変換 ADC_RegularChannelConfig( ADC3, ADC_Channel_12, 1, ADC_SampleTime_56Cycles); ADC_SoftwareStartConv( ADC3 ); // AD変換開始 while(ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) == RESET); adc3_data = ADC_GetConversionValue(ADC3); // AD変換データの取り込み adc3_data = adc3_data *3300/0xFFF; // 電圧に変換 ADC_RegularChannelConfig( ADC3, ADC_Channel_13, 1, ADC_SampleTime_56Cycles); ADC_SoftwareStartConv( ADC3 ); // AD変換開始 while(ADC_GetFlagStatus(ADC3,ADC_FLAG_EOC) == RESET); adc4_data = ADC_GetConversionValue(ADC3); // AD変換データの取り込み adc4_data = adc4_data *3300/0xFFF; // 電圧に変換 usart1_printf(\"%4d : AD ch1=%4d , ch2=0x%8X , ch3=%4d , ch4=%4d \\r\", time_sec,adc1_data,adc2_data,adc3_data,adc4_data); set_led(0x00); } } return 0; }
0 件のコメント:
コメントを投稿