Taula de continguts:

Oscil·loscopi de quatre bits: 6 passos
Oscil·loscopi de quatre bits: 6 passos

Vídeo: Oscil·loscopi de quatre bits: 6 passos

Vídeo: Oscil·loscopi de quatre bits: 6 passos
Vídeo: SisEn Pràctiques: Transistor, aplicacions 2024, Desembre
Anonim
Oscil·loscopi de quatre bits
Oscil·loscopi de quatre bits

És un projecte divertit només per veure fins a quin punt en velocitats podria empènyer una pantalla de matriu de punts MAX7219. I en lloc de fer-lo executar el "joc de la vida", vaig decidir fer-ne un "abast". Com s’entendrà pel títol, això no substitueix un oscil·loscopi real:-).

Com que no tinc previst fer-ho de manera seriosa, no faré cap placa de circuit imprès per a això. Potser, potser el poso en un tauler de perf, però de moment és, i es mantindrà, en una taula de treball. Tampoc hi ha amplificador / atenuador d’entrada, heu de subministrar un senyal entre 0 i 3,3 V, no passeu negativament ni supereu els 3,3 V, ja que podeu danyar el microcontrolador.

Pas 1: maquinari

Maquinari
Maquinari
Maquinari
Maquinari
Maquinari
Maquinari

És barat, molt econòmic quan compreu les peces a la Xina mitjançant ebay o llocs similars. Utilitza una placa de desenvolupament STM32F103C8, de vegades anomenada "píndola blava" que he comprat per uns 2 euros (o USD, són gairebé el mateix valor, a finals del 2018), dues pantalles de matriu de 8x8x4 amb xips MAX7219, comprades per 5 euros la peça i un codificador rotatiu d’aproximadament 1 euro.

Per descomptat, es necessita una font d'alimentació que proporcioni 3,3 V a uns centenars de miliamperis. El regulador de voltatge de la placa de desenvolupament STM32F103C8 no s’utilitza, no pot proporcionar prou corrent per a les pantalles. El full de dades del MAX7219 especifica que el voltatge de subministrament de funcionament hauria d’estar entre 4,0 i 5,5 V, però funciona bé a 3,3 V, potser no quan l’utilitzeu en un entorn molt calent o fred, però a 20 centígrads està bé. I ara no he d’utilitzar convertidors de nivell entre el microcontrolador i els taulers de visualització.

Pas 2: construeix

Construeix
Construeix
Construeix
Construeix
Construeix
Construeix

Quan mireu la imatge, és possible que vegeu que faig servir les línies elèctriques de les taules de suport de manera no convencional, ambdues línies a la part superior són el rail positiu i les dues a la part inferior són el rail de terra. És la forma en què estic acostumat a fer-ho i funciona bé, fa que la configuració s’assembli una mica més als esquemes que dibuixo. A més, he fet moltes tauletes amb peces que puc connectar a la placa per accelerar les coses i totes estan configurades per utilitzar les dues línies superiors com a positives i les línies inferiors com a terra. Com he dit, la resolució és de 4 bits (16 nivells) i, com que hi ha leds 4x8 al costat, només hi ha 32 punts de mostra (pts). Compareu-ho amb un Rigol Rigol DS1054Z (de 8 bits i 12 Mpts) i veureu que això difícilment és una joguina. Quin és l’amplada de banda real, no ho sé, l’he provat fins a 10 kHz i funciona bé.

Pas 3: Programes

Programes
Programes
Programes
Programes
Programes
Programes
Programes
Programes

L’IDE que faig servir és Atollic TrueStudio, que a principis d’aquest any (2018) va ser adoptat per ST Micro Electronics i està disponible de forma gratuïta, sense límit de temps, sense límit de mida de codi, ni amb pantalles nag. Juntament amb ell, faig servir STM32CubeMX, un programa que em proporciona el codi d’inici i que genera la inicialització de tots els perifèrics. I té una pantalla de tots els pins del microcontrolador i el seu ús. Fins i tot si no utilitzeu STM32CubeMX per generar codi, això és molt útil. Una cosa que no m’agrada és l’anomenat HAL, que és el valor per defecte de STM32CubeMX. Prefereixo el mètode de treball LowLayer.

