Πίνακας περιεχομένων:
- Βήμα 1: Υλικό
- Βήμα 2: Δημιουργία
- Βήμα 3: Προγράμματα
- Βήμα 4: Σχετικά με τον κώδικα
- Βήμα 5: Κύριο. H
- Βήμα 6: Κύριο.γ
Βίντεο: Παλαιογράφος τεσσάρων δυαδικών ψηφίων: 6 βήματα
2024 Συγγραφέας: John Day | [email protected]. Τελευταία τροποποίηση: 2024-01-30 08:36
Είναι ένα έργο διασκεδαστικό μόνο για να δούμε πόσο μακριά στις ταχύτητες θα μπορούσα να πιέσω μια οθόνη κουκκίδων MAX7219. Και αντί να το κάνω να τρέχει το «παιχνίδι της ζωής», αποφάσισα να κάνω ένα «πεδίο εφαρμογής» με αυτό. Όπως θα καταλάβετε από τον τίτλο, αυτό δεν αντικαθιστά ένα πραγματικό παλμογράφο:-).
Καθώς δεν σκοπεύω να το χρησιμοποιήσω με κανένα σοβαρό τρόπο, δεν θα φτιάξω μια πλακέτα τυπωμένου κυκλώματος γι 'αυτό. Maybeσως, απλώς ίσως το βάλω σε μια σανίδα, αλλά προς το παρόν είναι, και θα παραμείνει, σε ένα breadboard. Επίσης δεν υπάρχει ενισχυτής/εξασθενητής εισόδου, πρέπει να δώσετε ένα σήμα μεταξύ 0 και 3.3V, μην κάνετε αρνητικό ή πάνω από 3.3V, καθώς μπορεί να προκαλέσετε ζημιά στον μικροελεγκτή.
Βήμα 1: Υλικό
Είναι φθηνό, πολύ φθηνό όταν αγοράζετε ανταλλακτικά στην Κίνα μέσω ebay ή παρόμοιων ιστότοπων. Χρησιμοποιεί έναν πίνακα ανάπτυξης STM32F103C8, που μερικές φορές ονομάζεται "μπλε χάπι" που αγόρασα για περίπου 2 ευρώ (ή δολάρια ΗΠΑ, έχουν σχεδόν την ίδια αξία, τέλος 2018), δύο οθόνες 8x8x4 dot-matrix με τσιπ MAX7219, αγορασμένες για 5 ευρώ το τεμάχιο και ένας περιστροφικός κωδικοποιητής περίπου 1 ευρώ.
Απαιτείται φυσικά ένα τροφοδοτικό που αποδίδει 3.3V σε μερικές εκατοντάδες milliamps. Ο ρυθμιστής τάσης στον πίνακα ανάπτυξης STM32F103C8 δεν χρησιμοποιείται, δεν μπορεί να παρέχει αρκετό ρεύμα για τις οθόνες. Το φύλλο δεδομένων για το MAX7219 καθορίζει ότι η τάση τροφοδοσίας πρέπει να είναι μεταξύ 4,0 και 5,5V, αλλά λειτουργεί καλά στα 3,3V, ίσως όχι όταν το χρησιμοποιείτε σε πολύ ζεστό ή κρύο περιβάλλον, αλλά στους 20 βαθμούς Κελσίου είναι μια χαρά. Και τώρα δεν χρειάζεται να χρησιμοποιώ μετατροπείς επιπέδων μεταξύ του μικροελεγκτή και των πινάκων οθόνης.
Βήμα 2: Δημιουργία
Όταν κοιτάζετε την εικόνα, μπορείτε να δείτε ότι χρησιμοποιώ τα καλώδια τροφοδοσίας στους πίνακες ψωμιού με μη συμβατικό τρόπο, και οι δύο γραμμές στην κορυφή είναι η θετική ράγα και οι δύο στο κάτω μέρος είναι η ράγα εδάφους. Είναι ο τρόπος που το έχω συνηθίσει και λειτουργεί καλά, κάνει το setup να μοιάζει λίγο περισσότερο με τα σχήματα που σχεδιάζω. Επίσης, έχω φτιάξει πολλές μικρές σανίδες με τμήματα στα οποία μπορώ να συνδέσω στο breadboard για να επιταχύνω τα πράγματα και είναι όλα διαμορφωμένα ώστε να χρησιμοποιούν τις δύο κορυφαίες γραμμές ως θετικές και τις κάτω γραμμές ως έδαφος. Όπως είπα, η ανάλυση είναι 4 bit (16 επίπεδα) και καθώς υπάρχουν 4x8 led το ένα δίπλα στο άλλο, υπάρχουν μόνο 32 σημεία δειγματοληψίας (pts). Συγκρίνετε αυτό με ένα Rigol Rigol DS1054Z (8 bit και 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 απευθύνεται στα LED με αυτό που ονομάζω οριζόντια, με 8 led το ένα δίπλα στο άλλο. Για έναν παλμογράφο 8 τα LED που θα ήταν το ένα πάνω στο άλλο θα ήταν ευκολότερα, γι 'αυτό έφτιαξα ένα απλό πλαίσιο-buffer στο οποίο είναι γραμμένο με δεδομένα με κάθετο τρόπο και το διάβασα με τον απαιτούμενο οριζόντιο τρόπο. Το MAX7219 χρησιμοποιεί έναν κωδικό 16bit ανά 8 LED, όπου το πρώτο byte χρησιμοποιείται για την αντιμετώπιση της επιλεγμένης γραμμής. Και καθώς υπάρχουν τέσσερις από αυτές τις ενότητες στοιβαγμένες η μία δίπλα στην άλλη, με τις εισόδους τους συνδεδεμένες με τις εξόδους της μονάδας πριν από αυτήν, πρέπει να στείλετε αυτά τα 16bit τέσσερις φορές για να φτάσετε στην τελευταία μονάδα. (Ελπίζω να ξεκαθαρίζω τα πράγματα …) Τα δεδομένα αποστέλλονται στο MAX7219 χρησιμοποιώντας SPI, ένα απλό αλλά πολύ γρήγορο πρωτόκολλο. Αυτό πειραματιζόμουν, πόσο γρήγορα μπορείτε να αποστείλετε τα δεδομένα στο MAX7219. Στο τέλος, επέστρεψα πίσω στα 9 MHz ακριβώς κάτω από τη μέγιστη ταχύτητα που καθορίζει το φύλλο δεδομένων.
Χρησιμοποιώ δύο από τους τέσσερις διαθέσιμους χρονοδιακόπτες του STM32F103C8, έναν για τη δημιουργία της χρονικής βάσης και τον άλλο για την ανάγνωση του περιστροφικού κωδικοποιητή, ο οποίος καθορίζει τη χρονική βάση. Το TIMER3 δημιουργεί τη χρονική βάση, το κάνει διαιρώντας το ρολόι με 230, ενημερώνοντας τον μετρητή κάθε 3,2 uS. Μαγείρετε τον περιστροφικό κωδικοποιητή που μπορείτε να επιλέξετε για να έχετε τον μετρητή από 2 παλμούς ρολογιού έως 2000 παλμούς ρολογιού. Ας υποθέσουμε ότι επιλέξατε 100. Το TIMER3 δημιουργεί ένα συμβάν κάθε 320 uS. Αυτό το συμβάν ενεργοποιεί το ADC να καταγράψει ένα δείγμα του σήματος εισόδου και καθώς πρέπει να ληφθούν 32 δείγματα για μία οθόνη, αυτό θα ολοκληρωθεί μετά από περίπου. 10 mS Σε 10mS μπορείτε να χωρέσετε ένα μήκος κύματος 100 Hz, ή δύο από 200 Hz, και ούτω καθεξής. Η μετάβαση από 3 κύματα ανά οθόνη καθιστά μάλλον δύσκολη την αναγνώριση της κυματομορφής.
Για τα υπόλοιπα, μπορώ να σας παραπέμψω μόνο στον κώδικα, δεν είναι δύσκολο να το ακολουθήσετε ακόμη και αν έχετε μόνο κάποια εμπειρία με ένα Arduino. Στην πραγματικότητα, θα μπορούσατε να φτιάξετε το ίδιο πράγμα με ένα Arduino, αν και αμφιβάλλω ότι θα λειτουργούσε τόσο γρήγορα ένα "μπλε χάπι". Ο STM32F103C8 είναι ένας μικροελεγκτής 32bit που λειτουργεί στα 72 MHz, έχει δύο περιφερειακά SPI και πολύ γρήγορο ADC.
Βήμα 5: Κύριο. H
#ifndef _MAIN_H _#define _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 "stm32f1xx_ll_utils.h" #include "stm32f1xx_ll_pwr.h" # περιλαμβάνουν "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 _cplusplus
εξωτερικό "C" {#endif void _Error_Handler (char *, int);
#define Error_Handler () _Error_Handler (_ FILE_, _LINE_)
#ifdef _cplusplus} #endif
#τέλος εαν
Βήμα 6: Κύριο.γ
#include "main.h" static void LL_Init (void); void 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 (); void erase_frame_buffer (void)? void fill_frame_buffer (άκυρο)? void display_frame_buffer (void)? void set_timebase (void)?
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]; // buffer voor de resultaten van ADC
int main (άκυρο)
{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 (άκυρο)
{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; }}}
void fill_frame_buffer (άκυρο)
{uint8_t y = 0; // τάση uint8_t tijd = 0; // tijd uint8_t display_byte; // 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 - (tijd % 8);
y = sample_buffer [tijd];
εάν (y> 7) // στην επάνω οθόνη schrijven
{upper_display [display_byte] [15-y] | = (1 << display_bit); } else // στην κάτω οθόνη schrijven {lower_display [display_byte] [7-y] | = (1 << display_bit); }}}
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 bits van 16 bits woord
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 (άκυρο)
{uint8_t timebase_knop;
timebase_knop = LL_TIM_GetCounter (TIM4) / 2;
διακόπτης (timebase_knop)
{case 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); // testmode off SPI1_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01) // απενεργοποίηση, κανονική λειτουργία SPI1_send64 (0x0900, 0x0900, 0x0900, 0x0900). // χωρίς αποκωδικοποίηση 7seg, 64 pixel 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); // testmode off SPI2_send64 (0x0C01, 0x0C01, 0x0C01, 0x0C01) // απενεργοποίηση, κανονική λειτουργία SPI2_send64 (0x0900, 0x0900, 0x0900, 0x0900). // χωρίς αποκωδικοποίηση 7seg, 64 pixel 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 (άκυρο)
{static uint8_t sample_counter; σκανδάλη uint8_t; στατικό uint8_t previous_trigger;
εάν (LL_ADC_IsActiveFlag_EOS (ADC1)! = ΕΠΑΝΑΦΟΡΑ)
{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; } 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. 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. 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)
{ } #τέλος εαν
Συνιστάται:
Παλαιογράφος Arduino DIY 10Hz-50kHz σε οθόνη LCD 128x64: 3 βήματα
DIY 10Hz-50kHz Παλμογράφος Arduino σε οθόνη LCD 128x64: Αυτό το έργο περιγράφει έναν τρόπο κατασκευής ενός απλού παλμογράφου που έχει εύρος από 10Hz έως 50Khz. Αυτό είναι ένα εξαιρετικά μεγάλο εύρος, δεδομένου ότι η συσκευή δεν χρησιμοποιεί εξωτερικό τσιπ ψηφιακού σε αναλογικό μετατροπέα, αλλά μόνο Arduino
Σχεδιασμός ενός απλού τεσσάρων κατευθύνσεων συσχετιστικού ελεγκτή μνήμης cache σε VHDL: 4 βήματα
Σχεδιασμός ενός απλού τεσσάρων κατευθυντήριων συστημάτων ελεγκτή μνήμης προσωρινής μνήμης σε VHDL: Στο προηγούμενο διδάσκοντά μου, είδαμε πώς να σχεδιάσουμε έναν απλό ελεγκτή προσωρινής μνήμης απευθείας αντιστοιχισμένου. Αυτή τη φορά, προχωράμε ένα βήμα μπροστά. Θα σχεδιάσουμε ένα απλό τετράπλευρο σύνολο συσχετιστικού ελεγκτή προσωρινής μνήμης. Πλεονέκτημα; Λιγότερο ποσοστό χαμένων, αλλά με κόστος για
Ρολόι λέξεων τεσσάρων γραμμάτων με γεννήτρια λέξεων Akafugu και εμπνευσμένες φράσεις: 3 βήματα
Ρολόι λέξεων τεσσάρων γραμμάτων με γεννήτρια λέξεων Akafugu και εμπνευσμένες φράσεις: Αυτή είναι η δική μου έκδοση του ρολογιού με τέσσερα γράμματα, μια ιδέα που ξεκίνησε τη δεκαετία του 1970. Το ρολόι εμφανίζει μια σειρά λέξεων τεσσάρων γραμμάτων που παράγονται είτε από έναν αλγόριθμο τυχαίας δημιουργίας λέξεων είτε από μια βάση δεδομένων σχετικών τεσσάρων γραμμάτων
Το συνηθισμένο κιτ τηλεχειρισμού μετατράπηκε σε τηλεχειριστήριο τεσσάρων καναλιών RC Toy: 4 βήματα
Συνηθισμένο κιτ τηλεχειριστηρίου μετασχηματισμένο σε τετρακάναλο τηλεχειριστήριο RC Toy: 如何 将 通用 62 62 62 62 62 62 62 62 62 62 62改造 方法 非常 简单. 只需 准备 一些 瓦楞纸 板, 然后 按照 视频 教程 完成 这个 电子 项目 并 为 您 服务. 玩具 车船 提供 远程 无线 控制
Προγραμματιζόμενο ρολόι με οθόνη τεσσάρων χαρακτήρων: 5 βήματα (με εικόνες)
Προγραμματιζόμενο ρολόι με οθόνη τεσσάρων χαρακτήρων: Θα είστε ο λόγος της πόλης όταν φοράτε αυτό το αντιπαθητικό, υπερμεγέθη, εντελώς μη πρακτικό ρολόι χειρός. Προβάλετε την αγαπημένη σας βρώμικη γλώσσα, στίχους τραγουδιών, πρώτους αριθμούς κλπ. Εμπνευσμένο από το κιτ Microreader, αποφάσισα να φτιάξω ένα γιγάντιο ρολόι χρησιμοποιώντας