Перейти к содержанию
    

Где настройка GPIO, где хоть какие-то барьеры между разрешением клоков и доступом к регистрам периферии, где нормальная обработка флагов DMA?

К тому же, корректная настройка будет в порядке DMA -> SPI -> GPIO, но не наоборот.

Выкладывайте минимальный проект, раз уж мистика происходит, плюс укажите проц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проц STM32f407IGT6

Поместил весь код, касающийся SPI3, DMA1 и нужных GPIO в одну функцию, вызываю её один раз перед основным циклом.

Проект большой, больше нигде ничего не трогается из этой периферии

void SPI3_Send()
{
    //DMA1 Stream 5 SPI3_TX channel 0
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    
    // GPIO
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
    
    // PC10 - SCK - Выход
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    // PC11 - MISO - Вход
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    // PC12 - MOSI - Выход
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
    uint8_t data[] = {1,2,3};
    uint8_t len = 3;
        
    DMA1_Stream5->CR = 0;
    
    DMA1_Stream5->PAR = (uint32_t)(&SPI3->DR);
    DMA1_Stream5->M0AR = (uint32_t)data;
    DMA1_Stream5->NDTR = len;
    DMA1_Stream5->FCR = 0;							// Настройка FIFO буфера
    
    DMA1_Stream5->CR = 
     (0x00) << DMA_SxCR_CHSEL_Pos       // Выбор канала
    |(0x00) << DMA_SxCR_MBURST_Pos      //
    |(0x00) << DMA_SxCR_PBURST_Pos      //
    |0      << DMA_SxCR_CT_Pos          // Текущий буфер
    |0      << DMA_SxCR_DBM_Pos         // Двойной буфер
    |(0x03) << DMA_SxCR_PL_Pos          // Приоритет
    |0      << DMA_SxCR_PINCOS_Pos      // Инкремент адреса периферии
    |(0x00) << DMA_SxCR_MSIZE_Pos       // Размер данных в памяти 8 бит
    |(0x00) << DMA_SxCR_PSIZE_Pos       // Размер данных в периферии 8 бит
    |1      << DMA_SxCR_MINC_Pos        // Инкремент адреса памяти
    |0      << DMA_SxCR_PINC_Pos        // Инкремент адреса периферии
    |0      << DMA_SxCR_CIRC_Pos        // Циркуляционный режим
    |(0x01) << DMA_SxCR_DIR_Pos         // Направление данных из памяти в периферию
    |0      << DMA_SxCR_PFCTRL_Pos      // DMA управляет процессом
    |0      << DMA_SxCR_TCIE_Pos        // Прерывание по окончанию передачи
    |0      << DMA_SxCR_HTIE_Pos        // Прерывание по половине передачи
    |0      << DMA_SxCR_TEIE_Pos        // Прерывание по ошибке передачи
    |0      << DMA_SxCR_DMEIE_Pos       // Прерывание по 
    |1      << DMA_SxCR_EN_Pos;         // Активация DMA
    
    SPI3->CR2 = 1<<SPI_CR2_TXDMAEN_Pos
    | 1<<SPI_CR2_SSOE_Pos;
   
    SPI3->CR1 = 0<<SPI_CR1_DFF_Pos  //Размер кадра 8 бит
    | 0<<SPI_CR1_LSBFIRST_Pos     //MSB first
    | 1<<SPI_CR1_SSM_Pos          //Программное управление SS
    | 1<<SPI_CR1_SSI_Pos          //SS в высоком состоянии
    | 0x04<<SPI_CR1_BR_Pos        //Скорость передачи: F_PCLK/32
    | 1<<SPI_CR1_MSTR_Pos         //Режим Master (ведущий)
    | 0<<SPI_CR1_CPOL_Pos | 0<<SPI_CR1_CPHA_Pos //Режим работы SPI: 0
    | 1<<SPI_CR1_SPE_Pos; //Включаем SPI
}

 

Нужно ли обработчик прерывания делать если оно у меня не используется?

Изменено пользователем Reystlin

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще замечу сразу, пока не забыл - локальные данные data[] делайте либо глобальными, либо удерживайте CPU от выхода из функции до окончания отправки (последнее - костыль).

Прерывания - не знаю, Вам виднее, нужны они Вам или нет. Лично я не совсем понимаю, зачем тогда Вам DMA без прерываний по нему.

Дальше. Что рапортуют статусные регистры DMA после включения потока? Чем контролируете "отправляется / не отправляется"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Spoiler
#include "gpio_one.h" /// https://github.com/AVI-crak/gpio_one

void SPI3_Init()
{
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

	gpio_one_pin(zap_gpio.C.pin10.v_af06_i2s3_ck_spi3_sck.speed4.lock_on);
    gpio_one_pin(zap_gpio.C.pin11.v_af06_spi3_miso.speed4.lock_on);
    gpio_one_pin(zap_gpio.C.pin12.v_af06_i2s3_sd_spi3_mosi.speed4.lock_on);
    gpio_one_pin(zap_gpio.A.pin15.v_af06_i2s3_ws_spi3_nss.speed4.lock_on);

    SPI3->CR1  = 0x0;
    SPI3->CR2 = SPI_CR2_SSOE |              //Вывод NSS - выход управления
                SPI_CR2_TXDMAEN;

    SPI3->CR1 = _VAL2FLD(SPI_CR1_BR, 2)|    // Baud rate control /8
                SPI_CR1_MSTR |              // Режим Master
                SPI_CR1_BIDIMODE |          // 1 линия
                SPI_CR1_BIDIOE  |           // только передача
                SPI_CR1_SPE;                // вкл
};


void SPI3_Send(volatile uint8_t *data, uint16_t len)
{
	DMA1->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0);
    DMA1_Stream5->CR = 0;
    DMA1_Stream5->FCR = 0;
    DMA1_Stream5->NDTR = len;
    DMA1_Stream5->M0AR = (uint32_t)data;
    DMA1_Stream5->PAR = (uint32_t)(&SPI3->DR);
    DMA2_Stream5->CR =
		_VAL2FLD(DMA_SxCR_CHSEL, 0)|	/// channe - tmigger
        _VAL2FLD(DMA_SxCR_DIR, 1)|		/// memory_to_peripheral
        _VAL2FLD(DMA_SxCR_MBURST, 1)|	/// incremental_burst_of_4_beats
        DMA_SxCR_MINC|					/// memory increment mode
        DMA_SxCR_EN;
    while(!(DMA1->LISR & DMA_LISR_TCIF0 ));
	while((SPI3->SR & (SPI_SR_BSY | SPI_SR_TXE)) != SPI_SR_TXE);
};

 

 

Изменено пользователем AVI-crak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Флаги Transfer error и FIFO error устанавливаются после запуска DMA

Я пытаюсь сейчас в простом виде запустить SPI+DMA чтобы что-нибудь выдало а дальше буду накручивать функционал т.к. не понятно чего оно не работает

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 часа назад, AVI-crak сказал:
  Скрыть контент
#include "gpio_one.h" /// https://github.com/AVI-crak/gpio_one

void SPI3_Init()
{
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

	gpio_one_pin(zap_gpio.C.pin10.v_af06_i2s3_ck_spi3_sck.speed4.lock_on);
    gpio_one_pin(zap_gpio.C.pin11.v_af06_spi3_miso.speed4.lock_on);
    gpio_one_pin(zap_gpio.C.pin12.v_af06_i2s3_sd_spi3_mosi.speed4.lock_on);
    gpio_one_pin(zap_gpio.A.pin15.v_af06_i2s3_ws_spi3_nss.speed4.lock_on);

    SPI3->CR1  = 0x0;
    SPI3->CR2 = SPI_CR2_SSOE |              //Вывод NSS - выход управления
                SPI_CR2_TXDMAEN;

    SPI3->CR1 = _VAL2FLD(SPI_CR1_BR, 2)|    // Baud rate control /8
                SPI_CR1_MSTR |              // Режим Master
                SPI_CR1_BIDIMODE |          // 1 линия
                SPI_CR1_BIDIOE  |           // только передача
                SPI_CR1_SPE;                // вкл
};


