برق و الکترونیک *دانلود پروژه رایگان
2.28K subscribers
784 photos
96 videos
350 files
641 links
بسمه تعالی
دانلود پروژه و پی سی بی رایگان
Download Telegram
- تفسیر:
- در زمان ۱۰۰µs خطا (اضافهجریان) تشخیص داده میشود.
- در ۱۰۰.۱µs (کمتر از ۱۰۰ns پس از خطا)، خروجی PWM قطع میشود.

---

### ۵. ویژگیهای پیشرفته Fault Protection
1. حالتهای بازیابی (Recovery Modes):
- خودکار (Automatic): پس از رفع خطا، PWM بهطور خودکار ادامه مییابد.
- دستی (Manual): نیاز به ریست نرمافزاری دارد.
   // تنظیم بازیابی خودکار
sFaultConfig.FaultAutoRecovery = HRTIM_AUTORECOVERY_ENABLE;
HAL_HRTIM_FaultConfig(&hhrtim, HRTIM_FAULTID_FAULT1, &sFaultConfig);


2. حالتهای ترکیبی (Combined Faults):
- امکان ترکیب چند خطا با استفاده از AND/OR.
   sFaultConfig.FaultCombination = HRTIM_FAULTCOMBINATION_OR; // خطا اگر Fault1 یا Fault2 فعال شود


3. غیرفعالسازی انتخابی خروجیها:
- میتوانید برخی خروجیها را در صورت خطا غیرفعال کنید و بقیه را فعال نگه دارید.

---

### ۶. مقایسه با سیستمهای نرمافزاری
| ویژگی | Fault Protection سختافزاری (HRTIM) | قطع نرمافزاری (با وقفه) |
|---------------------|-----------------------------------|------------------------|
| زمان پاسخ | <100 ns | >1 µs (با تأخیر وقفه) |
| مصرف CPU | صفر | نیازمند پردازش وقفه |
| قابلیت اطمینان | بسیار بالا (غیروابسته به کد) | وابسته به صحت کد |

---

### ۷. نکات نهایی
- تست سیستم: همیشه Fault Protection را با ایجاد خطای مصنوعی (مثل اتصال کوتاه آزمایشی) تست کنید.
- فیلتر نویز: از فیلتر دیجیتال HRTIM برای جلوگیری از قطعهای کاذب استفاده کنید.
- اولویتبندی خطاها: اگر چند خطا دارید، اولویت آنها را در رجیستر HRTIM_FLTCR1 تنظیم کنید.
قابلیت Synchronization در HRTIM میکروکنترلر STM32H743
این قابلیت امکان هماهنگسازی تایمرهای HRTIM با یکدیگر یا با رویدادهای خارجی (مثل تریگر ADC یا تایمرهای دیگر) را فراهم میکند. سنکرونسازی برای کاربردهایی مانند تولید PWMهای چندفاز همزمان، کنترل موتورهای دقیق، یا هماهنگی با ماژولهای دیگر حیاتی است. در زیر بهصورت کامل با مثالهای عملی توضیح میدهیم:

---

### ۱. اصول Synchronization در HRTIM
- هدف:
- شروع/توقف/ریست همزمان یا با تاخیر چند تایمر.
- ایجاد اختلاف فاز دقیق بین خروجیهای PWM.
- هماهنگی با رویدادهای خارجی (مثل تریگر ADC برای نمونهبرداری همزمان).

- انواع سنکرونسازی:
1. داخلی: هماهنگی بین تایمرهای HRTIM (مثلاً Timer A بهعنوان Master و Timer B بهعنوان Slave).
2. خارجی: استفاده از سیگنالهای خارجی (مثل پین GPIO یا تایمرهای دیگر).

---

### ۲. منابع سنکرونسازی (Trigger Sources)
HRTIM از منابع زیر برای سنکرونسازی پشتیبانی میکند:
- تریگرهای داخلی: خروجی رویدادهای تایمرهای HRTIM (مثلاً پایان دوره PWM).
- تریگرهای خارجی: پینهای GPIO یا ماژولهای دیگر (مثلاً TIM1, ADC).
- نرمافزاری: سنکرونسازی با دستور مستقیم CPU.

---

### ۳. مثال ۱: سنکرونسازی داخلی (Master-Slave)
سناریو:
- Timer A بهعنوان Master با فرکانس ۱ MHz تنظیم شود.
- Timer B بهعنوان Slave با تاخیر فاز ۲۵۰ ns نسبت به Timer A شروع به کار کند.

#### مراحل پیکربندی:
// ۱. پیکربندی Timer A (Master)
HRTIM_TimeBaseInitTypeDef hrtim_master;
hrtim_master.CounterMode = HRTIM_COUNTERMODE_UP;
hrtim_master.Period = 460; // فرکانس ۱ MHz (۴۶۰ + ۱) / ۴.۶ GHz ≈ ۱۰۰ ns × ۱۰ = ۱ µs
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &hrtim_master);

// ۲. پیکربندی Timer B (Slave)
HRTIM_TimeBaseInitTypeDef hrtim_slave;
hrtim_slave.CounterMode = HRTIM_COUNTERMODE_UP;
hrtim_slave.Period = 460; // همان فرکانس Master
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &hrtim_slave);

// ۳. تنظیم تاخیر فاز برای Timer B (۲۵۰ ns)
uint32_t phase_shift = 250e-9 / 0.184e-9 ≈ ۱۳۵۸; // محاسبه بر اساس رزولوشن ۱۸۴ پیکوثانیه
HAL_HRTIM_SetPhaseShift(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, phase_shift);

// ۴. تنظیم سنکرونسازی
// Timer B با رویداد "پایان دوره" Timer A سنکرون شود
HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B,
HRTIM_SYNCINPUT_MASTER_PERIOD, // منبع سنکرون = پایان دوره Master
HRTIM_SYNCOUTPUT_TIMER_A, // خروجی سنکرون از Timer A
HRTIM_SYNC_DELAY_NONE); // بدون تاخیر اضافی

// ۵. شروع تایمرها
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_B);


#### شکل موج خروجی:
زمان (ns)    : ۰    ۲۵۰    ۵۰۰    ۷۵۰    ۱۰۰۰  
|-----|-----|-----|-----|
خروجی Timer A : ██████████████████████████████
خروجی Timer B : ░░░░░█████████████████████████


---

### ۴. مثال ۲: سنکرونسازی با تریگر خارجی (External Trigger)
سناریو:
- شروع همزمان تمام تایمرهای HRTIM با دریافت یک پالس روی پین PE9.

#### مراحل پیکربندی:
// ۱. پیکربندی پین PE9 بهعنوان ورودی تریگر
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_HRTIM1; // PE9 به HRTIM متصل است
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

// ۲. تنظیم تایمرها برای سنکرونسازی با تریگر خارجی
for (int i = HRTIM_TIMERINDEX_TIMER_A; i <= HRTIM_TIMERINDEX_TIMER_F; i++) {
HAL_HRTIM_SynchronizationConfig(&hhrtim, i,
HRTIM_SYNCINPUT_EXTERNAL, // منبع سنکرون = تریگر خارجی
HRTIM_SYNCOUTPUT_DISABLED,
HRTIM_SYNC_DELAY_NONE);
}

// ۳. فعالسازی تریگر خارجی
HAL_HRTIM_ExternalTriggerConfig(&hhrtim, HRTIM_EXTTRIG_1,
HRTIM_EXTTRIGPOLARITY_RISING, // لبه بالارونده فعال شود
HRTIM_EXTTRIGSOURCESEL_GPIO); // منبع = پین GPIO

// ۴. شروع تایمرها با دریافت تریگر
HAL_HRTIM_WaveformCounterStart_IT(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);


---
### ۵. مثال ۳: سنکرونسازی با ADC برای نمونهبرداری همزمان
سناریو:
- هنگام میانه پالس PWM (۵۰٪ Duty Cycle)، ADC بهطور خودکار نمونهبرداری کند.

#### مراحل پیکربندی:
// ۱. پیکربندی Timer A برای PWM با Duty Cycle 50%
// ...

// ۲. تنظیم تریگر ADC توسط HRTIM
HAL_HRTIM_ADCTriggerConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_ADCTRIGGEREVENT_CMP1, // تریگر در لحظه Compare 1
HRTIM_ADCTRIGGER_1); // استفاده از تریگر ADC1

// ۳. پیکربندی ADC برای دریافت تریگر از HRTIM
ADC_HandleTypeDef hadc1;
hadc1.Instance = ADC1;
hadc1.Init.TriggerSource = ADC_EXTERNALTRIG_HRTIM_ADCTRG1; // تریگر از HRTIM
HAL_ADC_Init(&hadc1);


---

### ۶. حالتهای پیشرفته سنکرونسازی
1. زنجیره رویدادها (Event Chaining):
- پس از پایان یک تایمر، تایمر بعدی بهطور خودکار شروع شود.
   HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B,
HRTIM_SYNCINPUT_MASTER_PERIOD,
HRTIM_SYNCOUTPUT_TIMER_A,
HRTIM_SYNC_DELAY_NONE);


2. Reset Synchronization:
- ریست شدن یک تایمر باعث ریست تایمرهای دیگر شود.
   HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B,
HRTIM_SYNCINPUT_MASTER_RESET,
HRTIM_SYNCOUTPUT_TIMER_A,
HRTIM_SYNC_DELAY_NONE);


3. ترکیب چند سنکرونسازی:
- یک تایمر همزمان با دو منبع سنکرون (مثلاً داخلی و خارجی) کار کند.

---

### ۷. جدول مقایسه حالتهای سنکرونسازی
| حالت سنکرونسازی | توضیح | مثال کاربرد |
|-----------------------|----------------------------------------|----------------------------|
| شروع همزمان | همه تایمرها با یک تریگر شروع شوند | کنترل چندفاز موتور |
| تاخیر فاز | تایمرها با اختلاف فاز مشخص شروع شوند | Interleaved PWM |
| ریست زنجیرهای | ریست یک تایمر، بقیه را ریست کند | سیستمهای ایمنی |
| هماهنگی با ADC/DAC | تریگر نمونهبرداری در لحظات دقیق | حلقههای کنترل فیدبک |

---

### ۸. نکات مهم
- اولویتبندی سنکرونسازی: اگر چند منبع سنکرون فعال باشند، اولویت توسط رجیستر HRTIM_TIMCR تنظیم میشود.
- فیلتر تریگر: برای جلوگیری از سنکرونسازی ناخواسته، از فیلتر دیجیتال استفاده کنید.
- دیباگ: با استفاده از قابلیت Breakpoints در Debugger، زمانبندی سنکرونسازی را بررسی کنید.
### ۱. معرفی قابلیت Burst Mode
Burst Mode یا حالت پالسی گروهی یکی از ویژگیهای پیشرفته تایمر HRTIM است که امکان تولید دستههای پالس (Burst) با تعداد مشخص و فرکانس بالا را فراهم میکند. این قابلیت برای کاربردهای زیر ایدهآل است:
- سیستمهای روشنایی پالسی (Strobe Lighting).
- کنترل رادار و سیستمهای سونار.
- منابع تغذیه سوییچینگ با عملکرد متناوب.
- تست تجهیزات الکترونیکی با سیگنالهای پالسی دقیق.

---

### ۲. پارامترهای کلیدی در Burst Mode
برای استفاده از این حالت، سه پارامتر اصلی را تنظیم میکنید:
1. تعداد پالسها در هر دسته (Burst Count): مثلاً ۱۰ پالس.
2. فرکانس پالسها (Burst Frequency): مثلاً ۵۰ مگاهرتز.
3. زمان توقف بین دستهها (Idle Time): مثلاً ۱ میلیثانیه.

---

### ۳. تنظیمات سختافزاری و محاسبات
#### الف) فرکانس کلاک HRTIM
- حداکثر فرکانس کلاک HRTIM در STM32H7: ۴۶۰ مگاهرتز (با فعالسازی ضربکننده داخلی).
- رزولوشن زمانی: با استفاده از اینترپولاتور، هر کلاک به ۱۲ بخش تقسیم میشود و دقت به ۱۸۴ پیکوثانیه میرسد.

#### ب) فرمولهای محاسباتی
- دوره تناوب پالس (T_Pulse):
\[
T_{Pulse} = \frac{1}{\text{فرکانس پالس}}
\]
- مقدار Period رجیستر:
\[
\text{Period} = \left(\frac{T_{Pulse}}{T_{Clock}}\right) - 1 \quad,\quad T_{Clock} = \frac{1}{460 \times 10^6} \approx 2.17 \, \text{ns}
\]

---

### ۴. مثال عملی: تولید ۵ پالس با فرکانس ۵۰ مگاهرتز
#### هدف:
- تولید ۵ پالس با فرکانس ۵۰ مگاهرتز (دوره تناوب ۲۰ نانوثانیه).

#### محاسبات:
1. دوره تناوب پالس:
\[
T_{Pulse} = \frac{1}{50 \times 10^6} = 20 \, \text{ns}
\]
2. مقدار Period:
\[
\text{Period} = \frac{20 \, \text{ns}}{2.17 \, \text{ns}} - 1 \approx 8.21 \rightarrow \text{مقدار صحیح: ۸}
\]
3. دوره تناوب واقعی:
\[
T_{Real} = (8 + 1) \times 2.17 \, \text{ns} \approx 19.53 \, \text{ns} \, (~51.2 \, \text{مگاهرتز})
\]

---

### ۵. کدنویسی گامبهگام
#### الف) پیکربندی پایهها و کلاک
// فعالسازی کلاک HRTIM
__HAL_RCC_HRTIM1_CLK_ENABLE();

// پیکربندی پین خروجی PWM (مثلاً PA8)
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_HRTIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


#### ب) پیکربندی تایمر
HRTIM_HandleTypeDef hhrtim;
hhrtim.Instance = HRTIM1;

// پیکربندی Time Base
HRTIM_TimeBaseInitTypeDef hrtim_config;
hrtim_config.CounterMode = HRTIM_COUNTERMODE_UP; // شمارش افزایشی
hrtim_config.Period = 8; // مقدار Period = 8
hrtim_config.RepetitionCounter = 5; // تعداد پالسها = 5
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &hrtim_config);

// تنظیم Duty Cycle 50%
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, 4);

// فعالسازی خروجی PWM
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);


#### ج) فعالسازی Burst Mode
// تنظیم Burst Mode
HAL_HRTIM_WaveformBurstModeConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_BURSTMODE_MAINTAIN_OFF, // توقف پس از اتمام پالسها
HRTIM_BURSTREPETITIONMODE_FINITE); // تعداد محدود پالسها

// شروع تایمر
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);


---

### ۶. شکل موج خروجی
زمان (ns)     : 0     20     40     60     80     100  
|------|------|------|------|------|
خروجی PWM : ███░░█████░░█████░░█████░░█████░░
تعداد پالسها : 1 2 3 4 5


---

### ۷. حالتهای پیشرفته
#### الف) Burst نامتناهی (Infinite Burst)
HAL_HRTIM_WaveformBurstModeConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_BURSTMODE_MAINTAIN_OFF,
HRTIM_BURSTREPETITIONMODE_INFINITE);


#### ب) استفاده از DMA برای انتقال داده
uint32_t burst_count = 20;
HAL_HRTIM_WaveformCounterStart_DMA(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &burst_count, 1);
#### ج) هماهنگی با تریگر خارجی
HAL_HRTIM_ExternalTriggerConfig(&hhrtim, HRTIM_EXTTRIG_1,
HRTIM_EXTTRIGPOLARITY_RISING,
HRTIM_EXTTRIGSOURCESEL_GPIO);


---

### ۸. نکات پایانی
- حداکثر تعداد پالسها: ۶۵۵۳۵ (با رجیستر ۱۶ بیتی).
- خطای فرکانس: بهدلیل محدودیت کلاک، فرکانس واقعی ممکن است کمی با مقدار هدف متفاوت باشد.
- دیباگ: از وقفه HRTIM_TIM_IRQHandler برای تشخیص پایان هر Burst استفاده کنید.
آموزش کامل حالت Dead-Time Insertion در تایمر HRTIM میکروکنترلر STM32H7
*(با مثال عملی و محاسبات دقیق)*

---

### ۱. مفهوم Dead-Time Insertion
در کاربردهای پل-H (H-Bridge) یا نیمپل (Half-Bridge) برای جلوگیری از اتصال کوتاه بین ترانزیستورهای بالا و پایین، باید یک زمان مرده (Dead Time) بین خاموش شدن یک ترانزیستور و روشن شدن ترانزیستور مکمل ایجاد شود. این زمان برای جلوگیری از شوت-ترو (Shoot-Through) و آسیب به مدار حیاتی است.

---

