Любопытно: а есть мнение о том, откуда у профи время на выяснение, кто лучше наизусть 243-ю страницу даташита процитирует?
Добавлено after 52 seconds:
P.S. это другое?
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
насчет говнокода -- все дружно согласились. насчет того, что он делает -- далеко не все.Хотя сработать сразу и через счет TIM1 может быть важно.
Код: Выделить всё
/* ==== DMA Channel Registers ========= */
#define D11 (*DMA1_Channel1) /* DMA1 Channel 1 (0x40020008) */
#define D12 (*DMA1_Channel2) /* DMA1 Channel 2 (0x4002001C) */
#define D13 (*DMA1_Channel3) /* DMA1 Channel 3 (0x40020030) */
#define D14 (*DMA1_Channel4) /* DMA1 Channel 4 (0x40020044) */
#define D15 (*DMA1_Channel5) /* DMA1 Channel 5 (0x40020058) */
#define D16 (*DMA1_Channel6) /* DMA1 Channel 6 (0x4002006C) */
#define D17 (*DMA1_Channel7) /* DMA1 Channel 7 (0x40020080) */
/* ================== Analog/Digital Converters ========= */
#define A1 (*ADC1) /* ADC1 (0x40012400) */
#define A2 (*ADC2) /* ADC2 (0x40012800) */
#define A (*AFIO) /* Alternate Function I/O (0x40010000) */
/* ================== Core System Peripherals =========== */
#define B (*BKP) /* Backup Registers (0x40006C00) */
#define C (*CRC) /* CRC Calculation Unit (0x40023000) */
#define C1 (*CAN1) /* CAN1 Controller (0x40006400) */
#define D (*DBGMCU) /* Debug MCU (0xE0042000) */
#define E (*EXTI) /* External Interrupts (0x40010400) */
#define F (*FLASH) /* Flash Memory (0x40022000) */
/* === GPIO Port Registers ============ */
#define PA (*GPIOA) /* GPIO Port A (0x40010800) */
#define PB (*GPIOB) /* GPIO Port B (0x40010C00) */
#define PC (*GPIOC) /* GPIO Port C (0x40011000) */
#define PD (*GPIOD) /* GPIO Port D (0x40011400) */
/* =================== Communication Interfaces ========= */
#define I1 (*I2C1) /* I2C1 (0x40005400) */
#define I2 (*I2C2) /* I2C2 (0x40005800) */
#define I (*IWDG) /* Independent Watchdog (0x40003000) */
/* == Option Byte/Flash =============== */
#define O (*OB) /* Option Bytes (0x1FFFF800) */
/* ================= Power/RCC/RTC Management =========== */
#define P (*PWR) /* Power Control (0x40007000) */
#define R (*RCC) /* Reset & Clock Control (0x40021000) */
#define RT (*RTC) /* Real-Time Clock (0x40002800) */
/* == SPI Controllers ================= */
#define S1 (*SPI1) /* SPI1 (0x40013000) */
#define S2 (*SPI2) /* SPI2 (0x40003800) */
/* === Timer Modules ================== */
#define T1 (*TIM1) /* Timer 1 (0x40012C00) */
#define T2 (*TIM2) /* Timer 2 (0x40000000) */
#define T3 (*TIM3) /* Timer 3 (0x40000400) */
#define T4 (*TIM4) /* Timer 4 (0x40000800) */
/* == USB Controller ================== */
#define U (*USB) /* USB Device (0x40005C00) */
/* =================== USART Controllers ================ */
#define U1 (*USART1) /* USART1 (0x40013800) */
#define U2 (*USART2) /* USART2 (0x40004400) */
#define U3 (*USART3) /* USART3 (0x40004800) */
/* == Watchdog Timers ================= */
#define W (*WWDG) /* Window Watchdog (0x40002C00) */
Код: Выделить всё
if (PA.IDR & 1) {
T1.PSC = 7999;
T1.ARR = 999;
T1.CR1 = 1;
}Код: Выделить всё
T1.CR1 = (T1_CR1_t){.DIR=1, .OPM=1, .CEN=1}.r;
Код: Выделить всё
TIM1->CR1 = TIM_CR1_DIR | TIM_CR_OPM | TIM_CR1_CEN;
Код: Выделить всё
T1.CR1 = (T1_CR1_t){.DIR=1, .OPM=1, .CEN=1}.r;При работе через DMA я получу одно прерывание в конце пакета, вы- 8. При отправке мне нужно обработать 2 прерывания,вам- 8. Заметьте, что количество прерываний при работе через DMA не зависит от длины пакета. Я уже не говорю о том, что при работе через DMA нет разницы, на какой скорости работает работает UART, 9600 бит/с или 10 Мбит/с.ARV писал(а):пакеты в среднем 8 байт
Поэтому логично использовать С++, тогда весь код оказывается в одном модуле.ARV писал(а):все в разных модулях
Код: Выделить всё
// Заголовок
class UART_base : public AbstractTransport, protected IRQ
{
.......
//----------------------------------------------------------------------
// Читает в буфер buff размером buffSize байты из буфера приёмника.
// Работает в неблокирующем режиме!
// Возвращает количество прочитанных байт или ноль в случае
// отсутствия доступных для чтения данных.
virtual int16
receive
(
void* buff,
int16 buffSize,
MODE mode = NON_BLOCK
)
= 0;
//----------------------------------------------------------------------
// Записывает buffSize байт из буфера buff в буфера передатчика.
// Работает в неблокирующем режиме!
// Возвращает количество записанных байт или ноль в случае
// невозможности записи. lastError указывает на ошибку.
// Перед вызовом send(..) во избежании склеивания отправляемых
// посылок, необходимо вызывать getAvailableTxBytes(..) для проверки
// того, что буфер передатчика пуст.
virtual int16
send
(
void* buff,
int16 buffSize,
MODE mode = NON_BLOCK
)
= 0;
.......
};
//===============
// Реализация.
int16 MB_RTU_UART::send
(
void* _buff,
int16 _buffSize,
MODE _mode
)
{
....
}
int16 MB_RTU_UART::receive
(
void* _buff,
int16 _buffSize,
MODE _mode
)
{
....
}
void MB_RTU_UART::IRQ_Handler( void )
{
if( usart == 0 )
{
abort();
}
IRQn_Type
irq = IRQ::getActiveIRQn() ;
if( irq == IRQn_dma_tx )
{
// Обработка прерывания от потока ПДП передатчика.
....
}
else if( irq == usart_IRQn )
{
....
}
else
{
// Чушь какая-то. Поймали прерывание, на которое не подписывались.
// Занавес!
asm( "nop" );
abort();
}
}
Применительно к МК уровня STM32 как раз нетрадиционным способом является приём-отправка одного байта с генерацией прерывания. Да, это возможно, как и наличие по мнению целого ЕС аж 42 гендеров. С ростом тактовой частоты процессоров прерывания становятся очень дорогими в части потери производительности из-за сброса кэшей опережающей выборки. Поэтому весь обмен через UART логично делать с использованием DMA, даже консоль.ARV писал(а):Лучше бы рассказали, чем руководствоваться при выборе варианта работы USART через DMA или традиционно по прерываниям
Код: Выделить всё
class ConIO : public MB_RTU_UART, Task
{
};
сгущаете. чтобы пользоваться stm32, вовсе не обязательно долбиться куда попало.И как же вы STM32 пользуетесь? Который в этом самом ЕС и разработан?
jcxz писал(а):Написал один раз драйвер UART с DMA и далее пользуюсь им во всех проектах на STM32. Хоть с 921600 бод,
Код: Выделить всё
T1.CR1 = (T1_CR1_t){.DIR=1, .OPM=1, .CEN=1}.r;