ออสซิลโลสโคปสี่บิต: 6 ขั้นตอน
ออสซิลโลสโคปสี่บิต: 6 ขั้นตอน
Anonim
ออสซิลโลสโคปสี่บิต
ออสซิลโลสโคปสี่บิต

มันเป็นโปรเจ็กต์เพื่อความสนุกเพื่อดูว่าฉันสามารถผลักดันการแสดงผลดอทเมทริกซ์ MAX7219 ได้เร็วแค่ไหน และแทนที่จะให้มันดำเนิน "เกมแห่งชีวิต" ฉันตัดสินใจสร้าง "ขอบเขต" ด้วยมัน ตามที่คุณเข้าใจจากชื่อเรื่อง นี่ไม่ใช่การแทนที่ออสซิลโลสโคปจริง:-)

เนื่องจากฉันไม่ได้ตั้งใจจะใช้สิ่งนี้อย่างจริงจัง ฉันจะไม่ทำแผงวงจรพิมพ์สำหรับมัน บางที บางที ฉันอาจจะวางมันลงบนกระดานที่สมบูรณ์แบบ แต่ตอนนี้ มันเป็นและจะอยู่บนเขียงหั่นขนม นอกจากนี้ยังไม่มีแอมพลิฟายเออร์/ตัวลดทอนอินพุต คุณจะต้องจ่ายสัญญาณระหว่าง 0 ถึง 3.3V อย่าให้เป็นค่าลบหรือเกิน 3.3V เนื่องจากอาจทำให้ไมโครคอนโทรลเลอร์เสียหายได้

ขั้นตอนที่ 1: ฮาร์ดแวร์

ฮาร์ดแวร์
ฮาร์ดแวร์
ฮาร์ดแวร์
ฮาร์ดแวร์
ฮาร์ดแวร์
ฮาร์ดแวร์

ราคาถูกและถูกมากเมื่อคุณซื้อชิ้นส่วนในจีนผ่าน ebay หรือเว็บไซต์ที่คล้ายคลึงกัน มันใช้บอร์ดพัฒนา STM32F103C8 ซึ่งบางครั้งเรียกว่า "ยาเม็ดสีน้ำเงิน" ที่ฉันซื้อมาประมาณ 2 ยูโร (หรือ USD เกือบจะเท่ากันเมื่อสิ้นปี 2018) จอแสดงผลดอทเมทริกซ์ขนาด 8x8x4 สองจอพร้อมชิป MAX7219 ซื้อมาเพื่อ 5 ยูโรต่อชิ้นและตัวเข้ารหัสแบบหมุนประมาณ 1 ยูโร

จำเป็นต้องมีแหล่งจ่ายไฟ 3.3V ที่ไม่กี่ร้อยมิลลิแอมป์ ไม่ได้ใช้ตัวควบคุมแรงดันไฟฟ้าบนบอร์ดพัฒนา STM32F103C8 ไม่สามารถให้กระแสไฟเพียงพอสำหรับการแสดงผล แผ่นข้อมูลสำหรับ MAX7219 ระบุว่าแรงดันไฟฟ้าของการจ่ายไฟในการทำงานควรอยู่ระหว่าง 4.0 ถึง 5.5V แต่ใช้งานได้ดีบน 3.3V ซึ่งอาจไม่ใช่เมื่อคุณใช้งานในสภาพแวดล้อมที่ร้อนจัดหรือเย็นจัด แต่ที่อุณหภูมิ 20 องศาเซลเซียส ถือว่าใช้ได้ และตอนนี้ฉันไม่จำเป็นต้องใช้ตัวแปลงระดับระหว่างไมโครคอนโทรลเลอร์กับบอร์ดแสดงผล

ขั้นตอนที่ 2: สร้าง

สร้าง
สร้าง
สร้าง
สร้าง
สร้าง
สร้าง

เมื่อคุณดูภาพ คุณอาจเห็นว่าฉันใช้สายไฟบนเขียงหั่นขนมในลักษณะที่ไม่ธรรมดา ทั้งสองเส้นด้านบนเป็นรางบวก และด้านล่างทั้งสองเป็นรางภาคพื้นดิน เป็นวิธีที่ฉันเคยทำและทำงานได้ดี ทำให้การตั้งค่าดูคล้ายกับแผนผังที่ฉันวาดขึ้น นอกจากนี้ ฉันได้สร้างบอร์ดขนาดเล็กจำนวนมากพร้อมชิ้นส่วนต่างๆ ที่ฉันสามารถเสียบเข้ากับเขียงหั่นขนมเพื่อเพิ่มความเร็วของสิ่งต่างๆ และพวกเขาทั้งหมดได้รับการกำหนดค่าให้ใช้บรรทัดบนสุดสองบรรทัดเป็นค่าบวก และบรรทัดล่างเป็นพื้น อย่างที่ฉันพูดไป ความละเอียดคือ 4 บิต (16 ระดับ) และเนื่องจากมีไฟ LED 4x8 ติดกัน จึงมีเพียง 32 จุดตัวอย่าง (pts) เปรียบเทียบกับ Rigol Rigol DS1054Z (8 บิตและ 12Mpts) แล้วคุณจะเห็นว่านี่เป็นเพียงของเล่นเท่านั้น แบนด์วิดธ์ที่แท้จริงคืออะไร ฉันไม่รู้ ฉันทดสอบแล้วได้ถึง 10kHz และใช้งานได้ดี

ขั้นตอนที่ 3: โปรแกรม

โปรแกรม
โปรแกรม
โปรแกรม
โปรแกรม
โปรแกรม
โปรแกรม
โปรแกรม
โปรแกรม

IDE ที่ฉันใช้คือ Atollic TrueStudio ซึ่งเมื่อต้นปีนี้ (2018) ได้รับการรับรองโดย ST Micro Electronics และให้บริการฟรี ไม่จำกัดเวลา ไม่จำกัดขนาดโค้ด ไม่มีหน้าจอจู้จี้ ร่วมกับมัน ฉันใช้ STM32CubeMX ซึ่งเป็นโปรแกรมที่ให้รหัสเริ่มต้นแก่ฉัน และสร้างการเริ่มต้นของอุปกรณ์ต่อพ่วงทั้งหมด และมีการแสดงหมุดทั้งหมดของไมโครคอนโทรลเลอร์และการใช้งาน แม้ว่าคุณจะไม่ได้ใช้ STM32CubeMX ในการสร้างโค้ด แต่ก็มีประโยชน์มาก สิ่งหนึ่งที่ฉันไม่ชอบคือ HAL ที่เรียกว่าซึ่งเป็นค่าเริ่มต้นของ STM32CubeMX ฉันชอบวิธีการทำงานแบบ LowLayer

ในการตั้งโปรแกรมไมโครคอนโทรลเลอร์ ฉันใช้โปรแกรมเมอร์/ดีบักเกอร์ ST-Link จาก ST Micro Electronics หรือ J-Link ที่สร้างโดย Segger อุปกรณ์ทั้งสองนี้ไม่ฟรี แม้ว่าคุณสามารถซื้อสำเนาภาษาจีนได้ในราคาไม่กี่ยูโร

ขั้นตอนที่ 4: เกี่ยวกับรหัส

MAX7219 ระบุ LEDs ในสิ่งที่ฉันเรียกว่าแนวนอน 8 LEDs ติดกัน สำหรับออสซิลโลสโคป 8 LED ที่วางทับกันน่าจะง่ายกว่า ดังนั้นฉันจึงสร้างบัฟเฟอร์เฟรมง่ายๆ ที่เขียนด้วยข้อมูลในแนวตั้ง และอ่านค่าในแนวนอนที่ต้องการ MAX7219 ใช้รหัส 16 บิตต่อ 8 LEDs โดยที่ไบต์แรกใช้เพื่อระบุบรรทัดที่เลือก และเนื่องจากมีสี่โมดูลเหล่านี้ซ้อนกันอยู่ติดกัน โดยอินพุตที่เชื่อมต่อกับเอาต์พุตของโมดูลก่อนหน้านั้น คุณต้องส่ง 16 บิตเหล่านั้นสี่ครั้งเพื่อไปยังโมดูลสุดท้าย (ฉันหวังว่าฉันจะทำให้ชัดเจน…) ข้อมูลถูกส่งไปยัง MAX7219 โดยใช้ SPI ซึ่งเป็นโปรโตคอลที่เรียบง่ายแต่เร็วมาก นี่คือสิ่งที่ฉันกำลังทดลองอยู่ คุณสามารถส่งข้อมูลไปยัง MAX7219 ได้เร็วแค่ไหน ในท้ายที่สุด ฉันเปลี่ยนกลับไปเป็น 9 MHz ซึ่งต่ำกว่าความเร็วสูงสุดที่แผ่นข้อมูลระบุ

ฉันใช้ตัวจับเวลาที่มีอยู่สองในสี่ตัวของ STM32F103C8 ตัวหนึ่งสำหรับสร้างฐานเวลาและอีกตัวสำหรับอ่านตัวเข้ารหัสแบบหมุนซึ่งกำหนดฐานเวลา TIMER3 สร้างฐานเวลา โดยหารนาฬิกาด้วย 230 อัปเดตตัวนับทุกๆ 3.2 uS แม่มดตัวเข้ารหัสแบบหมุนคุณสามารถเลือกให้นับตัวนับได้ตั้งแต่ 2 จังหวะนาฬิกาจนถึง 2,000 จังหวะนาฬิกา สมมติว่าคุณเลือก 100 TIMER3 จะสร้าง EVENT ทุกๆ 320 uS เหตุการณ์นี้ทริกเกอร์ ADC เพื่อบันทึกตัวอย่างของสัญญาณอินพุต และเนื่องจากมีตัวอย่าง 32 ตัวอย่างที่จะใช้สำหรับหนึ่งหน้าจอ การดำเนินการนี้จะเสร็จสมบูรณ์หลังจากประมาณ 10 มิลลิวินาที ใน 10mS คุณสามารถใส่ความยาวคลื่นหนึ่งช่วงที่ 100 Hz หรือสองช่วงที่ 200 Hz ได้ เป็นต้น การใช้คลื่นมากกว่า 3 คลื่นต่อหน้าจอทำให้ยากต่อการจดจำรูปคลื่น

สำหรับส่วนที่เหลือ ฉันสามารถแนะนำคุณถึงโค้ดเท่านั้น ทำตามได้ไม่ยาก แม้ว่าคุณจะมีประสบการณ์กับ Arduino เพียงเล็กน้อยก็ตาม อันที่จริง คุณสามารถทำสิ่งเดียวกันกับ Arduino ได้ แม้ว่าฉันสงสัยว่ามันจะทำงานได้เร็วเท่ากับ "ยาเม็ดสีน้ำเงิน" STM32F103C8 เป็นไมโครคอนโทรลเลอร์ 32 บิตที่ทำงานที่ 72 MHz มีอุปกรณ์ต่อพ่วง SPI สองตัวและ ADC ที่รวดเร็วมาก

ขั้นตอนที่ 5: Main.h

#ifndef _MAIN_H_#define _MAIN_H_

#รวม "stm32f1xx_ll_adc.h"

# รวม "stm32f1xx_ll_rcc.h" # รวม "stm32f1xx_ll_bus.h" # รวม "stm32f1xx_ll_system.h" # รวม "stm32f1xx_ll_exti.h" แล้ว # รวม "stm32f1xx_ll_cortex_h" # รวม "stm32f1xx_ll_exti.h" แล้ว #stm32f1xx_ll_cortex_h" # รวม "stm32fin" รวม "stm32f1xx_ll_dma.h" # รวม "stm32f1xx_ll_spi.h" # รวม "stm32f1xx_ll_tim.h" # รวม "stm32f1xx.h" # รวม "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 NVICUPx_0intITY GROUP_04) NVICUPX_04 ปลายทาง

#ifdef _cplusplus

extern "C" { #endif เป็นโมฆะ _Error_Handler (ถ่าน *, int);

#define Error_Handler() _Error_Handler(_FILE_, _LINE_)

#ifdef _cplusplus } #endif

#endif

ขั้นตอนที่ 6: Main.c

#include "main.h" โมฆะคงที่ LL_Init (เป็นโมฆะ); เป็นโมฆะ SystemClock_Config (เป็นโมฆะ); โมฆะคงที่ MX_GPIO_Init (เป็นโมฆะ); โมฆะคงที่ MX_ADC1_Init (โมฆะ); โมฆะคงที่ MX_SPI1_Init (เป็นโมฆะ); โมฆะคงที่ MX_SPI2_Init (โมฆะ); โมฆะคงที่ MX_TIM3_Init (โมฆะ); โมฆะคงที่ MX_TIM4_Init (โมฆะ);

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); เป็นโมฆะ MAX7219_1_init(); เป็นโมฆะ MAX7219_2_init(); เป็นโมฆะ Erase_frame_buffer(เป็นโมฆะ); เป็นโมฆะ fill_frame_buffer(เป็นโมฆะ); เป็นโมฆะ display_frame_buffer(เป็นโมฆะ); เป็นโมฆะ set_timebase (เป็นโมฆะ);

uint8_t upper_display[4][8]; //vier ไบต์ naast elkaar, acht บน elkaar

uint8_t lower_display[4][8]; //deze twe Samen vormen เดอเฟรมบัฟเฟอร์

uint8_t sample_buffer[32]; //บัฟเฟอร์ voor de resultaten van de ADC

int หลัก (เป็นโมฆะ)

{ 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 ต้องการเวลาหลังจากเปิดเครื่อง

MAX7219_1_init(); MAX7219_2_init();

//LL_TIM_SetAutoReload(TIM3, 9);

ในขณะที่ (1)

{ set_timebase(); Erase_frame_buffer(); fill_frame_buffer(); display_frame_buffer(); } }

เป็นโมฆะ Erase_frame_buffer(เป็นโมฆะ)

{ int8_t x; int8_t y;

สำหรับ (x = 0; x < 4; x++) //kolom_bytes {

สำหรับ (y = 0; y <8; y++) //lijnen { upper_display[x][y] = 0; // alle bitjes op nul lower_display[x][y] = 0; } } }

เป็นโมฆะ fill_frame_buffer(เป็นโมฆะ)

{ uint8_t y = 0; //แรงดันไฟฟ้า uint8_t tijd = 0; //tijd uint8_t display_byte; // steeds 8 บิต naast elkaar en dat 4 maal op een lijn uint8_t display_bit;

สำหรับ (tijd = 0; tijd <32; tijd ++) { display_byte = tijd / 8; display_bit = 7 - (tijd % 8);

y = sample_buffer[tijd];

if (y > 7) // ในหน้าจอด้านบน schrijven

{ upper_display[display_byte][15-y] |= (1 << display_bit); } else // ในการแสดงผลด้านล่าง schrijven { lower_display[display_byte][7-y] |= (1 << display_bit); } } }

เป็นโมฆะ display_frame_buffer(เป็นโมฆะ)

{

uint8_t y; //acht lijnen boven elkaar (ต่อการแสดงผล) uint16_t yl; //lijnnummer สำหรับ MAX7219

สำหรับ (y = 0; y < 8; y++) { yl = (y+1) << 8; //MAX7219 ยกสูง lijnnummer ในด้านบน 8 บิตรถตู้ 16 บิต 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])); }

}

เป็นโมฆะ set_timebase (เป็นโมฆะ)

{ uint8_t timebase_knop;

timebase_knop = LL_TIM_GetCounter(TIM4) / 2;

สวิตช์ (timebase_knop)

{ กรณี 0: LL_TIM_SetAutoReload (TIM3, 1999); หยุดพัก; กรณีที่ 1: LL_TIM_SetAutoReload(TIM3, 999); หยุดพัก; กรณีที่ 2: LL_TIM_SetAutoReload(TIM3, 499); หยุดพัก; กรณีที่ 3: LL_TIM_SetAutoReload(TIM3, 199); หยุดพัก; กรณีที่ 4: LL_TIM_SetAutoReload (TIM3, 99); หยุดพัก; กรณีที่ 5: LL_TIM_SetAutoReload(TIM3, 49); หยุดพัก; กรณีที่ 6: LL_TIM_SetAutoReload(TIM3, 19); หยุดพัก; กรณีที่ 7: LL_TIM_SetAutoReload(TIM3, 9); หยุดพัก; กรณีที่ 8: LL_TIM_SetAutoReload(TIM3, 4); หยุดพัก; กรณีที่ 9: LL_TIM_SetAutoReload(TIM3, 1); หยุดพัก;

ค่าเริ่มต้น:

LL_TIM_SetAutoReload (TIM3, 99); หยุดพัก; } }

เป็นโมฆะ MAX7219_1_init()

{ SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //ปิดเมื่อ SPI1_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI1_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); // โหมดทดสอบปิด SPI1_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //ปิดเครื่อง, การทำงานปกติ SPI1_send64(0x0900, 0x0900, 0x0900, 0x0900); // ไม่มีการถอดรหัส 7seg, 64 พิกเซล SPI1_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); // ความเข้ม 50% SPI1_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); // แถวทั้งหมดบน }

เป็นโมฆะ MAX7219_2_init()

{ SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0C00, 0x0C00, 0x0C00, 0x0C00); //ปิดเมื่อ SPI2_send64(0x0000, 0x0000, 0x0000, 0x0000); //nop SPI2_send64(0x0F00, 0x0F00, 0x0F00, 0x0F00); // โหมดทดสอบปิด SPI2_send64(0x0C01, 0x0C01, 0x0C01, 0x0C01); //ปิดเครื่อง, การทำงานปกติ SPI2_send64(0x0900, 0x0900, 0x0900, 0x0900); // ไม่มีการถอดรหัส 7seg, 64 พิกเซล SPI2_send64(0x0A07, 0x0A07, 0x0A07, 0x0A07); // ความเข้ม 50% SPI2_send64(0x0B07, 0x0B07, 0x0B07, 0x0B07); // แถวทั้งหมดบน }

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);

ในขณะที่ (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}

LL_SPI_TransmitData16(SPI1, data2);

ในขณะที่ (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}

LL_SPI_TransmitData16(SPI1, data1);

ในขณะที่ (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}

LL_SPI_TransmitData16(SPI1, data0);

ในขณะที่ (LL_SPI_IsActiveFlag_BSY(SPI1) == 1) {}

LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4);

ส่งคืน 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);

ในขณะที่ (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}

LL_SPI_TransmitData16(SPI2, data2);

ในขณะที่ (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}

LL_SPI_TransmitData16(SPI2, data1);

ในขณะที่ (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}

LL_SPI_TransmitData16(SPI2, data0);

ในขณะที่ (LL_SPI_IsActiveFlag_BSY(SPI2) == 1) {}

LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12);

ส่งคืน LL_SPI_ReceiveData16(SPI2); }

เป็นโมฆะ ADC1_2_IRQHandler (เป็นโมฆะ)

{ คงที่ uint8_t sample_counter; uint8_t ทริกเกอร์; คงที่ uint8_t Previous_trigger;

ถ้า (LL_ADC_IsActiveFlag_EOS(ADC1) != RESET)

{ ถ้า (sample_counter < 32) { sample_buffer [sample_counter] = LL_ADC_REG_ReadConversionData32 (ADC1) / 256; ถ้า (sample_counter < 32) sample_counter++; อื่น sample_counter = 0; } อื่น ๆ { ทริกเกอร์ = LL_ADC_REG_ReadConversionData32 (ADC1) / 256;

if ((trigger == 7) && (previous_trigger < trigger)) //gaat niet helemaal goed bij blokgolven… { sample_counter = 0; } Previous_trigger = ทริกเกอร์; }

LL_GPIO_TogglePin(GPIOC, LL_GPIO_PIN_13);

LL_ADC_ClearFlag_EOS(ADC1);

} }

โมฆะคงที่ LL_Init (เป็นโมฆะ)

{ 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();

}

เป็นโมฆะ SystemClock_Config (เป็นโมฆะ)

{ LL_FLASH_SetLatency (LL_FLASH_LATENCY_2); if(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) Error_Handler(); LL_RCC_HSE_Enable(); ในขณะที่(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(); ในขณะที่(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); ในขณะที่ (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));

}

โมฆะคงที่ MX_ADC1_Init (เป็นโมฆะ)

{ 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. SequencesScanMode = 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);

}

โมฆะคงที่ MX_SPI1_Init (เป็นโมฆะ)

{ 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_BAAUDRATEPRESCALER_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); }

โมฆะคงที่ MX_SPI2_Init (เป็นโมฆะ)

{ 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_BAAUDRATEPRESCALER_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); }

โมฆะคงที่ MX_TIM3_Init (เป็นโมฆะ)

{ 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); }

โมฆะคงที่ MX_TIM4_Init (เป็นโมฆะ)

{ 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); }

โมฆะคงที่ MX_GPIO_Init (เป็นโมฆะ)

{ 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); }

เป็นโมฆะ _Error_Handler (ไฟล์ถ่าน *, int line)

{ ในขณะที่(1) { } }

#ifdef USE_FULL_ASSERT

เป็นโมฆะ assert_failed (ไฟล์ uint8_t*, บรรทัด uint32_t)

{ } #endif