void SPI3_Send(volatile uint8_t *data, uint16_t len)
{
	DMA1->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0);
    DMA1_Stream5->CR = 0;
    DMA1_Stream5->FCR = 0;
    DMA1_Stream5->NDTR = len;
    DMA1_Stream5->M0AR = (uint32_t)data;
    DMA1_Stream5->PAR = (uint32_t)(&SPI3->DR);
    DMA2_Stream5->CR =
		_VAL2FLD(DMA_SxCR_CHSEL, 0)|	/// channe - tmigger
        _VAL2FLD(DMA_SxCR_DIR, 1)|		/// memory_to_peripheral
        _VAL2FLD(DMA_SxCR_MBURST, 1)|	/// incremental_burst_of_4_beats
        DMA_SxCR_MINC|					/// memory increment mode
        DMA_SxCR_EN;
    while(!(DMA1->LISR & DMA_LISR_TCIF0 ));
	while((SPI3->SR & (SPI_SR_BSY | SPI_SR_TXE)) != SPI_SR_TXE);
};

 

DMA2_Stream5->CR  заменил на DMA1_Stream5->CR

так-же у DMA1->HISR TEIF5 и FEIF5 = 1

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извиняюсь, f407 нету, проверить не смог. Но IDE весело собирает код без ошибок. Исправил.

Spoiler
void SPI3_Send(volatile uint8_t *data, uint16_t len)
{
    DMA1->HIFCR = (DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5);
    DMA1_Stream5->CR = 0;
    DMA1_Stream5->NDTR = len;
    DMA1_Stream5->M0AR = (uint32_t)data;
    DMA1_Stream5->PAR = (uint32_t)(&SPI3->DR);
    DMA1_Stream5->CR =
        _VAL2FLD(DMA_SxCR_CHSEL, 0)|    /// channe - tmigger
        _VAL2FLD(DMA_SxCR_DIR, 1)|      /// memory_to_peripheral
        DMA_SxCR_MINC|                  /// memory increment mode
        DMA_SxCR_EN;
    while(!(DMA1->HISR & DMA_HISR_TCIF5 ));
    while((SPI3->SR & (SPI_SR_BSY | SPI_SR_TXE)) != SPI_SR_TXE);
};

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 30.10.2022 в 22:14, Reystlin сказал:

Проц STM32f407IGT6

Поместил весь код, касающийся SPI3, DMA1 и нужных GPIO в одну функцию, вызываю её один раз перед основным циклом.

Проект большой, больше нигде ничего не трогается из этой периферии

Спойлер
void SPI3_Send()
{
    //DMA1 Stream 5 SPI3_TX channel 0
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    
    // GPIO
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
    
    // PC10 - SCK - Выход
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    // PC11 - MISO - Вход
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    // PC12 - MOSI - Выход
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
    uint8_t data[] = {1,2,3};
    uint8_t len = 3;
        
    DMA1_Stream5->CR = 0;
    
    DMA1_Stream5->PAR = (uint32_t)(&SPI3->DR);
    DMA1_Stream5->M0AR = (uint32_t)data;
    DMA1_Stream5->NDTR = len;
    DMA1_Stream5->FCR = 0;							// Настройка FIFO буфера
    
    DMA1_Stream5->CR = 
     (0x00) << DMA_SxCR_CHSEL_Pos       // Выбор канала
    |(0x00) << DMA_SxCR_MBURST_Pos      //
    |(0x00) << DMA_SxCR_PBURST_Pos      //
    |0      << DMA_SxCR_CT_Pos          // Текущий буфер
    |0      << DMA_SxCR_DBM_Pos         // Двойной буфер
    |(0x03) << DMA_SxCR_PL_Pos          // Приоритет
    |0      << DMA_SxCR_PINCOS_Pos      // Инкремент адреса периферии
    |(0x00) << DMA_SxCR_MSIZE_Pos       // Размер данных в памяти 8 бит
    |(0x00) << DMA_SxCR_PSIZE_Pos       // Размер данных в периферии 8 бит
    |1      << DMA_SxCR_MINC_Pos        // Инкремент адреса памяти
    |0      << DMA_SxCR_PINC_Pos        // Инкремент адреса периферии
    |0      << DMA_SxCR_CIRC_Pos        // Циркуляционный режим
    |(0x01) << DMA_SxCR_DIR_Pos         // Направление данных из памяти в периферию
    |0      << DMA_SxCR_PFCTRL_Pos      // DMA управляет процессом
    |0      << DMA_SxCR_TCIE_Pos        // Прерывание по окончанию передачи
    |0      << DMA_SxCR_HTIE_Pos        // Прерывание по половине передачи
    |0      << DMA_SxCR_TEIE_Pos        // Прерывание по ошибке передачи
    |0      << DMA_SxCR_DMEIE_Pos       // Прерывание по 
    |1      << DMA_SxCR_EN_Pos;         // Активация DMA
    
    SPI3->CR2 = 1<<SPI_CR2_TXDMAEN_Pos
    | 1<<SPI_CR2_SSOE_Pos;
   
    SPI3->CR1 = 0<<SPI_CR1_DFF_Pos  //Размер кадра 8 бит
    | 0<<SPI_CR1_LSBFIRST_Pos     //MSB first
    | 1<<SPI_CR1_SSM_Pos          //Программное управление SS
    | 1<<SPI_CR1_SSI_Pos          //SS в высоком состоянии
    | 0x04<<SPI_CR1_BR_Pos        //Скорость передачи: F_PCLK/32
    | 1<<SPI_CR1_MSTR_Pos         //Режим Master (ведущий)
    | 0<<SPI_CR1_CPOL_Pos | 0<<SPI_CR1_CPHA_Pos //Режим работы SPI: 0
    | 1<<SPI_CR1_SPE_Pos; //Включаем SPI
}

Вот прям скопировал весь приведенный исходник, стер только настройку пинов, залил в F407 и никаких ошибок в DMA - рапортует, что все отправил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Методом тыка выяснил, что LWIP не дает работать, когда комментирую инициализацию LWIP то SPI через DMA заводится...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Организовал в итоге работу SPI через DMA вот таким образом

#include "SPI3.h"

uint8_t SPI3_buff[1024];
uint8_t Empty_Flag = 1;

int rxCounter = 0;

void SPI3_Init(void)
{
     //DMA1 Stream 5 SPI3_TX channel 0
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOCEN;
   
    // GPIO
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
    
    // PA10 - SS - Выход
    GPIOA->MODER |= GPIO_MODER_MODE10_0;
        
    // PC10 - SCK - Выход
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    // PC11 - MISO - Вход
    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    // PC12 - MOSI - Выход
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    
    SPI3->CR2 = 
        SPI_CR2_RXDMAEN|    // Получение через DMA
        SPI_CR2_TXDMAEN;    // Отправка через DMA

    SPI3->CR1 =  0 << SPI_CR1_DFF_Pos  // Размер кадра 8 бит
        | 1<<SPI_CR1_SSM_Pos        // Программное управление SS
        | 1<<SPI_CR1_SSI_Pos        // SS в высоком состоянии
        | 0x02<<SPI_CR1_BR_Pos      // Скорость передачи 
        | 1<<SPI_CR1_MSTR_Pos       // Режим Master
        | 0<<SPI_CR1_CPOL_Pos
        | 0<<SPI_CR1_CPHA_Pos
        | SPI_CR1_SPE;   
    
    DMA1_Stream5->CR = 0;
    DMA1_Stream5->FCR = 0;
    DMA1_Stream5->PAR = (uint32_t)(&SPI3->DR);
    
    DMA1_Stream0->CR = 0;
    DMA1_Stream0->FCR = 0;
    DMA1_Stream0->PAR = (uint32_t)(&SPI3->DR);
    DMA1_Stream0->NDTR = 1024;
    DMA1_Stream0->M0AR = (uint32_t)SPI3_buff;
    DMA1_Stream0->CR =
		_VAL2FLD(DMA_SxCR_CHSEL, 0)|	/// channe - tmigger
        _VAL2FLD(DMA_SxCR_DIR, 0)|		/// peripheral to memory
        DMA_SxCR_MINC|					/// memory increment mode
        DMA_SxCR_EN;
}

void SPI3_Send(uint8_t *data, uint16_t len)
{
	while ((SPI3->SR & SPI_SR_BSY) | !(SPI3->SR & SPI_SR_TXE)) {} 
        Empty_Flag = 1;
    GPIOA->BSRR = GPIO_BSRR_BS_10;
     
    // На прием
    DMA1_Stream0->CR &=~(DMA_SxCR_EN);
    DMA1_Stream0->NDTR = 1024;
    DMA1_Stream0->M0AR = (uint32_t)SPI3_buff;
    DMA1_Stream0->CR |=(DMA_SxCR_EN);
      

    // На передачу
    DMA1->HIFCR = (DMA_HIFCR_CTCIF5| DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5);
    
    DMA1_Stream5->NDTR = len;
    DMA1_Stream5->M0AR = (uint32_t)data;
    DMA1_Stream5->CR =
		_VAL2FLD(DMA_SxCR_CHSEL, 0)|	/// channe - tmigger
        _VAL2FLD(DMA_SxCR_DIR, 1)|		/// memory_to_peripheral
        DMA_SxCR_MINC|					/// memory increment mode
        DMA_SxCR_TCIE|
        DMA_SxCR_EN;
    
    NVIC_EnableIRQ(SPI3_IRQn);
    NVIC_EnableIRQ(DMA1_Stream5_IRQn);
}

void DMA1_Stream5_IRQHandler(void) 
{
   if (DMA1->LISR & DMA_LISR_TCIF0)
   {     
        DMA1->LIFCR = DMA_LIFCR_CTCIF0;	// сброс флага события TCIF
        DMA1_Stream5->CR = 0;
        SPI3->CR2 |= SPI_CR2_TXEIE;
      //GPIOA->BSRR = GPIO_BSRR_BR_10; 
   }
}

uint8_t SPI3_Is_Empty(void)
{
    return Empty_Flag;
}

volatile uint8_t ssss;

void SPI3_IRQHandler(void)
{    
    const uint32_t sr = SPI3->SR;
    const uint32_t cr2 = SPI3->CR2;

	if(READ_BIT(sr, SPI_SR_TXE))
    {
        SPI3->SR = sr &(~SPI_SR_TXE);
        SPI3->CR2 = cr2 &(~SPI_CR2_TXEIE);
        Empty_Flag = 0;
      
        GPIOA->BSRR = GPIO_BSRR_BR_10;  
    }
    else if(READ_BIT(sr, SPI_SR_OVR))
    {
        __NOP();
    }
}

Не могу добиться правильного варианта с опусканием вывода PA10.

В прерыварии по DMA срабатывает рано, что понятно почему

Прерывание по TXE не срабатывает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TXE тоже ничего не даст, он также выставляется по опустошению буфера, для отслеживания опустошения передатчика надо мониторить BSY: Busy flag, но от него нет прерывания.

Изменено пользователем deni

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В прерывании по завершению передачи DMA разрешаете прерывание RXNE SPI, в его обработчике блокируете это прерывание и опускаете PA10.

Здесь на электрониксе была тема, когда путем экспериментов было установлено, что для некоторых режимов SPI ни RXNE, ни BSY не обеспечивают должного времени после передачи последнего бита. Так что - делете так, как, например, я только что написал, а дальше осциллом смотрите, как далеко от последнего бита опустился CS.

В крайнем случае можно в прерывании TC DMA запускать таймер, который через какое-то время опустит ногу. 100500 способов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...