Sadržaj:
- Korak 1: Hardver
- Korak 2: Izgradite
- Korak 3: Programi
- Korak 4: O Kodeksu
- Korak 5: Main.h
- Korak 6: Main.c
Video: Četiri bit osciloskop: 6 koraka
2024 Autor: John Day | [email protected]. Zadnja izmjena: 2024-01-30 08:07
To je projekt za zabavu samo da vidim koliko daleko u brzinama mogu pritisnuti matrični ekran 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, koja se ponekad naziva i "plava pilula" koju sam kupio za oko 2 eura (ili USD, gotovo su iste vrijednosti, krajem 2018.), dva matrična ekrana 8x8x4 sa čipovima MAX7219, kupljen za 5 eura po komadu i rotacijski koder 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 radni napon napajanja treba 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 nivoa 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 šine, a obje na dnu su šine za tlo. To je način na koji sam navikao da to radim i radi dobro, čini da postavka više liči na sheme koje crtam. Također, napravio sam puno malih ploča s dijelovima koje mogu priključiti na matičnu ploču kako bih ubrzao stvari, a sve su konfigurirane da koriste dvije gornje linije kao pozitivne, a donje kao tlo. Kao što sam rekao, rezolucija je 4 -bitna (16 nivoa), a kako postoje 4x8 LED diode jedna do druge, postoji samo 32 tačke uzorka (tačke). Uporedite to sa Rigol Rigol DS1054Z (8 bita i 12 Mps) i videćete da ovo teško da je igračka. Koja je stvarna propusnost, ne znam, testirao sam je na 10kHz i to radi dobro.
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 upotrebe. Č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 programator/debager iz 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 horizontalno, 8 LED dioda jedna do druge. Za osciloskop bi 8 LED dioda jedna na drugu bilo lakše, pa sam napravio jednostavan frame-tampon u koji se upisuju podaci s vertikalnim načinom i očitavaju na potreban horizontalni 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 drugog, sa svojim ulazima spojenim na izlaze modula prije njega, morate poslati tih 16 bita četiri puta da dođete do posljednjeg modula. (Nadam se da sam razjasnio stvari …) 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 tajmera 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 takta do 2000 impulsa. Recimo da odaberete 100. TIMER3 zatim generira DOGAĐAJ na 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 završiti nakon otprilike. 10 mS. U 10 mS možete uklopiti jednu valnu dužinu od 100 Hz ili dvije od 200 Hz itd. Prelazak preko 3 talasa po ekranu otežava prepoznavanje talasnog oblika.
U ostalom, mogu vas uputiti samo na kôd, nije ga teško slijediti čak i ako imate samo malo iskustva s Arduinom. U stvari, mogli biste napraviti istu stvar 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.
Korak 5: Main.h
#ifndef _MAIN_H _#definiraj _MAIN_H_
#include "stm32f1xx_ll_adc.h"
#include "stm32f1xx_llcxx" xxxxxxxxxxxxxxxxxxxx uključi "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
#endif
Korak 6: Main.c
#include "main.h" static void LL_Init (void); void SystemClock_Config (void); statička praznina MX_GPIO_Init (void); statička praznina MX_ADC1_Init (void); statička praznina MX_SPI1_Init (void); statička praznina MX_SPI2_Init (void); statička praznina MX_TIM3_Init (void); statička praznina MX_TIM4_Init (void);
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_displej [4] [8]; // vier bytes naast elkaar, acht onder elkaar
uint8_t niži_displej [4] [8]; // sa twee samen vormen iz frame-buffer-a
uint8_t uzorak_bufera [32]; // međuspremnik za rezultate s 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_bytes {
za (y = 0; y <8; y ++) // lijnen {gornji_displej [x] [y] = 0; // sve bitne vrijednosti za niži_displej [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 ekranu schrijven
{gornji_display [display_byte] [15-y] | = (1 << display_bit); } else // u donjem ekranu schrijven {lower_display [display_byte] [7-y] | = (1 << display_bit); }}}
void display_frame_buffer (void)
{
uint8_t y; // acht lijnen boven elkaar (po ekranu) uint16_t yl; // lijnnummer voor de MAX7219
za (y = 0; y <8; y ++) {yl = (y+1) << 8; // MAX7219 glavni broj u gornjim 8 bitova van 16 bitova
SPI2_send64 ((yl | gornji_prikaz [0] [y]), (yl | gornji_display [1] [y]), (yl | gornji_display [2] [y]), (yl | gornji_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 (void)
{uint8_t timebase_knop;
timebase_knop = LL_TIM_GetCounter (TIM4) / 2;
prekidač (timebase_knop)
{slučaj 0: LL_TIM_SetAutoReload (TIM3, 1999); break; slučaj 1: LL_TIM_SetAutoReload (TIM3, 999); break; slučaj 2: LL_TIM_SetAutoReload (TIM3, 499); break; slučaj 3: LL_TIM_SetAutoReload (TIM3, 199); break; slučaj 4: LL_TIM_SetAutoReload (TIM3, 99); break; slučaj 5: LL_TIM_SetAutoReload (TIM3, 49); break; slučaj 6: LL_TIM_SetAutoReload (TIM3, 19); break; slučaj 7: LL_TIM_SetAutoReload (TIM3, 9); break; slučaj 8: LL_TIM_SetAutoReload (TIM3, 4); break; slučaj 9: LL_TIM_SetAutoReload (TIM3, 1); break;
zadano:
LL_TIM_SetAutoReload (TIM3, 99); break; }}
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 redovi 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 redovi na}
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, 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 data3, uint16_t data2, uint16_t data1, uint16_t data0)
{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; uint8_t okidač; static uint8_t previous_trigger;
if (LL_ADC_IsActiveFlag_EOS (ADC1)! = RESET)
{if (brojač uzorka <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 (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 (); 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 linija)
{while (1) {}}
#ifdef USE_FULL_ASSERT
void assert_failed (datoteka uint8_t*, linija uint32_t)
{} #endif
Preporučuje se:
Weasley' Sat sa četiri ruke: 11 koraka (sa slikama)
Weasleyjev' satni sat sa četiri ruke: Dakle, s Raspberry Pi -jem koji je već neko vrijeme vrtio, htio 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 napraviti pomoću C ++ programa koji može sabirati, oduzimati, množiti i dijeliti dva operanda koja je unijeo korisnik. Naredba if i goto koristi se za kreiranje 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: Poštovani proizvođači, to je proizvođač moekoe! Danas vam želim pokazati kako izgraditi vrlo koristan linearni klizač za kameru zasnovan na V-Slot/Openbuilds šini, Nema17 koračnom motoru i samo četiri 3D štampana dijela .Prije nekoliko dana odlučio sam uložiti u bolju kameru za
Četiri pite - novi Raspberry Pi 4 - projekat Highlights & Celebration !: 6 koraka
Četiri pite - novi Raspberry Pi 4 - projekat Highlights & Celebration !: Ispod je kratak pregled sadržaja. Uvodni i prezentacijski video Pie Pi 3.14 Pite Rezultat
Kako napraviti video na podijeljenom ekranu u četiri koraka: 4 koraka (sa slikama)
Kako napraviti video na podijeljenom ekranu u četiri koraka: Često vidimo istu osobu kako se prikazuje u sceni dva puta u TV predstavi. Koliko znamo, glumac nema brata blizanca. Gledali smo i kako se dva pjevačka videa stavljaju na jedan ekran kako bi se uporedile njihove pjevačke sposobnosti. Ovo je moć spl