<?xml version="1.0" encoding="UTF-8"?>        <rss version="2.0"
             xmlns:atom="http://www.w3.org/2005/Atom"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
             xmlns:admin="http://webns.net/mvcb/"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:content="http://purl.org/rss/1.0/modules/content/">
        <channel>
            <title>
									TFT дисплей ILI9341. SPI - STM32				            </title>
            <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/</link>
            <description>Обсуждение вопросов, посвященных программированию микроконтроллеров, разработке электроники и не только.</description>
            <language>ru-RU</language>
            <lastBuildDate>Wed, 11 Mar 2026 22:40:33 +0000</lastBuildDate>
            <generator>wpForo</generator>
            <ttl>60</ttl>
							                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/6/#post-2429</link>
                        <pubDate>Tue, 17 Oct 2023 05:52:09 +0000</pubDate>
                        <description><![CDATA[От: @stm 
Для кодирования пикселей достаточно только нижнего цикла while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);, верхний для безопасности, это хорошо, но неправильной последовательностью...]]></description>
                        <content:encoded><![CDATA[<blockquote data-userid="2079" data-postid="2425" data-mention="stm">
<div class="wpforo-post-quote-author"><strong> От: @stm </strong></div>
<p>Для кодирования пикселей достаточно только нижнего цикла while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);, верхний для безопасности, это хорошо, но неправильной последовательностью думаю это нельзя назвать. Ок, пусть будет.</p>
</blockquote>
<p>И снова не совсем так ) При любом расположении строка</p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET); </pre>
<p>служит одной цели - убедиться, что предыдущие данные ушли, и можно писать новые.</p>
<p>Если вернуться к оберткам в виде функций для удобства:</p>
<pre contenteditable="false">/* ---------------------------------------------------------------------------*/
void ST7735_SendByte(uint8_t data)
{
  while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  
  SPI1-&gt;DR = data;
}

/* ---------------------------------------------------------------------------*/

/* ---------------------------------------------------------------------------*/
void ST7735_WaitLastData()
{
  while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
  while((SPI1-&gt;SR &amp; SPI_SR_BSY) != RESET);
}

/* ---------------------------------------------------------------------------*/</pre>
<p>Запись последовательности байт выглядит так:</p>
<pre contenteditable="false">for (uint32_t i = 0; i &lt; num; i++)
{
  ST7735_SendByte(*data);
  data++;
}

ST7735_WaitLastData();</pre>
<p>По шагам это превращается в:</p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  
SPI1-&gt;DR = data;

while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
while((SPI1-&gt;SR &amp; SPI_SR_BSY) != RESET);</pre>
<ul>
<li>Проверяем, что можно писать данные в регистр</li>
<li>Пишем данные в регистр DR</li>
<li>Проверяем, что эти данные ушли в сдвиговый регистр = можно писать новые данные</li>
<li>Пишем данные</li>
<li>...</li>
<li>...</li>
<li>После последнего байта проверяем и флаг SPI_SR_TXE и флаг SPI_SR_BSY, только после этого (!) можно менять сигналы на DC и т. д.</li>
</ul>
<p>Соответственно, если пишем только один байт, то последовательность такая:</p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
while((SPI1-&gt;SR &amp; SPI_SR_BSY) != RESET);</pre>
<ul>
<li>Проверяем, что ушли предыдущие данные</li>
<li>Пишем новые данные</li>
<li>Проверяем, что ушли новые данные</li>
</ul>
<p>Но при отправке последовательности байт проверка флага SPI_SR_BSY выполняется только при передаче последнего байта.</p>
<blockquote data-userid="2079" data-postid="2427" data-mention="stm">
<div class="wpforo-post-quote-author"><strong> От: @stm </strong></div>
<p>HAL овским функциям может было необходимо деактивировать Чип Селект после каждой передачи данных.<br />Передаче данных через регистры это не нужно.</p>
</blockquote>
<p>CS никак не связан с тем, какие библиотеки используются. Этот сигнал нужен для активации/деактивации slave'а на шине, у меня активируется внутри функций отрисовки:</p>
<pre contenteditable="false">void ST7735_DrawRect(uint16_t cStart, uint16_t rStart, uint16_t cStop, uint16_t rStop, uint16_t color)
{
  HAL_GPIO_WritePin(ST7735_CS_PORT, ST7735_CS_PIN, GPIO_PIN_RESET);
  ST7735_SetColAddr(cStart, cStop - 1);
  ST7735_SetRowAddr(rStart, rStop - 1);
  
  ST7735_SendCommand(ST7735_RAMWR);
  
  uint32_t size = (cStop - cStart) * (rStop - rStart);
  uint8_t colorBytes;
  colorBytes = (color &amp; 0xFF00) &gt;&gt; 8;
  colorBytes = color &amp; 0x00FF;
  
  HAL_GPIO_WritePin(ST7735_DC_PORT, ST7735_DC_PIN, GPIO_PIN_SET);
  
  for (uint32_t i = 0; i &lt; size; i++)
  {
    ST7735_SendByte(colorBytes);
    ST7735_SendByte(colorBytes);
  }
  
  ST7735_WaitLastData();
  HAL_GPIO_WritePin(ST7735_CS_PORT, ST7735_CS_PIN, GPIO_PIN_SET);
}</pre>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>Aveal</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/6/#post-2429</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/6/#post-2428</link>
                        <pubDate>Tue, 17 Oct 2023 03:10:04 +0000</pubDate>
                        <description><![CDATA[В этой статье очень доходчиво и красиво описано, как работать с дисплеями подключенными по SPI.]]></description>
                        <content:encoded><![CDATA[492
<p>В этой статье очень доходчиво и красиво описано, как работать с дисплеями подключенными по SPI.</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>Эдуард</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/6/#post-2428</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2427</link>
                        <pubDate>Mon, 16 Oct 2023 23:44:41 +0000</pubDate>
                        <description><![CDATA[HAL овским функциям может было необходимо деактивировать Чип Селект после каждой передачи данных.Передаче данных через регистры это не нужно.Ещё быстрее стали пиксели кодироваться и дисплей ...]]></description>
                        <content:encoded><![CDATA[<p>HAL овским функциям может было необходимо деактивировать Чип Селект после каждой передачи данных.<br />Передаче данных через регистры это не нужно.<br />Ещё быстрее стали пиксели кодироваться и дисплей заполняться без деактивации Чип Селект после передачи данных.</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>stm</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2427</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2426</link>
                        <pubDate>Mon, 16 Oct 2023 23:38:50 +0000</pubDate>
                        <description><![CDATA[У меня после каждой отсылки данных была деактивация Чип Селекта TFT_CS_SET();Поэтому играло роль где написан цикл, снизу или сверху передачи данных.
Я посмотрел, вы не деактивируете Чип Сел...]]></description>
                        <content:encoded><![CDATA[<p>У меня после каждой отсылки данных была деактивация Чип Селекта TFT_CS_SET();<br />Поэтому играло роль где написан цикл, снизу или сверху передачи данных.</p>
<p>Я посмотрел, вы не деактивируете Чип Селект после передачи данных.<br />Я в драйверах видел деактивацию Чип Селекта после передачи данных, поэтому её всегда вставлял в код.</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>stm</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2426</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2425</link>
                        <pubDate>Mon, 16 Oct 2023 22:38:03 +0000</pubDate>
                        <description><![CDATA[Для кодирования пикселей достаточно только нижнего цикла while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);, верхний для безопасности, это хорошо, но неправильной последовательностью думаю это ...]]></description>
                        <content:encoded><![CDATA[<p>Для кодирования пикселей достаточно только нижнего цикла while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);, верхний для безопасности, это хорошо, но неправильной последовательностью думаю это нельзя назвать. Ок, пусть будет.</p>
<p>Я просто хотел описать мысль, а не доказать как будет правильнее)</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>stm</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2425</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2424</link>
                        <pubDate>Mon, 16 Oct 2023 22:32:14 +0000</pubDate>
                        <description><![CDATA[&gt;Это плюс-минус то же самое, что сесть на стул, а только после этого проверить, не занят ли он.Ок, это да) Но работает как пауза между передачами только нижний цикл, который под SPI1-&gt;...]]></description>
                        <content:encoded><![CDATA[<p>&gt;Это плюс-минус то же самое, что сесть на стул, а только после этого проверить, не занят ли он.<br />Ок, это да) <br />Но работает как пауза между передачами только нижний цикл, который под SPI1-&gt;DR = 0; </p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);</pre>
<p><br />Ок, верхний цикл while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);  для безопасности)</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>stm</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2424</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2423</link>
                        <pubDate>Mon, 16 Oct 2023 22:22:15 +0000</pubDate>
                        <description><![CDATA[По поводу последовательности, Ваш вариант:
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
Это плюс-минус то же самое, что сесть на стул, а только после этого проверит...]]></description>
                        <content:encoded><![CDATA[<p>По поводу последовательности, Ваш вариант:</p>
<pre contenteditable="false">SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);</pre>
<p>Это плюс-минус то же самое, что сесть на стул, а только после этого проверить, не занят ли он.</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>Aveal</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2423</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2422</link>
                        <pubDate>Mon, 16 Oct 2023 22:17:16 +0000</pubDate>
                        <description><![CDATA[@stm]]></description>
                        <content:encoded><![CDATA[<p>@stm </p>
491]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>Aveal</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2422</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2421</link>
                        <pubDate>Mon, 16 Oct 2023 22:11:32 +0000</pubDate>
                        <description><![CDATA[BUSY flag – The BSY flag is useful to detect the end of a transfer if the software wants to disable the SPI and enter Halt mode (or disable the peripheral clock). This avoids corrupting the ...]]></description>
                        <content:encoded><![CDATA[<p>BUSY flag – The BSY flag is useful to detect the end of a transfer if the software wants to disable the SPI and enter Halt mode (or disable the peripheral clock). This avoids corrupting the last transfer. For this, the procedure described below must be strictly respected. The BSY flag is also useful to avoid write collisions in a multi-master system.<br />---------------------------------------------<br />Ок, может дело в SPI.<br />Как написано в описании флага BUSY : предыдущая передача может повреждаться.<br />This avoids corrupting the last transfer.</p>
<p><br />&gt;Плюс у Вас даже в этих двух строках неправильная последовательность.<br />У вас для передачи данных служат эти функции:</p>
<pre contenteditable="false">ST7735_SendByte(data);
ST7735_WaitLastData();</pre>
<p><br />Если их раскрыть, то получится:</p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
while((SPI1-&gt;SR &amp; SPI_SR_BSY) != RESET);</pre>
<p>Для чего у вас два раза? while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET); <br />-------------------------------------<br />Попробуйте заменить все эти 3 while просто HAL_Delay()<br />Ок, это понятно, что флаги лишь ускоряют передачу и по готовности флагов начинается передача.<br />Дело немного в другом. <br />Если не ждать нужное время после передачи, то предыдущая передача повреждается и пиксели у меня перестают кодироваться.</p>
<p>Достаточная пауза HAL_Delay() между передачами и while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET); по сути одно и то же, но вы сказали, что у меня неправильная последовательность</p>
<pre contenteditable="false">SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);</pre>
<p><br />Этот цикл как раз и обеспечивает нужную задержку, чтоб предыдущая передача не повреждалась</p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);</pre>
<p>У вас этот код работает точно по такому же принципу:</p>
<pre contenteditable="false">while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
SPI1-&gt;DR = data;
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET);
while((SPI1-&gt;SR &amp; SPI_SR_BSY) != RESET);</pre>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>stm</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2421</guid>
                    </item>
				                    <item>
                        <title>НА: TFT дисплей ILI9341. SPI</title>
                        <link>https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2420</link>
                        <pubDate>Mon, 16 Oct 2023 21:25:28 +0000</pubDate>
                        <description><![CDATA[От: @aveal 
@stm Я объяснил, почему дисплей ничего не выводит без проверки флага и тонко намекнул на то, что вот эту дичь надо выкинуть раз и навсегда:
for(int i=0;i&lt;10;i++){}
Плюс у В...]]></description>
                        <content:encoded><![CDATA[<blockquote data-userid="1" data-postid="2419" data-mention="aveal">
<div class="wpforo-post-quote-author"><strong> От: @aveal </strong></div>
<p><a title="stm" href="https://microtechnics.ru/community/profile/stm/">@stm</a> Я объяснил, почему дисплей ничего не выводит без проверки флага и тонко намекнул на то, что вот эту дичь надо выкинуть раз и навсегда:</p>
<pre contenteditable="false">for(int i=0;i&lt;10;i++){}</pre>
<p>Плюс у Вас даже в этих двух строках:</p>
<pre contenteditable="false">SPI1-&gt;DR = data;
перед
while((SPI1-&gt;SR &amp; SPI_SR_TXE) == RESET)</pre>
<p>неправильная последовательность.</p>
<p>А так да, просто так сижу, ерунду пишу от нечего делать видимо )</p>
</blockquote>
<p>Для читающих - это мой ответ на удаленное сообщение с претензией, что я будто бы перефразировал то же самое, что ТС написал ранее.</p>]]></content:encoded>
						                            <category domain="https://microtechnics.ru/community/stm32/">STM32</category>                        <dc:creator>Aveal</dc:creator>
                        <guid isPermaLink="true">https://microtechnics.ru/community/stm32/tft-displej-ili9341-spi/paged/5/#post-2420</guid>
                    </item>
							        </channel>
        </rss>
		