2018-12-05 08:50 AM
Hello! I apologize for the poor translation of Google)))
I have a STM32F100VLDiscouvery debug board with an STM32F100RBT6B chip. I try to display a small red square (for familiarization) on a TFT screen on an ILI9341 chip.
Through SPI1, it turned out to be derived, but through SPI2 - it does not work at all.
I wrote this code for SPI1 and then just remade it under SPI2, replacing the initialization of SPI1 with SPI2 and changing the legs of SPI1 to SPI2.
The oscilloscope sees the signals on SCK and MOSI and the width of the SCK varies with SPI2-> CR1_BR.
What is the problem? Already 5 days trying to decide ...
2018-12-05 08:51 AM
//#include "stm32f10x_conf.h"
#include "stm32f10x.h"
#define SPI_MASTER SPI2
// Colors
#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define BLACK 0x0000
#define YELLOW 0xffe0
#define WHITE 0xffff
#define CYAN 0x07ff
#define BRIGHT_RED 0xf810
#define GRAY1 0x8410
#define GRAY2 0x4208
#define TFT_CS_LOW GPIOB->BSRR |= GPIO_BSRR_BR0;
#define TFT_CS_HIGH GPIOB->BSRR |= GPIO_BSRR_BS0;
#define TFT_DC_LOW GPIOB->BSRR |= GPIO_BSRR_BR11;
#define TFT_DC_HIGH GPIOB->BSRR |= GPIO_BSRR_BS11;
#define TFT_RST_LOW GPIOB->BSRR |= GPIO_BSRR_BR10;
#define TFT_RST_HIGH GPIOB->BSRR |= GPIO_BSRR_BS10;
//void TFT_8b() {SPI2->CR1 &= ~SPI_CR1_SPE; SPI2->CR1 &= ~SPI_CR1_DFF; SPI2->CR1 |= SPI_CR1_SPE;}
//void TFT_16b() {SPI2->CR1 &= ~SPI_CR1_SPE; SPI2->CR1 |= SPI_CR1_DFF; SPI2->CR1 |= SPI_CR1_SPE;}
void TFT_sendByte(uint8_t data)
{
//TFT_8b();
while(!(SPI2->SR & SPI_SR_TXE));
SPI2->DR = data;
}
void TFT_sendCMD(int index)
{
// ждем чтобы �?тарые данные ушли до того как мы помен�?ем �?о�?то�?ние линий управлени�? ди�?плеем
//TFT_8b();
while(SPI2->SR & SPI_SR_BSY);
TFT_CS_HIGH;
TFT_DC_LOW;
TFT_CS_LOW;
TFT_sendByte(index);
}
void TFT_sendDATA(int data)
{
//TFT_8b();
while(SPI2->SR & SPI_SR_BSY);
TFT_DC_HIGH;
TFT_sendByte(data);
}
void TFT_sendWord(uint16_t data)
{
//TFT_16b();
while(SPI2->SR & SPI_SR_BSY);
TFT_DC_HIGH;
TFT_sendByte(data >> 8);
TFT_sendByte(data & 0x00ff);
}
void TFT_init()
{
GPIOB->CRL &= ~GPIO_CRL_CNF0; //CS
GPIOB->CRL |= GPIO_CRL_MODE0;
GPIOB->CRL &= ~GPIO_CRL_CNF1; //LED
GPIOB->CRL |= GPIO_CRL_MODE1;
GPIOB->CRH &= ~GPIO_CRH_CNF10; //RST
GPIOB->CRH |= GPIO_CRH_MODE10;
GPIOB->CRH &= ~GPIO_CRH_CNF11; //DC
GPIOB->CRH |= GPIO_CRH_MODE11;
//вывод SCK: выход двухтактный, альтернативна�? функци�?, 50MHz
GPIOB->CRH |= GPIO_CRH_MODE13; //
GPIOB->CRH &= ~GPIO_CRH_CNF13; //
GPIOB->CRH |= GPIO_CRH_CNF13_1; //
//вывод MISO: вход цифровой �? подт�?гивающим рези�?тором, подт�?жка к плю�?у
GPIOB->CRH &= ~GPIO_CRH_MODE14; //
GPIOB->CRH &= ~GPIO_CRH_CNF14; //
GPIOB->CRH |= GPIO_CRH_CNF14_1; //
GPIOB->BSRR = GPIO_BSRR_BS14; //
//вывод MOSI: выход двухтактный, альтернативна�? функци�?, 50MHz
GPIOB->CRH |= GPIO_CRH_MODE15; //
GPIOB->CRH &= ~GPIO_CRH_CNF15; //
GPIOB->CRH |= GPIO_CRH_CNF15_1; //
TFT_RST_LOW;
for(int i=0; i<0x0FFFF; i++);
TFT_RST_HIGH;
TFT_sendCMD(0xCB);
TFT_sendDATA(0x39);
TFT_sendDATA(0x2C);
TFT_sendDATA(0x00);
TFT_sendDATA(0x34);
TFT_sendDATA(0x02);
TFT_sendCMD(0xCF);
TFT_sendDATA(0x00);
TFT_sendDATA(0xC1);
TFT_sendDATA(0x30);
TFT_sendCMD(0xE8);
TFT_sendDATA(0x85);
TFT_sendDATA(0x00);
TFT_sendDATA(0x78);
TFT_sendCMD(0xEA);
TFT_sendDATA(0x00);
TFT_sendDATA(0x00);
TFT_sendCMD(0xED);
TFT_sendDATA(0x64);
TFT_sendDATA(0x03);
TFT_sendDATA(0x12);
TFT_sendDATA(0x81);
TFT_sendCMD(0xF7);
TFT_sendDATA(0x20);
TFT_sendCMD(0xC0); //Power control
TFT_sendDATA(0x23); //VRH[5:0]
TFT_sendCMD(0xC1); //Power control
TFT_sendDATA(0x10); //SAP[2:0];BT[3:0]
TFT_sendCMD(0xC5); //VCM control
TFT_sendDATA(0x3e); //Contrast
TFT_sendDATA(0x28);
TFT_sendCMD(0xC7); //VCM control2
TFT_sendDATA(0x86); //--
TFT_sendCMD(0x36); // Memory Access Control
TFT_sendDATA(0x48); //C8 //48 68з»�?ж §зќ†//28 E8 е¦ЇоЃ„зќ†
TFT_sendCMD(0x3A);
TFT_sendDATA(0x55);
TFT_sendCMD(0xB1);
TFT_sendDATA(0x00);
TFT_sendDATA(0x18);
TFT_sendCMD(0xB6); // Display Function Control
TFT_sendDATA(0x08);
TFT_sendDATA(0x82);
TFT_sendDATA(0x27);
TFT_sendCMD(0xF2); // 3Gamma Function Disable
TFT_sendDATA(0x00);
TFT_sendCMD(0x26); //Gamma curve selected
TFT_sendDATA(0x01);
TFT_sendCMD(0xE0); //Set Gamma
TFT_sendDATA(0x0F);
TFT_sendDATA(0x31);
TFT_sendDATA(0x2B);
TFT_sendDATA(0x0C);
TFT_sendDATA(0x0E);
TFT_sendDATA(0x08);
TFT_sendDATA(0x4E);
TFT_sendDATA(0xF1);
TFT_sendDATA(0x37);
TFT_sendDATA(0x07);
TFT_sendDATA(0x10);
TFT_sendDATA(0x03);
TFT_sendDATA(0x0E);
TFT_sendDATA(0x09);
TFT_sendDATA(0x00);
TFT_sendCMD(0xE1); //Set Gamma
TFT_sendDATA(0x00);
TFT_sendDATA(0x0E);
TFT_sendDATA(0x14);
TFT_sendDATA(0x03);
TFT_sendDATA(0x11);
TFT_sendDATA(0x07);
TFT_sendDATA(0x31);
TFT_sendDATA(0xC1);
TFT_sendDATA(0x48);
TFT_sendDATA(0x08);
TFT_sendDATA(0x0F);
TFT_sendDATA(0x0C);
TFT_sendDATA(0x31);
TFT_sendDATA(0x36);
TFT_sendDATA(0x0F);
TFT_sendCMD(0x11); //Exit Sleep
for(int i=0; i<0x00FFF; i++);
TFT_sendCMD(0x29); //Display on
TFT_sendCMD(0x2c);
}
void TFT_led(int state)
{
if (state)
GPIOB->BSRR |= GPIO_BSRR_BS1;
else
GPIOB->BSRR |= GPIO_BSRR_BR1;
}
void TFT_setCol(int StartCol, int EndCol)
{
TFT_sendCMD(0x2A); // Column Command address
TFT_sendWord(StartCol);
TFT_sendWord(EndCol);
}
void TFT_setPage(int StartPage, int EndPage)
{
TFT_sendCMD(0x2B); // Column Command address
TFT_sendWord(StartPage);
TFT_sendWord(EndPage);
}
void TFT_setXY(int poX, int poY)
{
TFT_setCol(poX, poX);
TFT_setPage(poY, poY);
TFT_sendCMD(0x2c);
}
void TFT_setPixel(int poX, int poY, int color)
{
TFT_setXY(poX, poY);
TFT_sendWord(color);
}
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
SPI2->CR1 &= ~SPI_CR1_BIDIMODE;
SPI2->CR1 &= ~SPI_CR1_BIDIOE;
SPI2->CR1 |= SPI_CR1_MSTR; //контроллер должен быть ма�?тером
SPI2->CR1 &= ~SPI_CR1_DFF; //8 bit data
SPI2->CR1 &= ~SPI_CR1_CPOL; //Polarity cls signal CPOL = 0;
SPI2->CR1 &= ~SPI_CR1_CPHA; //Phase cls signal CPHA = 0;
SPI2->CR1 |= SPI_CR1_SSI; //обе�?печить вы�?окий уровень программного NSS
SPI2->CR1 |= SPI_CR1_SSM; //разрешить программное формирование NSS
SPI2->CR1 |= SPI_CR1_BR; // fpclk/256
SPI2->CR1 &= ~SPI_CR1_LSBFIRST;
SPI2->CR1 |= SPI_CR1_SPE; //разрешить работу модул�? SPI2
int i, j;
TFT_led(1);
TFT_init();
//TFT_setPixel(10, 10, RED);
for(i=50; i<200; i++) {
for(j=150; j<200; j++) {
TFT_setPixel(i, j, RED);
}
}
while(1)
{
}
}
2018-12-05 01:24 PM
Don't know why SPI2 should be problematic, F1's are rather old, see if any SPL examples show remapping or specials settings, really not looking to dig into register level code.
You should just write to BSRR, not this RMW OR deal
2018-12-05 04:52 PM
Is there any other change in the code, except the particular port/bits in GPIO initialization of SCK/MISO/MOSI and changing SPI1 to SPI2?
Hardware connection is OK? Double check for shorts and bad solder joints.
JW
2018-12-05 09:01 PM
So it’s just #define. There is no difference, I will write through it, that through GPIO_BSRR ...?
2018-12-05 09:07 PM
There are no more changes. Replaced the pins of SPI1 with SPI2, in the initialization of SPI1 I just changed it to SPI2.
That's what I noticed ... I went to CubeMX and chose SPI2. At the same time, a warning appeared in front of TIM15 (the pin of which is just sitting on PB15, and this is my MOSI). I did remap TIM15, but it did not help ...
A multimeter rang from the pins of the STM32F100 chip to the pin connectors - everything is fine. I connect to TFT through a prototype board.