Дисплей LS020 + STM32, отказывается работать

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1303
Зарегистрирован: Вс апр 19, 2009 17:20:22
Откуда: г.Ростов-на-Дону/г.Таганрог/г.Геленджик

Сообщение КАШАК »

Доброго времени суток :)

Пытаюсь запустить дисплей на контроллере LS020 с STM32VL Discovery. Инициализация проходит, заливка работает, но вывести какую-либо графику не получается. Все время начинается вывод с краю дисплея и все время какая-то абракадабра. Инициализация вот такая:
Спойлер

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

void SPIsend(int Data)
{
	SPI1->DR = Data;
	while(!((SPI1->SR)&SPI_SR_TXE));
}

void lcd_init_c(void)
{
const unsigned int  INIT1[2] ={0xFDFD,0xFDFD};
const unsigned int  INIT2[10] ={0xEF00,0xEE04,0x1B04,0xFEFE,0xFEFE,0xEF90,0x4A04,0x7F3F,0xEE04,0x4306};
const unsigned int  INIT3[20]={0xEF90,0x0983,0x0800,0x0BAF,0x0A00,0x0500,0x0600,0x0700,0xEF00,0xEE0C,
							   0xEF90,0x0080,0xEFB0,0x4902,0xEF00,0x7F01,0xE181,0xE202,0xE276,0xE183};
const unsigned int  INIT4[3] ={0x8001,0xEF90,0x0000};

 unsigned char cnt;

	RSHi;
	CSHi;
	delay_ms(10);

	RSTLow;
        RSLow;
	delay_ms(15);
	RSTHi;
	CSHi;
	delay_ms(15);
	RSHi;
	delay_ms(15);
	CSLow;
	delay_ms(15);

for (cnt=0; cnt<2; cnt++)
	SPIsend(INIT1[cnt]);
delay_ms(50);

for (cnt=0; cnt<10; cnt++)
	SPIsend(INIT2[cnt]);
delay_ms(7);

for (cnt=0; cnt<20; cnt++)
	SPIsend(INIT3[cnt]);
delay_ms(50);

for (cnt=0; cnt<3; cnt++)
	SPIsend(INIT4[cnt]);
delay_ms(3);

	CSHi;
}
Заливка
Спойлер

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

uint8_t lcd_cmd(uint16_t data)
{
  RSHi;
  CSLow;

  SPI1->DR = data;
  while (!((SPI1->SR)&SPI_SR_RXNE));

  RSLow;
  CSHi;

  return(SPI1->DR);
}

void fill_screen(uint16_t color)
{
  uint16_t i;
  
  lcd_cmd(0xEF90);
  lcd_cmd(0x0500);
  lcd_cmd(0x0600);
  lcd_cmd(0x0700);
 
  for (i = 0; i < DISP_W*DISP_H; i++)
	  SPIsend(color);
}
А вот так пытаюсь вывести пиксель:
Спойлер

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

void put_pixel(int x, int y,long int color)
 {
	  RSHi;
	  CSLow;

	  SPIsend(0xEF90);
	  SPIsend(0x0504);
	  SPIsend((0x06<<8)+y);
	  SPIsend((0x07<<8)+x);

	  RSLow;
	  CSHi;

	  lcd_dat(color); 
 }
В итоге начинается вывод точек из угла дисплея и постепенно заполняются горизонтальные строки. SPI настроен вот так:
Спойлер

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

void SPIinit (void)
{
	SPI1->CR1 |= SPI_CR1_MSTR;		

	SPI1->CR1 |= SPI_CR1_DFF;			

	SPI1->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM;

	SPI1->CR1 |= SPI_CR1_SPE; 		
}
Что я делаю неправильно?

P.S.
На AVR дисплей работал нормально.
Опыт растет прямо пропорционально выведенному из строя оборудованию...
Контактная информация:
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 271
Зарегистрирован: Чт апр 01, 2010 14:14:55

Сообщение jordan »

в AVR spi наверное программно был организован? я помню у меня тоже была подобная ерунда, я сейчас не за своим компьютером, код не могу посмотреть, но помню что у меня тоже на avr работало нормально а на stm32 были проблемы...

Поставте в lcd_cmd перед ретерном небольшую задержку, буквально в 100-200 тактов, если у вас stm32VL это наверное stm32 discoverу, там у вас наверное частота генератор 24MHz? настройте spi что б его частота была не больше 8Mhz, это на верняка у меня с этим дисплеем spi работал на 10 легко, а на 12MHz уже по мойму выделывался, короче 8 мегагерц будет наверняка...

я не могу сейчас полностью проверить код, но помню что без задержки в командах к дисплею на больших скоростях он работать нормально отказывался!
Реклама
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1303
Зарегистрирован: Вс апр 19, 2009 17:20:22
Откуда: г.Ростов-на-Дону/г.Таганрог/г.Геленджик

Сообщение КАШАК »

Поставил предделитель частоты 4, добавил задержки. Но ничего не изменилось, только заливка медленнее стала...

P.S.
На AVR SPI аппаратный был.
Опыт растет прямо пропорционально выведенному из строя оборудованию...
Контактная информация:
Грызет канифоль
Аватара пользователя
Сообщения: 271
Зарегистрирован: Чт апр 01, 2010 14:14:55

Сообщение jordan »

а заливка правильным цветом идет? таким же как и на avr

и вообще я не понимаю если на avr аппаратный был то скорости примерно такая же была, - портируйте код на stm без изменений, ну изменение только в периферии...

и посмотрите у вас где филскрин там 4 команды на выставление окна заливки!!! - все правельно!!! а на выбор пикселя эти команды где???
вы вместо команды там отсылаете данные!!! это наверное и ошибка !!!
Реклама
Эиком - электронные компоненты и радиодетали
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1303
Зарегистрирован: Вс апр 19, 2009 17:20:22
Откуда: г.Ростов-на-Дону/г.Таганрог/г.Геленджик

Сообщение КАШАК »

Цвет выводит правильный. Ну значит так. Оказывается, дисплей вообще не реагирует на отправку команд lcd_cmd(); Например, если из функции fill_screen(); убрать

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

  lcd_cmd(0xEF90);
  lcd_cmd(0x0500);
  lcd_cmd(0x0600);
  lcd_cmd(0x0700);
то ничего не меняется, заливка все так же работает. Соответственно не срабатывают команды выбора окна, поэтому и не работает все остальное. Перешел на 8-битный режим, полностью скопировал код с рабочей библиотеки для AVR, включая инициализацию, но эффект нулевой. Вот эта функция вывода прямоугольника тоже не работает, хотя на AVR все нормально:

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

void lcd_set_window(char x1, char y1, char x2, char y2)
{
	lcd_cmd16(0xEF90);
	lcd_cmd16(0x0500); // Set Direction
	lcd_cmd16(0x0A00+x1);
	lcd_cmd16(0x0B00+x2);
	lcd_cmd16(0x0800+y1);
	lcd_cmd16(0x0900+y2);
}

void lcd_rectangle(char x1, char y1, char x2, char y2, uint16_t color)
{
  char x, y;

  lcd_set_window(x1, y1, x2, y2);

  for (y=y1; y<=y2; y++)
    for (x=x1; x<=x2; x++)
    	lcd_dat16(color);
}
Видимо, функция отправки команд неработоспособна:

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

uint8_t lcd_cmd(uint16_t data)
{
  RSHi;
  CSLow;

  SPI1->DR = data;
  while (!((SPI1->SR)&SPI_SR_RXNE));
 
  CSHi;

  for(data = 0; data<150; data++);

  return(SPI1->DR);
}
Что в ней не так? Для AVR была вот такая:

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

void ls020_wrcmd8(char cmd)
{
  PORTB |= (1<<RS); //Set RS
  PORTB &= ~(1<<CS); // select LCD
  SPCR = (1<<MSTR)|(1<<SPE);
  SPDR = cmd;
  while ( !(SPSR & (1 << SPIF)));
  PORTB |= (1<<CS); // deselect LCD
}

P.S.
Во всех проектах для ARM есть команда 0xEF90 перед заливкой, рисованием и т.п., а в AVR ее нет. Что она должна делать?
Опыт растет прямо пропорционально выведенному из строя оборудованию...
Контактная информация:
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 454
Зарегистрирован: Вс янв 15, 2012 19:58:40

Сообщение radiokot__ »

Ну видимо если 8 бит SPI то 8бит data и надо отправлять.
А у вас
uint8_t lcd_cmd(uint16_t data).
Соответственно дальше смотреть где косяки.
Ни один домашний кот незнает что он домашний.
Реклама
Грызет канифоль
Аватара пользователя
Сообщения: 271
Зарегистрирован: Чт апр 01, 2010 14:14:55

Сообщение jordan »

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

void LS020_CMD(unsigned short int comand)
{
   while (!(SPI1->SR & SPI_SR_TXE));  
                                      
   CS_LOW                            
   RS_HIGH                            
   
   SPI1->DR  = comand;                
   while (!(SPI1->SR & SPI_SR_TXE));  
   
   for(unsigned int i=0; i<100; i++); 
   CS_HIGH                            
   
}
я вот так на stm32f100discovery, если на stm32 вы пользуетесь не библиотечными функциями, то там легко запутаться в регистрах
set bit и reset bit, возьмите светодиодик и поверте работают ли фактически линии RS, ChipSelect и spi проверить не помешало б, spi проверяется просто, соединяете miso и mosi и в дебагере смотрите приходит ли на вход то что вы отправляете...
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1303
Зарегистрирован: Вс апр 19, 2009 17:20:22
Откуда: г.Ростов-на-Дону/г.Таганрог/г.Геленджик

Сообщение КАШАК »

В общем все оказалось предельно просто. Плата STM32 VL Discovery у меня воткнута вот в такую плату:
Изображение

Для подключения периферии выведены PLS линейки. И на выводе PA3 был непропай, а как раз к нему была подключена линия CS. Непропай устранил и дисплей заработал нормально в 16-битном режиме. Даже на максимальной частоте SPI :) Теперь выводится и текст и графические примитивы.
Теперь другой вопрос, как вывести рисунок? Вроде алгоритм должен быть простым:
1) Перегнать картинку в массив цветов пикселей на ПК.
2) Вывести массив на экран попиксельно.

Но размер такого массива будет огромным, 176*132 = 23232 элемента :shock: Может есть какие-то другие способы?
Опыт растет прямо пропорционально выведенному из строя оборудованию...
Контактная информация:
Грызет канифоль
Аватара пользователя
Сообщения: 271
Зарегистрирован: Чт апр 01, 2010 14:14:55

Сообщение jordan »

для вывода картинки, вам понадобится формат bmp, это и есть bit map, то есть каждому пикселю отвечает 3 байта R G B... точнее почитайте bmp файла http://c-site.h1.ru/infa/bmp_struct.htm и все станет понятно

есть конечно библиотеки для декодирования jpeg и jpg но они очень громоздки и для начала нужно научится работать с bmp
Ответить

Вернуться в «Периферия»