Per programar el microcontrolador utilitzo el programador / depurador ST-Link de ST Micro Electronics o el J-Link fabricat per Segger. Aquests dos dispositius no són gratuïts, tot i que en podeu comprar còpies xineses per uns quants euros.

Pas 4: Quant al codi

El MAX7219 s’adreça als LEDs en el que anomeno de forma horitzontal, 8 leds al costat de l’altre. Per a un oscil·loscopi, els 8 LED que s’encapçalaven haurien estat més fàcils, de manera que he creat un senzill frame-buffer que s’escriu amb dades de forma vertical i que he llegit de la manera horitzontal necessària. El MAX7219 utilitza un codi de 16 bits per 8 LED, on s’utilitza el primer byte per dirigir la línia seleccionada. I com hi ha quatre d'aquests mòduls apilats l'un al costat de l'altre, amb les seves entrades connectades a les sortides del mòdul abans que aquest, heu d'enviar aquests 16 bits quatre vegades per arribar a l'últim mòdul. (Espero deixar clar les coses …) Les dades s'envien al MAX7219 mitjançant SPI, un protocol senzill però molt ràpid. Amb això estava experimentant, amb quina velocitat podeu anar enviant les dades al MAX7219. Al final, vaig tornar a canviar a 9 MHz just per sota de la velocitat màxima que especifica el full de dades.

Faig servir dos dels quatre temporitzadors disponibles del STM32F103C8, un per a la generació de la base de temps i l’altre per llegir el codificador rotatiu, que estableix la base de temps. TIMER3 genera la base de temps, ho fa dividint el rellotge per 230, actualitzant el comptador cada 3,2 uS. Trieu el codificador rotatiu que podeu seleccionar per comptar el comptador de 2 impulsos de rellotge fins a 2.000 impulsos de rellotge. Suposem que trieu 100. TIMER3 genera un EVENT cada 320 uS. Aquest ESDEVENIMENT fa que l'ADC enregistri una mostra del senyal d'entrada i, com que hi ha 32 mostres a prendre per a una pantalla, es completarà després d'aproximadament. 10 mS. En 10 mS podeu ajustar una longitud d'ona de 100 Hz o dues de 200 Hz, etc. Superar les 3 ones per pantalla fa que sigui bastant difícil reconèixer la forma d'ona.

Per la resta, només puc referir-vos al codi, no és difícil de seguir encara que només tingueu experiència amb un Arduino. De fet, es podria fer el mateix amb un Arduino, tot i que dubto que funcionaria tan ràpid com una "pastilla blava". El STM32F103C8 és un microcontrolador de 32 bits que funciona a 72 MHz, té dos perifèrics SPI i un ADC molt ràpid.

Pas 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 "#include" st_32 " inclou "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 _plusplus

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

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

#ifdef _cplusplus} #endif

#endif

Pas 6: Main.c

#include "main.h" static void LL_Init (void); void SystemClock_Config (void); static void MX_GPIO_Init (buit); void estàtic MX_ADC1_Init (void); static void MX_SPI1_Init (void); static void MX_SPI2_Init (void); static void MX_TIM3_Init (void); static void 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 (); buit erase_frame_buffer (buit); void fill_frame_buffer (buit); buit display_frame_buffer (buit); 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 (buit)