### ۲. ویژگیهای Dead-Time Insertion در HRTIM
- پشتیبانی سختافزاری: زمان مرده بهصورت خودکار توسط تایمر اضافه میشود.
- تنظیم مستقل برای لبههای بالا و پایین:
- Rising Edge Delay: تاخیر بین خاموش شدن ترانزیستور پایین و روشن شدن ترانزیستور بالا.
- Falling Edge Delay: تاخیر بین خاموش شدن ترانزیستور بالا و روشن شدن ترانزیستور پایین.
- رزولوشن زمانی: تا ۱۸۴ پیکوثانیه (با استفاده از اینترپولاتور).

---

### ۳. مثال عملی: افزودن Dead Time برابر ۱۰۰ نانوثانیه
#### پارامترها:
- فرکانس کلاک HRTIM: ۴۶۰ مگاهرتز → \( T_{Clock} = \frac{1}{460 \times 10^6} \approx 2.17 \, \text{ns} \).
- Dead Time مورد نیاز: ۱۰۰ نانوثانیه.
- محاسبه مقدار رجیستر:
\[
\text{مقدار Dead Time} = \frac{100 \, \text{ns}}{2.17 \, \text{ns}} \approx 46 \quad (\text{مقدار صحیح: ۴۶})
\]

---

### ۴. کدنویسی گامبهگام
#### الف) پیکربندی پایههای خروجی مکمل (Complementary Outputs)
// پیکربندی پینهای خروجی PWM مکمل (مثلاً PA8 و PA9)
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_HRTIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


#### ب) تنظیم Dead Time برای تایمر A
// پیکربندی Dead Time (همان مقدار برای Rising و Falling)
HAL_HRTIM_DeadTimeConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
46, // Rising Edge Delay = 46 * 2.17 ns ≈ 100 ns
46); // Falling Edge Delay = 46 * 2.17 ns ≈ 100 ns

// فعالسازی خروجیهای مکمل
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);


#### ج) شروع تایمر
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);


---

### ۵. شکل موج خروجی
زمان (ns)     : ۰    ۵۰    ۱۰۰    ۱۵۰    ۲۰۰  
|-----|-----|-----|-----|
خروجی بالا : ██████████░░░░░░░░░░██████████
خروجی پایین : ░░░░░░░░░██████████░░░░░░░░░░
Dead Time : |----100ns----|


---

### ۶. تنظیمات پیشرفته
#### الف) Dead Time نامتقارن
// مثال: Rising Delay = 50 ns, Falling Delay = 150 ns
HAL_HRTIM_DeadTimeConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
23, // 50 ns / 2.17 ns ≈ 23
69); // 150 ns / 2.17 ns ≈ 69


#### ب) استفاده از اینترپولاتور برای دقت بالاتر
// فعالسازی اینترپولاتور برای Dead Time
HAL_HRTIM_DeadTimeInterpolatorConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_DEADTIMEINTERPOLATOR_ENABLE);


---

### ۷. نکات حیاتی
- حداقل Dead Time: به رزولوشن کلاک و اینترپولاتور بستگی دارد (حداقل ~۰.۱۸۴ نانوثانیه).
- تست عملی: همیشه با اسیلوسکوپ زمان مرده را اندازهگیری کنید.
- محافظت در برابر خطا: ترکیب Dead Time با سیستم Fault Protection برای ایمنی بیشتر.
آموزش کامل حالت ADC Synchronization در تایمر HRTIM میکروکنترلر STM32H7
*(با مثال عملی و محاسبات دقیق)*

---

### ۱. مفهوم ADC Synchronization
این قابلیت امکان هماهنگسازی زمان نمونهبرداری ADC با رویدادهای تایمر HRTIM (مثل نقطه میانی پالس PWM) را فراهم میکند. این هماهنگی برای کاربردهای زیر حیاتی است:
- کنترل حلقه بسته در منابع تغذیه سوییچینگ.
- نمونهبرداری همزمان از سیگنالهای آنالوگ در لحظات دقیق شکل موج.
- کاهش نویز و افزایش دقت اندازهگیری.

---

### ۲. مراحل پیکربندی ADC Synchronization
#### گام ۱: تنظیم تایمر HRTIM برای تولید تریگر
- ایجاد یک رویداد (مثلاً در نقطه میانی پالس PWM) بهعنوان تریگر ADC.
#### گام ۲: پیکربندی ADC برای دریافت تریگر از HRTIM
- انتخاب منبع تریگر مناسب در ADC.
#### گام ۳: فعالسازی DMA (اختیاری)
- انتقال خودکار دادههای نمونهبرداری شده به حافظه.

---

### ۳. مثال عملی: نمونهبرداری ADC در نقطه میانی پالس PWM
#### پارامترها:
- فرکانس PWM: ۱۰۰ کیلوهرتز → دوره تناوب \( T_{PWM} = 10 \, \mu s \).
- نقطه نمونهبرداری: ۵۰٪ Duty Cycle → \( 5 \, \mu s \).
- کلاک HRTIM: ۴۶۰ مگاهرتز → \( T_{Clock} = 2.17 \, \text{ns} \).

#### محاسبات:
- مقدار Period:
\[
\text{Period} = \frac{T_{PWM}}{T_{Clock}} - 1 = \frac{10 \, \mu s}{2.17 \, \text{ns}} - 1 \approx 4600 - 1 = 4599
\]
- مقدار Compare برای نقطه میانی:
\[
\text{Compare} = \frac{4599}{2} \approx 2300
\]

---

### ۴. کدنویسی گامبهگام
#### الف) پیکربندی HRTIM برای تولید تریگر
// پیکربندی تایمر A برای PWM
HRTIM_TimeBaseInitTypeDef hrtim_config;
hrtim_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtim_config.Period = 4599; // Period = 4600 کلاک → 10 µs
hrtim_config.RepetitionCounter = 0;
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &hrtim_config);

// تنظیم نقطه میانی (Compare Unit 1)
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, 2300);

// فعالسازی تریگر ADC در لحظه Compare Unit 1
HAL_HRTIM_ADCTriggerConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_ADCTRIGGEREVENT_CMP1, // تریگر در لحظه Compare 1
HRTIM_ADCTRIGGER_1); // استفاده از تریگر ADC1


#### ب) پیکربندی ADC
ADC_HandleTypeDef hadc1;
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_HRTIM_ADCTRG1; // تریگر از HRTIM
HAL_ADC_Init(&hadc1);

// کانال ADC را پیکربندی کنید (مثلاً Channel 0)
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);


#### ج) فعالسازی DMA (اختیاری)
// پیکربندی DMA برای انتقال داده
DMA_HandleTypeDef hdma_adc;
hdma_adc.Instance = DMA1_Stream0;
hdma_adc.Init.Request = DMA_REQUEST_ADC1;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc.Init.Mode = DMA_CIRCULAR;
HAL_DMA_Init(&hdma_adc);

// اتصال DMA به ADC
__HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc);

// شروع تبدیل ADC با DMA
uint32_t adc_buffer[100];
HAL_ADC_Start_DMA(&hadc1, adc_buffer, 100);


---

### ۵. شکل موج و زمانبندی
زمان (µs)     : ۰    ۵    ۱۰    ۱۵    ۲۰  
|-----|-----|-----|-----|
پالس PWM : █████████████████████░░░
تریگر ADC : ________█_______________
نمونهبرداری : ↑ (در ۵ µs)


---

### ۶. نکات حیاتی
- تأخیر تریگر: زمان بین تولید تریگر و شروع تبدیل ADC باید کمتر از زمان نمونهبرداری ADC باشد.
- هماهنگی فرکانسها: فرکانس کلاک ADC و HRTIM باید متناسب باشند تا از خطای نمونهبرداری جلوگیری شود.
- تست عملی: از اسیلوسکوپ برای مشاهده همزمان پالس PWM و تریگر ADC استفاده کنید.

---
### ۷. عیبیابی رایج
- عدم فعالسازی تریگر: مطمئن شوید تریگر ADC در HRTIM و ADC فعال شده است.
- تنظیمات نادرست DMA: اگر از DMA استفاده میکنید، حتماً پیکربندی آن را بررسی کنید.
- نویز الکتریکی: از فیلترهای آنالوگ و زمین مناسب برای سیگنال ADC استفاده کنید.
آموزش کامل پشتیبانی از ۶ تایمر مستقل (Timer A تا Timer F) در HRTIM میکروکنترلر STM32H7
*(با مثال عملی و تنظیمات دقیق)*

---

### ۱. معرفی تایمرهای مستقل HRTIM
ماژول HRTIM در STM32H7 شامل ۶ تایمر کاملاً مستقل به نامهای Timer A, B, C, D, E, F است. هر تایمر میتواند بهصورت مستقل یا هماهنگشده با دیگر تایمرها کار کند. این تایمرها برای کاربردهای زیر طراحی شدهاند:
- تولید PWMهای چندکاناله با فرکانس و فاز متفاوت.
- کنترل موتورهای چندفاز (BLDC, PMSM).
- منابع تغذیه سوییچینگ چندخروجی.

---

### ۲. ویژگیهای کلیدی هر تایمر
- کلاک مستقل: هر تایمر میتواند از کلاک داخلی یا خارجی استفاده کند.
- دو خروجی PWM با قابلیت مکمل (Complementary) و Dead-Time Insertion.
- ۴ رجیستر مقایسه (Compare Registers) برای تنظیم نقاط مختلف شکل موج.
- هماهنگسازی سختافزاری با دیگر تایمرها یا رویدادهای خارجی.
- سیستم محافظت خطا (Fault Protection) مستقل برای هر تایمر.

---

### ۳. مثال عملی: تنظیم دو تایمر مستقل (Timer A و Timer B)
#### هدف:
- Timer A: تولید PWM با فرکانس ۱۰۰ کیلوهرتز و Duty Cycle ۳۰٪.
- Timer B: تولید PWM با فرکانس ۵۰ کیلوهرتز و Duty Cycle ۶۰٪.

---

### ۴. مراحل پیکربندی
#### الف) پیکربندی پایههای خروجی
// پیکربندی پینهای خروجی PWM برای Timer A (PA8) و Timer B (PA9)
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_HRTIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


#### ب) پیکربندی Timer A
// پیکربندی Timer A برای فرکانس 100 kHz
HRTIM_TimeBaseInitTypeDef hrtimA_config;
hrtimA_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtimA_config.Period = 4599; // Period = 4600 کلاک → (4600 * 2.17 ns) ≈ 10 µs (100 kHz)
hrtimA_config.RepetitionCounter = 0;
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &hrtimA_config);

// تنظیم Duty Cycle 30% (Compare = 30% * Period)
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, 1380); // 4599 * 0.3 ≈ 1380

// فعالسازی خروجی PWM
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);


#### ج) پیکربندی Timer B
// پیکربندی Timer B برای فرکانس 50 kHz
HRTIM_TimeBaseInitTypeDef hrtimB_config;
hrtimB_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtimB_config.Period = 9199; // Period = 9200 کلاک → (9200 * 2.17 ns) ≈ 20 µs (50 kHz)
hrtimB_config.RepetitionCounter = 0;
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &hrtimB_config);

// تنظیم Duty Cycle 60% (Compare = 60% * Period)
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, 5520); // 9199 * 0.6 ≈ 5520

// فعالسازی خروجی PWM
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);


#### د) شروع تایمرها
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_B);


---

### ۵. شکل موج خروجی
زمان (µs)     : ۰    ۵    ۱۰    ۱۵    ۲۰    ۲۵    ۳۰  
|-----|-----|-----|-----|-----|-----|
خروجی Timer A : █████████████░░░░░░░░░░░░░░░░░░░░░░░ (100 kHz, 30%)
خروجی Timer B : ███████████████████████░░░░░░░░░░░░░ (50 kHz, 60%)


---

### ۶. کاربردهای پیشرفته ۶ تایمر مستقل
1. کنترل موتور سهفاز:
- استفاده از Timer A, B, C برای تولید سه PWM با اختلاف فاز ۱۲۰ درجه.
2. منبع تغذیه دوخروجی:
- تنظیم Timer D, E برای دو خروجی با فرکانس و Duty Cycle متفاوت.
3. هماهنگی با ADC/DAC:
- استفاده از Timer F برای تریگر نمونهبرداری همزمان ADC.

---

### ۷. نکات حیاتی
- استقلال تایمرها: هر تایمر میتواند کانالهای PWM، محافظت خطا و هماهنگی جداگانهای داشته باشد.
- مصرف حافظه: پیکربندی همزمان ۶ تایمر ممکن است به برنامهریزی دقیق حافظه نیاز داشته باشد.
- اشکالزدایی: از Breakpoints و Logic Analyzer برای بررسی همزمان خروجیها استفاده کنید.

---
### ۸. کد کامل برای ۳ تایمر (A, B, C)
// پیکربندی Timer C (بهعنوان مثال)
HRTIM_TimeBaseInitTypeDef hrtimC_config;
hrtimC_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtimC_config.Period = 2299; // فرکانس 200 kHz
hrtimC_config.RepetitionCounter = 0;
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_C, &hrtimC_config);
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_1, 1150); // Duty Cycle 50%
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_C,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_C);


---

جمعبندی:
با استفاده از ۶ تایمر مستقل HRTIM، میتوانید سیستمهای پیچیده صنعتی را با دقت زیر نانوثانیه کنترل کنید.
آموزش کامل Master Timer Control در تایمر HRTIM میکروکنترلر STM32H7
*(با مثال عملی و تنظیمات دقیق)*

---

### ۱. معرفی Master Timer در HRTIM
Master Timer یک تایمر مرکزی است که برای هماهنگسازی و کنترل تایمرهای دیگر (Timer A تا Timer F) استفاده میشود. این تایمر میتواند رویدادهایی مانند شروع/توقف، ریست، یا تولید تریگر برای سایر تایمرها و ماژولهای خارجی (مثل ADC) ایجاد کند.

---

### ۲. ویژگیهای کلیدی Master Timer
- هماهنگسازی تایمرها: شروع همزمان یا با تاخیر تایمرهای Slave.
- ایجاد تریگرهای داخلی/خارجی: برای ADC، DAC یا ماژولهای دیگر.
- تولید سیگنال مرجع: برای سنکرونسازی سیستمهای چندپردازندهای.
- حالتهای کاری:
- Continuous Mode: اجرای مداوم.
- One-Shot Mode: اجرای یکباره.

---

### ۳. مثال عملی: سنکرونسازی دو تایمر (A و B) با Master Timer
#### هدف:
- Master Timer با فرکانس ۱ مگاهرتز پیکربندی شود.
- Timer A و Timer B با تاخیر فاز ۲۵۰ نانوثانیه نسبت به Master شروع به کار کنند.

---

### ۴. مراحل پیکربندی
#### الف) پیکربندی Master Timer
// پیکربندی Master Timer با فرکانس 1 MHz
HRTIM_TimeBaseInitTypeDef hrtimMaster_config;
hrtimMaster_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtimMaster_config.Period = 459; // Period = 460 کلاک → (460 * 2.17 ns) ≈ 1 µs
hrtimMaster_config.RepetitionCounter = 0;
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_MASTER, &hrtimMaster_config);

// فعالسازی خروجی تریگر برای سنکرونسازی
HAL_HRTIM_MasterTimerSynchronizationConfig(&hhrtim, HRTIM_SYNC_MASTER, HRTIM_SYNCOUTPUT_ENABLE);


#### ب) پیکربندی Timer A (Slave)
// پیکربندی Timer A با تاخیر فاز 250 ns
HAL_HRTIM_SetPhaseShift(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, 115); // 250 ns / 2.17 ns ≈ 115

// سنکرونسازی Timer A با Master
HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_SYNCINPUT_MASTER_PERIOD, // منبع سنکرون = Master Timer
HRTIM_SYNCOUTPUT_MASTER,
HRTIM_SYNC_DELAY_NONE);


#### ج) پیکربندی Timer B (Slave)
// پیکربندی Timer B با تاخیر فاز 500 ns
HAL_HRTIM_SetPhaseShift(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, 230); // 500 ns / 2.17 ns ≈ 230

// سنکرونسازی Timer B با Master
HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B,
HRTIM_SYNCINPUT_MASTER_PERIOD,
HRTIM_SYNCOUTPUT_MASTER,
HRTIM_SYNC_DELAY_NONE);


#### د) شروع تایمرها
// شروع Master Timer
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_MASTER);

// شروع Timer A و B (بهصورت خودکار با تاخیر فاز)
HAL_HRTIM_TimerStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);
HAL_HRTIM_TimerStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_B);


---

### ۵. شکل موج خروجی
زمان (ns)     : ۰    ۲۵۰    ۵۰۰    ۷۵۰    ۱۰۰۰  
|-------|-------|-------|-------|
خروجی Master : ████████████████████████████████
خروجی Timer A : ░░░░░███████████████████████████ (تاخیر ۲۵۰ ns)
خروجی Timer B : ░░░░░░░░░███████████████████████ (تاخیر ۵۰۰ ns)


---

### ۶. کاربردهای پیشرفته Master Timer
1. تریگر ADC/DAC:
- Master Timer میتواند در هر نقطه از دوره تناوب، تریگر نمونهبرداری ADC را تولید کند.
   HAL_HRTIM_ADCTriggerConfig(&hhrtim, HRTIM_TIMERINDEX_MASTER,
HRTIM_ADCTRIGGEREVENT_PERIOD,
HRTIM_ADCTRIGGER_1);

2. حالت One-Shot:
- اجرای یک سیکل کاری و توقف خودکار.
   HAL_HRTIM_WaveformBurstModeConfig(&hhrtim, HRTIM_TIMERINDEX_MASTER,
HRTIM_BURSTMODE_MAINTAIN_OFF,
HRTIM_BURSTREPETITIONMODE_FINITE);

3. هماهنگی با تریگر خارجی:
- شروع Master Timer با دریافت سیگنال از GPIO.
   HAL_HRTIM_ExternalTriggerConfig(&hhrtim, HRTIM_EXTTRIG_1,
HRTIM_EXTTRIGPOLARITY_RISING,
HRTIM_EXTTRIGSOURCESEL_GPIO);


---
### ۷. نکات حیاتی
- اولویتبندی سنکرونسازی: اگر چند منبع سنکرون فعال باشند، اولویت در رجیستر HRTIM_MCR تنظیم میشود.
- خطای فاز: تاخیر فاز نباید از دوره تناوب Master Timer بیشتر شود.
- دیباگ: از وقفه HRTIM_MST_IRQHandler برای رصد وضعیت Master Timer استفاده کنید.

---

جمعبندی:
با استفاده از Master Timer در HRTIM، میتوانید سیستمهای چندتایمری پیچیده را با دقت زیر نانوثانیه مدیریت کنید. این مثالها را میتوانید برای پروژههای صنعتی مانند کنترل موتورهای پرقدرت یا منابع تغذیه پیشرفته بهکار ببرید! 🚀
آموزش کامل Dynamic Frequency Scaling (DFS) در تایمر HRTIM میکروکنترلر STM32H7
*(با مثال عملی و تنظیمات دقیق)*

---

### ۱. مفهوم Dynamic Frequency Scaling (DFS)
این قابلیت امکان تغییر فرکانس تایمر در حین اجرا (بدون توقف آن) را فراهم میکند. DFS برای کاربردهای زیر حیاتی است:
- صرفهجویی در مصرف انرژی با کاهش فرکانس در حالتهای کممصرف.
- بهبود عملکرد با افزایش فرکانس در شرایط نیاز به پردازش سریعتر.
- سازگاری با شرایط دینامیکی مانند تغییر سرعت موتور یا بار منابع تغذیه.

---

### ۲. ویژگیهای DFS در HRTIM
- تغییر فرکانس بلادرنگ: با بهروزرسانی رجیسترهای Period و Compare در حین کار تایمر.
- استفاده از Shadow Registers: اعمال تغییرات در پایان دوره تناوب فعلی برای جلوگیری از گلیچ.
- پشتیبانی از اینترپولاتور: حفظ دقت زمانی حتی در فرکانسهای پایین.

---

### ۳. مثال عملی: تغییر فرکانس PWM از ۱۰۰ kHz به ۵۰ kHz در حین اجرا
#### پارامترها:
- فرکانس اولیه: ۱۰۰ kHz → Period = 4599 (دوره تناوب ۱۰ µs).
- فرکانس جدید: ۵۰ kHz → Period = 9199 (دوره تناوب ۲۰ µs).
- Duty Cycle ثابت: ۳۰٪ → Compare = 30% × Period.

---

### ۴. مراحل پیکربندی
#### الف) پیکربندی اولیه تایمر
// پیکربندی Timer A با فرکانس 100 kHz
HRTIM_TimeBaseInitTypeDef hrtim_config;
hrtim_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtim_config.Period = 4599; // 10 µs
hrtim_config.RepetitionCounter = 0;
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &hrtim_config);

// تنظیم Duty Cycle 30%
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, 1380); // 4599 * 0.3 ≈ 1380

// فعالسازی خروجی PWM
HAL_HRTIM_WaveformOutputConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_OUTPUT_POLARITY_HIGH,
HRTIM_OUTPUT_IDLESTATE_INACTIVE);

// شروع تایمر
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);


#### ب) تغییر فرکانس در حین اجرا
// تغییر فرکانس به 50 kHz (دوره تناوب 20 µs)
uint32_t new_period = 9199;
uint32_t new_compare = new_period * 0.3; // 2759

// غیرفعالسازی پیشبارگذاری خودکار (برای اعمال تغییرات دستی)
HAL_HRTIM_WaveformAutoPreloadConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_AUTOPRELOAD_DISABLE);

// بهروزرسانی Period و Compare
HAL_HRTIM_WaveformPeriodConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, new_period);
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, new_compare);

// فعالسازی پیشبارگذاری و اعمال تغییرات در پایان دوره جاری
HAL_HRTIM_WaveformAutoPreloadConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_AUTOPRELOAD_ENABLE);


---

### ۵. شکل موج خروجی
زمان (µs)     : ۰    ۱۰    ۲۰    ۳۰    ۴۰    ۵۰  
|-----|-----|-----|-----|-----|
فرکانس 100 kHz : █████████████░░░░░░░░░░░░░░░░░
فرکانس 50 kHz : ███████████████████████░░░░░░░ (تغییر از ۲۰ µs)


---

### ۶. کاربردهای پیشرفته DFS
1. کنترل موتورهای پلهای:
- کاهش فرکانس در هنگام رسیدن به سرعت مطلوب.
2. منابع تغذیه سوییچینگ:
- افزایش فرکانس برای کاهش نویز EMI در بارهای سنگین.
3. سیستمهای روشنایی:
- تنظیم فرکانس PWM برای کاهش سوسوزدن LEDها.

---

### ۷. نکات حیاتی
- زمانبندی تغییر فرکانس: تغییرات باید در پایان دوره تناوب فعلی اعمال شوند تا از گلیچ جلوگیری شود.
- محدودیتهای سختافزاری:
- حداکثر فرکانس مجاز: ۴۶۰ مگاهرتز (با فعالسازی ضربکننده).
- حداقل فرکانس: به اندازه رجیستر ۱۶ بیتی Period بستگی دارد.
- استفاده از وقفهها:
  // فعالسازی وقفه پایان دوره تناوب
HAL_HRTIM_EnableInterrupt(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_IT_PERIOD);


---

### ۸. مثال با وقفه
// در تابع وقفه HRTIM
void HRTIM_TIM_IRQHandler(void) {
if (__HAL_HRTIM_GET_FLAG(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_FLAG_PERIOD)) {
// تغییر فرکانس در اینجا
__HAL_HRTIM_CLEAR_FLAG(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_FLAG_PERIOD);
}
}


---

جمعبندی:
با استفاده از DFS در HRTIM، میتوانید سیستمهای انعطافپذیر و بهینهشده انرژی طراحی کنید. این آموزش را برای پروژههای IoT، صنعتی و خودرویی بهکار ببرید! 🚀
آموزش کامل قابلیت Event Linking در تایمر HRTIM میکروکنترلر STM32H7
*(با مثال عملی و تنظیمات دقیق)*

---

### ۱. مفهوم Event Linking
این قابلیت امکان اتصال رویدادهای داخلی/خارجی به اقدامات خاص در تایمرهای HRTIM را فراهم میکند. بهعنوان مثال، میتوانید یک رویداد (مثل پایان دوره تناوب یک تایمر) را به شروع/توقف/ریست تایمر دیگر یا فعالسازی ADC/DAC پیوند دهید.

---

### ۲. کاربردهای کلیدی
- هماهنگی چند تایمر برای تولید سیگنالهای پلهای (مثل کنترل موتور سهفاز).
- ساخت زنجیره رویدادها برای سیستمهای چندمرحلهای.
- واکنش خودکار به خطاها یا شرایط خاص.

---

### ۳. مثال عملی: تولید سه PWM با اختلاف فاز ۱۲۰ درجه
#### هدف:
- Timer A پس از پایان دوره تناوب، Timer B را شروع کند.
- Timer B پس از پایان دوره تناوب، Timer C را شروع کند.

---

### ۴. مراحل پیکربندی
#### الف) پیکربندی تایمرها
// پیکربندی Timer A, B, C با فرکانس 100 kHz (Period = 4599)
HRTIM_TimeBaseInitTypeDef hrtim_config;
hrtim_config.CounterMode = HRTIM_COUNTERMODE_UP;
hrtim_config.Period = 4599; // دوره تناوب 10 µs
hrtim_config.RepetitionCounter = 0;

