Sisällysluettelo:

Nelibittinen oskilloskooppi: 6 vaihetta
Nelibittinen oskilloskooppi: 6 vaihetta

Video: Nelibittinen oskilloskooppi: 6 vaihetta

Video: Nelibittinen oskilloskooppi: 6 vaihetta
Video: Linus - “Day 6 in Kleve Hades” (C64, Real SID) [Oscilloscope View] 2024, Marraskuu
Anonim
Nelibittinen oskilloskooppi
Nelibittinen oskilloskooppi

Se on hauska projekti vain nähdäkseni, kuinka pitkälle nopeudella voisin työntää MAX7219-pistematriisinäytön. Ja sen sijaan, että se ajaisi "elämän peliä", päätin tehdä "laajuuden" sen kanssa. Kuten otsikosta ymmärrät, tämä ei korvaa oikeaa oskilloskooppia:-).

Koska en aio käyttää tätä vakavasti, en tee siihen piirilevyä. Ehkä, vain ehkä laitan sen perf-boardille, mutta toistaiseksi se on ja pysyy leipälaudalla. Myöskään tulovahvistinta/vaimenninta ei ole, sinun on syötettävä signaali välillä 0 - 3.3 V, älä mene negatiiviseksi tai yli 3.3 V: ksi, koska voit vahingoittaa mikro -ohjainta.

Vaihe 1: Laitteisto

Laitteisto
Laitteisto
Laitteisto
Laitteisto
Laitteisto
Laitteisto

Se on halpaa, erittäin halpaa, kun ostat osia Kiinasta ebayn tai vastaavien sivustojen kautta. Se käyttää STM32F103C8-kehityskorttia, jota joskus kutsutaan "siniseksi pillereksi" ja jonka ostin noin 2 eurolla (tai USD, ne ovat melkein saman arvoisia vuoden 2018 lopussa), kaksi 8x8x4 pistematriisinäyttöä, joissa on MAX7219-sirut, ostettu 5 euroa kappale ja kiertokooderi noin 1 euro.

Tarvitaan tietysti virtalähde, joka tuottaa 3,3 V: n muutaman sadan milliampeerin virralla. STM32F103C8 -kehityskortin jännitesäädintä ei käytetä, se ei voi antaa riittävästi virtaa näytöille. MAX7219: n tietolomakkeen mukaan käyttöjännitteen tulisi olla 4,0 - 5,5 V, mutta se toimii hyvin 3,3 V: lla, ehkä ei silloin, kun käytät sitä erittäin kuumassa tai kylmässä ympäristössä, mutta 20 celsiusasteessa se on hyvä. Ja nyt minun ei tarvitse käyttää tasonmuuntimia mikro-ohjaimen ja näyttölaitteiden välillä.

Vaihe 2: Rakenna

Rakentaa
Rakentaa
Rakentaa
Rakentaa
Rakentaa
Rakentaa

Kun katsot kuvaa, saatat huomata, että käytän leipälautojen sähköjohtoja epätavallisella tavalla, molemmat ylhäällä olevat linjat ovat positiivinen kisko ja molemmat alhaalla ovat maadoituskisko. Se on tapa, jolla olen tottunut tekemään sen, ja se toimii hyvin, se saa asennuksen näyttämään hieman enemmän piirtämistäni kaavioilta. Lisäksi olen tehnyt paljon pieniä levyjä, joiden osia voin liittää leipälautaan nopeuttaakseni asioita, ja ne kaikki on määritetty käyttämään kahta yläriviä positiivisina ja alempia viivoja maana. Kuten sanoin, resoluutio on 4 bittiä (16 tasoa), ja koska 4x8 lediä vierekkäin on vain 32 näytepistettä (pistettä). Vertaa sitä Rigol Rigol DS1054Z: hen (8 bittiä ja 12 Mpts) ja huomaat, että tämä on tuskin lelu. Mikä on todellinen kaistanleveys, en tiedä, olen testannut sitä 10 kHz: iin asti ja se toimii hyvin.

