Sommario:

Oscilloscopio a quattro bit: 6 passaggi
Oscilloscopio a quattro bit: 6 passaggi

Video: Oscilloscopio a quattro bit: 6 passaggi

Video: Oscilloscopio a quattro bit: 6 passaggi
Video: Обзор недорогих китайских осциллографов Нужны ли они 2024, Dicembre
Anonim
Oscilloscopio a quattro bit
Oscilloscopio a quattro bit

È un progetto per divertimento solo per vedere fino a che punto in velocità potrei spingere un display a matrice di punti MAX7219. E invece di fargli eseguire il "gioco della vita", ho deciso di farne uno "scope". Come capirai dal titolo, questo non è un sostituto di un vero oscilloscopio:-).

Dato che non ho intenzione di usarlo in alcun modo serio, non realizzerò un circuito stampato per questo. Forse, solo forse lo metterò su una perf-board ma per ora è, e rimarrà, su una breadboard. Inoltre non c'è un amplificatore/attenuatore di ingresso, devi fornire un segnale compreso tra 0 e 3,3V, non andare in negativo o oltre 3,3V poiché potresti danneggiare il microcontrollore.

Passaggio 1: hardware

Hardware
Hardware
Hardware
Hardware
Hardware
Hardware

È economico, molto economico quando si acquistano le parti in Cina tramite ebay o siti simili. Utilizza una scheda di sviluppo STM32F103C8, a volte chiamata "pillola blu" che ho acquistato per circa 2 euro (o USD, hanno quasi lo stesso valore, fine 2018), due display a matrice di punti 8x8x4 con chip MAX7219, acquistati per 5 euro a pezzo e un encoder rotativo di circa 1 euro.

Ovviamente è necessario un alimentatore che fornisca 3,3 V a poche centinaia di milliampere. Il regolatore di tensione sulla scheda di sviluppo STM32F103C8 non è utilizzato, non è in grado di fornire corrente sufficiente per i display. La scheda tecnica del MAX7219 specifica che la tensione di alimentazione operativa dovrebbe essere compresa tra 4,0 e 5,5 V ma funziona bene a 3,3 V, forse non quando lo si utilizza in un ambiente molto caldo o freddo, ma a 20 gradi Celsius va bene. E ora non devo più usare convertitori di livello tra il microcontrollore ei tabelloni.

Passaggio 2: costruire

Costruire
Costruire
Costruire
Costruire
Costruire
Costruire

Quando guardi l'immagine potresti vedere che uso le linee elettriche sulle breadboard in modo non convenzionale, entrambe le linee in alto sono il binario positivo ed entrambi in basso sono il binario di terra. È il modo in cui sono abituato a farlo e funziona bene, rende l'installazione un po' più simile agli schemi che disegno. Inoltre, ho realizzato molte piccole schede con parti che posso collegare alla breadboard per accelerare le cose e sono tutte configurate per utilizzare le due linee superiori come positive e le linee inferiori come massa. Come ho detto, la risoluzione è di 4 bit (16 livelli), e poiché ci sono 4x8 led uno accanto all'altro ci sono solo 32 punti campione (pt). Confrontalo con un Rigol Rigol DS1054Z (8 bit e 12Mpts) e vedrai che questo non è certo un giocattolo. Quale sia la larghezza di banda effettiva, non lo so, l'ho testata fino a 10kHz e funziona bene.

Passaggio 3: programmi

Programmi
Programmi
Programmi
Programmi
Programmi
Programmi
Programmi
Programmi

L'IDE che utilizzo è Atollic TrueStudio che all'inizio di quest'anno (2018) è stato adottato da ST Micro Electronics ed è disponibile gratuitamente, senza limiti di tempo, senza limiti di dimensioni del codice, senza fastidiosi schermi. Insieme ad esso utilizzo STM32CubeMX, un programma che mi fornisce il codice di partenza e genera l'inizializzazione di tutte le periferiche. E ha un display di tutti i pin del microcontrollore e del loro utilizzo. Anche se non usi STM32CubeMX per generare codice, questo è molto utile. Una cosa che non mi piace è il cosiddetto HAL che è l'impostazione predefinita di STM32CubeMX. Preferisco il metodo di lavoro LowLayer.

Per programmare il microcontrollore utilizzo il programmatore/debugger ST-Link di ST Micro Electronics o il J-Link di Segger. Entrambi questi dispositivi non sono gratuiti, anche se puoi acquistarne copie cinesi per pochi euro.

Passaggio 4: Informazioni sul codice

