Skip to content

Instantly share code, notes, and snippets.

@MarrekNozka
Created April 30, 2021 07:16
Show Gist options
  • Select an option

  • Save MarrekNozka/e179c19a2815523a3d35bec6e9bcdf13 to your computer and use it in GitHub Desktop.

Select an option

Save MarrekNozka/e179c19a2815523a3d35bec6e9bcdf13 to your computer and use it in GitHub Desktop.
TIM1 ultrasonic
// generuje na výstupu PC5 kladný impulz o délce PULSE_LEN jako spouštěcí impulz pro ultrazvukvý modul
// detekuje na pinu PC1 (TIM1_CH1) pomocí funkce input capture příchod echo pulzu z ultrazvukového modulu a měří jeho délku
// měření zpracovává neblokujícím způsobem periodicky opakuje. Výsledek vrací do proměnné capture
// pomocí proměnné/vlajky capture_flag informuje zbytek programu že byl změřen nový výsledek
#include "stm8s.h"
#include "milis.h"
#define PULSE_LEN 2 // délka spouštěcího (trigger) pulzu pro ultrazvuk
#define MEASURMENT_PERIOD 100 // perioda měření ultrazvukem (měla by být víc jak (maximální_dosah*2)/rychlost_zvuku)
void process_measurment(void);
void init_tim1(void);
uint16_t capture; // tady bude aktuální výsledek měření (času)
uint8_t capture_flag = 0; // tady budeme indikovat že v capture je čerstvý výsledek
void main(void)
{
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz z interního RC oscilátoru
init_milis(); // milis kvůli delay_ms()
init_tim1(); // nastavit a spustit timer
GPIO_Init(GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW); // výstup - "trigger pulz pro ultrazvuk"
while (1) {
process_measurment(); // obsluhuje neblokujícím způsobem měření ultrazvukem
}
}
void process_measurment(void)
{
static uint8_t stage = 0; // stavový automat
static uint16_t time = 0; // pro časování pomocí milis
switch (stage) {
case 0: // čekáme než uplyne MEASURMENT_PERIOD abychom odstartovali měření
if (milis() - time > MEASURMENT_PERIOD) {
time = milis();
GPIO_WriteHigh(GPIOC, GPIO_PIN_5); // zahájíme trigger pulz
stage = 1; // a bdueme čekat až uplyne čas trigger pulzu
}
break;
case 1: // čekáme než uplyne PULSE_LEN (generuje trigger pulse)
if (milis() - time > PULSE_LEN) {
GPIO_WriteLow(GPIOC, GPIO_PIN_5); // ukončíme trigger pulz
stage = 2; // a přejdeme do fáze kdy očekáváme echo
}
break;
case 2: // čekáme jestli dostaneme odezvu (čekáme na echo)
if (TIM1_GetFlagStatus(TIM1_FLAG_CC2) != RESET) { // hlídáme zda timer hlásí změření pulzu
capture = TIM1_GetCapture2(); // uložíme výsledek měření
capture_flag = 1; // dáme vědět zbytku programu že máme nový platný výsledek
stage = 0; // a začneme znovu od začátku
} else if (milis() - time > MEASURMENT_PERIOD) { // pokud timer nezachytil pulz po dlouhou dobu, tak echo nepřijde
stage = 0; // a začneme znovu od začátku
}
break;
default: // pokud se cokoli pokazí
stage = 0; // začneme znovu od začátku
}
}
void init_tim1(void)
{
GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_IN_FL_NO_IT); // PC1 (TIM1_CH1) jako vstup
TIM1_TimeBaseInit(15, TIM1_COUNTERMODE_UP, 0xffff, 0); // timer necháme volně běžet (do maximálního stropu) s časovou základnou 1MHz (1us)
// Konfigurujeme parametry capture kanálu 1 - komplikované, nelze popsat v krátkém komentáři
TIM1_ICInit(TIM1_CHANNEL_1, TIM1_ICPOLARITY_RISING,
TIM1_ICSELECTION_DIRECTTI, TIM1_ICPSC_DIV1, 0);
// Konfigurujeme parametry capture kanálu 2 - komplikované, nelze popsat v krátkém komentáři
TIM1_ICInit(TIM1_CHANNEL_2, TIM1_ICPOLARITY_FALLING,
TIM1_ICSELECTION_INDIRECTTI, TIM1_ICPSC_DIV1, 0);
TIM1_SelectInputTrigger(TIM1_TS_TI1FP1); // Zdroj signálu pro Clock/Trigger controller
TIM1_SelectSlaveMode(TIM1_SLAVEMODE_RESET); // Clock/Trigger má po příchodu signálu provést RESET timeru
TIM1_ClearFlag(TIM1_FLAG_CC2); // pro jistotu vyčistíme vlajku signalizující záchyt a změření echo pulzu
TIM1_Cmd(ENABLE); // spustíme timer ať běží na pozadí
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment