Skocz do zawartości

[STM32L] Alkomat


viruss3000

Pomocna odpowiedź

Witam szanownych użytkowników forum.

Jestem w trakcie wykonywania projektu - mianowicie chce zbudować alkomat z wykorzystaniem STM32L152RBT6 http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF250990

oraz czujnika MQ3 http://botland.com.pl/attachment.php?id_attachment=10

Aktualny układ:

Płytka zasilana jest za pomocą USB. Do pinu 7 skonfigurowanego jako wyjście podłączona dioda. Do Pinu 6 skonfigurowanego jako analogowe wejście podłączony czujnik. Czujnik jest zasilany oddzielnie 5V. Dioda jest zasilana z wyjścia mikrokontrolera.

Mam w związku z tym kilka pytań:

1.Konfiguracja ADC

Program wykorzystując przetwornik ADC powinien mierzyć napięcie na Pinie nr 6.

Napięcie to jest wyjściem analogowego czujnika alkoholu. Czujnik jest raczej dobrze podłączony ponieważ testowałem go w tej konfiguracji za pomocą woltomierza.

Program niestety zamiast wyświetlać napięcie wyświetla dziwnie wartości.

Dodam że ADC przy zapisywaniu do pamięci korzysta z DMA więc tam też się może kryć błąd.

2.Nie dokońca rozumiem konfiguracje portów. Otóż moja płytka posiada wlutowany wyświetlacz. Do jego obsług korzystam z zbioru funkcji napisanego przez stma http://pastie.org/8698804

Widze w kodzie tych funkcji że wyświetlacz podczas inicjalizacji zabiera wszystkie PINy, ustawia je do trybu funkcji alternatywnej. Czy to oznacza że korzystając z wbudowanego wyświetlacza nie mogę korzystać z tych pinów ? A może mogę się przełączać jakoś między trybami ?

Dotychczas poprostu olałem to że wyświetlacz korzysta z pinu i dodawałem do niego swoja konfiguracje. Ale zauważyłem że niektóre pola wyświetlacza się dziwnie zachowują.

Oto kod mojego programu:




#include "stm32l1xx.h"
#include "stdio.h"
#include "discover_board.h"
#include "stm32l_discovery_lcd.h"
#include "main.h"



typedef enum {START, MEASURE, RESULT , eMin = START, eMax = RESULT} ProgramState_TypeDef;
#define BEEP_PIN  GPIO_Pin_5
#define BUTTON_PIN GPIO_Pin_0
#define RED_LED_PIN  GPIO_Pin_7
#define MQ3_PIN GPIO_Pin_6 
#define MQ3_ADC_CHANNEL ADC_Channel_9
#define ADC1_DR_ADDRESS       ((uint32_t)0x40012458)  // ??


RCC_ClocksTypeDef  RCC_Clocks;
GPIO_InitTypeDef   GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
ProgramState_TypeDef programState;


char strDisp[20] ;
double measureResult;
static uint16_t Voltage;
static uint16_t MaxVoltage;
static __IO uint16_t ConvertedValue;


void RCC_Configuration(void);
void RTC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
void ADC1_Configuration(void);
void NVIC_Configuration(void);

void start(void);
void measure(void);
void result(void);

/*******************************************************************************/

int main(void)
{ 
 RCC_Configuration();
 RTC_Configuration();
NVIC_Configuration();
 SysTick_Config(SystemCoreClock / 1000);
LCD_GLASS_Configure_GPIO();
 LCD_GLASS_Init();


GPIO_ResetBits(GPIOB,RED_LED_PIN);
GPIO_ResetBits(GPIOB,BEEP_PIN);
 //LCD_GLASS_ScrollSentence("ALOKOMAT",1,SCROLL_SPEED);
 programState = START;
GPIO_Configuration();
DMA_Configuration();
ADC1_Configuration();

 while(1)
 {

 LCD_GLASS_Clear();
switch(programState)
{
	case START:
		start();
		break;
	case MEASURE:
		measure();
		break;
	case RESULT:
		result();
		break;
}

 }

}

/*---------------------------------------------------------------------------*/



