Šiam pavizdyje naudosiu PlatformIO IDE su Arduino (https://github.com/stm32duino/Arduino_Core_STM32) framework bei khoih-prog/TimerInterrupt_Generic@^1.11.0 biblioteka paprastesniam darbui su Timer pertraukimais (interrupts).
Taigi, platformio.ini
[env:bluepill_f103c8]
platform = ststm32
board = bluepill_f103c8
board_build.f_cpu = 72000000L
debug_tool = custom
debug_port = :4242
debug_server = $PLATFORMIO_CORE_DIR/packages/tool-stlink/bin/st-util
debug_init_cmds =
define pio_reset_halt_target
monitor reset
monitor halt
end
define pio_reset_run_target
monitor reset
end
target extended-remote $DEBUG_PORT
$LOAD_CMDS
pio_reset_halt_target
$INIT_BREAK
framework = arduino
upload_protocol = stlink
upload_flags = -c set CPUTAPID 0x2ba01477 ; jeigu mes klaidą, pakeisti į 0x1ba01477
Iterpiame bibliotekas:
#include <Arduino.h>
#include "TimerInterrupt_Generic.h"
Naudosime Timer3
STM32Timer ITimer3(TIM3);
Encoderiu padėties nuskaitymo funkcija\
volatile int32_t encoder1Count;
volatile int32_t encoder2Count;
volatile int32_t encoder3Count;
volatile int32_t encoder4Count;
void encoder1_read()
{
// tiesioginė prieiga prie įvesčių. žymiai greitesnis būsenos nuskaitymas.
// encoder 1
bool currentStateA = GPIOB->IDR & GPIO_PIN_12; // PB12
bool cvb = GPIOB->IDR & GPIO_PIN_13; // PB13
if (currentStateA != lastStateA)
{
if (cvb != currentStateA)
{
encoder1Count++;
}
else
{
encoder1Count--;
}
lastStateA = currentStateA;
}
// encoder 2
currentStateA = GPIOB->IDR & GPIO_PIN_14; // PB14
cvb = GPIOB->IDR & GPIO_PIN_15; // PB15
if (currentStateA != lastStateA)
{
if (cvb != currentStateA)
{
encoder2Count++;
}
else
{
encoder2Count--;
}
lastStateA = currentStateA;
}
// encoder 3
currentStateA = GPIOA->IDR & GPIO_PIN_3; // PA3
cvb = GPIOA->IDR & GPIO_PIN_2; // PA2
if (currentStateA != lastStateA)
{
if (cvb != currentStateA)
{
encoder3Count++;
}
else
{
encoder3Count--;
}
lastStateA = currentStateA;
}
// encoder 4
currentStateA = GPIOA->IDR & GPIO_PIN_1; // PA1
cvb = GPIOA->IDR & GPIO_PIN_0; // PA0
if (currentStateA != lastStateA)
{
if (cvb != currentStateA)
{
encoder4Count++;
}
else
{
encoder4Count--;
}
lastStateA = currentStateA;
}
}
void setup funkcijoje, nustatome Timer dažnį i 20kHz
ITimer1.setFrequency(20000, encoder1_read);
ir galiausiai, void loop
atspauzdiname enkoderių poziciją
void loop() {
static int32_t prev1Count = 0;
static int32_t prev2Count = 0;
static int32_t prev3Count = 0;
static int32_t prev4Count = 0;
if (encoder1Count != prev1Count)
{
prev1Count = encoder1Count;
Serial1.print("Encoder 1 counter: ");
Serial1.println(count);
}
if (encoder2Count != prev2Count)
{
prev2Count = encoder2Count;
Serial1.print("Encoder 2 counter: ");
Serial1.println(count);
}
if (encoder3Count != prev1Count)
{
prev1Count = encoder3Count;
Serial1.print("Encoder 3 counter: ");
Serial1.println(count);
}
if (encoder4Count != prev1Count)
{
prev1Count = encoder4Count;
Serial1.print("Encoder 4 counter: ");
Serial1.println(count);
}
}
Skanaus 😉 Ir pabaigai, jeigu encoder pulsai viršys 20kHz greičiausiai atsitiks kaip šiame paveiksliuke. Kelis pulsus priskaičiuos kaip vieną.