
Բովանդակություն:
2025 Հեղինակ: John Day | [email protected]. Վերջին փոփոխված: 2025-01-23 14:48

Դա զվարճալի նախագիծ է պարզապես տեսնելու համար, թե որքան արագությամբ կարող եմ առաջ մղել MAX7219 կետային մատրիցային էկրան: Եվ այն «կյանքի խաղը» վարելու փոխարեն ես որոշեցի «շրջանակ» կազմել դրա հետ: Ինչպես կհասկանաք վերնագրից, սա իրական օսլիլոսկոպի փոխարինում չէ:-):
Քանի որ ես չեմ պատրաստվում օգտագործել դա որևէ լուրջ ձևով, ես դրա համար տպագիր տպատախտակ չեմ պատրաստի: Միգուցե, գուցե ես այն դնեմ ծայրամասային տախտակի վրա, բայց առայժմ այն, և կմնա, հացահատիկի վրա: Նաև մուտքային ուժեղացուցիչ/թուլացուցիչ չկա, դուք պետք է ազդանշան տաք 0 -ից 3.3 Վ -ի միջև, բացասական չգնաք կամ 3.3 Վ -ից բարձր, քանի որ կարող եք վնասել միկրոկոնտրոլերը:
Քայլ 1: Սարքավորումներ



Այն էժան է, շատ էժան, երբ մասերը գնում եք Չինաստանում ebay- ի կամ նմանատիպ կայքերի միջոցով: Այն օգտագործում է STM32F103C8 զարգացման տախտակ, որը երբեմն անվանում են «կապույտ դեղահատ», որը ես գնել եմ մոտ 2 եվրոյով (կամ ԱՄՆ դոլարով, դրանք գրեթե նույն արժեքն են, մինչև 2018 թ.), Երկու 8x8x4 կետային մատրիցային էկրան ՝ MAX7219 չիպերով, գնված 5 եվրո / հատ և պտտվող կոդավորիչ ՝ մոտ 1 եվրո:
Անշուշտ, անհրաժեշտ է 3.3 Վ էլեկտրամատակարարում `մի քանի հարյուր միլիամպ արագությամբ: STM32F103C8 զարգացման տախտակի վրա լարման կարգավորիչը չի օգտագործվում, այն չի կարող բավարար հոսանք ապահովել դիսփլեյների համար: MAX7219- ի տվյալների թերթը սահմանում է, որ մատակարարման լարումը պետք է լինի 4.0 -ից 5.5 Վ -ի միջև, բայց այն լավ է աշխատում 3.3 Վ -ով, գուցե ոչ այն դեպքում, երբ այն օգտագործում եք շատ տաք կամ սառը միջավայրում, բայց 20 Cելսիուս ջերմաստիճանում դա լավ է: Եվ հիմա ես կարիք չունեմ միկրոկառավարիչի և ցուցատախտակների միջև մակարդակի փոխարկիչներ օգտագործել:
Քայլ 2: Կառուցեք



Երբ նայում եք նկարին, կարող եք տեսնել, որ ես հացաթղթերի էլեկտրահաղորդման գծերը օգտագործում եմ ոչ սովորական եղանակով, վերևում երկու գծերն էլ դրական երկաթուղի են, իսկ երկուսը ՝ ներքևի, գետնային: Դա այնպիսին է, ինչպիսին ես սովոր էի դա անել, և այն լավ է աշխատում: Այն կարգավորումն ավելի նման է դարձնում իմ գծած սխեմաներին: Բացի այդ, ես պատրաստել եմ շատ փոքր տախտակներ, որոնց մասերը կարող եմ միացնել հացաթղթին `ամեն ինչ արագացնելու համար: Դրանք բոլորը կազմաձևված են, որպեսզի երկու վերին տողերը օգտագործեն որպես դրական, իսկ ստորին տողերը` որպես հիմք: Ինչպես ասացի, բանաձևը 4 բիթ է (16 մակարդակ), և քանի որ միմյանց կողքին կան 4x8 լուսարձակներ, կան ընդամենը 32 նմուշի միավոր (միավոր): Համեմատեք այն Rigol Rigol DS1054Z- ի հետ (8 բիթ և 12Mpts) և կտեսնեք, որ սա գրեթե խաղալիք չէ: Ինչ է իրական թողունակությունը, ես չգիտեմ, ես այն փորձարկել եմ մինչև 10 կՀց, և դա լավ է աշխատում:
Քայլ 3: րագրեր




IDE- ն, որն օգտագործում եմ, Atollic TrueStudio- ն է, որն այս տարվա սկզբի դրությամբ (2018) ընդունվել է ST Micro Electronics- ի կողմից և հասանելի է անվճար, առանց ժամկետի, առանց կոդի չափի սահմանափակման, առանց հուզիչ էկրանների: Դրա հետ միասին ես օգտագործում եմ STM32CubeMX, ծրագիր, որն ինձ մատակարարում է մեկնարկային ծածկագիրը և առաջացնում է բոլոր ծայրամասային սարքերի նախաստորագրում: Եվ այն ցուցադրում է միկրոկառավարիչի բոլոր կապումներն ու դրանց օգտագործումը: Նույնիսկ եթե դուք չեք օգտագործում STM32CubeMX ծածկագիրը ստեղծելու համար, սա շատ հարմար է: Մի բան, որն ինձ դուր չի գալիս, այսպես կոչված HAL- ն է, որը STM32CubeMX- ի կանխադրվածն է: Ես նախընտրում եմ աշխատանքի LowLayer մեթոդը:
Միկրոկառավարիչը ծրագրավորելու համար ես օգտագործում եմ ST-Link ծրագրավորող/վրիպազերծիչ ST Micro Electronics- ից կամ Սեգերի կողմից պատրաստված J-Link- ից: Այս երկու սարքերն անվճար չեն, չնայած դրանց չինական օրինակները կարող եք գնել մի քանի եվրոյով:
Քայլ 4: Օրենսգրքի մասին
MAX7219- ի հասցեագրված LED- ները, ինչպես ես անվանում եմ հորիզոնական, 8 լուսարձակներ միմյանց կողքին: Օսքիլոսկոպի համար 8 լուսադիոդները միմյանց վրա ավելի հեշտ կլիներ, այնպես որ ես պատրաստեցի մի պարզ շրջանակ-բուֆեր, որի վրա տվյալները գրված են ուղղահայաց և կարդացի անհրաժեշտ հորիզոնական եղանակով: MAX7219- ը օգտագործում է 16 բիթանոց կոդ յուրաքանչյուր 8 LED- ի համար, որտեղ առաջին բայթը օգտագործվում է ընտրված տողի հասցեագրման համար: Եվ քանի որ այս մոդուլներից չորսն իրար կողք են դրված, որոնց մուտքերը միացված են դրանից առաջ մոդուլի ելքերին, դուք պետք է չորս անգամ ուղարկեք այդ 16 բիթերը `վերջին մոդուլին հասնելու համար: (Հուսով եմ, որ ես պարզաբանում եմ բաները …) Տվյալները MAX7219 են ուղարկվում SPI- ի միջոցով ՝ պարզ, բայց շատ արագ արձանագրություն: Սա այն էր, ինչ ես փորձարկում էի, որքան արագ կարող եք տվյալները ուղարկել MAX7219- ին: Ի վերջո, ես վերադարձրեցի 9 ՄՀց հաճախականություն `տվյալների թերթիկի սահմանած առավելագույն արագությունից ցածր:
Ես օգտագործում եմ STM32F103C8- ի չորս հասանելի ժամանակաչափերից երկուսը ՝ մեկը ժամային բազայի ստեղծման համար, իսկ մյուսը ՝ պտտվող կոդավորիչը կարդալու համար, որը սահմանում է ժամային բազան: TIMER3- ը առաջացնում է ժամային բազա, դա անում է ՝ ժամացույցը բաժանելով 230 -ի, թարմացնելով հաշվիչը յուրաքանչյուր 3,2 uS- ով: Կախարդեք պտտվող կոդավորիչը, որը կարող եք ընտրել, որպեսզի հաշվիչն ունենա ժամացույցի 2 իմպուլսից մինչև 2000 ժամացույցի իմպուլս: Ենթադրենք, դուք ընտրում եք 100 -ը: TIMER3- ը այնուհետև յուրաքանչյուր 320 US- ի դեպքում ստեղծում է իրադարձություն: Այս ՄԻ EVՈԱՌՈԹՅՈՆԸ դրդում է ADC- ին գրանցել մուտքային ազդանշանի նմուշ, և քանի որ 32 նմուշ է պետք վերցնել մեկ էկրանի համար, այն կավարտվի մոտավորապես: 10 մՍ 10mS- ում կարող եք տեղավորել մեկ ալիքի երկարություն 100 Հց, կամ երկուսը 200 Հց և այլն: Մեկ էկրանի վրա 3 ալիք անցնելը բավականին դժվարացնում է ալիքի ձևի ճանաչումը:
Մնացածի համար ես կարող եմ ձեզ հղել միայն ծածկագրին, դժվար չէ հետևել, նույնիսկ եթե դուք ունեք որոշակի փորձ Arduino- ի հետ: Իրականում, դուք կարող եք նույնը պատրաստել Arduino- ով, չնայած ես կասկածում եմ, որ այն նույնքան արագ կաշխատի «կապույտ դեղահատ»: STM32F103C8- ը 32 բիթանոց միկրոկառավարիչ է, որն աշխատում է 72 ՄՀց հաճախականությամբ, ունի երկու SPI ծայրամասային սարքավորում և շատ արագ ADC:
Քայլ 5: Հիմնական: ժ
#ifndef _MAIN_H _#սահմանել _ MAIN_H_
#ներառել "stm32f1xx_ll_adc.h"
#ներառել "stm32f1xx_ll_rcc.h" #include "stm32f1xx_ll_bus.h" #Include "stm32f1xx_ll_system.h" #include "stm32f1xx_ll_exti.h" #include "stm32f1_xhx_xxxxx_xxx_x_x_xll_xxx_x_xll_xll_xxx_xll_xll_xll_xll_xll_xll_xll_xll_xll_xml_xhll_xhll_xll_xll_xll_xll_xll_xll_xll_32_scl_mel_xml_xml_xml_xml_xml_xml_xml_xml_xll_32_scl_mel_xml_xml_xml_xml_xml_xml_xml_32_1_x_xml_xl ներառել "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 _plusplus
արտաքին «C» {#endif void _Error_Handler (char *, int);
#սահմանել Error_Handler () _Error_Handler (_ FILE_, _LINE_)
#ifdef _cplusplus} #endif
#էնդիֆ
Քայլ 6. Հիմնական. Գ
#ներառել «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 (դատարկ); void display_frame_buffer (անվավեր); դատարկ set_timebase (անվավեր);
uint8_t վերին_էկրան [4] [8]; // vier bytes naast elkaar, acht onder elkaar
uint8_t ավելի ցածր_էկրան [4] [8]; // deze twee samen vormen de frame-buffer
uint8_t sample_buffer [32]; // բուֆերային արդյունքների և 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_Anable (SPI1);
LL_SPI_Anable (SPI2);
LL_TIM_EnableCounter (TIM3);
LL_TIM_EnableCounter (TIM4);
LL_ADC_Anable (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 {վերին_էկրան [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 ցուցադրման_բայթ; // steeds 8 bits 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 - (լրացնել % 8);
y = sample_buffer [tijd];
if (y> 7) // վերին ցուցադրման մեջ schrijven
{above_display [display_byte] [15-y] | = (1 << ցուցադրման_բիթ); } else // ստորին ցուցադրման ժամանակ schrijven {lower_display [display_byte] [7-y] | = (1 << ցուցադրման_բիթ); }}}
void display_frame_buffer (անվավեր)
{
uint8_t y; // acht lijnen boven elkaar (մեկ ցուցադրման համար) uint16_t yl; // lijnnummer voor de MAX7219
(y = 0; y <8; y ++) {yl = (y+1) << 8; // MAX7219 բազմակի թվով վերին 8 բիթանոց վան 16 բիթանոց բառի մեջ
SPI2_send64 ((yl | վերին_էկրան [0] [y]), (yl | վերին_էկրան [1] [y]), (yl | վերին_էկրան [2] [y]), (yl | վերին_էկրան [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); // ոչ SPI1_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // անջատում SPI1_send64- ում (0x0000, 0x0000, 0x0000, 0x0000); // ոչ SPI1_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testmode off 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); // ոչ SPI2_send64 (0x0C00, 0x0C00, 0x0C00, 0x0C00); // անջատում SPI2_send64 (0x0000, 0x0000, 0x0000, 0x0000) վրա; // ոչ SPI2_send64 (0x0F00, 0x0F00, 0x0F00, 0x0F00); // testmode off 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, տվյալներ 3);
իսկ (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, տվյալներ 2);
իսկ (LL_SPI_IsActiveFlag_TXE (SPI1) == 0) {}
LL_SPI_TransmitData16 (SPI1, տվյալներ 1);
իսկ (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, տվյալներ 3);
իսկ (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, data2);
իսկ (LL_SPI_IsActiveFlag_TXE (SPI2) == 0) {}
LL_SPI_TransmitData16 (SPI2, տվյալներ 1);
իսկ (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 (անվավեր)
{static uint8_t sample_counter; uint8_t ձգան; static uint8_t previous_trigger;
եթե (LL_ADC_IsActiveFlag_EOS (ADC1)! = Վերականգնել)
{if (sample_counter <32) {sample_buffer [sample_counter] = LL_ADC_REG_ReadConversionData32 (ADC1) / 256; եթե (sample_counter <32) sample_counter ++; հակառակ դեպքում 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; } 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); եթե (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_Anable (); իսկ (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. 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. DMAT Փոխանցում = 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_BAUDRATEPRESCALER_DIV8; SPI_InitStruct. BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct. CRCC հաշվարկ = 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_BAUDRATEPRESCALER_DIV4; SPI_InitStruct. BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct. CRCC հաշվարկ = 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); }
void _Error_Handler (char *ֆայլ, int տող)
{մինչ (1) {}}
#ifdef USE_FULL_ASSERT
void assert_failed (uint8_t* ֆայլ, uint32_t տող)
{} #endif
Խորհուրդ ենք տալիս:
Կրկնակի հետքի օսլիլոսկոպ. 11 քայլ (նկարներով)

Երկակի հետքի օսլիոսկոպ. Երբ ես կառուցում էի իմ նախորդ մինի օսլիոսկոպը, ես ուզում էի տեսնել, թե որքան լավ կարող եմ իմ ամենափոքր ARM միկրոկոնտրոլերը կատարել STM32F030 (F030), և դա լավ աշխատանք կատարեց: Մեկնաբանություններից մեկում առաջարկվել է, որ « Կապույտ դեղահատ " STM32F103- ով
DIY 10Hz-50kHz Arduino օսլիլոսկոպ 128x64 LCD էկրանով ՝ 3 քայլ

DIY 10Hz-50kHz Arduino օսլիլոսկոպ 128x64 LCD էկրանով. Այս նախագիծը նկարագրում է մի պարզ օսլիլոսկոպ պատրաստելու միջոց, որն ունի 10 Հց-ից մինչև 50 ԿՀց միջակայք: Սա չափազանց մեծ տեսականի է ՝ հաշվի առնելով, որ սարքը չի օգտագործում արտաքին թվայինից անալոգային փոխարկիչ չիպ, այլ միայն Arduino
Գրպանի ազդանշանային վիզուալիզատոր (գրպանի օսլիլոսկոպ). 10 քայլ (նկարներով)

Գրպանի ազդանշանային վիզուալիզատոր (գրպանի տատանում). Բարև բոլորին, մենք բոլորս շատ բաներ ենք անում ամեն օր: Յուրաքանչյուր աշխատանքի համար այնտեղ, որտեղ անհրաժեշտ են որոշ գործիքներ: Դա պատրաստելու, չափելու, ավարտելու և այլն: Այսպիսով, էլեկտրոնային աշխատողների համար նրանք պետք են գործիքներ, ինչպիսիք են զոդման երկաթը, բազմաչափը, տատանումները և այլն
Օսլիլոսկոպ երաժշտություն. 7 քայլ

Oscilloscope Music: Ներածություն. Այս հրահանգը պետք է կատարի Յուտայի պետական համալսարանի միկրոհամակարգչային միջերեսային նախագծի փաստաթղթերի մասի պահանջը
Ինչպես պատրաստել պարզ օսլիլոսկոպ Arduino- ի միջոցով. 3 քայլ

Ինչպես պատրաստել պարզ օսլիլոսկոպ Arduino- ի միջոցով. Այս հրահանգում դուք կտեսնեք, թե ինչպես պատրաստել պարզ տատանումներ Arduino uno- ի միջոցով: Օսկիլոսկոպը սարք է, որն օգտագործվում է ազդանշանները տեսնելու և վերլուծելու համար: Բայց սարքը շատ թանկ է: Որպես էլեկտրոնային տղա, երբեմն պետք է վերլուծել