void start()
{
		GPIO_ResetBits(GPIOB,RED_LED_PIN);
		GPIO_SetBits(GPIOB,BEEP_PIN);
		sprintf(strDisp, "Click to Start");
		LCD_GLASS_DisplayString( (unsigned char *) strDisp );
		MaxVoltage = 0;
}
void measure()
{
	GPIO_SetBits(GPIOB,RED_LED_PIN);
	GPIO_ResetBits(GPIOB,BEEP_PIN);

	if (DMA_GetFlagStatus(DMA1_FLAG_TC1)) 
	{       
		//Voltage     = (ConvertedValue * 3300 * 2) / 4095; 
		Voltage     = ConvertedValue;
		ADC_SoftwareStartConv(ADC1);
				if(Voltage > MaxVoltage)
		MaxVoltage = Voltage;
	}
	sprintf(strDisp, "%d", Voltage);
	LCD_GLASS_DisplayString( (unsigned char *) strDisp );

}
void result()
{
	GPIO_ResetBits(GPIOB,RED_LED_PIN);
	GPIO_SetBits(GPIOB,BEEP_PIN);
	//ADD converstion to promils
	sprintf(strDisp, "%d", MaxVoltage);
	LCD_GLASS_DisplayString( (unsigned char *) strDisp );
}
void RTC_Configuration(void)
{

/* Allow access to the RTC */
 PWR_RTCAccessCmd(ENABLE);

 /* Reset Backup Domain */
 RCC_RTCResetCmd(ENABLE);
 RCC_RTCResetCmd(DISABLE);

 /* LSE Enable */
 RCC_LSEConfig(RCC_LSE_ON);

 /* Wait till LSE is ready */
 while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
 {}

 RCC_RTCCLKCmd(ENABLE);

 /* LCD Clock Source Selection */
 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

}

void RCC_Configuration(void)
{  

 /* Enable HSI Clock */
 RCC_HSICmd(ENABLE);

 /*!< Wait till HSI is ready */
 while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
 {}

 RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);

 RCC_MSIRangeConfig(RCC_MSIRange_6);

 RCC_HSEConfig(RCC_HSE_OFF);  
 if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET )
 {
   while(1);
 }

 /* Enable  comparator clock LCD and PWR mngt */
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_LCD | RCC_APB1Periph_PWR, ENABLE);

 /* Enable ADC clock & SYSCFG */
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG, ENABLE);

}

void GPIO_Configuration()
{
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

GPIO_InitStructure.GPIO_Pin = RED_LED_PIN | BEEP_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);

//ADC
GPIO_InitStructure.GPIO_Pin = MQ3_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
 GPIO_Init(GPIOB, &GPIO_InitStructure); 

//BUTTON
GPIO_InitStructure.GPIO_Pin = BUTTON_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);    

}

void nextStateGlobal()
{
if(programState == eMax)
	programState = eMin;
else
	++programState;		
}
void DMA_Configuration()
{
DMA_InitTypeDef DMA_InitStructure;
/* Enable DMA1 clock */
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 /* DMA1 channel1 configuration */
 DMA_DeInit(DMA1_Channel1);
 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS;
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ConvertedValue;
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
 DMA_InitStructure.DMA_BufferSize = 3;
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 DMA_Init(DMA1_Channel1, &DMA_InitStructure); 

 /* Enable DMA1 channel1 */
 DMA_Cmd(DMA1_Channel1, ENABLE);
}
void NVIC_Configuration()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

 EXTI_InitStructure.EXTI_Line = EXTI_Line0 ;  // PA0 for User button AND IDD_WakeUP
 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
 EXTI_InitStructure.EXTI_LineCmd = ENABLE;
 EXTI_Init(&EXTI_InitStructure);
}

void ADC1_Configuration()
{
 ADC_InitTypeDef  ADC_InitStructure;

/* Enable The HSI (16Mhz) */
 RCC_HSICmd(ENABLE);

 /* Check that HSI oscillator is ready */
 while (!RCC_GetFlagStatus(RCC_FLAG_HSIRDY));

 /* Enable ADC1 clock */
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

 /* ADC1 Configuration -----------------------------------------------------*/
 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
 ADC_InitStructure.ADC_ScanConvMode = ENABLE;
 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
 ADC_InitStructure.ADC_ExternalTrigConv = 0;
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 ADC_InitStructure.ADC_NbrOfConversion = 3;
 ADC_Init(ADC1, &ADC_InitStructure);

 /* Enable temperature sensor and Vref */
 ADC_TempSensorVrefintCmd(ENABLE);

 /* ADC1 regular channel configuration */
 ADC_RegularChannelConfig(ADC1, MQ3_ADC_CHANNEL,       1, ADC_SampleTime_24Cycles);
 ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 2, ADC_SampleTime_24Cycles);
 ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint,    3, ADC_SampleTime_24Cycles);

 /* Enable the request after last transfer for DMA Circular mode */
 ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

 /* Define delay between ADC1 conversions */
 ADC_DelaySelectionConfig(ADC1, ADC_DelayLength_7Cycles);

 /* Enable ADC1 Power Down during Delay */
 ADC_PowerDownCmd(ADC1, ADC_PowerDown_Idle_Delay, ENABLE); 

 /* Enable ADC1 DMA */
 ADC_DMACmd(ADC1, ENABLE);

 /* Enable ADC1 */
 ADC_Cmd(ADC1, ENABLE);

 /* Wait until the ADC1 is ready */
 while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS));

 /* Start ADC1 Software Conversion */
 ADC_SoftwareStartConv(ADC1);
}
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.