Vaihe 3: Ohjelmat

Ohjelmat
Ohjelmat
Ohjelmat
Ohjelmat
Ohjelmat
Ohjelmat
Ohjelmat
Ohjelmat

IDE, jota käytän, on Atollic TrueStudio, jonka ST Micro Electronics otti käyttöön tämän vuoden (2018) alusta lähtien ja joka on saatavana ilmaiseksi, ilman aikarajoitusta, ilman koodikokorajoitusta tai ei nag-näyttöjä. Yhdessä sen kanssa käytän STM32CubeMX -ohjelmaa, joka toimittaa minulle aloituskoodin ja luo kaikkien oheislaitteiden alustamisen. Ja siinä on näyttö kaikista mikrokontrollerin nastoista ja niiden käytöstä. Vaikka et käytä STM32CubeMX: ää koodin luomiseen, tämä on erittäin kätevää. Yksi asia, josta en pidä, on ns. Pidän parempana LowLayer -työskentelytapaa.

Mikro-ohjaimen ohjelmointiin käytän joko ST-Link-ohjelmoijaa/debuggeria ST Micro Electronicsilta tai Seggerin J-Link-ohjelmaa. Molemmat laitteet eivät ole ilmaisia, vaikka voit ostaa niistä kiinalaisia kopioita muutamalla eurolla.

Vaihe 4: Tietoja koodista

MAX7219: n osoitteet osoittavat LEDit vaakasuunnassa, 8 lediä vierekkäin. Oskilloskoopille 8 LEDiä päällekkäin olisi ollut helpompaa, joten tein yksinkertaisen kehyspuskurin, johon kirjoitetaan tiedot pystysuunnassa ja luetaan vaaditulla vaakasuoralla tavalla. MAX7219 käyttää 16 -bittistä koodia 8 LEDiä kohti, ja ensimmäistä tavua käytetään valitun rivin osoittamiseen. Ja koska neljä näistä moduuleista on pinottu vierekkäin ja niiden tulot on kytketty moduulin ulostuloihin ennen sitä, sinun on lähetettävä nämä 16 bittiä neljä kertaa päästäksesi viimeiseen moduuliin. (Toivon, että teen asiat selväksi …) Tiedot lähetetään MAX7219 -laitteeseen käyttämällä SPI: tä, joka on yksinkertainen mutta erittäin nopea protokolla. Tätä kokeilin, kuinka nopeasti voit lähettää tiedot MAX7219 -laitteeseen. Lopulta vaihdoin takaisin 9 MHz: iin, joka on hieman alle tietolomakkeen määrittämän enimmäisnopeuden.

Käytän kahta STM32F103C8: n neljästä saatavilla olevasta ajastimesta, yhtä aikakannan luomiseen ja toista rotaatiokooderin lukemiseen, joka asettaa aikakannan. TIMER3 luo aikakannan, se jakaa sen jakamalla kellon 230: lla, päivittämällä laskurin 3,2 uS: n välein. Kytke kiertokooderi, jonka voit valita laskurin laskemiseksi 2 kellopulssista 2 000 kellopulssiin. Oletetaan, että valitset 100. AJASTIN3 luo sitten TAPAHTUMAN 320 uS: n välein. Tämä TAPAHTUMA laukaisee ADC: n tallentamaan otoksen tulosignaalista, ja koska 32 näytettä otetaan yhdeltä näytöltä, tämä päättyy n. 10 mS. 10 mS: iin mahtuu yksi aallonpituus 100 Hz tai kaksi 200 Hz jne. Kolmen aallon ylittäminen näyttöä kohden tekee kuitenkin melko vaikeaksi tunnistaa aaltomuodon.

Muuten voin viitata vain koodiin, sitä ei ole vaikea seurata, vaikka sinulla olisi vain jonkin verran kokemusta Arduinosta. Itse asiassa voit tehdä saman asian Arduinolla, vaikka epäilen, että se toimisi yhtä nopeasti kuin "sininen pilleri". STM32F103C8 on 32 -bittinen mikrokontrolleri, joka toimii 72 MHz: llä, siinä on kaksi SPI -oheislaitetta ja erittäin nopea ADC.

