Микроконтроллеры STM32 - тонкости работы, отладочные платы

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

Берём отладчик в руки и останавливаемся на команде включения таймера. Непосредственно сразу перед её выполнением смотрим состояние всех регистров. Выход CH2 это функция от значения этих регистров. Тыкаем в отладчике значения и смотрим какой бит влияет на неправильное поведение.
Реклама
Мучитель микросхем
Сообщения: 446
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Откуда: 69.Ржев

Сообщение a797945 »

так там и должна быть "1", исходно CNT < CCR =ARR/10. чего не так?

"110: PWM mode 1 (режим 1 ШИМ) - при счете вверх канал 1 активен (OC1REF=1), пока TIMx_CNT < TIMx_CCR1, иначе не активен (OC1REF=0). "

при включении TIM2->CCER |= TIM_CCER_CC2E;
состояние OCxREF отображается на ногу.
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 153
Зарегистрирован: Чт дек 05, 2019 16:28:11
Откуда: Самара

Сообщение TEPEM »

Просто сделал програмный шим.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 153
Зарегистрирован: Чт дек 05, 2019 16:28:11
Откуда: Самара

Сообщение TEPEM »

Здравствуйте! Подключаю дисплей ST7735 к 32L476. SPI1. Использую проверенную инициализацию. И он вроде запускается, рябь все дела. А залить не заливается.
Единственное что поменял кроме пинов - переключение 8 / 16 битовой передачи. Ибо до этого юзал 411 стм. Там было SPI2->CR1 &= ~SPI_CR1_DFF;
А в 476 нет DEF и вместо него я юзаю SPI1->CR1 &= ~SPI_CR1_CRCL;
Вроде синониумы. Еще грешу на пины дисплея TP0 & TP1 они у меня в воздухе. Подскажите пж, давно сношаюс
вот код инициализации и заливки
Спойлер

Код: Выделить всё