I MAX7219 indirizzano i LED in quello che io chiamo un modo orizzontale, 8 LED uno accanto all'altro. Per un oscilloscopio 8 LED uno sopra l'altro sarebbe stato più facile, quindi ho creato un semplice frame-buffer che viene scritto con i dati in modo verticale e letto nel modo orizzontale richiesto. Il MAX7219 utilizza un codice a 16 bit per 8 LED, in cui il primo byte viene utilizzato per indirizzare la linea selezionata. E poiché ci sono quattro di questi moduli impilati uno accanto all'altro, con i loro ingressi collegati alle uscite del modulo prima di esso, devi inviare quei 16 bit quattro volte per raggiungere l'ultimo modulo. (Spero di essere stato chiaro…) I dati vengono inviati al MAX7219 tramite SPI, un protocollo semplice ma molto veloce. Questo è ciò che stavo sperimentando, quanto velocemente puoi andare a inviare i dati al MAX7219. Alla fine, sono tornato a 9 MHz appena al di sotto della velocità massima specificata dal foglio dati.

Uso due dei quattro timer disponibili dell'STM32F103C8, uno per la generazione della base dei tempi e l'altro per la lettura dell'encoder rotativo, che imposta la base dei tempi. TIMER3 genera la base tempi, lo fa dividendo l'orologio per 230, aggiornando il contatore ogni 3,2 uS. Con l'encoder rotativo è possibile selezionare per avere il conteggio del contatore da 2 impulsi di clock fino a 2000 impulsi di clock. Supponiamo che tu scelga 100. TIMER3 quindi genera un EVENTO ogni 320 uS. Questo EVENTO attiva l'ADC per registrare un campione del segnale di ingresso e, poiché ci sono 32 campioni da prendere per una schermata, questo verrà completato dopo circa. 10 ms. In 10 ms puoi adattare una lunghezza d'onda di 100 Hz o due di 200 Hz e così via. Tuttavia, superare 3 onde per schermo rende piuttosto difficile riconoscere la forma d'onda.

Per il resto posso solo rimandarti al codice, non è difficile da seguire anche se hai solo una certa esperienza con un Arduino. In effetti, potresti fare la stessa cosa con un Arduino, anche se dubito che funzionerebbe velocemente come una "pillola blu". L'STM32F103C8 è un microcontrollore a 32 bit che funziona a 72 MHz, ha due periferiche SPI e un ADC molto veloce.

Passaggio 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_xxhllputil "stm32s.f1xx 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_C00000) (define NVIC_PRIORITYGROUP0x00000) (define NVIC_3PRIOR000) (int32_VIOR_PRIORITYGROUP000000)

#ifdef _cplusplus

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

#define Error_Handler() _Error_Handler(_FILE_, _LINE_)

#ifdef _cplusplus } #endif

#finisci se

Passaggio 6: Main.c

#include "main.h" static void LL_Init(void); void SystemClock_Config(void); vuoto statico MX_GPIO_Init(void); vuoto statico MX_ADC1_Init(void); vuoto statico MX_SPI1_Init(void); vuoto statico MX_SPI2_Init(void); vuoto statico MX_TIM3_Init(void); vuoto statico MX_TIM4_Init(void);

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(void); void fill_frame_buffer(void); void display_frame_buffer(void); void set_timebase(void);

uint8_t upper_display[4][8]; //vier bytes naast elkaar, acht onder elkaar

uint8_t lower_display[4][8]; //deze twee samen vormen de frame-buffer

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

int main (vuoto)

