Daftar Isi:
- Langkah 1: Perangkat Keras
- Langkah 2: Bangun
- Langkah 3: Program
- Langkah 4: Tentang Kode
- Langkah 5: Main.h
- Langkah 6: Main.c
Video: Osiloskop Empat Bit: 6 Langkah
2024 Pengarang: John Day | [email protected]. Terakhir diubah: 2024-01-30 09:57
Ini adalah proyek untuk bersenang-senang hanya untuk melihat seberapa jauh dalam kecepatan saya dapat mendorong tampilan dot matrix MAX7219. Dan alih-alih menjalankan "permainan kehidupan", saya memutuskan untuk membuat "ruang lingkup" dengannya. Seperti yang akan Anda pahami dari judulnya, ini bukan pengganti osiloskop asli:-).
Karena saya tidak berencana untuk menggunakan ini secara serius, saya tidak akan membuat papan sirkuit tercetak untuk itu. Mungkin, mungkin saja saya akan meletakkannya di papan perf tetapi untuk saat ini, dan akan tetap, di papan tempat memotong roti. Juga tidak ada input amplifier/attenuator, Anda harus menyediakan sinyal antara 0 dan 3.3V, jangan negatif atau lebih dari 3.3V karena Anda dapat merusak mikrokontroler.
Langkah 1: Perangkat Keras
Itu murah, sangat murah ketika Anda membeli suku cadang di Cina melalui ebay atau situs serupa. Ini menggunakan papan pengembangan STM32F103C8, kadang-kadang disebut "pil biru" yang saya beli sekitar 2 euro (atau USD, nilainya hampir sama, akhir 2018), dua layar dot-matrix 8x8x4 dengan chip MAX7219 di atasnya, dibeli seharga 5 euro per potong dan rotary encoder sekitar 1 euro.
Yang dibutuhkan tentu saja adalah catu daya yang menghasilkan 3.3V pada beberapa ratus miliampere. Regulator tegangan pada papan pengembangan STM32F103C8 tidak digunakan, tidak dapat memberikan arus yang cukup untuk tampilan. Lembar data untuk MAX7219 menentukan tegangan suplai operasi harus antara 4.0 dan 5.5V tetapi berjalan dengan baik pada 3.3V, mungkin tidak ketika Anda menggunakannya di lingkungan yang sangat panas atau dingin, tetapi pada 20 Celcius itu baik-baik saja. Dan sekarang saya tidak perlu menggunakan konverter level antara mikrokontroler dan papan display.
Langkah 2: Bangun
Ketika Anda melihat gambar, Anda mungkin melihat bahwa saya menggunakan saluran listrik pada papan tempat memotong roti dengan cara yang tidak konvensional, kedua saluran di atas adalah rel positif dan keduanya di bawah adalah rel tanah. Ini adalah cara yang biasa saya lakukan dan bekerja dengan baik, itu membuat pengaturan terlihat sedikit lebih seperti skema yang saya gambar. Juga, saya telah membuat banyak papan kecil dengan bagian-bagian yang dapat saya tancapkan ke papan tempat memotong roti untuk mempercepat segalanya dan semuanya dikonfigurasikan untuk menggunakan dua garis atas sebagai positif dan garis bawah sebagai tanah. Seperti yang saya katakan, resolusinya adalah 4 bit (16 level), dan karena ada 4x8 led yang bersebelahan, hanya ada 32 titik sampel (pts). Bandingkan dengan Rigol Rigol DS1054Z (8 bit dan 12Mpts) dan Anda akan melihat bahwa ini bukan mainan. Berapa bandwidth sebenarnya, saya tidak tahu, saya telah mengujinya hingga 10kHz dan itu berfungsi dengan baik.
Langkah 3: Program
IDE yang saya gunakan adalah Atollic TrueStudio yang mulai awal tahun ini (2018) diadopsi oleh ST Micro Electronics dan tersedia secara gratis, tanpa batas waktu, tanpa batasan ukuran kode, tanpa layar cerewet. Bersamaan dengan itu, saya menggunakan STM32CubeMX, sebuah program yang memberi saya kode awal dan menghasilkan inisialisasi semua periferal. Dan memiliki tampilan semua pin mikrokontroler dan penggunaannya. Bahkan jika Anda tidak menggunakan STM32CubeMX untuk menghasilkan kode, ini sangat berguna. Satu hal yang saya tidak suka adalah apa yang disebut HAL yang merupakan default dari STM32CubeMX. Saya lebih suka metode kerja LowLayer.
Untuk memprogram mikrokontroler saya menggunakan programmer/debugger ST-Link dari ST Micro Electronics atau J-Link buatan Segger. Kedua perangkat ini tidak gratis, meskipun Anda dapat membeli salinannya dalam bahasa Cina dengan harga beberapa euro.
Langkah 4: Tentang Kode
Alamat MAX7219 LED dalam apa yang saya sebut mode horizontal, 8 led bersebelahan. Untuk osiloskop 8 LED di atas satu sama lain akan lebih mudah, jadi saya membuat penyangga bingkai sederhana yang ditulis dengan data secara vertikal, dan dibacakan dengan cara horizontal yang diperlukan. MAX7219 menggunakan kode 16bit per 8 LED, di mana byte pertama digunakan untuk menangani jalur yang dipilih. Dan karena ada empat modul ini yang ditumpuk di samping satu sama lain, dengan inputnya terhubung ke output modul sebelumnya, Anda harus mengirim 16 bit tersebut empat kali untuk mencapai modul terakhir. (Saya harap saya menjelaskan semuanya…) Data dikirim ke MAX7219 menggunakan SPI, protokol yang sederhana namun sangat cepat. Inilah yang saya coba, seberapa cepat Anda bisa mengirim data ke MAX7219. Pada akhirnya, saya beralih kembali ke 9 MHz tepat di bawah kecepatan maksimum yang ditentukan oleh datasheet.
Saya menggunakan dua dari empat pengatur waktu STM32F103C8 yang tersedia, satu untuk menghasilkan basis waktu dan yang lainnya untuk membacakan encoder putar, yang menetapkan basis waktu. TIMER3 menghasilkan basis waktu, ia melakukannya dengan membagi jam dengan 230, memperbarui penghitung setiap 3,2 uS. Penyihir rotary encoder Anda dapat memilih untuk menghitung counter dari 2 pulsa clock hingga 2000 pulsa clock. Katakanlah Anda memilih 100. TIMER3 kemudian menghasilkan EVENT setiap 320 uS. EVENT ini memicu ADC untuk merekam sampel sinyal input, dan karena ada 32 sampel yang harus diambil untuk satu layar penuh, ini akan selesai setelah kira-kira. 10 mS. Dalam 10mS Anda dapat memasukkan satu panjang gelombang 100 Hz, atau dua 200 Hz, dan seterusnya. Melewati 3 gelombang per layar membuatnya agak sulit untuk mengenali bentuk gelombang.
Selebihnya, saya hanya bisa merujuk Anda ke kode, tidak sulit untuk diikuti bahkan jika Anda hanya memiliki beberapa pengalaman dengan Arduino. Sebenarnya, Anda bisa membuat hal yang sama dengan Arduino, meskipun saya ragu itu akan bekerja secepat "pil biru". STM32F103C8 adalah mikrokontroler 32bit yang berjalan pada 72 MHz, ia memiliki dua periferal SPI dan ADC yang sangat cepat.
Langkah 5: Main.h
#ifndef _MAIN_H_#define _MAIN_H_
#sertakan "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 "stmutilf1" 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)0x0000005) #define NVIC_PRIORITY(GRO00000003_3endt)
#ifdef _cplusplus
extern "C" { #endif void _Error_Handler(char *, int);
#define Error_Handler() _Error_Handler(_FILE_, _LINE_)
#ifdef _cplusplus } #endif
#berakhir jika
Langkah 6: Main.c
#include "main.h" static void LL_Init(void); batal SystemClock_Config(batal); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); static void MX_SPI1_Init(void); static void MX_SPI2_Init(void); static void MX_TIM3_Init(void); static 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); batal MAX7219_1_init(); batal MAX7219_2_init(); void erase_frame_buffer(void); void fill_frame_buffer(void); void display_frame_buffer(void); batal set_timebase(batal);
uint8_t upper_display[4][8]; //vier byte 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 utama (kosong)
{ LL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); MX_SPI1_Init(); MX_SPI2_Init(); MX_TIM3_Init(); MX_TIM4_Init();
LL_SPI_Aktifkan(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_mTunda(500); //MAX7219 perlu beberapa saat setelah dihidupkan
MAX7219_1_init(); MAX7219_2_init();
//LL_TIM_SetAutoReload(TIM3, 9);
sementara (1)
{ set_timebase(); hapus_frame_buffer(); fill_frame_buffer(); display_frame_buffer(); } }
batal hapus_frame_buffer(batal)
{ int8_t x; int8_t y;
untuk (x = 0; x < 4; x++) //kolom_byte {
for (y = 0; y < 8; y++) //lijnen { upper_display[x][y] = 0; //semua bitjes op nul lower_display[x][y] = 0; } } }
void fill_frame_buffer(kosong)
{ uint8_t y = 0; //tegangan uint8_t tijd = 0; //tijd uint8_t display_byte; //steeds 8 bit 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 = sample_buffer[tijd];
if (y > 7) //di tampilan atas schrijven
{ upper_display[display_byte][15-y] |= (1 << display_bit); } else //di tampilan bawah schrijven { lower_display[display_byte][7-y] |= (1 << display_bit); } } }
batal display_frame_buffer(batal)
{
uint8_t y; //acht lijnen boven elkaar (per tampilan) uint16_t yl; //jumlah nomor untuk MAX7219
untuk (y = 0; y < 8; y++) { yl = (y+1) << 8; //MAX7219 heeft lijnnummer di de atas 8 bit van 16 bit woord
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 | lower_display[0][y]), (yl | lower_display[1][y]), (yl | lower_display[2][y]), (yl | lower_display[3][y])); }
}
batal set_timebase(batal)
{ uint8_t timebase_knop;
timebase_knop = LL_TIM_GetCounter(TIM4) / 2;
beralih (timebase_knop)
{ kasus 0: LL_TIM_SetAutoReload(TIM3, 1999); merusak; kasus 1: LL_TIM_SetAutoReload(TIM3, 999); merusak; kasus 2: LL_TIM_SetAutoReload(TIM3, 499); merusak; kasus 3: LL_TIM_SetAutoReload(TIM3, 199); merusak; kasus 4: LL_TIM_SetAutoReload(TIM3, 99); merusak; kasus 5: LL_TIM_SetAutoReload(TIM3, 49); merusak; kasus 6: LL_TIM_SetAutoReload(TIM3, 19); merusak; kasus 7: LL_TIM_SetAutoReload(TIM3, 9); merusak; kasus 8: LL_TIM_SetAutoReload(TIM3, 4); merusak; kasus 9: LL_TIM_SetAutoReload(TIM3, 1); merusak;
bawaan:
LL_TIM_SetAutoReload(TIM3, 99); merusak; } }
batalkan MAX7219_1_init()
{ SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //shutdown pada SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); //testmode nonaktif SPI1_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //shutdown off, operasi normal SPI1_send64(0x0900, 0x0900, 0x0900, 0x0900); //tidak ada dekode 7seg, 64 piksel SPI1_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); //intensitas 50% SPI1_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); //semua baris aktif }
batalkan MAX7219_2_init()
{ SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //shutdown pada SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); //testmode nonaktif SPI2_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //shutdown off, operasi normal SPI2_send64(0x0900, 0x0900, 0x0900, 0x0900); //tidak ada dekode 7seg, 64 piksel SPI2_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); //intensitas 50% SPI2_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); //semua baris aktif }
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);
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);
kembalikan 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);
while (LL_SPI_IsActiveFlag_TXE(SPI2) == 0) {}
LL_SPI_TransmitData16(SPI2, data2);
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);
kembalikan LL_SPI_ReceiveData16(SPI2); }
batal ADC1_2_IRQHandler(batal)
{ static uint8_t sample_counter; pemicu uint8_t; uint8_t static sebelumnya_trigger;
jika (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++; lain sample_counter = 0; } else { pemicu = LL_ADC_REG_ReadConversionData32(ADC1) / 256;
if ((trigger == 7) && (previous_trigger < trigger)) //gaat niet helemaal goed bij blokgolven… { sample_counter = 0; } sebelumnya_pemicu = pemicu; }
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();
}
batal SystemClock_Config (batal)
{ 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));
}
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(char *file, int line)
{ sementara(1) {} }
#ifdef USE_FULL_ASSERT
batalkan assert_failed (file uint8_t*, baris uint32_t)
{ } #berakhir jika
Direkomendasikan:
Tempat DIY Seperti Robot Berkaki Empat (membuat Log V2): 9 Langkah
Tempat DIY Seperti Robot Berkaki Empat (Log bangunan V2): Ini adalah log bangunan dengan petunjuk terperinci tentang cara membuat https://www.instructables.com/DIY-Spot-Like-Quadru…robot dog v2.Follow Robolab youtube situs untuk informasi lebih lanjut. https://www.youtube.com/robolab19Ini adalah robot pertama saya dan saya telah
Penguji Elektronik Tegangan Rendah Empat Kali Lipat: 7 Langkah
Penguji Elektronik Tegangan Rendah Empat Kali Lipat: Apa benda ini? Penguji tegangan rendah empat kali lipat yang serbaguna, berkontribusi pada dunia yang lebih hijau karena dengan bantuan gadget kecil ini banyak perangkat elektronik yang rusak dapat bertahan hidup kedua atau ketiga, dan tidak akan dikirim ke tempat pembuangan sampah ! Aman
CARA MEMBUAT EMPAT KALKULATOR FUNGSIONAL DI CPP: 6 Langkah
CARA MEMBUAT EMPAT KALKULATOR FUNGSIONAL DI CPP: Kalkulator digunakan untuk semua orang dalam kehidupan sehari-hari. Kalkulator sederhana dapat dibuat dengan menggunakan program C++ yang mampu menambah, mengurangi, mengalikan dan membagi, dua operan yang dimasukkan oleh pengguna. Pernyataan if dan goto digunakan untuk membuat kalkulator
GorillaBot, Robot Berkaki Empat Arduino Autonomous Sprint 3D yang Dicetak: 9 Langkah (dengan Gambar)
GorillaBot Robot Berkaki Empat Arduino Autonomous Sprint Cetak 3D: Setiap tahun di Toulouse (Prancis) ada Balap Robot Toulouse #TRR2021Perlombaan terdiri dari sprint otonom 10 meter untuk robot berkaki dua dan berkaki empat. Rekor saat ini yang saya kumpulkan untuk hewan berkaki empat adalah 42 detik untuk Lari cepat 10 meter. Jadi dengan itu dalam m
Cara Membuat Video Split Screen Dengan Empat Langkah: 4 Langkah (dengan Gambar)
Cara Membuat Video Split Screen Dengan Empat Langkah: Kita sering melihat orang yang sama tampil dalam satu adegan dua kali dalam sebuah drama TV. Dan sejauh yang kami tahu, aktor itu tidak memiliki saudara kembar. Kami juga telah menyaksikan dua video bernyanyi di satu layar untuk membandingkan kemampuan menyanyi mereka. Ini adalah kekuatan sp