Skocz do zawartości

[C][STM32]Czujnik ultradźwiękowy


ziger

Pomocna odpowiedź

Witam mam taki problem z czujnikiem HC-SR04, że po skonfigurowaniu licznika TIM1 aby zmierzył mi szerokość impulsu pinu ECHO, wyświetlają mi się na wyświetlaczu LCD liczby nie zależnie czy czujnik coś wykrywa. Nie mam pojęcia gdzie coś źle skonfigurowałem i prosił bym o pomoc kogoś bardziej doświadczonego 🙂

Pozdrawiam

#include "stm32f10x_conf.h"
#include "LCDI2C.h"
#include "stdio.h"
#include "stdlib.h"




// D7 D6 D5 D4 LED E RW RS

void RCC_Config(void);
void GPIO_Config(void);
void NVIC_Config(void);
void TIM_Config(void);
void I2C_Config(void);
unsigned long int SysTick_Config_Mod(unsigned long int SysTick_CLKSource,unsigned long int Ticks);
void Delay(unsigned long int Opoznienieus);
extern volatile unsigned long int Licznikus;
extern unsigned short int czestotliwosc;



int main(void)
{
int i;
int dystans = 0;
char* odleglosc;
RCC_Config();
GPIO_Config();
NVIC_Config();
TIM_Config();
I2C_Config();
/*Tu nalezy umiescic ewentualne dalsze funkcje konfigurujace system*/
GPIO_ResetBits(GPIOC, GPIO_Pin_10);
/* wywolanie odpowiedniego czasu przerwania SysTick*/
	if (SysTick_Config_Mod(SysTick_CLKSource_HCLK_Div8, 30ul)){
		while(1); //w razie bledu petla nieskonczona
	}
   while(1)
   {

   	I2C_GenerateSTART(I2C1, ENABLE);
   		while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
   		I2C_Send7bitAddress(I2C1, 0x4E, I2C_Direction_Transmitter);
   		while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
   		LCD_WriteCommand(0x14);
   	    LCD_WriteCommand(0x24); //Sets 4 bit interface
   	    LCD_line_dot(2,8);
   	    LCD_Display(1,0,0);
   	    LCD_Entry(1,0);
   	    //LCD_GoTo(1,0);
   	    //LCD_WriteText("Odleglosc:");
   	    GPIO_WriteBit(GPIOC, GPIO_Pin_10, Bit_SET);
   	    Delay(100);
   	    GPIO_WriteBit(GPIOC, GPIO_Pin_10, Bit_RESET);
   	    Delay(2000);
   	    //dystans=(1/czestotliwosc)*1000000;
   	    //dystans=((dystans) * 34)/2000;
   	    sprintf(odleglosc,"%i", czestotliwosc);
   	    LCD_GoTo(1,0);
   	    LCD_WriteText(odleglosc);
   	    czestotliwosc = 0;
   	    dystans=0;
   	    //LCD_GoTo(1,0);
   	    //LCD_WriteText("                ");
  	    I2C_GenerateSTOP(I2C1,ENABLE);


   };
   return 0;
}

void RCC_Config(void)
//konfigurowanie sygnalow taktujacych
{
//zmienna opisujaca rezultat uruchomienia HSE
ErrorStatus HSEStartUpStatus;
//reset ustawien RCC
RCC_DeInit();

//wlacz HSE
RCC_HSEConfig(RCC_HSE_ON);

//odczekaj na gotowosc HSE
HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)
{
	//ustaw zwloke dla pamieci FLASH
	//zaleznie od taktowania rdzenia
	//0 gdy <24MHZ; 1 gdy 24-48 Mhz; 2 gdy >48Mhz
	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
	FLASH_SetLatency(FLASH_Latency_1);

	//ustaw HCLK=SYSCLK
	RCC_HCLKConfig(RCC_SYSCLK_Div1);

	//ustaw PCLK2=HCLK
	RCC_PCLK2Config(RCC_HCLK_Div1);

	//ustaw PLCK1=HCLK
	RCC_PCLK1Config(RCC_HCLK_Div1);

	//ustaw PLLCLK= HSE*3 czyli 8Mhz * 3 = 24 Mhz
	RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_3);

	//wlacz PLL
	RCC_PLLCmd(ENABLE);

	//odczekaj na poprawne uruchomienie PLL
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

	//ustaw PLL jako zrodlo sygnalu zegarowego
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

	//odczekaj az PLL bedzie sygnalem zegarowym systemu
	while(RCC_GetSYSCLKSource() != 0x08);

	/* Tu nalezy umiescic kod zwiazany z konfiguracja
	 * sygnalow zegarowych potrzebnych w programie peryferiow*/

	//wlacz taktowanie portu GPIOC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}else{}
}

