Índice:
- Etapa 1: Hardware
- Etapa 2: construir
- Etapa 3: Programas
- Etapa 4: Sobre o Código
- Etapa 5: Main.h
- Etapa 6: Main.c
Vídeo: Osciloscópio de quatro bits: 6 etapas
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:38
É 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
É 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
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
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:
COMO FAZER UMA CALCULADORA DE QUATRO FUNCIONAIS NO CPP: 6 etapas
COMO FAZER UMA CALCULADORA DE QUATRO FUNCIONAIS NO CPP: As calculadoras são usadas para todos na vida diária. Uma calculadora simples pode ser feita usando um programa C ++ que é capaz de somar, subtrair, multiplicar e dividir dois operandos inseridos pelo usuário. As instruções if e goto são usadas para criar uma calculadora
Arduino Nano - MMA8452Q 3 eixos 12 bits / 8 bits acelerômetro digital Tutorial: 4 etapas
Arduino Nano - MMA8452Q 3 eixos 12 bits / 8 bits Acelerômetro digital Tutorial: O MMA8452Q é um acelerômetro inteligente, de baixo consumo de energia, capacitivo, microusinado e de três eixos com 12 bits de resolução. Opções flexíveis programáveis pelo usuário são fornecidas com o auxílio de funções incorporadas no acelerômetro, configuráveis para duas interrupções
Raspberry Pi MMA8452Q 3 eixos 12 bits / 8 bits acelerômetro digital Python Tutorial: 4 etapas
Raspberry Pi MMA8452Q 3 eixos 12 bits / 8 bits Acelerômetro digital Python Tutorial: O MMA8452Q é um acelerômetro inteligente, de baixo consumo de energia, capacitivo, microusinado e de três eixos com 12 bits de resolução. Opções flexíveis programáveis pelo usuário são fornecidas com o auxílio de funções incorporadas no acelerômetro, configuráveis para duas interrupções
Raspberry Pi MMA8452Q 3 eixos 12 bits / 8 bits acelerômetro digital Java Tutorial: 4 etapas
Raspberry Pi MMA8452Q Acelerômetro digital de 3 eixos, 12 bits / 8 bits, Java Tutorial: O MMA8452Q é um acelerômetro inteligente, de baixo consumo de energia, capacitivo, microusinado e de três eixos com 12 bits de resolução. Opções flexíveis programáveis pelo usuário são fornecidas com o auxílio de funções incorporadas no acelerômetro, configuráveis para duas interrupções
Como fazer um vídeo em tela dividida com quatro etapas: 4 etapas (com imagens)
Como fazer um vídeo de tela dividida com quatro etapas: Freqüentemente, vemos uma mesma pessoa ser exibida em uma cena duas vezes em uma peça de TV. E, pelo que sabemos, o ator não tem irmão gêmeo. Também vimos que dois vídeos de canto são colocados em uma tela para comparar suas habilidades de canto. Este é o poder do spl