// پیکربندی Timer A
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &hrtim_config);

// پیکربندی Timer B با شیفت فاز 120 درجه (3.33 µs)
HAL_HRTIM_SetPhaseShift(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, 1538); // 3.33 µs / 2.17 ns ≈ 1538
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B, &hrtim_config);

// پیکربندی Timer C با شیفت فاز 240 درجه (6.66 µs)
HAL_HRTIM_SetPhaseShift(&hhrtim, HRTIM_TIMERINDEX_TIMER_C, 3076); // 6.66 µs / 2.17 ns ≈ 3076
HAL_HRTIM_TimeBaseConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_C, &hrtim_config);


#### ب) پیوند رویدادها (Event Linking)
// تنظیم Event Output برای Timer A (ارسال رویداد در پایان دوره تناوب)
HAL_HRTIM_EventConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_EVENTSOURCE_PERIOD, // منبع رویداد = پایان دوره تناوب
HRTIM_EVENT_OUTPUT_1); // خروجی رویداد به Event 1

// تنظیم Event Input برای Timer B (شروع با دریافت رویداد از Timer A)
HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_B,
HRTIM_SYNCINPUT_EVENT_1, // ورودی رویداد از Event 1
HRTIM_SYNCOUTPUT_DISABLED,
HRTIM_SYNC_DELAY_NONE);

// تنظیم Event Input برای Timer C (شروع با دریافت رویداد از Timer B)
HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_C,
HRTIM_SYNCINPUT_EVENT_2, // ورودی رویداد از Event 2
HRTIM_SYNCOUTPUT_DISABLED,
HRTIM_SYNC_DELAY_NONE);


#### ج) شروع تایمرها
// فقط Timer A را شروع کنید، بقیه بهصورت خودکار شروع میشوند
HAL_HRTIM_WaveformCounterStart(&hhrtim, HRTIM_TIMERINDEX_TIMER_A);


---

### ۵. شکل موج خروجی
زمان (µs)     : ۰    ۳.۳۳    ۶.۶۶    ۱۰    ۱۳.۳۳    
|-------|-------|-------|-------|
خروجی Timer A : ████████████████████████████████
خروجی Timer B : ░░░░░░░█████████████████████████
خروجی Timer C : ░░░░░░░░░░░░░███████████████████


---

### ۶. تنظیمات پیشرفته Event Linking
#### الف) استفاده از رویدادهای خارجی
// مثال: شروع Timer A با دریافت سیگنال از GPIO
HAL_HRTIM_ExternalTriggerConfig(&hhrtim, HRTIM_EXTTRIG_1,
HRTIM_EXTTRIGPOLARITY_RISING,
HRTIM_EXTTRIGSOURCESEL_GPIO);
HAL_HRTIM_SynchronizationConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A,
HRTIM_SYNCINPUT_EXTERNAL,
HRTIM_SYNCOUTPUT_DISABLED,
HRTIM_SYNC_DELAY_NONE);


#### ب) ترکیب Event Linking با محافظت خطا
// غیرفعالسازی Timer B در صورت خطا
HAL_HRTIM_FaultOutputConfig(&hhrtim, HRTIM_FAULTID_FAULT1,
HRTIM_OUTPUT_TB1,
HRTIM_FAULTOUTPUTACTION_FORCE_INACTIVE);


#### ج) ایجاد زنجیره رویداد با DMA
// انتقال داده به DMA پس از هر رویداد
HAL_HRTIM_WaveformCounterStart_DMA(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, &data, 1);


---
### ۷. نکات حیاتی
- اولویتبندی رویدادها: در صورت تداخل رویدادها، اولویت در رجیستر HRTIM_EECR1 تنظیم میشود.
- فیلتر نویز: برای جلوگیری از فعالسازی ناخواسته رویدادها، از فیلتر دیجیتال استفاده کنید.
- دیباگ: از وقفه HRTIM_TIM_IRQHandler برای رصد وضعیت رویدادها استفاده کنید.

---

جمعبندی:
با استفاده از Event Linking در HRTIM، میتوانید سیستمهای همزمانشده سختافزاری با حداقل دخالت CPU طراحی کنید. این آموزش را برای پروژههای صنعتی پیچیده مانند کنترل موتورهای پرقدرت یا منابع تغذیه چندفاز بهکار ببرید! 🚀
# آموزش کامل استفاده از ماکرو در برنامه‌نویسی STM32 با مثال‌های عملی

ماکروها (Macros) ابزارهای قدرتمندی در زبان C هستند که به توسعه‌دهندگان اجازه می‌دهند کدهای تکراری را ساده‌سازی کنند، خوانایی کد را افزایش دهند و مدیریت بهینه‌تری روی تنظیمات سخت‌افزاری داشته باشند. در این آموزش، نحوه استفاده از ماکروها در برنامه‌نویسی میکروکنترلرهای STM32 را با مثال‌های کاربردی بررسی می‌کنیم.

---

## فهرست مطالب
1. [ماکرو چیست؟](#۱-ماکرو-چیست؟)
2. [انواع ماکروها](#۲-انواع-ماکروها)
3. [استفاده از ماکرو در STM32](#۳-استفاده-از-ماکرو-در-stm32)
- [پیکربندی GPIO](#۳۱-پیکربندی-gpio)
- [مدیریت رجیسترها](#۳۲-مدیریت-رجیسترها)
- [وقفه‌ها (Interrupts)](#۳۳-وقفهها-interrupts)
4. [ماکروهای پیش‌پردازنده](#۴-ماکروهای-پیشپردازنده)
5. [نکات مهم](#۵-نکات-مهم)
6. [جمع‌بندی](#۶-جمعبندی)

---

## ۱. ماکرو چیست؟
ماکروها دستوراتی هستند که پیش از کامپایل توسط پیش‌پردازنده (Preprocessor) پردازش می‌شوند. آنها می‌توانند:
- مقادیر ثابت را تعریف کنند.
- بلوک‌های کد را جایگزین کنند.
- پارامترهای قابل تنظیم بپذیرند.

### مثال ساده:
#define PI 3.1415
#define MAX(a, b) ((a) > (b) ? (a) : (b))


---

## ۲. انواع ماکروها
- ماکروهای شیءگونه (Object-like):
تعریف مقادیر ثابت.
  #define LED_PIN GPIO_PIN_5


- ماکروهای تابع‌گونه (Function-like):
پذیرش پارامتر و جایگزینی کد.
  #define TOGGLE_LED(port, pin) HAL_GPIO_TogglePin(port, pin)


---

## ۳. استفاده از ماکرو در STM32
### ۳.۱ پیکربندی GPIO
ماکروها می‌توانند تنظیمات پورت‌ها را ساده‌سازی کنند.

#### مثال ۱: تعریف پین‌های LED
// تعریف پین‌ها
#define LED_GREEN_PIN GPIO_PIN_0
#define LED_GREEN_PORT GPIOA
#define LED_BLUE_PIN GPIO_PIN_7
#define LED_BLUE_PORT GPIOB

// ماکرو برای روشن/خاموش کردن LED
#define LED_ON(port, pin) HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET)
#define LED_OFF(port, pin) HAL_GPIO_WritePin(port, pin, GPIO_PIN_RESET)


#### مثال ۲: پیکربندی GPIO با ماکرو
// ماکرو برای پیکربندی پین به عنوان خروجی
#define GPIO_OUTPUT(port, pin, mode, speed) { \
GPIO_InitTypeDef gpio_config = {0}; \
gpio_config.Pin = pin; \
gpio_config.Mode = mode; \
gpio_config.Pull = GPIO_NOPULL; \
gpio_config.Speed = speed; \
HAL_GPIO_Init(port, &gpio_config); \
}

// استفاده:
GPIO_OUTPUT(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_MODE_OUTPUT_PP, GPIO_SPEED_FREQ_HIGH);


---

### ۳.۲ مدیریت رجیسترها
ماکروها برای دسترسی مستقیم به رجیسترهای سخت‌افزاری مفید هستند.

#### مثال: دسترسی به رجیستر GPIO
// تعریف آدرس رجیستر GPIOA
#define GPIOA_BASE 0x40020000
#define GPIOA_MODER *(volatile uint32_t*)(GPIOA_BASE + 0x00)

// ماکرو برای تنظیم پین به عنوان خروجی
#define SET_PIN_OUTPUT(port, pin) (port->MODER |= (0x1 << (2 * pin)))


---

### ۳.۳ وقفه‌ها (Interrupts)
ماکروها می‌توانند فعال‌سازی وقفه‌ها را ساده کنند.

#### مثال: فعال‌سازی وقفه خارجی
// ماکرو برای تنظیم وقفه روی لبه بالارونده
#define ENABLE_EXTI_IRQ(pin, line) { \
EXTI_ConfigTypeDef exti_config = {0}; \
exti_config.Line = line; \
exti_config.Mode = EXTI_MODE_INTERRUPT; \
exti_config.Trigger = EXTI_TRIGGER_RISING; \
exti_config.GPIOSel = GPIO_PORT_REG(pin); \
HAL_EXTI_SetConfigLine(&hexti, &exti_config); \
HAL_NVIC_SetPriority(EXTI_IRQn, 0, 0); \
HAL_NVIC_EnableIRQ(EXTI_IRQn); \
}


---

## ۴. ماکروهای پیش‌پردازنده
این ماکروها برای مدیریت شرایط کامپایل استفاده می‌شوند.

#### مثال ۱: فعال‌سازی قابلیت‌ها
#define USE_DEBUG_MODE 1

#if USE_DEBUG_MODE
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#endif


#### مثال ۲: پشتیبانی از چند پلتفرم
#ifdef STM32F4
#define SYSTEM_CLOCK 168000000 // 168 MHz
#elif defined(STM32F1)
#define SYSTEM_CLOCK 72000000 // 72 MHz
#endif


---

## ۵. نکات مهم
- پرانتزگذاری: همیشه پارامترها و عبارات را در پرانتز قرار دهید.
  //  اشتباه
#define MULTIPLY(a, b) a * b
// صحیح
#define MULTIPLY(a, b) ((a) * (b))
- اجتناب از عوارض جانبی:
از پارامترهایی که اثر جانبی دارند (مثل x++) در ماکروها خودداری کنید.

- ماکروهای چندخطی:
از \ برای شکستن خطوط استفاده کنید.
  #define INIT_ADC(hadc) {              \
hadc.Instance = ADC1; \
hadc.Init.Resolution = ADC_RESOLUTION_12B; \
HAL_ADC_Init(&hadc); \
}


---

## ۶. جمع‌بندی
ماکروها ابزارهای ضروری برای توسعه برنامه‌های کارآمد در STM32 هستند. با استفاده از آنها می‌توانید:
- خوانایی کد را افزایش دهید.
- از تکرار جلوگیری کنید.
- تنظیمات سخت‌افزاری را ساده‌سازی کنید.

با رعایت نکات ایمنی و استفاده هوشمندانه از ماکروها، کدهای شما تمیزتر و قابل نگهداری‌تر خواهند شد.
# آموزش پیشرفته استفاده از ماکروها در برنامه‌نویسی STM32 با مثال‌های پیچیده

ماکروها در برنامه‌نویسی سیستم‌های نهفته (Embedded) مانند STM32 نقشی حیاتی ایفا می‌کنند. در این آموزش پیشرفته، تکنیک‌های حرفه‌ای استفاده از ماکروها را با مثال‌های واقعی از دنیای STM32 بررسی می‌کنیم.

---

## ۱. ماکروهای پیشرفته برای مدیریت رجیسترها

### مثال ۱: دسترسی امن به بیت‌های رجیستر
// تعریف ماکرو برای دسترسی به بیت‌های خاص رجیستر
#define BIT_SET(reg, bit) ((reg) |= (1U << (bit)))
#define BIT_CLEAR(reg, bit) ((reg) &= ~(1U << (bit)))
#define BIT_TOGGLE(reg, bit) ((reg) ^= (1U << (bit)))
#define BIT_READ(reg, bit) (((reg) >> (bit)) & 1U)

// استفاده در تنظیمات GPIO
#define GPIOA_MODER (*((volatile uint32_t*)0x40020000))
#define LED_PIN 5

// تنظیم پین 5 پورت A به عنوان خروجی
BIT_CLEAR(GPIOA_MODER, (2 * LED_PIN)); // MODER0 = 00
BIT_SET(GPIOA_MODER, (2 * LED_PIN + 1)); // MODER1 = 01 (Output)


### مثال ۲: ماکروهای هوشمند برای پیکربندی Clock
// تعریف ماکرو برای محاسبه مقادیر PLL
#define PLL_CONFIGURATION(M, N, P, Q) \
(RCC_PLLCFGR_PLLM_##M | \
RCC_PLLCFGR_PLLN_##N | \
RCC_PLLCFGR_PLLP_##P | \
RCC_PLLCFGR_PLLQ_##Q)

// استفاده برای STM32F4 @ 168 MHz
RCC->PLLCFGR = PLL_CONFIGURATION(8, 336, 2, 7);


---

## ۲. ماکروهای پارامتری پیشرفته

### مثال ۳: ماکرو برای ایجاد توابع ISR پویا
// تعریف ماکرو برای تولید خودکار هندلرهای وقفه
#define CREATE_IRQ_HANDLER(irq_num, callback) \
void IRQHandler_##irq_num(void) { \
callback(); \
HAL_NVIC_ClearPendingIRQ(irq_num##_IRQn); \
} \
void Enable_##irq_num##_IRQ(uint8_t priority) { \
HAL_NVIC_SetPriority(irq_num##_IRQn, priority, 0); \
HAL_NVIC_EnableIRQ(irq_num##_IRQn); \
}

// استفاده
void Button_Pressed_Callback() {
// عملیات هنگام فشرده شدن دکمه
}

CREATE_IRQ_HANDLER(EXTI0, Button_Pressed_Callback)

// در main
Enable_EXTI0_IRQ(0);


---

## ۳. ماکروهای چندسطحی برای دیباگ پیشرفته

### مثال ۴: سیستم لاگینگ سلسله مراتبی
// سطوح دیباگ
#define LOG_LEVEL_NONE 0
#define LOG_LEVEL_ERROR 1
#define LOG_LEVEL_INFO 2
#define LOG_LEVEL_DEBUG 3

// تنظیم سطح فعلی
#define CURRENT_LOG_LEVEL LOG_LEVEL_DEBUG

// ماکروهای شرطی
#define LOG_ERROR(fmt, ...) \
if(CURRENT_LOG_LEVEL >= LOG_LEVEL_ERROR) \
printf("[ERROR] " fmt "\n", ##__VA_ARGS__)

#define LOG_INFO(fmt, ...) \
if(CURRENT_LOG_LEVEL >= LOG_LEVEL_INFO) \
printf("[INFO] " fmt "\n", ##__VA_ARGS__)

#define LOG_DEBUG(fmt, ...) \
if(CURRENT_LOG_LEVEL >= LOG_LEVEL_DEBUG) \
printf("[DEBUG] " fmt "\n", ##__VA_ARGS__)

// استفاده
LOG_DEBUG("ADC Value: %d, Temperature: %.2f", adc_val, temp);


---

## ۴. ماکروهای متا-برنامه‌نویسی برای HAL

### مثال ۵: تولید خودکار کد پیکربندی
// ماکرو برای تولید کد پیکربندی UART
#define CONFIGURE_UART(huart, baudrate, wordlen, parity, stopbits) \
do { \
huart.Instance = USART1; \
huart.Init.BaudRate = baudrate; \
huart.Init.WordLength = UART_WORDLENGTH_##wordlen##B; \
huart.Init.Parity = UART_PARITY_##parity; \
huart.Init.StopBits = UART_STOPBITS_##stopbits; \
huart.Init.Mode = UART_MODE_TX_RX; \
if (HAL_UART_Init(&huart) != HAL_OK) { \
Error_Handler(); \
} \
} while(0)

// استفاده
UART_HandleTypeDef huart1;
CONFIGURE_UART(huart1, 115200, 8, NONE, 1);


---

## ۵. ماکروهای پیشرفته برای مدیریت حافظه

### مثال ۶: سیستم تخصیص حافظه امن
// ماکرو برای تخصیص حافظه با بررسی خطا
#define SAFE_MALLOC(size, type) \
({ \
type *ptr = (type*)malloc(size * sizeof(type)); \
if(!ptr) { \
LOG_ERROR("Memory allocation failed at %s:%d", __FILE__, __LINE__); \
Error_Handler(); \
} \
memset(ptr, 0, size * sizeof(type)); \
ptr; \
})

// استفاده
int *sensor_data = SAFE_MALLOC(10, int);


---

## ۶. ماکروهای زمان کامپایل برای بهینه‌سازی
### مثال ۷: محاسبات ثابت در زمان کامپایل
// ماکرو برای محاسبه فرکانس PWM
#define PWM_FREQUENCY(sysclk, prescaler, period) \
((sysclk) / ((prescaler) * (period)))

// محاسبه در زمان کامپایل
const uint32_t required_freq = PWM_FREQUENCY(168000000, 84, 2000); // 1000 Hz

// استفاده در تنظیمات تایمر
TIM_HandleTypeDef htim;
htim.Instance = TIM1;
htim.Init.Prescaler = 84 - 1;
htim.Init.Period = 2000 - 1;
HAL_TIM_PWM_Init(&htim);


---

## ۷. ماکروهای پیشرفته برای کار با سخت‌افزار

### مثال ۸: سیستم مدیریت پین‌های چندگانه
// ماکرو برای کار با آرایه‌ای از پین‌ها
#define INIT_GPIO_BANK(port, pins, mode, speed) \
do { \
GPIO_InitTypeDef gpio_config = {0}; \
gpio_config.Pin = pins; \
gpio_config.Mode = mode; \
gpio_config.Pull = GPIO_NOPULL; \
gpio_config.Speed = speed; \
HAL_GPIO_Init(port, &gpio_config); \
} while(0)

// استفاده برای ۴ LED در پورت B
#define LED_PINS (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3)
INIT_GPIO_BANK(GPIOB, LED_PINS, GPIO_MODE_OUTPUT_PP, GPIO_SPEED_FREQ_HIGH);


---

## ۸. ماکروهای پیشرفته برای ارتباطات پروتکلی

### مثال ۹: رمزگشایی پروتکل سفارشی
// ماکرو برای استخراج فیلدها از یک فریم
#define EXTRACT_FIELD(frame, start_bit, mask) \
((frame >> start_bit) & mask)

// استفاده در پردازش داده
void Process_CAN_Frame(uint32_t frame) {
uint8_t sensor_id = EXTRACT_FIELD(frame, 0, 0xFF);
uint16_t value = EXTRACT_FIELD(frame, 8, 0xFFFF);
uint8_t status = EXTRACT_FIELD(frame, 24, 0x0F);

// پردازش داده‌ها
}


---

## نکات حرفه‌ای برای استفاده از ماکروها
1. توکن پاستینگ (Token Pasting):
   #define CREATE_VARIABLE(name, type) type var_##name
CREATE_VARIABLE(temp, float); // تولید: float var_temp;


2. استرینگفیکیشن (Stringification):
   #define DEBUG_VAR(var) printf(#var " = %d\n", var)
DEBUG_VAR(sensor_value); // چاپ: sensor_value = 25


3. ماکروهای بازگشتی:
   #define REPEAT_3_TIMES(action) \
do { action; action; action; } while(0)


4. ماکروهای نوع-امن (Type-Safe):
   #define MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})


---

## جمع‌بندی
با استفاده از این تکنیک‌های پیشرفته می‌توانید:
- کدهای STM32 را تا ۴۰% فشرده‌تر کنید
- خطاهای زمان اجرا را کاهش دهید
- قابلیت نگهداری کد را افزایش دهید
- وابستگی به کتابخانه‌های خارجی را کم کنید

همیشه به یاد داشته باشید:
- از ماکروها برای منطق ساده استفاده کنید
- تست واحد (Unit Testing) را جدی بگیرید
- مستندات ماکروها را به دقت بنویسید

این تکنیک‌ها مخصوصاً در پروژه‌های صنعتی با محدودیت منابع و نیاز به بهینه‌سازی بالا بسیار کاربردی هستند.
ITM (Instrumentation Trace Macrocell) چیست؟
ITM یک ماژول دیباگینگ پیشرفته در هستههای Cortex-M (مثل STM32) است که امکان ارسال دادههای دیباگ (مثل متغیرها، لاگها و ...) را بدون نیاز به پورت UART یا وقفه فراهم میکند. این ماژول از طریق پروتکل SWO (Serial Wire Output) با ابزارهای دیباگ (مثل ST-Link) ارتباط برقرار میکند.

---

### چرا ITM مفید است؟
1. سرعت بالا: نرخ انتقال داده تا چند مگابیت بر ثانیه (بستگی به فرکانس هسته دارد).
2. عدم مصرف منابع: نیاز به پورت اضافی یا وقفه ندارد.
3. یکپارچگی با IDE: در محیطهایی مثل STM32CubeIDE یا Keil، خروجی ITM را مستقیماً در پنجره Debug مشاهده میکنید.
4. همزمانی: میتوانید همزمان با اجرای کد، دادهها را مانیتور کنید.

---

### سختافزار مورد نیاز
- ST-Link/V2 (یا نسخههای بالاتر) با پین SWO (معمولاً پین شماره ۱۰ کانکتور ST-Link).
- اتصال صحیح پین SWO میکروکنترلر به ST-Link.

---

### توضیح مثال ارسال داده با ITM
کد مثال شما برای فعال‌سازی ITM و ارسال داده:
// فعال کردن Trace در هسته
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;

// باز کردن قفل دسترسی به رجیسترهای ITM (برای جلوگیری از دسترسی ناخواسته)
ITM->LAR = 0xC5ACCE55;

// پیکربندی TCR (Trace Control Register)
ITM->TCR = ITM_TCR_TraceBusID_Msk | // شناسه باس برای تفکیک دادهها
ITM_TCR_SWOENA_Msk | // فعال کردن خروجی SWO
ITM_TCR_SYNCENA_Msk | // فعال کردن سنکرونیزاسیون
ITM_TCR_ITMENA_Msk; // فعال کردن کل ماژول ITM

// تنظیم TPR (Trace Privilege Register) برای اجازه دسترسی به تمام پورتها
ITM->TPR = ITM_TPR_PRIVMASK_Msk;

// فعال کردن پورت ۰ ITM برای ارسال داده
ITM->TER |= 1 << 0;

// تابع ارسال رشته از طریق ITM
void ITM_SendString(char *str) {
while (*str) {
while (ITM->PORT[0].u32 == 0); // منتظر خالی شدن بافر
ITM->PORT[0].u8 = *str++;
}
}

---

### خط به خط توضیح کد
1. فعال‌سازی Trace در هسته:

   CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;


- رجیستر DEMCR (Debug Exception and Monitor Control Register) کنترل ماژولهای دیباگ را برعهده دارد.
- بیت TRCENA را ست میکنیم تا دسترسی به ماژولهای Trace (مثل ITM) فعال شود.

2. باز کردن قفل ITM:

   ITM->LAR = 0xC5ACCE55;


- رجیستر LAR (Lock Access Register) برای جلوگیری از تغییرات ناخواسته در تنظیمات ITM استفاده میشود.
- نوشتن مقدار 0xC5ACCE55 قفل ITM را باز میکند.

3. پیکربندی TCR (Trace Control Register):

   ITM->TCR = ... ;


- TraceBusID: شناسه باس برای تفکیک دادهها در صورت استفاده از چندین منبع.
- SWOENA: فعال کردن خروجی SWO.
- SYNCENA: اضافه کردن بایت سنکرون برای هماهنگی دادهها.
- ITMENA: فعال کردن کل ماژول ITM.

4. تنظیم TPR (Trace Privilege Register):

   ITM->TPR = ITM_TPR_PRIVMASK_Msk;


- این رجیستر سطح دسترسی (Privilege) برای پورتهای ITM را تعیین میکند.
- با تنظیم PRIVMASK، تمام پورتها در سطح کاربر (User Mode) قابل دسترسی میشوند.

5. فعال کردن پورت ۰ ITM:

   ITM->TER |= 1 << 0;


- رجیستر TER (Trace Enable Register) پورتهای ITM را فعال/غیرفعال میکند.
- پورت ۰ (معمولاً برای ارسال داده استفاده میشود) را فعال میکنیم.

6. تابع ارسال رشته:

   while (ITM->PORT[0].u32 == 0);


- منتظر میمانیم تا بافر پورت ۰ خالی شود (آماده ارسال داده جدید).
- داده را در رجیستر PORT[0] مینویسیم تا از طریق SWO ارسال شود.

---

### نحوه مشاهده خروجی ITM در STM32CubeIDE
1. پروژه را در حالت Debug باز کنید.
2. به مسیر Window > Show View > SWV > SWV ITM Data Console بروید.
3. در پنجره SWV ITM Data Console Settings، پورت ۰ را فعال کنید.
4. شروع به اجرای کد کنید. رشته ارسالی در پنجره SWV نمایش داده میشود.

---

### مقایسه ITM با UART
| ویژگی | ITM | UART |
|-------------------|------------------------------|-------------------------------|