Vaihe 5: Main.h

#ifndef _MAIN_H _#define _MAIN_H_

#include "stm32f1xx_ll_adc.h"

#include "stm32f1xx_ll_rcc.h" #include "stm32f1xx_ll_bus.h" #include "stm32f1xx_ll_system.h" #include "stm32f1xx_ll_exti.h" #include "stm32f1xx_ll_cortex.h" #include "stm32 #fll" stm32 " include "stm32f1xx_ll_dma.h" #include "stm32f1xx_ll_spi.h" #include "stm32f1xx_ll_tim.h" #include "stm32f1xx.h" #include "stm32f1xx_ll_gpio.h"

#ifndef NVIC_PRIORITYGROUP_0

#define NVIC_PRIORITYGROUP_0 ((uint32_t) 0x00000007) #define NVIC_PRIORITYGROUP_1 ((uint32_t) 0x00000006) #define NVIC_PRIORITYGROUP_2 ((uint32_t) 0x00000005) #define NVIC_PRIORITYGROUP_3 ((uint32_t) 0x00000004) #define NVIC_PRIORITYGROUP_4 ((uint32_t) 0x00000003) #endif

#ifdef _cplusplus

extern "C" {#endif void _Error_Handler (char *, int);

#define Error_Handler () _Error_Handler (_ FILE_, _LINE_)

#ifdef _cplusplus} #endif

#loppu Jos

Vaihe 6: Main.c

#include "main.h" staattinen void LL_Init (void); void SystemClock_Config (mitätön); staattinen void MX_GPIO_Init (mitätön); staattinen void MX_ADC1_Init (mitätön); staattinen void MX_SPI1_Init (mitätön); staattinen void MX_SPI2_Init (mitätön); staattinen void MX_TIM3_Init (mitätön); staattinen void MX_TIM4_Init (mitätön);

uint16_t SPI1_send64 (uint16_t data3, uint16_t data2, uint16_t data1, uint16_t data0);

uint16_t SPI2_send64 (uint16_t data3, uint16_t data2, uint16_t data1, uint16_t data0); void MAX7219_1_init (); void MAX7219_2_init (); void erase_frame_buffer (mitätön); void fill_frame_buffer (mitätön); void display_frame_buffer (mitätön); void set_timebase (mitätön);

uint8_t ylempi_näyttö [4] [8]; // vier bytes naast elkaar, acht onder elkaar

uint8_t alempi_näyttö [4] [8]; // deze twee samen vormen de frame-buffer

uint8_t sample_buffer [32]; // puskuri voor de resultaten van de ADC

int main (mitätön)

{LL_Init (); SystemClock_Config (); MX_GPIO_Init (); MX_ADC1_Init (); MX_SPI1_Init (); MX_SPI2_Init (); MX_TIM3_Init (); MX_TIM4_Init ();

LL_SPI_Enable (SPI1);

LL_SPI_Enable (SPI2);

LL_TIM_EnableCounter (TIM3);

LL_TIM_EnableCounter (TIM4);

LL_ADC_Enable (ADC1);

LL_ADC_REG_StartConversionSWStart (ADC1); LL_ADC_EnableIT_EOS (ADC1);

LL_mDelay (500); // MAX7219 tarvitsee jonkin aikaa virran kytkemisen jälkeen

MAX7219_1_init (); MAX7219_2_init ();

// LL_TIM_SetAutoReload (TIM3, 9);

samalla (1)

{set_timebase (); erase_frame_buffer (); fill_frame_buffer (); display_frame_buffer (); }}

void erase_frame_buffer (mitätön)

{int8_t x; int8_t y;

for (x = 0; x <4; x ++) // kolom_bytes {

for (y = 0; y <8; y ++) // lijnen {ylempi_näyttö [x] [y] = 0; // alle bitjes op nul low_display [x] [y] = 0; }}}

void fill_frame_buffer (mitätön)

{uint8_t y = 0; // jännite uint8_t tijd = 0; // tijd uint8_t display_byte; // steeds 8 bittiä naast elkaar en dat 4 maal op een lijn uint8_t display_bit;

for (tijd = 0; tijd <32; tijd ++) {display_byte = tijd / 8; display_bit = 7 - (tijd % 8);

y = näytepuskuri [tijd];

if (y> 7) // näytön yläosassa schrijven

{ylempi_näyttö [display_byte] [15-y] | = (1 << display_bit); } else // alemmassa näytössä schrijven {alempi_näyttö [display_byte] [7-y] | = (1 << display_bit); }}}

mitätön display_frame_buffer (mitätön)

{

uint8_t y; // acht lijnen boven elkaar (näyttöä kohden) uint16_t yl; // lijnnummer voor de MAX7219

(y = 0; y <8; y ++) {yyl = (y+1) << 8; // MAX7219 heeft lijnnummer ylemmässä 8 bitissä ja 16 bittiä

SPI2_send64 ((yl | ylempi_näyttö [0] [y]), (yl | ylempi_näyttö [1] [y]), (yl | ylempi_näyttö [2] [y]), (yl | ylempi_näyttö [3] [y]));

SPI1_send64 ((yl | alempi_näyttö [0] [y]), (yl | alempi_näyttö [1] [y]), (yl | alempi_näyttö [2] [y]), (yl | alempi_näyttö [3] [y])); }

}

void set_timebase (mitätön)

{uint8_t timebase_knop;

timebase_knop = LL_TIM_GetCounter (TIM4) / 2;

kytkin (timebase_knop)

{tapaus 0: LL_TIM_SetAutoReload (TIM3, 1999); tauko; tapaus 1: LL_TIM_SetAutoReload (TIM3, 999); tauko; tapaus 2: LL_TIM_SetAutoReload (TIM3, 499); tauko; tapaus 3: LL_TIM_SetAutoReload (TIM3, 199); tauko; tapaus 4: LL_TIM_SetAutoReload (TIM3, 99); tauko; tapaus 5: LL_TIM_SetAutoReload (TIM3, 49); tauko; tapaus 6: LL_TIM_SetAutoReload (TIM3, 19); tauko; tapaus 7: LL_TIM_SetAutoReload (TIM3, 9); tauko; tapaus 8: LL_TIM_SetAutoReload (TIM3, 4); tauko; tapaus 9: LL_TIM_SetAutoReload (TIM3, 1); tauko;

oletus:

LL_TIM_SetAutoReload (TIM3, 99); tauko; }}

void MAX7219_1_init ()

{SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // SPI1_send64: n sammutus (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testitila pois SPI1_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // sammutus, normaali toiminta SPI1_send64 (0x0900, 0x0900, 0x0900, 0x0900); // ei 7segmentin dekoodausta, 64 pikseliä SPI1_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensiteetti 50% SPI1_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // kaikki rivit käytössä}

void MAX7219_2_init ()

{SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // sammutus SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testitila pois SPI2_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // sammutus, normaali toiminta SPI2_send64 (0x0900, 0x0900, 0x0900, 0x0900); // ei 7segmentin dekoodausta, 64 pikseliä SPI2_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensiteetti 50% SPI2_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // kaikki rivit käytössä}

uint16_t SPI1_send64 (uint16_t data3, uint16_t data2, uint16_t data1, uint16_t data0)

{LL_GPIO_ResetOutputPin (GPIOA, LL_GPIO_PIN_4);

LL_SPI_TransmitData16 (SPI1, data3);

kun taas (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}

LL_SPI_TransmitData16 (SPI1, data2);

kun taas (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}

LL_SPI_TransmitData16 (SPI1, data1);

kun taas (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}

LL_SPI_TransmitData16 (SPI1, data0);

kun taas (LL_SPI_IsActiveFlag_BSY (SPI1) == 1) {}

LL_GPIO_SetOutputPin (GPIOA, LL_GPIO_PIN_4);

return LL_SPI_ReceptData16 (SPI1); }

uint16_t SPI2_send64 (uint16_t data3, uint16_t data2, uint16_t data1, uint16_t data0)

{LL_GPIO_ResetOutputPin (GPIOB, LL_GPIO_PIN_12);

LL_SPI_TransmitData16 (SPI2, data3);

kun taas (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}

LL_SPI_TransmitData16 (SPI2, data2);

kun taas (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}

LL_SPI_TransmitData16 (SPI2, data1);

kun taas (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}

LL_SPI_TransmitData16 (SPI2, data0);

kun taas (LL_SPI_IsActiveFlag_BSY (SPI2) == 1) {}

LL_GPIO_SetOutputPin (GPIOB, LL_GPIO_PIN_12);

return LL_SPI_ReceptData16 (SPI2); }

mitätön ADC1_2_IRQHandler (mitätön)

{static uint8_t sample_counter; uint8_t liipaisin; staattinen uint8_t previous_trigger;

jos (LL_ADC_IsActiveFlag_EOS (ADC1)! = NOLLAUS)

{if (sample_counter <32) {sample_buffer [sample_counter] = LL_ADC_REG_ReadConversionData32 (ADC1) / 256; jos (näytelaskuri <32) näytelaskuri ++; muu näyte_laskuri = 0; } else {trigger = LL_ADC_REG_ReadConversionData32 (ADC1) / 256;

if ((trigger == 7) && (previous_trigger <trigger)) // gaat niet helemaal goed bij blokgolven… {sample_counter = 0; } previous_trigger = liipaisin; }

LL_GPIO_TogglePin (GPIOC, LL_GPIO_PIN_13);

LL_ADC_ClearFlag_EOS (ADC1);

} }

staattinen void LL_Init (mitätön)

{LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_AFIO); LL_APB1_GRP1_EnableClock (LL_APB1_GRP1_PERIPH_PWR);

NVIC_SetPriorityGrouping (NVIC_PRIORITYGROUP_4);

NVIC_SetPriority (MemoryManagement_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); NVIC_SetPriority (BusFault_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); NVIC_SetPriority (UsageFault_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); NVIC_SetPriority (SVCall_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); NVIC_SetPriority (DebugMonitor_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); NVIC_SetPriority (PendSV_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); NVIC_SetPriority (SysTick_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0));

LL_GPIO_AF_Remap_SWJ_NOJTAG ();

}

mitätön SystemClock_Config (mitätön)

{LL_FLASH_SetLatency (LL_FLASH_LATENCY_2); jos (LL_FLASH_GetLatency ()! = LL_FLASH_LATENCY_2) Error_Handler (); LL_RCC_HSE_Enable (); while (LL_RCC_HSE_IsReady ()! = 1); LL_RCC_PLL_ConfigDomain_SYS (LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_9); LL_RCC_PLL_Enable (); while (LL_RCC_PLL_IsReady ()! = 1); LL_RCC_SetAHBPrescaler (LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler (LL_RCC_APB1_DIV_2); LL_RCC_SetAPB2Prescaler (LL_RCC_APB2_DIV_1); LL_RCC_SetSysClkSource (LL_RCC_SYS_CLKSOURCE_PLL); kun taas (LL_RCC_GetSysClkSource ()! = LL_RCC_SYS_CLKSOURCE_STATUS_PLL); LL_Init1msTick (72000000); LL_SYSTICK_SetClkSource (LL_SYSTICK_CLKSOURCE_HCLK); LL_SetSystemCoreClock (72000000); LL_RCC_SetADCClockSource (LL_RCC_ADC_CLKSRC_PCLK2_DIV_6);

NVIC_SetPriority (SysTick_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0));

}

staattinen void MX_ADC1_Init (mitätön)

{LL_ADC_InitTypeDef ADC_InitStruct; LL_ADC_CommonInitTypeDef ADC_CommonInitStruct; LL_ADC_REG_InitTypeDef ADC_REG_InitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct;

LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_ADC1);

GPIO_InitStruct. Pin = LL_GPIO_PIN_0;

GPIO_InitStruct. Mode = LL_GPIO_MODE_ANALOG; LL_GPIO_Init (GPIOA ja GPIO_InitStruct);

NVIC_SetPriority (ADC1_2_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0));

NVIC_EnableIRQ (ADC1_2_IRQn);

ADC_InitStruct. DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;

ADC_InitStruct. SequencersScanMode = LL_ADC_SEQ_SCAN_DISABLE; LL_ADC_Init (ADC1 ja ADC_InitStruct);

ADC_CommonInitStruct. Multimode = LL_ADC_MULTI_INDEPENDENT;

LL_ADC_CommonInit (_ LL_ADC_COMMON_INSTANCE (ADC1), & ADC_CommonInitStruct);

ADC_REG_InitStruct. TriggerSource = LL_ADC_REG_TRIG_EXT_TIM3_TRGO;

ADC_REG_InitStruct. SequencerLength = 1; ADC_REG_InitStruct. SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; ADC_REG_InitStruct. ContinuousMode = LL_ADC_REG_CONV_SINGLE; ADC_REG_InitStruct. DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE; LL_ADC_REG_Init (ADC1 ja & ADC_REG_InitStruct);

LL_ADC_SetChannelSamplingTime (ADC1, LL_ADC_CHANNEL_0, LL_ADC_SAMPLINGTIME_41CYCLES_5);

}

staattinen void MX_SPI1_Init (mitätön)

{LL_SPI_InitTypeDef SPI_InitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct;

LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_SPI1);

GPIO_InitStruct. Pin = LL_GPIO_PIN_5 | LL_GPIO_PIN_7;

GPIO_InitStruct. Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct. Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct. OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init (GPIOA ja GPIO_InitStruct);

// NVIC_SetPriority (SPI1_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0));

// NVIC_EnableIRQ (SPI1_IRQn);

SPI_InitStruct. TransferDirection = LL_SPI_FULL_DUPLEX;

SPI_InitStruct. Mode = LL_SPI_MODE_MASTER; SPI_InitStruct. DataWidth = LL_SPI_DATAWIDTH_16BIT; SPI_InitStruct. ClockPolarity = LL_SPI_POLARITY_LOW; SPI_InitStruct. ClockPhase = LL_SPI_PHASE_1EDGE; SPI_InitStruct. NSS = LL_SPI_NSS_SOFT; SPI_InitStruct. BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8; SPI_InitStruct. BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct. CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; SPI_InitStruct. CRCPoly = 10; LL_SPI_Init (SPI1 ja SPI_InitStruct); }

staattinen void MX_SPI2_Init (mitätön)

{LL_SPI_InitTypeDef SPI_InitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct;

LL_APB1_GRP1_EnableClock (LL_APB1_GRP1_PERIPH_SPI2);

GPIO_InitStruct. Pin = LL_GPIO_PIN_13 | LL_GPIO_PIN_15;

GPIO_InitStruct. Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct. Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct. OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init (GPIOB ja & GPIO_InitStruct);

// NVIC_SetPriority (SPI2_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0));

// NVIC_EnableIRQ (SPI2_IRQn);

SPI_InitStruct. TransferDirection = LL_SPI_FULL_DUPLEX;

SPI_InitStruct. Mode = LL_SPI_MODE_MASTER; SPI_InitStruct. DataWidth = LL_SPI_DATAWIDTH_16BIT; SPI_InitStruct. ClockPolarity = LL_SPI_POLARITY_LOW; SPI_InitStruct. ClockPhase = LL_SPI_PHASE_1EDGE; SPI_InitStruct. NSS = LL_SPI_NSS_SOFT; SPI_InitStruct. BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; SPI_InitStruct. BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct. CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; SPI_InitStruct. CRCPoly = 10; LL_SPI_Init (SPI2 ja SPI_InitStruct); }

staattinen void MX_TIM3_Init (mitätön)

{LL_TIM_InitTypeDef TIM_InitStruct;

LL_APB1_GRP1_EnableClock (LL_APB1_GRP1_PERIPH_TIM3);

TIM_InitStruct. Prescaler = 229;

TIM_InitStruct. CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct. Autoreload = 9; TIM_InitStruct. ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; LL_TIM_Init (TIM3, & TIM_InitStruct);

LL_TIM_DisableARRPreload (TIM3);

LL_TIM_SetClockSource (TIM3, LL_TIM_CLOCKSOURCE_INTERNAL); LL_TIM_SetTriggerOutput (TIM3, LL_TIM_TRGO_UPDATE); LL_TIM_EnableMasterSlaveMode (TIM3); }

staattinen void MX_TIM4_Init (mitätön)

{LL_TIM_InitTypeDef TIM_InitStruct; LL_GPIO_InitTypeDef GPIO_InitStruct;

LL_APB1_GRP1_EnableClock (LL_APB1_GRP1_PERIPH_TIM4);

GPIO_InitStruct. Pin = LL_GPIO_PIN_6 | LL_GPIO_PIN_7;

GPIO_InitStruct. Mode = LL_GPIO_MODE_FLOATING; LL_GPIO_Init (GPIOB ja & GPIO_InitStruct);

LL_TIM_SetEncoderMode (TIM4, LL_TIM_ENCODERMODE_X2_TI1);

LL_TIM_IC_SetActiveInput (TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler (TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1); LL_TIM_IC_SetFilter (TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1); LL_TIM_IC_SetPolarity (TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING); LL_TIM_IC_SetActiveInput (TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI); LL_TIM_IC_SetPrescaler (TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); LL_TIM_IC_SetFilter (TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1); LL_TIM_IC_SetPolarity (TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING);

TIM_InitStruct. Prescaler = 0;

TIM_InitStruct. CounterMode = LL_TIM_COUNTERMODE_UP; TIM_InitStruct. Autoreload = 19; TIM_InitStruct. ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; LL_TIM_Init (TIM4, & TIM_InitStruct);

LL_TIM_DisableARRPreload (TIM4);

LL_TIM_SetTriggerOutput (TIM4, LL_TIM_TRGO_RESET); LL_TIM_DisableMasterSlaveMode (TIM4); }

staattinen void MX_GPIO_Init (mitätön)

{LL_GPIO_InitTypeDef GPIO_InitStruct;

LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_GPIOC);

LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_GPIOD); LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_GPIOA); LL_APB2_GRP1_EnableClock (LL_APB2_GRP1_PERIPH_GPIOB);

LL_GPIO_SetOutputPin (GPIOC, LL_GPIO_PIN_13);

LL_GPIO_SetOutputPin (GPIOA, LL_GPIO_PIN_4); LL_GPIO_SetOutputPin (GPIOB, LL_GPIO_PIN_12);

GPIO_InitStruct. Pin = LL_GPIO_PIN_13;

GPIO_InitStruct. Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct. Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct. OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init (GPIOC ja GPIO_InitStruct);

GPIO_InitStruct. Pin = LL_GPIO_PIN_4;

GPIO_InitStruct. Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct. Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct. OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init (GPIOA ja GPIO_InitStruct);

GPIO_InitStruct. Pin = LL_GPIO_PIN_12;

GPIO_InitStruct. Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct. Speed = LL_GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct. OutputType = LL_GPIO_OUTPUT_PUSHPULL; LL_GPIO_Init (GPIOB ja & GPIO_InitStruct); }

void _Error_Handler (char *tiedosto, int line)

{while (1) {}}

#ifdef USE_FULL_ASSERT

void assert_failed (tiedosto uint8_t*, rivi uint32_t)

{ } #loppu Jos

Suositeltava: