Índice:

Osciloscópio de quatro bits: 6 etapas
Osciloscópio de quatro bits: 6 etapas

Vídeo: Osciloscópio de quatro bits: 6 etapas

Vídeo: Osciloscópio de quatro bits: 6 etapas
Vídeo: Aprenda a usar o osciloscópio em 28 minutos!! 2024, Novembro
Anonim
Osciloscópio de quatro bits
Osciloscópio de quatro bits

É um projeto divertido apenas para ver o quão longe em velocidades eu poderia empurrar um display de matriz de pontos MAX7219. E em vez de fazê-lo rodar o "jogo da vida", decidi fazer um "escopo" com ele. Como você verá no título, este não é um substituto para um osciloscópio real:-).

Como não pretendo usar isso de forma séria, não farei uma placa de circuito impresso para ele. Talvez, apenas talvez eu o coloque em uma placa de desempenho, mas por enquanto ele é, e permanecerá, em uma placa de ensaio. Também não há amplificador / atenuador de entrada, você deve fornecer um sinal entre 0 e 3,3V, não vá negativo ou acima de 3,3V, pois pode danificar o microcontrolador.

Etapa 1: Hardware

Hardware
Hardware
Hardware
Hardware
Hardware
Hardware

É barato, muito barato quando você compra as peças na China via ebay ou sites semelhantes. Ele usa uma placa de desenvolvimento STM32F103C8, às vezes chamada de "pílula azul" que comprei por cerca de 2 euros (ou USD, eles têm quase o mesmo valor, final de 2018), dois monitores matriciais 8x8x4 com chips MAX7219, comprados por 5 euros por peça e um codificador rotativo de cerca de 1 euro.

É necessária, claro, uma fonte de alimentação fornecendo 3,3 V a algumas centenas de miliamperes. O regulador de tensão na placa de desenvolvimento STM32F103C8 não é usado, ele não pode fornecer corrente suficiente para os visores. A ficha técnica do MAX7219 especifica que a tensão de alimentação operacional deve estar entre 4,0 e 5,5 V, mas funciona bem com 3,3 V, talvez não quando você o usa em um ambiente muito quente ou frio, mas a 20 Celsius está bom. E agora não preciso mais usar conversores de nível entre o microcontrolador e as telas.

Etapa 2: construir

Construir
Construir
Construir
Construir
Construir
Construir

Quando você olha para a foto, você pode ver que eu uso os cabos de força nas placas de ensaio de uma forma não convencional, ambas as linhas na parte superior são o trilho positivo e as duas na parte inferior são o trilho de aterramento. É como estou acostumado a fazer e funciona bem, faz com que a configuração se pareça um pouco mais com os esquemas que desenho. Além disso, fiz um monte de pequenas placas com peças que posso conectar na placa de ensaio para acelerar as coisas e todas elas são configuradas para usar as duas linhas superiores como positivas e as linhas inferiores como aterramento. Como eu disse, a resolução é de 4 bits (16 níveis), e como existem 4x8 leds um ao lado do outro, existem apenas 32 pontos de amostragem (pts). Compare isso com um Rigol Rigol DS1054Z (8 bits e 12 milhões) e você verá que dificilmente é um brinquedo. Qual é a largura de banda real, eu não sei, eu testei até 10kHz e funciona bem.

Etapa 3: Programas

Programas
Programas
Programas
Programas
Programas
Programas
Programas
Programas

O IDE que uso é o Atollic TrueStudio que no início deste ano (2018) foi adotado pela ST Micro Electronics e está disponível gratuitamente, sem limite de tempo, sem limite de tamanho de código, sem telas nag. Junto com ele, utilizo o STM32CubeMX, um programa que me fornece o código de partida e gera a inicialização de todos os periféricos. E tem um display de todos os pinos do microcontrolador e sua utilização. Mesmo se você não usar o STM32CubeMX para gerar código, isso é muito útil. Uma coisa que eu não gosto é o chamado HAL, que é o padrão do STM32CubeMX. Eu prefiro o método de trabalho LowLayer.

Para programar o microcontrolador, uso o programador / depurador ST-Link da ST Micro Electronics ou o J-Link fabricado pela Segger. Ambos os dispositivos não são gratuitos, embora você possa comprar cópias chinesas deles por alguns euros.

Etapa 4: Sobre o Código

O MAX7219 endereça os LEDs no que eu chamo de forma horizontal, 8 leds um ao lado do outro. Para um osciloscópio, 8 LEDs um em cima do outro teria sido mais fácil, então fiz um buffer de quadro simples que é gravado com os dados de maneira vertical e lido da maneira horizontal exigida. O MAX7219 usa um código de 16 bits por 8 LEDs, onde o primeiro byte é usado para endereçar a linha selecionada. E como há quatro desses módulos empilhados um ao lado do outro, com suas entradas conectadas às saídas do módulo anterior, é necessário enviar esses 16 bits quatro vezes para chegar ao último módulo. (Espero estar deixando as coisas claras …) Os dados são enviados para o MAX7219 usando SPI, um protocolo simples, mas muito rápido. Isso é o que eu estava experimentando, quão rápido você consegue enviar os dados para o MAX7219. No final, voltei para 9 MHz, logo abaixo da velocidade máxima que a folha de dados especifica.

Eu uso dois dos quatro timers disponíveis do STM32F103C8, um para a geração da base de tempo e o outro para a leitura do codificador rotativo, que define a base de tempo. TIMER3 gera a base de tempo, ele faz isso dividindo o relógio por 230, atualizando o contador a cada 3,2 uS. Com o codificador rotativo, você pode selecionar para que o contador conte de 2 pulsos de clock até 2.000 pulsos de clock. Digamos que você escolha 100. TIMER3 então gera um EVENTO a cada 320 uS. Este EVENTO aciona o ADC para gravar uma amostra do sinal de entrada e, como há 32 amostras para tirar para uma tela cheia, isso será concluído após aprox. 10 mS. Em 10 ms você pode ajustar um comprimento de onda de 100 Hz ou dois de 200 Hz e assim por diante. No entanto, ultrapassar 3 ondas por tela torna bastante difícil reconhecer a forma de onda.

Quanto ao resto, posso apenas referir-lhe o código, não é difícil de seguir, mesmo se você só tiver alguma experiência com um Arduino. Na verdade, você poderia fazer a mesma coisa com um Arduino, embora eu duvide que funcionaria tão rápido como uma "pílula azul". O STM32F103C8 é um microcontrolador de 32 bits rodando a 72 MHz, possui dois periféricos SPI e um ADC muito rápido.

Etapa 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_cortex1xx" #32f1xx_ll_cortex.hils "#32f1xx_ll_cortex1xx" #32finclude.hils "#32f1xx_ll_cortex.hils" # incluir "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

#fim se

Etapa 6: Main.c

#include "main.h" static void LL_Init (void); void SystemClock_Config (void); estático void MX_GPIO_Init (void); estático void MX_ADC1_Init (void); estático void MX_SPI1_Init (void); estático void MX_SPI2_Init (void); estático void MX_TIM3_Init (void); estático 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 (); 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 (vazio)

{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 precisa de algum tempo após ligar

MAX7219_1_init (); MAX7219_2_init ();

// LL_TIM_SetAutoReload (TIM3, 9);

enquanto (1)

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

void erase_frame_buffer (void)

{int8_t x; int8_t y;

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

para (y = 0; y <8; y ++) // lijnen {exibição_uperior [x] [y] = 0; // todos os bits op nul lower_display [x] [y] = 0; }}}

void fill_frame_buffer (void)

{uint8_t y = 0; // tensão 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;

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

y = sample_buffer [tijd];

if (y> 7) // no display superior schrijven

{display_ superior [display_byte] [15-y] | = (1 << display_bit); } else // no display inferior schrijven {lower_display [display_byte] [7-y] | = (1 << display_bit); }}}

void display_frame_buffer (void)

{

uint8_t y; // acht lijnen boven elkaar (por exibição) uint16_t yl; // lijnnummer voor de MAX7219

para (y = 0; y <8; y ++) {il = (y + 1) << 8; // MAX7219 heeft lijnnummer nos 8 bits superiores do woord de 16 bits

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

SPI1_send64 ((il | exibição_inferior [0] [y]), (il | exibição_inferior [1] [y]), (il | exibição_inferior [2] [y]), (il | exibição_inferior [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); pausa; caso 1: LL_TIM_SetAutoReload (TIM3, 999); pausa; caso 2: LL_TIM_SetAutoReload (TIM3, 499); pausa; caso 3: LL_TIM_SetAutoReload (TIM3, 199); pausa; caso 4: LL_TIM_SetAutoReload (TIM3, 99); pausa; caso 5: LL_TIM_SetAutoReload (TIM3, 49); pausa; caso 6: LL_TIM_SetAutoReload (TIM3, 19); pausa; caso 7: LL_TIM_SetAutoReload (TIM3, 9); pausa; caso 8: LL_TIM_SetAutoReload (TIM3, 4); pausa; caso 9: LL_TIM_SetAutoReload (TIM3, 1); pausa;

predefinição:

LL_TIM_SetAutoReload (TIM3, 99); pausa; }}

void MAX7219_1_init ()

{SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // desligamento em SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testmode off SPI1_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // desligamento, operação normal SPI1_send64 (0x0900, 0x0900, 0x0900, 0x0900); // sem decodificação 7seg, 64 pixels SPI1_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensidade 50% SPI1_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // todas as linhas em}

void MAX7219_2_init ()

{SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // desligamento em SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testmode off SPI2_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // desligamento, operação normal SPI2_send64 (0x0900, 0x0900, 0x0900, 0x0900); // sem decodificação 7seg, 64 pixels SPI2_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensidade 50% SPI2_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // todas as linhas em}

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

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

LL_SPI_TransmitData16 (SPI1, dados2);

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

LL_SPI_TransmitData16 (SPI1, dados1);

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

LL_SPI_TransmitData16 (SPI1, dados0);

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

LL_GPIO_SetOutputPin (GPIOA, LL_GPIO_PIN_4);

retornar 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, dados3);

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

LL_SPI_TransmitData16 (SPI2, dados2);

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

LL_SPI_TransmitData16 (SPI2, dados1);

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

LL_SPI_TransmitData16 (SPI2, dados0);

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

LL_GPIO_SetOutputPin (GPIOB, LL_GPIO_PIN_12);

retornar LL_SPI_ReceiveData16 (SPI2); }

void ADC1_2_IRQHandler (void)

{static uint8_t sample_counter; gatilho uint8_t; static uint8_t previous_trigger;

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 ++; senão 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; } anterior_trigger = gatilho; }

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

}

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

}

static void 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); }

static void 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); }

static void 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); }

static void 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); }

static void 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 (arquivo char *, linha interna)

{enquanto (1) {}}

#ifdef USE_FULL_ASSERT

void assert_failed (arquivo uint8_t *, linha uint32_t)

{ } #fim se

Recomendado: