İçindekiler:
2025 Yazar: John Day | [email protected]. Son düzenleme: 2025-01-13 06:58
Bir MAX7219 nokta vuruşlu ekranı ne kadar hızlarda itebileceğimi görmek için eğlenceli bir proje. Ve onu "hayat oyunu"na sokmak yerine, onunla bir "kapsam" yapmaya karar verdim. Başlıktan da anlayacağınız gibi, bu gerçek bir osiloskopun yerini tutmaz:-).
Bunu ciddi bir şekilde kullanmayı düşünmediğim için baskılı devre kartı da yapmayacağım. Belki, sadece belki onu mükemmel bir tahtaya koyacağım ama şimdilik bir devre tahtasında ve öyle kalacak. Ayrıca giriş yükselticisi/zayıflatıcısı yoktur, 0 ile 3,3V arasında bir sinyal vermeniz gerekir, negatif veya 3,3V üzerine çıkmayın çünkü mikrodenetleyiciye zarar verebilirsiniz.
Adım 1: Donanım
Parçaları Çin'de ebay veya benzeri sitelerden satın aldığınızda ucuz, çok ucuz. Bazen "mavi hap" olarak adlandırılan ve yaklaşık 2 euro'ya (veya USD, neredeyse aynı değerdeler, 2018'in sonunda) satın aldığım bir STM32F103C8 geliştirme kartı, üzerinde MAX7219 yongaları olan iki adet 8x8x4 nokta vuruşlu ekran kullanıyor. Parça başı 5 euro ve döner kodlayıcı yaklaşık 1 euro.
Elbette gerekli olan, birkaç yüz miliamperde 3.3V sağlayan bir güç kaynağı. STM32F103C8 geliştirme kartı üzerinde bulunan voltaj regülatörü kullanılmaz, ekranlara yeterli akım sağlayamaz. MAX7219'un veri sayfası, çalışma besleme voltajının 4,0 ile 5,5 V arasında olması gerektiğini belirtir, ancak 3,3 V'ta iyi çalışır, belki çok sıcak veya soğuk bir ortamda kullandığınızda değil, ancak 20 Santigratta iyidir. Ve artık mikrodenetleyici ve ekran kartları arasında seviye dönüştürücü kullanmak zorunda değilim.
2. Adım: Oluşturun
Resme baktığınızda, devre tahtalarındaki güç hatlarını geleneksel olmayan bir şekilde kullandığımı görebilirsiniz, üstteki her iki hat da pozitif ray ve alt taraftaki her ikisi de zemin rayı. Benim alışkın olduğum yol bu ve iyi çalışıyor, kurulumu biraz daha çizdiğim şemalara benziyor. Ayrıca, işleri hızlandırmak için breadboard'a takabileceğim parçaları olan birçok küçük tahta yaptım ve hepsi iki üst çizgiyi pozitif ve alt çizgileri toprak olarak kullanacak şekilde yapılandırıldı. Dediğim gibi çözünürlük 4 bit (16 seviye) ve yan yana 4x8 led olduğu için sadece 32 örnek nokta (pts) var. Bunu bir Rigol Rigol DS1054Z (8 bit ve 12Mpts) ile karşılaştırın ve bunun bir oyuncak olmadığını göreceksiniz. Gerçek bant genişliği nedir, bilmiyorum, 10kHz'e kadar test ettim ve bu iyi çalışıyor.
3. Adım: Programlar
Kullandığım IDE, bu yılın başından itibaren (2018) ST Micro Electronics tarafından kabul edilen ve ücretsiz olarak sunulan Atollic TrueStudio'dur, zaman sınırı yoktur, kod boyutu sınırı yoktur, nag ekranı yoktur. Bununla birlikte, bana başlangıç kodunu sağlayan ve tüm çevre birimlerinin başlatılmasını sağlayan bir program olan STM32CubeMX'i kullanıyorum. Ve mikrodenetleyicinin tüm pinlerini ve kullanımlarını gösteren bir ekrana sahiptir. Kod üretmek için STM32CubeMX kullanmasanız bile, bu çok kullanışlı. Sevmediğim bir şey, STM32CubeMX'in varsayılanı olan HAL denen şey. LowLayer çalışma yöntemini tercih ederim.
Mikrodenetleyiciyi programlamak için ya ST Micro Electronics'in ST-Link programlayıcısını/hata ayıklayıcısını ya da Segger tarafından yapılan J-Link'i kullanıyorum. Bu cihazların her ikisi de ücretsiz değil, ancak Çince kopyalarını birkaç avroya satın alabilirsiniz.
4. Adım: Kod Hakkında
MAX7219'lar LED'leri yatay olarak adlandırdığım şekilde adresler, yan yana 8 led. Bir osiloskop için 8 LED'in üst üste gelmesi daha kolay olurdu, bu yüzden verilerle dikey olarak yazılan ve istenen yatay şekilde okunan basit bir çerçeve tamponu yaptım. MAX7219, seçilen hattı adreslemek için ilk baytın kullanıldığı her 8 LED için 16 bitlik bir kod kullanır. Ve bu modüllerden yan yana yığılmış dört tane olduğundan, girişleri ondan önceki modülün çıkışlarına bağlı olduğundan, son modüle ulaşmak için o 16 biti dört kez göndermeniz gerekir. (Umarım her şeyi açıklığa kavuşturuyorumdur…) Veriler, basit ama çok hızlı bir protokol olan SPI kullanılarak MAX7219'a gönderilir. Benim denediğim şey buydu, verileri MAX7219'a gönderirken ne kadar hızlı gidebilirsiniz. Sonunda, veri sayfasının belirttiği maksimum hızın hemen altına 9 MHz'e geri döndüm.
STM32F103C8'in mevcut dört zamanlayıcısından ikisini, biri zaman tabanının oluşturulması için, diğeri ise zaman tabanını ayarlayan döner kodlayıcıyı okumak için kullanıyorum. TIMER3 zaman tabanını oluşturur, bunu saati 230'a bölerek, sayacı her 3,2 uS'de güncelleyerek yapar. Sayacın 2 saat darbesinden 2000 saat darbesine kadar saymasını sağlamak için döner kodlayıcıyı büyüleyin. Diyelim ki 100'ü seçtiniz. TIMER3 daha sonra her 320 uS'de bir OLAY üretir. Bu OLAY, ADC'yi giriş sinyalinin bir örneğini kaydetmesi için tetikler ve bir ekran için alınacak 32 örnek olduğundan, bu yaklaşık olarak sonra tamamlanacaktır. 10 ms. 10mS'de 100 Hz'lik bir dalga boyu veya 200 Hz'lik iki dalga boyu vb. sığdırabilirsiniz. Ekran başına 3 dalganın üzerine çıkmak, dalga biçimini tanımayı oldukça zorlaştırıyor.
Geri kalanı için, sizi sadece koda yönlendirebilirim, sadece bir Arduino ile biraz tecrübeniz olsa bile takip etmesi zor değil. Aslında, bir "mavi hap" kadar hızlı çalışacağından şüpheli olsam da, aynı şeyi bir Arduino ile yapabilirsiniz. STM32F103C8, 72 MHz'de çalışan 32 bit bir mikro denetleyicidir, iki SPI çevre birimine ve çok hızlı bir ADC'ye sahiptir.
Adım 5: Main.h
#ifndef _MAIN_H_#tanımla _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" #include "_llm32fwr1s" #include "_llm32util.h" "stm32f1xx_ll_dma.h" dahil #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_2 ((uint32_t)0x00000005) #define NVIC_PRIORITY_3ROIN4#define NVIC_PRIORITY_3ROIC0004#define NVIC_PRIOR_3ROIC04)int
#ifdef _cplusplus
extern "C" { #endif void _Error_Handler(char *, int);
#define Error_Handler() _Error_Handler(_FILE_, _LINE_)
#ifdef _cplusplus } #endif
#endif
Adım 6: Main.c
#include "main.h" statik void LL_Init(void); geçersiz SystemClock_Config(void); statik boşluk MX_GPIO_Init(void); statik boşluk MX_ADC1_Init(void); statik boşluk MX_SPI1_Init(void); statik boşluk MX_SPI2_Init(void); statik boşluk MX_TIM3_Init(void); statik boşluk MX_TIM4_Init(void);
uint16_t SPI1_send64(uint16_t veri3, uint16_t veri2, uint16_t veri1, uint16_t veri0);
uint16_t SPI2_send64(uint16_t veri3, uint16_t veri2, uint16_t veri1, uint16_t veri0); geçersiz MAX7219_1_init(); geçersiz MAX7219_2_init(); void delete_frame_buffer(void); void fill_frame_buffer(void); void display_frame_buffer(void); geçersiz set_timebase(void);
uint8_t üst_görüntü[4][8]; //vier bytes naast elkaar, acht onder elkaar
uint8_t low_display[4][8]; // samen vormen de frame-buffer twee
uint8_t sample_buffer[32]; // ADC'nin sonucunun arabelleği
int ana(boşluk)
{ LL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); MX_SPI1_Init(); MX_SPI2_Init(); MX_TIM3_Init(); MX_TIM4_Init();
LL_SPI_Etkinleştir(SPI1);
LL_SPI_Etkinleştir(SPI2);
LL_TIM_EnableCounter(TIM3);
LL_TIM_EnableCounter(TIM4);
LL_ADC_Etkinleştir(ADC1);
LL_ADC_REG_StartConversionSWStart(ADC1); LL_ADC_EnableIT_EOS(ADC1);
LL_mGecikme(500); //MAX7219'un güç açıldıktan sonra biraz zamana ihtiyacı var
MAX7219_1_init(); MAX7219_2_init();
//LL_TIM_SetAutoReload(TIM3, 9);
süre (1)
{ set_timebase(); delete_frame_buffer(); fill_frame_buffer(); display_frame_buffer(); } }
void delete_frame_buffer(void)
{ int8_t x; int8_t y;
için (x = 0; x < 4; x++) //kolom_bytes {
for (y = 0; y < 8; y++) //lijnen { üst_görüntü[x][y] = 0; //tüm bitjeler op nul low_display[x][y] = 0; } } }
void fill_frame_buffer(void)
{ uint8_t y = 0; //voltaj uint8_t tijd = 0; //tijd uint8_t display_byte; //steeds 8 bit naast elkaar ve dat 4 maal açık lijn uint8_t display_bit;
for (tijd = 0; tijd < 32; tijd++) { display_byte = tijd / 8; display_bit = 7 - (tijd % 8);
y = sample_buffer[tijd];
if (y > 7) //üst ekranda schrijven
{ üst_display[display_byte][15-y] |= (1 << display_bit); } else // alt ekranda schrijven { low_display[display_byte][7-y] |= (1 << display_bit); } } }
geçersiz display_frame_buffer(void)
{
uint8_t y; //acht lijnen boven elkaar (görüntü başına) uint16_t yl; // MAX7219'un bir numarası
for (y = 0; y < 8; y++) { yl = (y+1) << 8; //MAX7219 heeft lijnnummer in üst 8 bit van 16 bit ahşap
SPI2_send64((yl | üst_görüntü[0][y]), (yl | üst_görüntü[1][y]), (yl | üst_görüntü[2][y]), (yl | üst_görüntü[3][y]));
SPI1_send64((yl | low_display[0][y]), (yl | low_display[1][y]), (yl | low_display[2][y]), (yl | low_display[3][y])); }
}
geçersiz set_timebase(void)
{ uint8_t zaman tabanı_knop;
timebase_knop = LL_TIM_GetCounter(TIM4) / 2;
geçiş (zaman tabanı_knop)
{ durum 0: LL_TIM_SetAutoReload(TIM3, 1999); kırmak; durum 1: LL_TIM_SetAutoReload(TIM3, 999); kırmak; durum 2: LL_TIM_SetAutoReload(TIM3, 499); kırmak; durum 3: LL_TIM_SetAutoReload(TIM3, 199); kırmak; durum 4: LL_TIM_SetAutoReload(TIM3, 99); kırmak; durum 5: LL_TIM_SetAutoReload(TIM3, 49); kırmak; durum 6: LL_TIM_SetAutoReload(TIM3, 19); kırmak; durum 7: LL_TIM_SetAutoReload(TIM3, 9); kırmak; durum 8: LL_TIM_SetAutoReload(TIM3, 4); kırmak; durum 9: LL_TIM_SetAutoReload(TIM3, 1); kırmak;
varsayılan:
LL_TIM_SetAutoReload(TIM3, 99); kırmak; } }
geçersiz MAX7219_1_init()
{ SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //SPI1_send64'te kapatma (0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); //test modu kapalı SPI1_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //kapanma, normal çalışma SPI1_send64(0x0900, 0x0900, 0x0900, 0x0900); //7seg kod çözme yok, 64 piksel SPI1_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); //yoğunluk %50 SPI1_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); //tüm satırlar }
geçersiz MAX7219_2_init()
{ SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //SPI2_send64'te kapatma (0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); //test modu kapalı SPI2_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //kapanma, normal çalışma SPI2_send64(0x0900, 0x0900, 0x0900, 0x0900); //7seg kod çözme yok, 64 piksel SPI2_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); //yoğunluk %50 SPI2_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); //tüm satırlar }
uint16_t SPI1_send64(uint16_t veri3, uint16_t veri2, uint16_t veri1, uint16_t veri0)
{ LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_4);
LL_SPI_TransmitData16(SPI1, data3);
while (LL_SPI_IsActiveFlag_TXE(SPI1) == 0) {}
LL_SPI_TransmitData16(SPI1, data2);
while (LL_SPI_IsActiveFlag_TXE(SPI1) == 0) {}
LL_SPI_TransmitData16(SPI1, data1);
while (LL_SPI_IsActiveFlag_TXE(SPI1) == 0) {}
LL_SPI_TransmitData16(SPI1, data0);
while (LL_SPI_IsActiveFlag_BSY(SPI1) == 1) {}
LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4);
dönüş LL_SPI_ReceiveData16(SPI1); }
uint16_t SPI2_send64(uint16_t veri3, uint16_t veri2, uint16_t veri1, uint16_t veri0)
{ LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
LL_SPI_TransmitData16(SPI2, data3);
while (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}
LL_SPI_TransmitData16(SPI2, veri2);
while (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}
LL_SPI_TransmitData16(SPI2, data1);
while (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}
LL_SPI_TransmitData16(SPI2, data0);
while (LL_SPI_IsActiveFlag_BSY(SPI2) == 1) {}
LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12);
dönüş LL_SPI_ReceiveData16(SPI2); }
geçersiz ADC1_2_IRQHandler(void)
{ statik uint8_t sample_counter; uint8_t tetikleyici; statik uint8_t önceki_tetikleyici;
if (LL_ADC_IsActiveFlag_EOS(ADC1) != SIFIRLA)
{ if (sample_counter < 32) { sample_buffer[sample_counter] = LL_ADC_REG_ReadConversionData32(ADC1) / 256; if (sample_counter < 32) sample_counter++; başka örnek_sayaç = 0; } else { tetikleyici = LL_ADC_REG_ReadConversionData32(ADC1) / 256;
if ((trigger == 7) && (previous_trigger <tetikleyici)) //gaat niet helemaal gitti bij blokgolven… { sample_counter = 0; } önceki_trigger = tetikleyici; }
LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);
LL_ADC_ClearFlag_EOS(ADC1);
} }
statik boşluk 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();
}
geçersiz 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_SetAPB2Ön Ölçekleyici(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));
}
statik boşluk 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. ContinulousMode = 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);
}
statik boşluk 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); }
statik boşluk 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); }
statik boşluk 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); }
statik boşluk 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); }
statik boşluk 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(char *dosyası, int satırı)
{ süre(1) { } }
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* dosyası, uint32_t satırı)
{ } #endif