void GPIO_Config(void)
//konfigurowanie portow GPIO
{
GPIO_InitTypeDef GPIO_InitStructure;
/*Tu nalezy umiescic kod zwiazany z konfiguracja portow GPIO potrzebnych w programie*/
//inicjalizacja portow I2C
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

//inicjalizacja przycisku na plytce
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

//inicjalizacja diody LED PC8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

//inicjalizacja wyjscia PC10 i wejscia PC11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);


}

void NVIC_Config(void)
//Konfigurowanie kontrolera przerwan NVIC
{
NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM
//Jezeli tablica wektorow w RAM, to ustaw jej adres na 0x20000000
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else VECT_TAB_FLASH
// W przeciwnym przypadku ustaw na 0x08000000
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

void I2C_Config(void)
//konfigurowanie I2C
{
int i;
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}





unsigned long int SysTick_Config_Mod(unsigned long int SysTick_CLKSource,unsigned long int Ticks)
{
//inicjalizacja licznika SysTick
//zastepuje funkcje z blibliotek STM
unsigned long int Settings;
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
//Kontrola, czy wartosc poczatkowa nie przekracza max
if(Ticks > SysTick_LOAD_RELOAD_Msk)	return(1);
//Ustaw wartosc poczatkowa licznika
SysTick->LOAD = (Ticks & SysTick_LOAD_RELOAD_Msk) - 1;
//Ustaw priorytet przerwania
NVIC_SetPriority(SysTick_IRQn, 0);
//Ustaw wartosc aktualna licznika
SysTick->VAL = 0;
//Ustaw znaczniki wlaczenia SysTick IRQ i samego licznika
Settings=SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
//Wybierz znacznik ustawien zrodla sygnalu zerowego
if (SysTick_CLKSource == SysTick_CLKSource_HCLK){
	Settings |= SysTick_CLKSource_HCLK;
} else {
	Settings &=SysTick_CLKSource_HCLK_Div8;
}
//Zapisz ustawienia do rejestru sterujacego SysTick
//(i wlacz licznik)
SysTick->CTRL = Settings;
return(0);
}


volatile unsigned long int Licznikus;

/*obsluga przerwania SysTick*/
void SysTick_Handler(void)
{
Licznikus++;
}

void Delay(unsigned long int Opoznienieus)
{
Licznikus=0;
while ((Licznikus) < Opoznienieus);
}


void TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_IC;
TIM_TimeBaseStructure.TIM_Prescaler = 8-1;
TIM_TimeBaseStructure.TIM_Period = 65535ul;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_IC.TIM_Channel = TIM_Channel_1;
TIM_IC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_IC.TIM_ICFilter = 0x0;
TIM_IC.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_PWMIConfig(TIM1, &TIM_IC);
TIM_SelectInputTrigger(TIM1, TIM_TS_ITR0);
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
TIM_Cmd(TIM1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);

}
unsigned short int czestotliwosc = 0;
void TIM1_CC_IRQHandler(void)
{
unsigned short int IC1 = 0;
if (TIM_GetITStatus(TIM1, TIM_IT_CC1)!= RESET)
{
	//czyszczenie bitu przerwania
	TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);

	GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
	//odczyt wartosci z kanalu IC1
	IC1=TIM_GetCapture1(TIM1);
	if(IC1 != 0)
	{
		czestotliwosc = (24000000/8) /IC1;

	} else {czestotliwosc = 0;}

}
}
Link do komentarza
Share on other sites

Jesteś kolejną osobą w ciągu kilku ostatnich dni która próbuje tego samego. Umówiliście się?

Ponieważ to Ty musisz uruchomić swój program, opowiedz własnymi słowami jak skonfigurowałeś timer i w jaki sposób ma on mierzyć długość impulsu z czujnika. Ponieważ ani timer ani sam pomiar nie są jakoś zbytnio skomplikowane, powinieneś zmieścić się w 10 zdaniach.

EDIT: Ups, to chyba odkop.... 😖

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.