void Send_CMD(uint8_t dat)
{ 
        CS_LOY;  //ChipSelect loy
	DC_LOY;  //DC LoyLevel	     
	SPI1->CR1 &= ~SPI_CR1_CRCL;	
	while (!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = dat;
	while (!(SPI1->SR & SPI_SR_TXE));
	while ((SPI1->SR & SPI_SR_BSY));
        CS_H;  //ChipSelect Up
        
}
void Send_DAT(uint8_t dat){ 
        CS_LOY;  //ChipSelect loy
	DC_H;  //DC H			
	SPI1->CR1 &= ~SPI_CR1_CRCL;		
	while (!(SPI1->SR & SPI_SR_TXE));
	SPI1->DR = dat;
	while (!(SPI1->SR & SPI_SR_TXE));
	while ((SPI1->SR & SPI_SR_BSY));	
         CS_H;//ChipSelect Up
}

void Send_DAT16(uint16_t dat){ 
        CS_LOY;  //ChipSelect loy
	DC_H;  //DC H		
	SPI1->CR1 |= SPI_CR1_CRCL;		
	while (!(SPI1->SR & SPI_SR_TXE)){};
	SPI1->DR = dat;
	while (!(SPI1->SR & SPI_SR_TXE)){};
	while ((SPI1->SR & SPI_SR_BSY)){};
         CS_H;//ChipSelect Up
}

void LCD_Init()
{
 CS_LOY;  //ChipSelect loy
        SPI1->CR1 |= SPI_CR1_SPE;//On Spi1
         RST_H;  //RST Hay
        Delay(5);
 	RST_LOY;  //RST loy
	Delay(15);
        RST_H;  //RST Hay
	Delay(15); 
        Send_CMD(0x01);//Sbros nastroek 
        Delay(35);
        
    Send_CMD(ST77XX_SWRESET);
    Delay(150);
    Send_CMD(ST77XX_SLPOUT);
    Delay(500);

    Send_CMD(ST7735_FRMCTR1);
    Send_DAT(0x01);
    Send_DAT(0x2C);
    Send_DAT(0x2D);
 
    Send_CMD(ST7735_FRMCTR2);
    Send_DAT(0x01);
    Send_DAT(0x2C);
    Send_DAT(0x2D);

    Send_CMD(ST7735_FRMCTR3);
    Send_DAT(0x01);
    Send_DAT(0x2C);
    Send_DAT(0x2D);
    Send_DAT(0x01);
    Send_DAT(0x2C);
    Send_DAT(0x2D);


    Send_CMD(ST7735_INVCTR);
    Send_DAT(0x07);

    Send_CMD(ST7735_PWCTR1);
    Send_DAT(0xA2);
    Send_DAT(0x02);
    Send_DAT(0x84);

    Send_CMD(ST7735_PWCTR2);
    Send_DAT(0xC5);
 
    Send_CMD(ST7735_PWCTR3);
    Send_DAT(0x0A);
    Send_DAT(0x00);

    Send_CMD(ST7735_PWCTR4);
    Send_DAT(0x8A);
    Send_DAT(0x2A);

    Send_CMD(ST7735_PWCTR5);
    Send_DAT(0x8A);
    Send_DAT(0xEE);
    Send_CMD(ST7735_VMCTR1);
    Send_DAT(0x0E);
    Send_CMD(ST77XX_INVOFF);
    Send_CMD(ST77XX_MADCTL);
    Send_DAT(0xC0);
    Send_CMD(ST77XX_COLMOD);
    Send_DAT(0x05);
    Send_CMD(ST7735_GMCTRP1);
    Send_DAT(0x02);
    Send_DAT(0x1C);
    Send_DAT(0x07);
    Send_DAT(0x12);
    Send_DAT(0x37);
    Send_DAT(0x32);
    Send_DAT(0x29);
    Send_DAT(0x2D);
    Send_DAT(0x29);
    Send_DAT(0x25);
    Send_DAT(0x2B);
    Send_DAT(0x39);
    Send_DAT(0x00);
    Send_DAT(0x01);
    Send_DAT(0x03);
    Send_DAT(0x10);
    Send_CMD(ST7735_GMCTRN1);
    Send_DAT(0x03);
    Send_DAT(0x1D);
    Send_DAT(0x07);
    Send_DAT(0x06);
    Send_DAT(0x2E);
    Send_DAT(0x2C);
    Send_DAT(0x29);
    Send_DAT(0x2D);
    Send_DAT(0x2E);
    Send_DAT(0x2E);
    Send_DAT(0x37);
    Send_DAT(0x3F);
    Send_DAT(0x00);
    Send_DAT(0x00);
    Send_DAT(0x02);
    Send_DAT(0x10);
    Send_CMD(ST77XX_NORON);
    Delay(10);
    Send_CMD(ST77XX_DISPON);
    Delay(100);
    CS_H;//ChipSelect Up
}
void SetWindow(uint16_t startX, uint16_t startY, uint16_t stopX, uint16_t stopY) {
	Send_CMD(0x2A);
	Send_DAT(0);
	Send_DAT(startX);
	Send_DAT(0);
	Send_DAT(stopX);    
	Send_CMD(0x2B);
	Send_DAT(0);
	Send_DAT(startY);
        Send_DAT(0);
	Send_DAT(stopY);
}

void bufer()
{
        uint16_t x = 0, y = 0;
        SetWindow(10, 10, 128, 160);
	Send_CMD(0x2C);
        while(x++ <= 159)
        {
          y=0;
          while(y++ <=  127)
          {
            Send_DAT16(0xFF00);//buf[128][160];
          }
        }
}
Изображение

Ну и соответственно вызывается ини потом буффер
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

У L476 FIFO на SPI и команда SPI1->DR = dat; записывает два байта. Переделайте на байтовый доступ там где это надо.
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 153
Зарегистрирован: Чт дек 05, 2019 16:28:11
Откуда: Самара

Сообщение TEPEM »

Команды 8 битные передаются при стирании флага SPI1->CR1 &= ~SPI_CR1_CRCL;, а 16 битные при установке. Или я не то что то понял
Реклама
Мучитель микросхем
Сообщения: 457
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

[uquote="TEPEM",url="/forum/viewtopic.php?p=4552791#p4552791"]Команды 8 битные передаются при стирании флага SPI1->CR1 &= ~SPI_CR1_CRCL;, а 16 битные при установке. Или я не то что то понял[/uquote]
Нужно ещё и обращение к порту на 8 бит переделать.
*((__IO uint8_t *)&SPI1->DR) = dat;
И сам dat сделать uint8_t.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 153
Зарегистрирован: Чт дек 05, 2019 16:28:11
Откуда: Самара

Сообщение TEPEM »

[uquote="HardWareMan",url="/forum/viewtopic.php?p=4552794#p4552794"][uquote="TEPEM",url="/forum/viewtopic.php?p=4552791#p4552791"]Команды 8 битные передаются при стирании флага SPI1->CR1 &= ~SPI_CR1_CRCL;, а 16 битные при установке. Или я не то что то понял[/uquote]
Нужно ещё и обращение к порту на 8 бит переделать.
*((__IO uint8_t *)&SPI1->DR) = dat;
И сам dat сделать uint8_t.[/uquote]

Там uint8_t стоит dat.
Заработало. Но не понятно почему. Там написано в рефе по умолчанию CRCL не записан что соответствует 8 бит. я его еще и стираю на всякий. Почему не работало без

Код: Выделить всё

*((__IO uint8_t *)&SPI1->DR)  = dat;
вообще не понятно. инициализация же работала
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

1. Читайте RM, там всё есть
СпойлерИзображение
изображение_2024-03-07_223300122.png
(37.39 КБ) 426 скачиваний
2. Посмотрите ассемблерный листинг обоих вариантов и всё поймёте.
3. Разрядность dat вообще не причём.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 153
Зарегистрирован: Чт дек 05, 2019 16:28:11
Откуда: Самара

Сообщение TEPEM »

Спасибо вам большое ребята! Очень выручили а то я уже нос повесил.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

TEPEM, предлагаю слегка облагородить инициализацию. Ссылка на Compiler Explorer.
СпойлерИзображение
изображение_2024-03-08_095816011.png
(45.49 КБ) 443 скачивания
Ещё и размер кода уменьшится.
Мучитель микросхем
Сообщения: 457
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

VladislavS, можно же просто оформить значения инита в массив констант и оттуда в цикле вычитывать. Зачем эти пляски с объектами?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="HardWareMan",url="/forum/viewtopic.php?p=4553000#p4553000"]VladislavS, можно же просто оформить значения инита в массив констант и оттуда в цикле вычитывать.[/uquote]Собственно так и сделано. Только более современными средствами.

[uquote="HardWareMan",url="/forum/viewtopic.php?p=4553000#p4553000"]Зачем эти пляски с объектами?[/uquote]Где вы там объекты увидели? Покажите хоть один.

PS: Насчёт зачем. Я смею утверждать, что этот код лучше оптимизируется компилятором.
Мучитель микросхем
Сообщения: 457
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4553004#p4553004"]Где вы там объекты увидели? Покажите хоть один.

PS: Насчёт зачем. Я смею утверждать, что этот код лучше оптимизируется компилятором.[/uquote]
По ошибке бегло зацепился за токен class и обращение к членам. А потом уже увидел структуру. Ну да, так тоже можно, но я не уверен, что такая погоня за универсальностью (и удобством для человека) будет более оптимальным решением. Ну да ладно, решение достаточно изящно.
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="HardWareMan",url="/forum/viewtopic.php?p=4553264#p4553264"]но я не уверен, что такая погоня за универсальностью (и удобством для человека) будет более оптимальным решением.[/uquote]Поверьте, компилятор лучше программиста знает как по массиву ходить. Впрочем, это легко проверяется. Ссылка на Compiler Explorer.
Пишем алгоритм обхода массива двумя способами.
СпойлерИзображение
изображение_2024-03-09_123816329.png
(37.58 КБ) 1096 скачиваний
И видим, что начхал компилятор на счётчик цикла и сгенерировал одинаковый бит в бит код для обоих вариантов.
СпойлерИзображение
изображение_2024-03-09_124234554.png
(48.95 КБ) 1054 скачивания
Мучитель микросхем
Сообщения: 457
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4553350#p4553350"][uquote="HardWareMan",url="/forum/viewtopic.php?p=4553264#p4553264"]но я не уверен, что такая погоня за универсальностью (и удобством для человека) будет более оптимальным решением.[/uquote]Поверьте, компилятор лучше программиста знает как по массиву ходить. Впрочем, это легко проверяется.[/uquote]
Это хорошо, что x86/x64 компилеры последние 25 лет не стояли на месте. Но что там под РУКУ? Топик же не про x86/x64. Что там с тулчейнами под РУКУ?
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

x86 выбран только чтобы показать результат выполнения кода в Compiler Explorer. Для ARM компиляторы ни разу не отстают.
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 153
Зарегистрирован: Чт дек 05, 2019 16:28:11
Откуда: Самара

Сообщение TEPEM »

Добрый день! Это больше похоже на плюсы, сейчас попробую разобратся, совсем сложно пока для меня, но я стараюсь)
У меня все работает, кроме цветов. Вот фон один и тот же сзади 411 на дисплей выводит доски а с переди 476 кляксы вывел какие то. И что интересно вообще не понятно почему так может быть. Дисплеи одного класса(((Изображение

У меня белый это черный, черный это белый а красный синий ппц(((

В дисплее включал инверсию - не то(
Скорее всего дело в передаче выходит

Код: Выделить всё

void Send_DAT16(uint16_t dat){ 
        CS_LOY;  //ChipSelect loy
	DC_H;  //DC H		
	SPI1->CR1 |= SPI_CR1_CRCL;
	while (!(SPI1->SR & SPI_SR_TXE)){};
	SPI1->DR = dat;
	while (!(SPI1->SR & SPI_SR_TXE)){};
	while ((SPI1->SR & SPI_SR_BSY)){};
         CS_H;//ChipSelect Up
}
Я попробовал по анологии но не помогло)

Код: Выделить всё

*((__IO uint16_t *)&SPI1->DR) = dat;
а так похожи цвета, но все равно где то близко

Код: Выделить всё

void Send_DAT16(uint16_t dat){ 
 uint8_t  bytes[2];
bytes[0] = dat >> 8;     // high byte (0x12)
bytes[1] = dat & 0x00FF; // low byte (0x34)
Send_DAT(bytes[0]);
Send_DAT(bytes[1]);
}
Пробовал цвет разбирать на ргб и менять местами, лажа какая то(((


Методом научного тыка добилсяя того что INVON + BGR режимы дисплея плюс перестановка битов при отправке дают нужные цвета
Собутыльник Кота
Аватара пользователя
Сообщения: 2567
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

TEPEM, не знаю надо ли это для вашего индикатора, но если нужно переставить местами два байта в uint16_t, то в Cortecx-M4 можно вот так сделать.

Код: Выделить всё

SPI1->DR = __REV16(dat);
Это одна ассемблерная команда.
Мучитель микросхем
Сообщения: 457
Зарегистрирован: Ср сен 02, 2015 07:47:20

Сообщение HardWareMan »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4553488#p4553488"]TEPEM, не знаю надо ли это для вашего индикатора, но если нужно переставить местами два байта в uint16_t, то в Cortecx-M4 можно вот так сделать.

Код: Выделить всё

SPI1->DR = __REV16(dat);
Это одна ассемблерная команда.[/uquote]
Это несколько ассемблерных команд. Следует уточнять, что это именно своп байтов в каждом полуслове REV16 - одна атомарная команда. /душнила: офф
Ответить

Вернуться в «ARM»