Управление дисплеем с помощью SPI.
- Войдите на сайт для отправки комментариев
Пт, 01/11/2013 - 11:51
Добрый день! Есть дисплей LPH8731-3C, для него был написан вот такой код, в котором было использованы куски из других работ, в том числе с этого форума.
//Определяем пины для подключения дисплея
#define LCD_CS 10
#define LCD_RESET 3
#define LCD_RS 4
#define LCD_CLK 13
#define LCD_DATA 11
#define CMD 0
#define DAT 1
byte color;
//Определяем значения вкл/выкл пинов
#define LCD_CLK_ON digitalWrite(LCD_CLK,HIGH);
#define LCD_CLK_OFF digitalWrite(LCD_CLK,LOW);
#define LCD_RS_ON digitalWrite(LCD_RS,HIGH);
#define LCD_RS_OFF digitalWrite(LCD_RS,LOW);
#define LCD_CS_OFF digitalWrite(LCD_CS,LOW);
#define LCD_CS_ON digitalWrite(LCD_CS,HIGH);
#define LCD_RESET_ON digitalWrite(LCD_RESET,HIGH);
#define LCD_RESET_OFF digitalWrite(LCD_RESET,LOW);
void setup() {
pinMode (LCD_CS, OUTPUT);
pinMode (LCD_RESET, OUTPUT);
pinMode (LCD_RS, OUTPUT);
pinMode (LCD_CLK, OUTPUT);
pinMode (LCD_DATA, OUTPUT);
LCD_init ();
}
void loop() {
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 80; j++) {
Send_to_lcd(CMD,0x2a);
Send_to_lcd(DAT, i);
Send_to_lcd(DAT, 100);
Send_to_lcd(CMD, 0x2b);
Send_to_lcd(DAT, j+1);
Send_to_lcd(DAT, 80);
Send_to_lcd(CMD,0x2c);
Send_to_lcd(DAT, 0x00);
}
}
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 80; j++) {
//command
Send_to_lcd(CMD, 0x2a);
//data
Send_to_lcd(DAT, i);
Send_to_lcd(DAT, 10);
Send_to_lcd(CMD, 0x2b);
//data
Send_to_lcd(DAT,j+1);
Send_to_lcd(DAT, 50);
Send_to_lcd(CMD, 0x2c);
//data
Send_to_lcd(DAT, 0x16);
}}
}
void reset () //Функция сброса дисплея, ПОРТИРОВАНА
{
LCD_CS_OFF;
digitalWrite(LCD_DATA,LOW);
LCD_RESET_OFF;
delay(100);
LCD_RESET_ON;
delay(500);
LCD_CS_ON;
delay(5);
LCD_CS_OFF;
}
void Send_to_lcd (unsigned char RS, unsigned char data)//портирована
{
if (RS==HIGH){
LCD_RS_ON;
LCD_CS_OFF;
shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, data);
LCD_CS_ON;
}
else
{
LCD_RS_OFF;
LCD_CS_OFF;
shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, data);
LCD_CS_ON;
}
}
void LCD_init ()//портирована
{
reset ();
Send_to_lcd(CMD,0x01); //reset sw
delay(50);
Send_to_lcd(CMD,0xc6); //initial escape
delay(50);
Send_to_lcd(CMD,0xb9); //Refresh set
Send_to_lcd(DAT,0x00);
Send_to_lcd(CMD,0xb6); //Display control
Send_to_lcd(DAT,0x80); //
Send_to_lcd(DAT,0x04); //
Send_to_lcd(DAT,0x8a); //
Send_to_lcd(DAT,0x54); //
Send_to_lcd(DAT,0x45); //
Send_to_lcd(DAT,0x52); //
Send_to_lcd(DAT,0x43); //
Send_to_lcd(CMD,0xb3); //Gray scale position set 0
Send_to_lcd(DAT,0x02); //
Send_to_lcd(DAT,0x0a); //
Send_to_lcd(DAT,0x15); //
Send_to_lcd(DAT,0x1f); //
Send_to_lcd(DAT,0x28); //
Send_to_lcd(DAT,0x30); //
Send_to_lcd(DAT,0x37); //
Send_to_lcd(DAT,0x3f); //
Send_to_lcd(DAT,0x47); //
Send_to_lcd(DAT,0x4c); //
Send_to_lcd(DAT,0x54); //
Send_to_lcd(DAT,0x65); //
Send_to_lcd(DAT,0x75); //
Send_to_lcd(DAT,0x80); //
Send_to_lcd(DAT,0x85); //
Send_to_lcd(CMD,0xb5); //Gamma curve
Send_to_lcd(DAT,0x01); //
Send_to_lcd(CMD,0xb7); //Temperature gradient
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(CMD,0xbd); //Common driver output select
Send_to_lcd(DAT,0x00); //
/*
Send_to_lcd(CMD,0x33); //Vertical scrolling definition - Границы вертикальной прокрутки
Send_to_lcd(DAT,0x00); //Число линий, используемых в качестве верхней фиксированной области дисплея (max - 0x53)
Send_to_lcd(DAT,0x53); //Определяем область прокрутки
Send_to_lcd(DAT,0x00); //Число линий, используемых в качестве нижней фиксированной области дисплея
Send_to_lcd(CMD,0x37); //Vertical scrolling start adress
Send_to_lcd(DAT,0x00);
*/
Send_to_lcd(CMD,0x36); //Memory access control - Метод доступа к дисплейной памяти (установка нулевого адреса страницы и столбца, направление записи в память дисплея)
Send_to_lcd(DAT,0x48); //6-й бит, установленный в "1" делает адресацию столбца - слева-направо, а 3-й бит в "1" - порядок RGB (а в даташите - ошибка!!!)
Send_to_lcd(CMD,0x2d); //Colour set
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x03); //
Send_to_lcd(DAT,0x05); //
Send_to_lcd(DAT,0x07); //
Send_to_lcd(DAT,0x09); //
Send_to_lcd(DAT,0x0b); //
Send_to_lcd(DAT,0x0d); //
Send_to_lcd(DAT,0x0f); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x03); //
Send_to_lcd(DAT,0x05); //
Send_to_lcd(DAT,0x07); //
Send_to_lcd(DAT,0x09); //
Send_to_lcd(DAT,0x0b); //
Send_to_lcd(DAT,0x0d); //
Send_to_lcd(DAT,0x0f); //
Send_to_lcd(DAT,0x00); //
Send_to_lcd(DAT,0x05); //
Send_to_lcd(DAT,0x0b); //
Send_to_lcd(DAT,0x0f); //
Send_to_lcd(CMD,0xba); //Voltage control
//Send_to_lcd(DAT,0x2f); //
Send_to_lcd(DAT,0x6d);//из сектча
Send_to_lcd(DAT,0x03);//из скетча
Send_to_lcd(CMD,0x25); //Установка контраста
Send_to_lcd(DAT,0x29); //от этого значения зависит контрастность изображения.
Send_to_lcd(CMD,0xbe); //Power control
Send_to_lcd(DAT,0x58); //
Send_to_lcd(CMD,0x3a); //Информация о выводе пикселя
//#ifdef _8_BIT_COLOR
Send_to_lcd(DAT,0x02); //8-ми битный цвет
//#else
// Send_to_lcd(DAT,0x03); //12-ти битный цвет
// #endif
Send_to_lcd(CMD,0x03); //Booster voltage ON
delay(40);
Send_to_lcd(CMD,0x11); //Выход из спящего режима
delay(20); //Перед включением ждем 20 миллисекунд
Send_to_lcd(CMD,0x29); //Включение дисплея
}
Беда в том, что все это работает безумно медленно, обновление экрана за 9 секунд это не айс. Хотелось бы для этих целей использовать SPI, на сколько я понимаю дисплей именно по такому протоколу и работает, но как использовать библиотеку я пока не пойму. Пробовал, но не получилось. Может кто то поможет написать пример, на основе даннного скетча?
Прежде всего мне не понятно как работать с CS, обязательно ли называть пин как в примерах? И какой режим работы интерфеса мне нужен?
А разве shiftout это не из библиотеки SPI?
В вашем коде место вызова этой функции это самое важное место для производительности
Нет, SPI аппаратный интерфейс. И скорость там должна быть на порядок выше.
Нет, SPI аппаратный интерфейс. И скорость там должна быть на порядок выше.
в терминах стоит быть аккуратным. SPI это стандарт синхронного последовательного обмена данными. Реализация может быть хоть железной хоть програмной. И та и другая будет называться SPI. Нужно очень постараться в кривонаписании программной реализации, чтобы разница была на порядок. По крайней мере на avr эта разница не такая драматичная. Я не использую ардуиновских библиотек для SPI, поэтому и спрашиваю откуда в скетче функция shiftout? В начале скетча нет ни одной директивы #include, чтобы это понять. Может быть скетч не полный
Хотя не важно, вместо shiftout надо поставить методы из стандартно для ардуино SPI библиотеки, не забыв прочитать к ней описание. Настройки Spi следуют из скетча - младший бит вперед. Со скоростью можно поиграть. Начать с предлелителя на 4 и довести до 1. Минимальный делитель при котором булет работать дисплей и обеспечит наибольшую скорость
Ошибся, MSB это старшим битом вперед, вам нужны буду эти методы для настройки:
Вроде shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, data); надо заменить на SPI.transfer( data);
Не забыть перед этим проиницилизировать: SPI.begin();
Выводы LCD_DATA и LCD_CLK заменяются на аппаратные выводы SPI..
Взял кусочек кода, который отправляли тут на форуме, и чуть переписал с ипользованием SPI как тут писали товарищи, не работает именно кусок с SPI, что бы небыло вопросов о работе вообще.
//Определяем пины для подключения дисплея #define LCD_CS 10 #define LCD_RESET 3 #define LCD_RS 4 #define LCD_CLK 13 #define LCD_DATA 11 #include <SPI.h> //Определяем значения вкл/выкл пинов #define LCD_CLK_ON digitalWrite(LCD_CLK,HIGH); #define LCD_CLK_OFF digitalWrite(LCD_CLK,LOW); #define LCD_RS_ON digitalWrite(LCD_RS,HIGH); #define LCD_RS_OFF digitalWrite(LCD_RS,LOW); #define LCD_CS_OFF digitalWrite(LCD_CS,LOW); #define LCD_CS_ON digitalWrite(LCD_CS,HIGH); #define LCD_RESET_ON digitalWrite(LCD_RESET,HIGH); #define LCD_RESET_OFF digitalWrite(LCD_RESET,LOW); int i,j; //переменная для цикла //Пины выходные void setup () { pinMode (LCD_CS, OUTPUT); pinMode (LCD_RESET, OUTPUT); pinMode (LCD_RS, OUTPUT); pinMode (LCD_CLK, OUTPUT); pinMode (LCD_DATA, OUTPUT); digitalWrite(LCD_DATA,LOW); LCD_RESET_OFF; delay(100); LCD_RESET_ON; delay(250); delay(250); LCD_CS_ON; delay(5); LCD_CS_OFF; LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x01); //софтовый сброс дисплея delay(50); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xc6); // delay(50); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xb9); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xb6); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x80); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x04); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x8a); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x54); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x45); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x52); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x43); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xb3); //УРОВЕНЬ СЕРОГО //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x02); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0a); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x15); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x1f); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x28); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x30); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x37); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x3f); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x47); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x4c); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x54); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x65); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x75); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x80); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x85); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xb5); // КРИВАЯ ГАММЫ //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x01); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xb7); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xbd); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x36); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x48); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2d); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x03); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x05); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x07); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x09); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0b); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0d); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0f); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x03); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x05); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x07); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x09); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0b); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0b); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0f); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x05); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0b); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x0f); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xba); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x6d); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x03); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x25); //УСТАНОВИТЬ КОНТРАСТ //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x29); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0xbe); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x58); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x3a); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x02); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x03); delay(40); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x11); delay(20); //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x29); //КОНЕЦ ИНИЦИАЛИЗАЦИИ } void loop () { for (i = 0; i < 101; i++) { //закрасить дисплей в черный цвет for (j = 0; j < 80; j++) { //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2a); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, i); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 100); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2b); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, j+1); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 80); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2c); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x00); } } for (i = 0; i < 101; i++) { //закрасить дисплей в черный цвет for (j = 0; j < 80; j++) { //command LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2a); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, i); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 100); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2b); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, j+1); shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 80); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x2c); //data LCD_RS_ON; LCD_CLK_OFF; shiftOut(LCD_DATA, LCD_CLK, MSBFIRST, 0x03); } } SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV32); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE1); for (i = 0; i < 101; i++) { //закрасить дисплей в черный цвет for (j = 0; j < 80; j++) { //command LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; SPI.transfer(0x2a); LCD_CS_ON; //data LCD_RS_ON; LCD_CLK_OFF; SPI.transfer(i); LCD_CS_ON; LCD_CS_OFF; SPI.transfer(100); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; SPI.transfer(0x2b); LCD_CS_ON; //data LCD_RS_ON; LCD_CS_OFF; LCD_CLK_OFF; SPI.transfer( j+1); LCD_CS_ON; LCD_CS_OFF; SPI.transfer( 80); LCD_CS_ON; LCD_RS_OFF; LCD_CS_OFF; LCD_CLK_OFF; SPI.transfer(0x2c); LCD_CS_ON; //data LCD_RS_ON; LCD_CLK_OFF; LCD_CS_OFF; SPI.transfer(0x1a); LCD_CS_ON; } } delay(1000); SPI.end(); }В моем примере мне надо CS дергать вниз, на сколько я понимаю CS и SS из описния библиотеки SPI это одно и то же. В какое он состояние переходит при инициализации интерфеса?
Вот реализация begin
void SPIClass::begin() { // Set SS to high so a connected chip will be "deselected" by default digitalWrite(SS, HIGH); // When the SS pin is set as OUTPUT, it can be used as // a general purpose output port (it doesn't influence // SPI operations). pinMode(SS, OUTPUT); // Warning: if the SS pin ever becomes a LOW INPUT then SPI // automatically switches to Slave, so the data direction of // the SS pin MUST be kept as OUTPUT. SPCR |= _BV(MSTR); SPCR |= _BV(SPE); // Set direction register for SCK and MOSI pin. // MISO pin automatically overrides to INPUT. // By doing this AFTER enabling SPI, we avoid accidentally // clocking in a single bit since the lines go directly // from "input" to SPI control. // http://code.google.com/p/arduino/issues/detail?id=888 pinMode(SCK, OUTPUT); pinMode(MOSI, OUTPUT); }Тут видно, что ss переводится в high.
Получается что по этому ничего не работает?
Вот реализация transfer
byte SPIClass::transfer(byte _data) { SPDR = _data; while (!(SPSR & _BV(SPIF))) ; return SPDR; }У меня Duemilanova, если что вдруг. Есть какие то мысли?
вы вопросы здесь для чего задаете? вам MaksMS совершенно конкретный совет дал. Вы его проигнорировали, начитались разрозненной ерунды. Пользуетесь ардуино - читайте первоисточники http://arduino.cc/en/Reference/SPI
Я конечно понимаю, что код длинный, вы бы хоть в конец посмтрели. Я же написал свои конкретные вопросы и именно первоисточник я и цитирую. И все равно меня не покидает мысли что вы мой пости ли не прочитали ил не поняли. Еще раз повторяю - я сделал именно как советовали - не заработало, именно та часть, которая должна испльзовать SPI. То, что код, который я привел последним отличается от того что я приводил в первом посте - всего лишь значит, что я использую этот кусок как более удобный в отладке. И он так же хорошо работает, но не через SPI.
Я конечно понимаю, что код длинный, вы бы хоть в конец посмтрели. Я же написал свои конкретные вопросы и именно первоисточник я и цытирую. И все равно меня не покидает мысли что вы мой пости ли не прочитали ил не поняли.
я прочитал ваши посты, но извините, не вижу в них ни одного осознанного вопроса, идет повествование
вы привели пример реализации SPI transfer прямым обращением к регистрам МК. Зачем? Вы попробовали просто взять и использовать стандартную библиотеку SPI? Этот совет в этой ветке звучит уже 4-й раз. Я не знаю в каких форумах вы нахватали слухов и кусков кода, поэтому что-то на ваше повествование ответить сложно. Про пин SS написано по моей ссылке выше. обычно его не используют, оставляют не подключенным, потому что его подключение не позволяет подключать к шине SPI больше одного устройства. С одним устройством можно использовать именно его
Вы бы в эту библиотеку заглянули, и унали бы что там написано...эх зажили бы...Я ведь вам и привел реализацию из библотеки то...для наглядности.
А спрашиваю я уже третий раз, при вызове последовательнсоти begin transfer end как меняется cs? он же ss.
Ничто не мешает после begin установить нужный уровень CS по умолчанию,а потом его уже дергать в нужную сторону..
Вы бы в эту библиотеку заглянули, и унали бы что там написано...эх зажили бы...Я ведь вам и привел реализацию из библотеки то...для наглядности.
А спрашиваю я уже третий раз, при вызове последовательнсоти begin transfer end как меняется cs? он же ss.
зачем мне заглядывать в библиотеку которой я не пользуюсь? Но вы могли бы ее взять и просто использовать вместо того, чтобы разбираться с чужими кусками кода. Если же хотите разобраться с сутью происходящего, то читайте раздел SPI (19-й параграф), если у вас МК мега 328p то тут http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf
Там все подробно расписано и про то что происходит и про SS в частности.
В частности. CS - chip select или что в данном контексте тоже самое SS - slave select используется для активации того устройства на шине SPI с которым в данный момент МК производит сессию связи. Обычно для активации используется логический ноль (надо смотреть что написано в документе на конкретное устройство/чип). Логика простая - в начале любого обмена с устройством выставляем на CS ноль, по завершении обмена ставим там единицу.
посмотрите в свой код - у вас перед каждым shiftOut стоит
LCD_CS_OFF - перевод CS в нольвсе что вам нужно - в setup() сделать инициализацию библиотеки SPI, настроить на нужный режим и это нужно сделать до первого вызова shifyOut(). Сами shiftOut() заменить на transfer()Почему собственно так было сделано, как у меня сейчас - что бы небыло проблем с инициализацие дисплея. То есть на момент инициализации SPI дисплей готов принимать команды. В чем осбственно проблема инициализировать SPI в теле?
Нашел я реализацию вот такую. http://playground.arduino.cc/S1D15G10NokiaLCD/S1D15G10NokiaLCD Буду ее пробовать и паралельно в протеусе попробую свой код прогнать через логический анализатор.