Innholdsfortegnelse:
- Trinn 1: Maskinvare
- Trinn 2: Bygg
- Trinn 3: Programmer
- Trinn 4: Om koden
- Trinn 5: Main. H
- Trinn 6: Main. C
Video: Fire bits oscilloskop: 6 trinn
2024 Forfatter: John Day | [email protected]. Sist endret: 2024-01-30 11:24
Det er et moro-prosjekt bare for å se hvor langt i hastigheter jeg kan skyve en MAX7219 dot matrix display. Og i stedet for å la det kjøre "livets spill", bestemte jeg meg for å lage et "omfang" med det. Som du vil forstå av tittelen, er dette ikke en erstatning for et ekte oscilloskop:-).
Siden jeg ikke har tenkt å bruke dette på noen seriøs måte, vil jeg ikke lage et kretskort for det. Kanskje, bare kanskje jeg legger det på et perf-brett, men foreløpig er det, og blir det, på et brødbrett. Det er heller ingen inngangsforsterker/demper. Du må levere et signal mellom 0 og 3.3V, ikke gå negativt eller over 3.3V, da du kan skade mikrokontrolleren.
Trinn 1: Maskinvare
Det er billig, veldig billig når du kjøper delene i Kina via ebay eller lignende nettsteder. Den bruker et utviklingsbord STM32F103C8, noen ganger kalt en "blå pille" som jeg kjøpte for rundt 2 euro (eller USD, de er nesten like mye, slutten av 2018), to 8x8x4 dot-matrix-skjermer med MAX7219-chips på, kjøpt for 5 euro stykket og en roterende encoder på ca 1 euro.
Nødvendig er selvfølgelig en strømforsyning som leverer 3,3V på noen hundre milliampere. Spenningsregulatoren på utviklingskortet STM32F103C8 brukes ikke, den kan ikke gi nok strøm til displayene. Databladet for MAX7219 spesifiserer at driftsspenningen skal være mellom 4,0 og 5,5 V, men det går fint på 3,3 V, kanskje ikke når du bruker det i et veldig varmt eller kaldt miljø, men ved 20 Celsius er det greit. Og nå trenger jeg ikke å bruke nivåomformere mellom mikrokontrolleren og displaybordene.
Trinn 2: Bygg
Når du ser på bildet kan du se at jeg bruker kraftledningene på brødbrettene på en ikke -konvensjonell måte, begge linjene på toppen er den positive skinnen og begge på bunnen er bakken. Det er slik jeg er vant til å gjøre det, og det fungerer bra, det får oppsettet til å ligne litt mer på skjemaene jeg tegner. Jeg har også laget mange små brett med deler på som jeg kan koble til brødbrettet for å få fart på ting, og de er alle konfigurert til å bruke de to topplinjene som positive og de nedre linjene som bakken. Som jeg sa, er oppløsningen 4 bit (16 nivåer), og da det er 4x8 lysdioder ved siden av hverandre er det bare 32 prøvepunkter (poeng). Sammenlign det med en Rigol Rigol DS1054Z (8 bit og 12Mpts), så ser du at dette neppe er et leketøy. Hva den faktiske båndbredden er, vet jeg ikke, jeg har testet den opp til 10 kHz og det fungerer bra.
Trinn 3: Programmer
IDE-en jeg bruker er Atollic TrueStudio som fra begynnelsen av dette året (2018) ble adoptert av ST Micro Electronics og er tilgjengelig gratis, ingen tidsbegrensning, ingen kodestørrelsesgrense, ingen nag-skjermer. Sammen med det bruker jeg STM32CubeMX, et program som gir meg startkoden og genererer initialisering av alle eksterne enheter. Og den har en visning av alle pinnene på mikrokontrolleren og deres bruk. Selv om du ikke bruker STM32CubeMX for å generere kode, er dette veldig praktisk. En ting jeg ikke liker er den såkalte HAL som er standarden på STM32CubeMX. Jeg foretrekker LowLayer -arbeidsmetoden.
For å programmere mikrokontrolleren bruker jeg enten ST-Link programmerer/debugger fra ST Micro Electronics eller J-Link laget av Segger. Begge disse enhetene er ikke gratis, selv om du kan kjøpe kinesiske kopier av dem for noen få euro.
Trinn 4: Om koden
MAX7219 adresserer lysdiodene på det jeg kaller horisontalt, 8 lysdioder ved siden av hverandre. For et oscilloskop ville 8 lysdioder på hverandre ha vært enklere, så jeg laget en enkel rammebuffer som skrives til med data på en vertikal måte, og leses opp på den nødvendige horisontale måten. MAX7219 bruker en 16 -biters kode per 8 lysdioder, der den første byten brukes til å adressere den valgte linjen. Og siden det er fire av disse modulene stablet ved siden av hverandre, med inngangene koblet til utgangene til modulen før den, må du sende de 16 bitene fire ganger for å nå den siste modulen. (Jeg håper jeg gjør ting klart …) Dataene sendes til MAX7219 ved hjelp av SPI, en enkel, men veldig rask protokoll. Dette var det jeg eksperimenterte med, hvor raskt kan du gå med å sende dataene til MAX7219. Til slutt byttet jeg tilbake til 9 MHz like under maksimal hastighet databladet angir.
Jeg bruker to av de fire tilgjengelige timerne til STM32F103C8, en for generering av tidsbasen og den andre for å lese ut den roterende omkoderen, som angir tidsbasen. TIMER3 genererer tidsbasen, den gjør det ved å dele klokken med 230, oppdatere telleren hver 3,2 uS. Troll den roterende omkoderen du kan velge for å ha telleren fra 2 klokkeimpulser opp til 2000 klokkeimpulser. La oss si at du velger 100. TIMER3 genererer deretter et EVENT hvert 320 uS. Denne HENDELSEN utløser ADC for å registrere en prøve av inngangssignalet, og ettersom det er 32 prøver å ta for en screenful, vil dette fullføres etter ca. 10 mS. I 10mS kan du passe til en bølgelengde på 100 Hz, eller to på 200 Hz, og så videre. Å gå over 3 bølger per skjerm gjør det imidlertid ganske vanskelig å gjenkjenne bølgeformen.
For resten kan jeg bare henvise deg til koden. Det er ikke vanskelig å følge selv om du bare har litt erfaring med en Arduino. Faktisk kan du lage det samme med en Arduino, selv om jeg tviler på at den ville fungere like raskt som en "blå pille". STM32F103C8 er en 32 -biters mikrokontroller som kjører på 72 MHz, den har to SPI -enheter og en veldig rask ADC.
Trinn 5: Main. H
#ifndef _MAIN_H _#definere _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" #inc_x_h1 #h1.h1 #h1 #h1 #h1 #h1 #h1 #h32 #h1 #h32 #h_http. inkludere "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
ekstern "C" {#endif void _Error_Handler (char *, int);
#define Error_Handler () _Error_Handler (_ FILE_, _LINE_)
#ifdef _cplusplus} #endif
#slutt om
Trinn 6: Main. C
#include "main.h" static void LL_Init (void); void SystemClock_Config (void); statisk tomrom MX_GPIO_Init (ugyldig); statisk tomrom MX_ADC1_Init (ugyldig); statisk void MX_SPI1_Init (void); statisk void MX_SPI2_Init (void); statisk tomrom MX_TIM3_Init (ugyldig); statisk tomrom MX_TIM4_Init (ugyldig);
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); ugyldig MAX7219_1_init (); ugyldig MAX7219_2_init (); void erase_frame_buffer (void); void fill_frame_buffer (void); void display_frame_buffer (void); void set_timebase (void);
uint8_t øvre_display [4] [8]; // vier bytes ved siden av hverandre, åtte under hverandre
uint8_t lavere_display [4] [8]; // disse to sammensatte rammebufferen
uint8_t sample_buffer [32]; // buffer for de resultaten av de ADC
int main (ugyldig)
{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 trenger litt tid etter at den er slått på
MAX7219_1_init (); MAX7219_2_init ();
// LL_TIM_SetAutoReload (TIM3, 9);
mens (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 {øvre_display [x] [y] = 0; // alle bitjes op nul lavere_display [x] [y] = 0; }}}
void fill_frame_buffer (void)
{uint8_t y = 0; // spenning uint8_t tijd = 0; // tijd uint8_t display_byte; // alle 8 biter ved siden av hverandre og det 4 maal på en linje uint8_t display_bit;
for (tijd = 0; tijd <32; tijd ++) {display_byte = tijd / 8; display_bit = 7 - (tijd % 8);
y = sample_buffer [tijd];
hvis (y> 7) // i øvre skjerm skrive
{upper_display [display_byte] [15-å] | = (1 << display_bit); } annet // i nedre skjermskriv {lavere_display [display_byte] [7-y] | = (1 << display_bit); }}}
void display_frame_buffer (ugyldig)
{
uint8_t y; // acht lijnen boven elkaar (per display) uint16_t yl; // lijnnummer voor de MAX7219
for (y = 0; y <8; y ++) {yl = (y+1) << 8; // MAX7219 har lijnnummer in the upper 8 bits van 16 bits word
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 | lavere_display [0] [y]), (yl | lavere_display [1] [y]), (yl | lavere_display [2] [y]), (yl | lavere_display [3] [y])); }
}
void set_timebase (void)
{uint8_t timebase_knop;
timebase_knop = LL_TIM_GetCounter (TIM4) / 2;
bryter (tidsbase_knop)
{sak 0: LL_TIM_SetAutoReload (TIM3, 1999); gå i stykker; sak 1: LL_TIM_SetAutoReload (TIM3, 999); gå i stykker; sak 2: LL_TIM_SetAutoReload (TIM3, 499); gå i stykker; sak 3: LL_TIM_SetAutoReload (TIM3, 199); gå i stykker; sak 4: LL_TIM_SetAutoReload (TIM3, 99); gå i stykker; sak 5: LL_TIM_SetAutoReload (TIM3, 49); gå i stykker; sak 6: LL_TIM_SetAutoReload (TIM3, 19); gå i stykker; sak 7: LL_TIM_SetAutoReload (TIM3, 9); gå i stykker; sak 8: LL_TIM_SetAutoReload (TIM3, 4); gå i stykker; sak 9: LL_TIM_SetAutoReload (TIM3, 1); gå i stykker;
misligholde:
LL_TIM_SetAutoReload (TIM3, 99); gå i stykker; }}
ugyldig MAX7219_1_init ()
{SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nei SPI1_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // nedleggelse på SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nei SPI1_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testmodus av SPI1_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // avstengning, normal drift SPI1_send64 (0x0900, 0x0900, 0x0900, 0x0900); // ingen 7seg -dekode, 64 piksler SPI1_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensitet 50% SPI1_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // alle radene på}
ugyldig MAX7219_2_init ()
{SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nei SPI2_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // nedleggelse på SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nei SPI2_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testmodus av SPI2_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // avstengning, normal drift SPI2_send64 (0x0900, 0x0900, 0x0900, 0x0900); // ingen 7seg -dekode, 64 piksler SPI2_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intensitet 50% SPI2_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // alle radene på}
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);
mens (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, data2);
mens (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, data1);
mens (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, data0);
mens (LL_SPI_IsActiveFlag_BSY (SPI1) == 1) {}
LL_GPIO_SetOutputPin (GPIOA, LL_GPIO_PIN_4);
returner 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);
mens (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, data2);
mens (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, data1);
mens (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, data0);
mens (LL_SPI_IsActiveFlag_BSY (SPI2) == 1) {}
LL_GPIO_SetOutputPin (GPIOB, LL_GPIO_PIN_12);
returner LL_SPI_ReceiveData16 (SPI2); }
ugyldig ADC1_2_IRQHandler (ugyldig)
{statisk uint8_t sample_counter; uint8_t trigger; statisk uint8_t forrige_utløser;
hvis (LL_ADC_IsActiveFlag_EOS (ADC1)! = RESET)
{if (sample_counter <32) {sample_buffer [sample_counter] = LL_ADC_REG_ReadConversionData32 (ADC1) / 256; hvis (sample_counter <32) sample_counter ++; annet sample_counter = 0; } annet {trigger = LL_ADC_REG_ReadConversionData32 (ADC1) / 256;
if ((trigger == 7) && (previous_trigger <trigger)) // gaat niet helemaal goed bij blokgolven… {sample_counter = 0; } previous_trigger = utløser; }
LL_GPIO_TogglePin (GPIOC, LL_GPIO_PIN_13);
LL_ADC_ClearFlag_EOS (ADC1);
} }
statisk tomrom LL_Init (ugyldig)
{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 (); mens (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 (); mens (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); mens (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));
}
statisk tomrom MX_ADC1_Init (ugyldig)
{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);
}
statisk tomrom MX_SPI1_Init (ugyldig)
{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); }
statisk tomrom MX_SPI2_Init (ugyldig)
{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); }
statisk tomrom MX_TIM3_Init (ugyldig)
{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); }
statisk tomrom MX_TIM4_Init (ugyldig)
{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); }
statisk tomrom MX_GPIO_Init (ugyldig)
{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)
{while (1) {}}
#ifdef BRUK_FULL_ASSERT
void assert_failed (uint8_t* fil, uint32_t linje)
{ } #slutt om
Anbefalt:
Minibatteridrevet CRT -oscilloskop: 7 trinn (med bilder)
Minibatteridrevet CRT -oscilloskop: Hei! I denne instruksen vil jeg vise deg hvordan du lager et mini -batteridrevet CRT -oscilloskop. Et oscilloskop er et viktig verktøy for å arbeide med elektronikk; du kan se alle signalene som strømmer rundt i en krets, og feilsøke
Analog frontend for oscilloskop: 6 trinn (med bilder)
Analog frontend for oscilloskop: Hjemme har jeg noen billige USB -lydkort, som kan kjøpes i Banggood, Aliexpress, Ebay eller andre globale nettbutikker for noen dollar. Jeg lurte på hva interessant jeg kan bruke dem til og bestemte meg for å prøve å lage et lavfrekvent PC -omfang med
DIY 10Hz-50kHz Arduino-oscilloskop på 128x64 LCD-skjerm: 3 trinn
DIY 10Hz-50kHz Arduino Oscilloscope on 128x64 LCD Display: Dette prosjektet beskriver en måte å lage et enkelt oscilloskop som har et område fra 10Hz til 50Khz. Dette er et ekstremt stort område, gitt at enheten ikke bruker en ekstern digital til analog omformerbrikke, men bare Arduino
Lag ditt eget oscilloskop (Mini DSO) med STC MCU enkelt: 9 trinn (med bilder)
Lag ditt eget oscilloskop (Mini DSO) med STC MCU enkelt: Dette er et enkelt oscilloskop laget med STC MCU. Du kan bruke denne Mini DSO til å observere bølgeform. Tidsintervall: 100us-500ms Spenningsområde: 0-30V Tegningsmodus: Vector eller prikker
Vanlig fjernkontrollsett transformert til fire-kanals RC-fjernkontroll: fire trinn
Vanlig fjernkontrollsett transformert til fire-kanals fjernkontroll for RC-leketøy: 如何 将 通用 遥控 器 套件 转换 为 玩具 模型 中 的 四 通道 器 器 器 套件。。 它 它 62 62改造 方法 非常 简单。 只需 准备 一些 瓦楞纸 板 , 然后 视频 教程 完成 这个 电子 项目 并 您 服务。 玩具 车船 提供 远程 无线 控制 控制。