{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 necessita un temps després de l’encesa

MAX7219_1_init (); MAX7219_2_init ();

// LL_TIM_SetAutoReload (TIM3, 9);

mentre que (1)

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

buit erase_frame_buffer (buit)

{int8_t x; int8_t y;

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

for (y = 0; y <8; y ++) // lijnen {upper_display [x] [y] = 0; // alle bitjes op nul lower_display [x] [y] = 0; }}}

buid omplir_quadrament_marc (buit)

{uint8_t y = 0; // voltatge 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;

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

y = sample_buffer [tijd];

if (y> 7) // a la pantalla superior schrijven

{upper_display [display_byte] [15-y] | = (1 << display_bit); } else // in lower display schrijven {lower_display [display_byte] [7-y] | = (1 << display_bit); }}}

buit display_frame_buffer (buit)

{

uint8_t y; // acht lijnen boven elkaar (per display) uint16_t yl; // lijnnummer voor de MAX7219

per a (y = 0; y <8; y ++) {yl = (y + 1) << 8; // MAX7219 heeft lijnnummer in de 8 bits superior de 16 bits 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 | lower_display [0] [y]), (yl | lower_display [1] [y]), (yl | lower_display [2] [y]), (yl | lower_display [3] [y])); }

}

void set_timebase (buit)

{uint8_t timebase_knop;

timebase_knop = LL_TIM_GetCounter (TIM4) / 2;

commutador (timebase_knop)

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

per defecte:

LL_TIM_SetAutoReload (TIM3, 99); trencar; }}

void MAX7219_1_init ()

{SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // apagat a SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // mode de prova desactivat SPI1_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // apagat, funcionament normal SPI1_send64 (0x0900, 0x0900, 0x0900, 0x0900); // no es descodifica 7seg, 64 píxels SPI1_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensitat 50% SPI1_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // totes les files a}

void MAX7219_2_init ()

{SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // apagada a SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // mode de prova desactivat SPI2_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // apagat, funcionament normal SPI2_send64 (0x0900, 0x0900, 0x0900, 0x0900); // no es descodifica 7seg, 64 píxels SPI2_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensitat 50% SPI2_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // totes les files a}

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

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

LL_SPI_TransmitData16 (SPI1, data2);

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

LL_SPI_TransmitData16 (SPI1, data1);

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

LL_SPI_TransmitData16 (SPI1, data0);

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

LL_GPIO_SetOutputPin (GPIOA, LL_GPIO_PIN_4);

retorn LL_SPI_ReceiveData16 (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);

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

LL_SPI_TransmitData16 (SPI2, data2);

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

LL_SPI_TransmitData16 (SPI2, data1);

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

LL_SPI_TransmitData16 (SPI2, data0);

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

LL_GPIO_SetOutputPin (GPIOB, LL_GPIO_PIN_12);

retorn LL_SPI_ReceiveData16 (SPI2); }

void ADC1_2_IRQHandler (void)

{static uint8_t sample_counter; uint8_t activador; static uint8_t trigger_ anterior;

if (LL_ADC_IsActiveFlag_EOS (ADC1)! = RESET)

{if (sample_counter <32) {sample_buffer [sample_counter] = LL_ADC_REG_ReadConversionData32 (ADC1) / 256; if (sample_counter <32) sample_counter ++; else sample_counter = 0; } else {trigger = LL_ADC_REG_ReadConversionData32 (ADC1) / 256;

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

LL_GPIO_TogglePin (GPIOC, LL_GPIO_PIN_13);

LL_ADC_ClearFlag_EOS (ADC1);

} }

static void LL_Init (buit)

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

}

estàtic de buit MX_ADC1_Init (buit)

{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 i & 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 i & ADC_InitStruct);

ADC_CommonInitStruct. Multimode = LL_ADC_MULTI_INDEPENDENT;

LL_ADC_CommonInit (_ LL_ADC_COMMON_INSTANCE (ADC1) i & 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 i & ADC_REG_InitStruct);

LL_ADC_SetChannelSamplingTime (ADC1, LL_ADC_CHANNEL_0, LL_ADC_SAMPLINGTIME_41CYCLES_5);

}

estàtic de buit MX_SPI1_Init (buit)

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

estàtic de buit MX_SPI2_Init (buit)

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

estàtic de buit MX_TIM3_Init (buit)

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

estàtic de buit MX_TIM4_Init (buit)

{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 i & TIM_InitStruct);

LL_TIM_DisableARRPreload (TIM4);

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

estàtic de buit MX_GPIO_Init (buit)

{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 i & 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 i & 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 (fitxer char *, línia int)

{while (1) {}}

#ifdef USE_FULL_ASSERT

void assert_failed (fitxer uint8_t *, línia uint32_t)

{} #endif

Recomanat: