Съдържание:
- Стъпка 1: Хардуер
- Стъпка 2: Изградете
- Стъпка 3: Програми
- Стъпка 4: За кода
- Стъпка 5: Main.h
- Стъпка 6: Main.c
Видео: Четири битов осцилоскоп: 6 стъпки
2024 Автор: John Day | [email protected]. Последно модифициран: 2024-01-30 07:53
Това е проект за забавление, само за да видя колко далеч в скорости мога да натисна MAX7219 матричен дисплей. И вместо да го накарам да играе „играта на живота“, реших да направя „обхват“с него. Както ще разберете от заглавието, това не е заместител на истински осцилоскоп:-).
Тъй като не смятам да използвам това по някакъв сериозен начин, няма да правя печатна платка за него. Може би, просто може би ще го сложа на перф дъска, но засега е и ще остане на дъска. Също така няма входен усилвател/атенюатор, трябва да подадете сигнал между 0 и 3.3V, не преминавайте отрицателно или над 3.3V, тъй като може да повредите микроконтролера.
Стъпка 1: Хардуер
Това е евтино, много евтино, когато купувате частите в Китай чрез ebay или подобни сайтове. Той използва дъска за разработка STM32F103C8, понякога наричана „синьо хапче“, която закупих за около 2 евро (или щатски долари, те са почти същата стойност, края на 2018 г.), два матрични дисплея 8x8x4 с чипове MAX7219, купени за 5 евро на парче и въртящ се енкодер около 1 евро.
Разбира се, е необходимо захранване, доставящо 3.3V при няколкостотин милиампера. Регулаторът на напрежението на платката за разработка STM32F103C8 не се използва, той не може да осигури достатъчно ток за дисплеите. Информационният лист за MAX7219 посочва, че работното захранващо напрежение трябва да бъде между 4.0 и 5.5V, но работи добре при 3.3V, може би не, когато го използвате в много гореща или студена среда, но при 20 градуса по Целзий е добре. И сега не трябва да използвам преобразуватели на нива между микроконтролера и дисплеите.
Стъпка 2: Изградете
Когато погледнете снимката, може да видите, че използвам захранващите линии на макетите по неконвенционален начин, и двете линии отгоре са положителната релса, а двете отдолу са наземната релса. Това е начинът, по който съм свикнал да го правя и работи добре, прави настройката да прилича малко повече на схемите, които рисувам. Също така направих много малки дъски с части, които мога да включа в макетната платка, за да ускоря нещата и всички те са конфигурирани да използват двете горни линии като положителни, а долните като земя. Както казах, разделителната способност е 4 битова (16 нива) и тъй като има 4x8 светодиоди един до друг, има само 32 точки за извадка (точки). Сравнете това с Rigol Rigol DS1054Z (8 бита и 12 Mpts) и ще видите, че това едва ли е играчка. Каква е действителната честотна лента, не знам, тествах я до 10kHz и това работи добре.
Стъпка 3: Програми
IDE, който използвам, е Atollic TrueStudio, който от началото на тази година (2018 г.) беше приет от ST Micro Electronics и е достъпен безплатно, без ограничение във времето, без ограничение за размер на кода, без екрани. Заедно с него използвам STM32CubeMX, програма, която ми доставя началния код и генерира инициализацията на всички периферни устройства. И има дисплей на всички пинове на микроконтролера и тяхното използване. Дори и да не използвате STM32CubeMX за генериране на код, това е много удобно. Едно нещо, което не ми харесва, е така нареченият HAL, който е по подразбиране на STM32CubeMX. Предпочитам метода на работа LowLayer.
За програмиране на микроконтролера използвам или програмист/дебъгер ST-Link от ST Micro Electronics или J-Link, произведен от Segger. И двете устройства не са безплатни, въпреки че можете да си купите китайски копия от тях за няколко евро.
Стъпка 4: За кода
MAX7219 адресира светодиодите по така наречения от мен хоризонтален начин, 8 светодиода един до друг. За осцилоскоп 8 светодиода един върху друг биха били по-лесни, затова направих прост рамков буфер, който се записва с данни по вертикален начин и се чете по необходимия хоризонтален начин. MAX7219 използва 16 -битов код на 8 светодиода, където първият байт се използва за адресиране на избрания ред. И тъй като има четири от тези модули, подредени един до друг, като техните входове са свързани към изходите на модула преди него, трябва да изпратите тези 16 бита четири пъти, за да стигнете до последния модул. (Надявам се да изясня нещата …) Данните се изпращат до MAX7219 с помощта на SPI, прост, но много бърз протокол. Това е, с което експериментирах, колко бързо можете да изпратите данните до MAX7219. В крайна сметка се върнах на 9 MHz точно под максималната скорост, посочена в листа с данни.
Използвам два от четирите налични таймера на STM32F103C8, единият за генериране на времевата база, а другият за отчитане на въртящия се енкодер, който задава времевата база. TIMER3 генерира времевата база, прави го чрез разделяне на часовника на 230, актуализиране на брояча на всеки 3,2 uS. Включете въртящия се енкодер, който можете да изберете да има брояч от 2 тактови импулса до 2000 тактови импулса. Да предположим, че избирате 100. След това TIMER3 генерира СЪБИТИЕ на всеки 320 uS. Това СЪБИТИЕ задейства ADC да записва проба от входния сигнал и тъй като са 32 проби, които трябва да се вземат за един екран, това ще приключи след приблизително. 10 mS. В 10 mS можете да поставите една дължина на вълната от 100 Hz или две от 200 Hz и т.н. Преминаването над 3 вълни на екран прави доста трудно разпознаването на формата на вълната.
За останалото мога да ви насоча само към кода, не е трудно да го следвате, дори ако имате само известен опит с Arduino. Всъщност можете да направите същото с Arduino, въпреки че се съмнявам, че ще работи толкова бързо, колкото „синьо хапче“. STM32F103C8 е 32 -битов микроконтролер, работещ на 72 MHz, има две SPI периферни устройства и много бърз ADC.
Стъпка 5: Main.h
#ifndef _MAIN_H _#дефинирайте _MAIN_H_
#include "stm32f1xx_ll_adc.h"
#include "stm32f1xx_llcxhllxxxxxxx" включва "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
# определят NVIC_PRIORITYGROUP_0 ((uint32_t) 0x00000007) # определят NVIC_PRIORITYGROUP_1 ((uint32_t) 0x00000006) # определят NVIC_PRIORITYGROUP_2 ((uint32_t) 0x00000005) # определят NVIC_PRIORITYGROUP_3 ((uint32_t) 0x00000004) # определят 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
Стъпка 6: Main.c
#include "main.h" static void LL_Init (void); void SystemClock_Config (void); статична празнота MX_GPIO_Init (невалидна); статична празнота MX_ADC1_Init (void); статична празнота MX_SPI1_Init (void); статична празнота MX_SPI2_Init (void); статична празнота MX_TIM3_Init (void); статична празнота MX_TIM4_Init (void);
uint16_t SPI1_send64 (uint16_t данни3, uint16_t данни2, uint16_t данни1, uint16_t данни0);
uint16_t SPI2_send64 (uint16_t data3, uint16_t data2, uint16_t data1, uint16_t data0); 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 горен_дисплей [4] [8]; // vier bytes naast elkaar, acht onder elkaar
uint8_t lower_display [4] [8]; // deze twee samen vormen de frame-buffer
uint8_t sample_buffer [32]; // буфер за резултатите от ADC
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 се нуждае от известно време след включване
MAX7219_1_init (); MAX7219_2_init ();
// LL_TIM_SetAutoReload (TIM3, 9);
докато (1)
{set_timebase (); erase_frame_buffer (); fill_frame_buffer (); display_frame_buffer (); }}
void erase_frame_buffer (void)
{int8_t x; int8_t y;
за (x = 0; x <4; x ++) // kolom_bytes {
for (y = 0; y <8; y ++) // lijnen {горен_дисплей [x] [y] = 0; // всички bitjes op nul lower_display [x] [y] = 0; }}}
void fill_frame_buffer (void)
{uint8_t y = 0; // напрежение uint8_t tijd = 0; // tijd uint8_t display_byte; // кончета 8 бита 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 = буфер за извадка [tijd];
if (y> 7) // в горния дисплей schrijven
{gor_display [display_byte] [15-y] | = (1 << display_bit); } else // в долния дисплей schrijven {lower_display [display_byte] [7-y] | = (1 << display_bit); }}}
void display_frame_buffer (void)
{
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])); }
}
void set_timebase (void)
{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); прекъсване; }}
void 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); // без 7сег декодиране, 64 пиксела SPI1_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // интензивност 50% SPI1_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // всички редове на}
void 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); // без 7сег декодиране, 64 пиксела SPI2_send64 (0x0A07, 0x0A07, 0x0A07, 0x0A07); // интензивност 50% SPI2_send64 (0x0B07, 0x0B07, 0x0B07, 0x0B07); // всички редове на}
uint16_t SPI1_send64 (uint16_t данни3, uint16_t данни2, uint16_t данни1, uint16_t данни0)
{LL_GPIO_ResetOutputPin (GPIOA, LL_GPIO_PIN_4);
LL_SPI_TransmitData16 (SPI1, data3);
докато (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 данни3, uint16_t данни2, uint16_t данни1, uint16_t данни0)
{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); }
void ADC1_2_IRQHandler (void)
{static uint8_t sample_counter; uint8_t спусък; статичен uint8_t предишен_тригер;
if (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 ++; 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; } предишен_тригер = спусък; }
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 ();
}
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));
}
статична празнота 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. 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_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); }
статична празнота 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. 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); }
void _Error_Handler (char *файл, ред int)
{while (1) {}}
#ifdef USE_FULL_ASSERT
void assert_failed (uint8_t* файл, uint32_t ред)
{} #endif
Препоръчано:
Arduino Nano-MMA8452Q 3-ос 12-битов/8-битов цифров акселерометър Урок: 4 стъпки
Arduino Nano-MMA8452Q 3-ос 12-битов/8-битов цифров акселерометър Урок: MMA8452Q е интелигентен, триосен, капацитивен, микромашинен акселерометър с 12 бита резолюция. Гъвкави програмируеми от потребителя опции се предлагат с помощта на вградени функции в акселерометъра, конфигурируеми за две прекъсвания
Raspberry Pi MMA8452Q 3-ос 12-битов/8-битов цифров акселерометър Python Урок: 4 стъпки
Raspberry Pi MMA8452Q 3-осен 12-битов/8-битов цифров акселерометър Python Урок: MMA8452Q е интелигентен, триосен, капацитивен, микромашинен акселерометър с 12 бита резолюция. Гъвкави програмируеми от потребителя опции се предлагат с помощта на вградени функции в акселерометъра, конфигурируеми за две прекъсвания
Програмиране на микро: битов робот и джойстик: битов контролер с MicroPython: 11 стъпки
Програмиране на микро: битов робот и джойстик: битов контролер с MicroPython: За Robocamp 2019, нашия летен лагер по роботика, млади хора на възраст 10-13 години запояват, програмират и изграждат BBC микро: битов базиран „робот с тегло“, както и програмиране микро: бит, който да използвате като дистанционно управление. Ако в момента сте в Robocamp, карайте ски
Raspberry Pi MMA8452Q 3-ос 12-битов/8-битов цифров акселерометър Java Урок: 4 стъпки
Raspberry Pi MMA8452Q 3-осен 12-битов/8-битов цифров акселерометър Java Урок: MMA8452Q е интелигентен, триосен, капацитивен, микромашинен акселерометър с ниска мощност с 12 бита резолюция. Гъвкави програмируеми от потребителя опции се предлагат с помощта на вградени функции в акселерометъра, конфигурируеми за две прекъсвания
Как да направите видео на разделен екран с четири стъпки: 4 стъпки (със снимки)
Как да направите видео на разделен екран с четири стъпки: Често виждаме едно и също лице да се показва в сцена два пъти в телевизионна пиеса. А доколкото знаем, актьорът няма брат близнак. Гледахме също, че два пеещи клипа се поставят на един екран, за да се сравнят техните певчески умения. Това е силата на spl