Sadržaj:
- Korak 1: Hardver
- Korak 2: Izgradite
- Korak 3: Programi
- Korak 4: O Kodeksu
- 5. korak: Main.h
- Korak 6: Main.c
Video: Četiri bit osciloskop: 6 koraka
2024 Autor: John Day | [email protected]. Zadnja promjena: 2024-01-30 09:36
To je projekt za zabavu samo da vidim koliko daleko u brzinama mogu gurnuti matrični zaslon MAX7219. I umjesto da vodim "igru života", odlučio sam napraviti "opseg" s njom. Kao što ćete razumjeti iz naslova, ovo nije zamjena za pravi osciloskop:-).
Kako ovo ne namjeravam koristiti na ozbiljan način, neću za njega napraviti tiskanu ploču. Možda, samo možda ću ga staviti na perf-board, ali zasad je, i ostat će, na ploči. Također nema ulaznog pojačala/prigušivača, morate dati signal između 0 i 3,3 V, nemojte ići negativno ili preko 3,3 V jer možete oštetiti mikrokontroler.
Korak 1: Hardver
Jeftino je, vrlo jeftino kada dijelove kupujete u Kini putem ebaya ili sličnih web stranica. Koristi razvojnu ploču STM32F103C8, ponekad nazvanu "plava pilula" koju sam kupio za oko 2 eura (ili USD, gotovo su iste vrijednosti, kraj 2018.), dva matrična zaslona veličine 8x8x4 s čipovima MAX7219, kupljena za 5 eura po komadu i rotacijski enkoder od oko 1 eura.
Naravno potrebno je napajanje koje daje 3.3V pri nekoliko stotina miliampera. Regulator napona na razvojnoj ploči STM32F103C8 se ne koristi, ne može osigurati dovoljno struje za zaslone. Tehnički list za MAX7219 navodi da bi radni napon trebao biti između 4,0 i 5,5 V, ali radi dobro na 3,3 V, možda ne kada ga koristite u vrlo toplom ili hladnom okruženju, ali na 20 Celzijevih je u redu. I sada ne moram koristiti pretvarače razine između mikrokontrolera i ploča za prikaz.
Korak 2: Izgradite
Kada pogledate sliku, mogli biste vidjeti da ja koristim vodove na matičnim pločama na nekonvencionalan način, obje linije na vrhu su pozitivne tračnice, a obje na dnu su tračnice za tlo. To je način na koji sam navikao to raditi i radi dobro, čini da postavka više liči na sheme koje crtam. Također, napravio sam puno malih ploča s dijelovima na koje se mogu uključiti u matičnu ploču kako bi se stvari ubrzale, a sve su konfigurirane da koriste dvije gornje linije kao pozitivne, a donje kao tlo. Kao što sam rekao, razlučivost je 4 bita (16 razina), a kako se LED diode 4x8 nalaze jedna do druge, postoje samo 32 točke uzorka (točaka). Usporedite to s Rigol Rigolom DS1054Z (8 bita i 12 Mps) i vidjet ćete da ovo teško da je igračka. Koja je stvarna propusnost, ne znam, testirao sam je na 10kHz i to dobro radi.
Korak 3: Programi
IDE koji koristim je Atollic TrueStudio koji je od početka ove godine (2018.) usvojio ST Micro Electronics i dostupan je besplatno, bez vremenskog ograničenja, bez ograničenja veličine koda, bez nag-ekrana. Zajedno s njim koristim STM32CubeMX, program koji mi isporučuje početni kod i generira inicijalizaciju svih perifernih uređaja. I ima prikaz svih pinova mikrokontrolera i njihove uporabe. Čak i ako ne koristite STM32CubeMX za generiranje koda, ovo je vrlo zgodno. Jedna stvar koja mi se ne sviđa je takozvani HAL koji je zadana vrijednost za STM32CubeMX. Više volim LowLayer metodu rada.
Za programiranje mikrokontrolera koristim ili ST-Link programer/ispravljač pogrešaka tvrtke ST Micro Electronics ili J-Link proizvođača Segger. Oba ova uređaja nisu besplatna, iako ih za nekoliko eura možete kupiti u kineskim kopijama.
Korak 4: O Kodeksu
MAX7219 adresira LED diode na ono što ja nazivam vodoravno, 8 LED dioda jedna do druge. Za osciloskop bi 8 LED dioda jedna na drugoj bilo lakše, pa sam napravio jednostavan međuspremnik okvira na koji se upisuju podaci s vertikalnim načinom i očitavaju na potrebni vodoravni način. MAX7219 koristi 16 -bitni kôd na 8 LED dioda, pri čemu se prvi bajt koristi za adresiranje odabrane linije. A kako su četiri od ovih modula naslagana jedan do drugoga, a njihovi su ulazi povezani s izlazima modula prije njega, morate poslati tih 16 bita četiri puta da dođete do zadnjeg modula. (Nadam se da sam pojasnio …) Podaci se šalju na MAX7219 koristeći SPI, jednostavan, ali vrlo brz protokol. S ovim sam eksperimentirao, koliko brzo možete poslati podatke na MAX7219. Na kraju sam se vratio na 9 MHz malo ispod maksimalne brzine koju specificira podatkovna tablica.
Koristim dva od četiri dostupna mjerača vremena STM32F103C8, jedan za generiranje vremenske baze, a drugi za čitanje rotacijskog davača, koji postavlja vremensku bazu. TIMER3 generira vremensku bazu, to čini dijeljenjem sata sa 230, ažurirajući brojač svakih 3,2 uS. Pomoću okretnog davača možete odabrati da brojač broji od 2 impulsa do 2000 impulsa. Recimo da odaberete 100. TIMER3 zatim generira DOGAĐAJ svakih 320 uS. Ovaj DOGAĐAJ pokreće ADC da zabilježi uzorak ulaznog signala, a kako je potrebno uzeti 32 uzorka za jedan ekran, to će se dovršiti nakon otprilike. 10 mS. U 10 mS možete uklopiti jednu valnu duljinu od 100 Hz ili dvije od 200 Hz itd. Prelazak preko 3 vala po ekranu otežava prepoznavanje valnog oblika.
U ostalom, mogu vas uputiti samo na kôd, nije ga teško slijediti čak i ako imate samo malo iskustva s Arduinom. Zapravo, istu stvar možete napraviti i s Arduinom, iako sumnjam da bi djelovao jednako brzo kao "plava pilula". STM32F103C8 je 32 -bitni mikrokontroler koji radi na 72 MHz, ima dvije SPI periferije i vrlo brz ADC.
5. korak: Main.h
#ifndef _MAIN_H _#definiraj _MAIN_H_
#include "stm32f1xx_ll_adc.h"
#include "stm32f1xx_ll_rcc.h" #include "stm32f1xx_ll_system.h" #include "stm32f1xx_ll_xxxxxllx32" xx 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_PRIORITYGROUP_3 ((uint32_t) 0x00000004) #define NVIC_PRIORITYGROUP_4 ((uint32_t) 0x00000003) #endif
#ifdef _cplusplus
vanjski "C" {#endif void _Error_Handler (char *, int);
#define Error_Handler () _Error_Handler (_ FILE_, _LINE_)
#ifdef _cplusplus} #endif
#završi ako
Korak 6: Main.c
#include "main.h" static void LL_Init (void); void SystemClock_Config (void); statička praznina MX_GPIO_Init (praznina); statička praznina MX_ADC1_Init (praznina); statička praznina MX_SPI1_Init (praznina); statička praznina MX_SPI2_Init (praznina); statička praznina MX_TIM3_Init (praznina); statička praznina MX_TIM4_Init (praznina);
uint16_t SPI1_send64 (uint16_t podataka3, uint16_t podataka2, uint16_t podataka1, uint16_t podataka0);
uint16_t SPI2_send64 (uint16_t podataka3, uint16_t podataka2, uint16_t podataka1, uint16_t podataka0); 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 gornji_zaslon [4] [8]; // vier bytes naast elkaar, acht onder elkaar
uint8_t niži_displej [4] [8]; // deze twee samen vormen de frame-buffer
uint8_t uzorak_bufera [32]; // međuspremnik za rezultate van ADC -a
int main (void)
{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 treba neko vrijeme nakon uključivanja
MAX7219_1_init (); MAX7219_2_init ();
// LL_TIM_SetAutoReload (TIM3, 9);
dok (1)
{set_timebase (); erase_frame_buffer (); fill_frame_buffer (); display_frame_buffer (); }}
void erase_frame_buffer (void)
{int8_t x; int8_t y;
za (x = 0; x <4; x ++) // kolom_bajta {
za (y = 0; y <8; y ++) // lijnen {gornji_zaslon [x] [y] = 0; // all bitjes op nul lower_display [x] [y] = 0; }}}
void fill_frame_buffer (void)
{uint8_t y = 0; // napon 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 = međuspremnik_uzoraka [tijd];
if (y> 7) // u gornjem zaslonu schrijven
{gornji_display [display_byte] [15-y] | = (1 << display_bit); } else // u donjem zaslonu schrijven {lower_display [display_byte] [7-y] | = (1 << display_bit); }}}
void display_frame_buffer (void)
{
uint8_t y; // acht lijnen boven elkaar (po zaslonu) uint16_t yl; // lijnnummer voor de MAX7219
za (y = 0; y <8; y ++) {yl = (y+1) << 8; // MAX7219 heeft lijnnummer in the upper 8 bits van 16 bits woord
SPI2_send64 ((yl | gornji_zaslon [0] [y]), (yl | gornji_zaslon [1] [y]), (yl | gornji_display [2] [y]), (yl | gornji_display [3] [y]));
SPI1_send64 ((yl | donji_display [0] [y]), (yl | donji_display [1] [y]), (yl | donji_display [2] [y]), (yl | donji_displej [3] [y])); }
}
void set_timebase (void)
{uint8_t vremenska baza_knop;
timebase_knop = LL_TIM_GetCounter (TIM4) / 2;
prekidač (timebase_knop)
{slučaj 0: LL_TIM_SetAutoReload (TIM3, 1999.); pauza; slučaj 1: LL_TIM_SetAutoReload (TIM3, 999); pauza; slučaj 2: LL_TIM_SetAutoReload (TIM3, 499); pauza; slučaj 3: LL_TIM_SetAutoReload (TIM3, 199); pauza; slučaj 4: LL_TIM_SetAutoReload (TIM3, 99); pauza; slučaj 5: LL_TIM_SetAutoReload (TIM3, 49); pauza; slučaj 6: LL_TIM_SetAutoReload (TIM3, 19); pauza; slučaj 7: LL_TIM_SetAutoReload (TIM3, 9); pauza; slučaj 8: LL_TIM_SetAutoReload (TIM3, 4); pauza; slučaj 9: LL_TIM_SetAutoReload (TIM3, 1); pauza;
zadano:
LL_TIM_SetAutoReload (TIM3, 99); pauza; }}
void MAX7219_1_init ()
{SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // isključivanje na SPI1_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI1_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testni način isključen SPI1_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // isključivanje, normalan rad SPI1_send64 (0x0900, 0x0900, 0x0900, 0x0900); // bez 7seg dekodiranja, 64 piksela SPI1_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intenzitet 50% SPI1_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // svi retci na}
void MAX7219_2_init ()
{SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // isključivanje na SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000); // nop SPI2_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testni način isključen SPI2_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01); // isključivanje, normalan rad SPI2_send64 (0x0900, 0x0900, 0x0900, 0x0900); // bez 7seg dekodiranja, 64 piksela SPI2_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // intenzitet 50% SPI2_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // svi retci na}
uint16_t SPI1_send64 (uint16_t podataka3, uint16_t podataka2, uint16_t podataka1, uint16_t podataka0)
{LL_GPIO_ResetOutputPin (GPIOA, LL_GPIO_PIN_4);
LL_SPI_TransmitData16 (SPI1, podaci3);
dok je (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, podaci2);
dok je (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, podatak1);
dok je (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, data0);
dok je (LL_SPI_IsActiveFlag_BSY (SPI1) == 1) {}
LL_GPIO_SetOutputPin (GPIOA, LL_GPIO_PIN_4);
return LL_SPI_ReceiveData16 (SPI1); }
uint16_t SPI2_send64 (uint16_t podataka3, uint16_t podataka2, uint16_t podataka1, uint16_t podataka0)
{LL_GPIO_ResetOutputPin (GPIOB, LL_GPIO_PIN_12);
LL_SPI_TransmitData16 (SPI2, podaci3);
dok je (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, data2);
dok je (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, podatak1);
dok je (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, data0);
dok je (LL_SPI_IsActiveFlag_BSY (SPI2) == 1) {}
LL_GPIO_SetOutputPin (GPIOB, LL_GPIO_PIN_12);
return LL_SPI_ReceiveData16 (SPI2); }
void ADC1_2_IRQHandler (void)
{static uint8_t sample_counter; okidač uint8_t; statički uint8_t prethodni_trigger;
if (LL_ADC_IsActiveFlag_EOS (ADC1)! = RESET)
{if (brojač uzoraka <32) {uzorak_bufera [uzorak_brojač] = LL_ADC_REG_ReadConversionData32 (ADC1) / 256; if (brojač_uzoraka <32) brojač_uzoraka ++; 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; } prethodni_trigger = okidač; }
LL_GPIO_TogglePin (GPIOC, LL_GPIO_PIN_13);
LL_ADC_ClearFlag_EOS (ADC1);
} }
statička praznina LL_Init (praznina)
{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));
}
statička praznina MX_ADC1_Init (praznina)
{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);
}
statička praznina MX_SPI1_Init (praznina)
{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); }
statička praznina MX_SPI2_Init (praznina)
{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); }
statička praznina MX_TIM3_Init (praznina)
{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); }
statička praznina MX_TIM4_Init (praznina)
{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); }
statička praznina MX_GPIO_Init (praznina)
{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 *datoteka, int redak)
{while (1) {}}
#ifdef USE_FULL_ASSERT
void assert_failed (datoteka uint8_t*, redak uint32_t)
{ } #završi ako
Preporučeni:
Weasleyjev' sat sa četiri ruke: 11 koraka (sa slikama)
Weasleyjev' lokacijski sat sa četiri ruke: Dakle, s Raspberry Pi -jem koji se već neko vrijeme vrtio, želio sam pronaći lijep projekt koji će mi omogućiti da ga najbolje iskoristim. Naišao sam na ovaj sjajni Instructable Build Your Own Weasley Location Clock od ppeters0502 i pomislio da
KAKO NAČINITI ČETIRI FUNKCIONALNOG KALKULATORA U CPP -u: 6 koraka
KAKO NAČINITI ČETIRI FUNKCIONALNOG KALKULATORA U CPP -u: Kalkulatori se koriste svima u svakodnevnom životu. Jednostavan kalkulator može se izraditi pomoću C ++ programa koji može zbrajati, oduzimati, množiti i dijeliti dva operanda koja je korisnik unio. Naredba if i goto koristi se za izradu kalkulatora
DIY motorizirani klizač za kameru iz četiri 3D ispisana dijela: 5 koraka (sa slikama)
DIY motorizirani klizač za kameru iz četiri 3D ispisana dijela: Pozdrav, proizvođači, to je proizvođač moekoe! Danas vam želim pokazati kako izgraditi vrlo koristan linearni klizač za kameru na temelju V-Slot/Openbuilds šine, Nema17 koračnog motora i samo četiri 3D ispisana dijela .Prije nekoliko dana odlučio sam uložiti u bolju kameru za
Četiri pite - novi projekt Raspberry Pi 4 - Izdvajamo i slavimo !: 6 koraka
Četiri pite - novi Raspberry Pi 4 - projekt Highlights & Celebration !: Ispod je kratak pregled sadržaja. Uvodni i prezentacijski video Pie Pi 3.14 Pite Rezultat
Kako napraviti video s podijeljenim zaslonom u četiri koraka: 4 koraka (sa slikama)
Kako napraviti video s podijeljenim ekranom u četiri koraka: Često vidimo istu osobu kako se prikazuje u sceni dva puta u TV predstavi. A koliko znamo, glumac nema brata blizanca. Također smo gledali kako se dva pjevačka videa stavljaju na jedan ekran radi usporedbe njihovih pjevačkih sposobnosti. Ovo je moć spl