{ 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_mRitardo(500); //MAX7219 ha bisogno di un po' di tempo dopo l'accensione

MAX7219_1_init(); MAX7219_2_init();

//LL_TIM_SetAutoReload(TIM3, 9);

mentre (1)

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

void erase_frame_buffer(void)

{ int8_t x; int8_t y;

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

for (y = 0; y < 8; y++) //lijnen { display_superiore[x][y] = 0; //tutti i bit su null lower_display[x][y] = 0; } } }

void fill_frame_buffer(void)

{ uint8_t y = 0; //tensione uint8_t tijd = 0; //tijd uint8_t display_byte; //Steeds 8 bits 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 = sample_buffer[tijd];

if (y > 7) //nel display superiore schrijven

{ display_superiore[display_byte][15-y] |= (1 << display_bit); } else //nel display inferiore schrijven { display_inferiore[display_byte][7-y] |= (1 << display_bit); } } }

void display_frame_buffer(void)

{

uint8_t y; //acht lijnen boven elkaar (per display) uint16_t yl; //numero di riferimento per MAX7219

for (y = 0; y < 8; y++) { yl = (y+1) << 8; //MAX7219 heeft lijnnummer in de superiore 8 bit e 16 bit woord

SPI2_send64((yl | upper_display[0][y]), (yl | upper_display[1][y]), (yl | upper_display[2][y]), (yl | upper_display[3][y]));

SPI1_send64((yl | display_inferiore[0][y]), (yl | display_inferiore[1][y]), (yl | display_inferiore[2][y]), (yl | display_inferiore[3][y])); }

}

void set_timebase(void)

{ uint8_t timebase_knop;

timebase_knop = LL_TIM_GetCounter(TIM4) / 2;

switch (timebase_knop)

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

predefinito:

LL_TIM_SetAutoReload(TIM3, 99); rottura; } }

void MAX7219_1_init()

{SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //spegnimento su SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); //testmode disattivato SPI1_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //spegnimento, funzionamento normale SPI1_send64(0x0900, 0x0900, 0x0900, 0x0900); //nessuna decodifica 7seg, 64 pixel SPI1_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); //intensità 50% SPI1_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); //tutte le righe su }

void MAX7219_2_init()

{SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //spegnimento su SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); //testmode disattivato SPI2_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //spegnimento, funzionamento normale SPI2_send64(0x0900, 0x0900, 0x0900, 0x0900); //nessuna decodifica 7seg, 64 pixel SPI2_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); //intensità 50% SPI2_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); //tutte le righe su }

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, dati3);

mentre (LL_SPI_IsActiveFlag_TXE(SPI1) == 0) {}

LL_SPI_TransmitData16(SPI1, dati2);

mentre (LL_SPI_IsActiveFlag_TXE(SPI1) == 0) {}

LL_SPI_TransmitData16(SPI1, dati1);

mentre (LL_SPI_IsActiveFlag_TXE(SPI1) == 0) {}

LL_SPI_TransmitData16(SPI1, data0);

mentre (LL_SPI_IsActiveFlag_BSY(SPI1) == 1) {}

LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4);

restituisce LL_SPI_ReceiveData16(SPI1); }

uint16_t SPI2_send64(uint16_t dati3, uint16_t dati2, uint16_t dati1, uint16_t dati0)

{ LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);

LL_SPI_TransmitData16(SPI2, dati3);

mentre (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}

LL_SPI_TransmitData16(SPI2, dati2);

mentre (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}

LL_SPI_TransmitData16(SPI2, dati1);

mentre (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}

LL_SPI_TransmitData16(SPI2, dati0);

mentre (LL_SPI_IsActiveFlag_BSY(SPI2) == 1) {}

LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12);

restituire LL_SPI_ReceiveData16(SPI2); }

void ADC1_2_IRQHandler(void)

{ statico uint8_t sample_counter; uint8_t trigger; statico uint8_t precedente_trigger;

if (LL_ADC_IsActiveFlag_EOS(ADC1) != RESET)

{ if (contatore_campione < 32) { buffer_campione[contatore_campione] = LL_ADC_REG_ReadConversionData32(ADC1) / 256; if (contatore_campione < 32) contatore_campione++; altrimenti contatore_campione = 0; } else { trigger = LL_ADC_REG_ReadConversionData32(ADC1) / 256;

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

LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);

LL_ADC_ClearFlag_EOS(ADC1);

} }

static void LL_Init(void)

{ 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();

}

void SystemClock_Config(void)

{ LL_FLASH_SetLatency(LL_FLASH_LATENCY_2); if(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); while(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));

}

vuoto statico MX_ADC1_Init(void)

{ 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, &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, &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, &ADC_REG_InitStruct);

LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_0, LL_ADC_SAMPLINGTIME_41CYCLES_5);

}

vuoto statico MX_SPI1_Init(void)

{ 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, &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, &SPI_InitStruct); }

vuoto statico MX_SPI2_Init(void)

{ 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, &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, &SPI_InitStruct); }

vuoto statico MX_TIM3_Init(void)

{ 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); }

vuoto statico MX_TIM4_Init(void)

{ 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, &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); }

vuoto statico MX_GPIO_Init(void)

{ 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, &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, &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, &GPIO_InitStruct); }

void _Error_Handler(char *file, int line)

{ mentre(1) { } }

#ifdef USE_FULL_ASSERT

void assert_failed (file uint8_t*, riga uint32_t)

{ } #finisci se

Consigliato: