#include "SPISlave.h" // #include #include GyverOLED oled; #define DDR_SPI DDRB #define DD_MOSI PB3 #define DD_MISO PB4 #define DD_SCK PB5 #define DD_SS PB2 // GyverOLED oled; static int index = 0; static int arIndex = 0; static char data[64]; // void SPI_SlaveInit(void) // { // DDR_SPI = (1 << DD_MISO); // SPCR = (1 << SPE) | (1 << SPIE); // } // biblary // внутренние константы #define OLED_WIDTH 128 #define OLED_HEIGHT_64 0x12 #define OLED_64 0x3F #define OLED_32 0x1F #define OLED_DISPLAY_OFF 0xAE #define OLED_DISPLAY_ON 0xAF #define OLED_COMMAND_MODE 0x00 #define OLED_ONE_COMMAND_MODE 0x80 #define OLED_DATA_MODE 0x40 #define OLED_ONE_DATA_MODE 0xC0 #define OLED_ADDRESSING_MODE 0x20 #define OLED_HORIZONTAL 0x00 #define OLED_VERTICAL 0x01 #define OLED_NORMAL_V 0xC8 #define OLED_FLIP_V 0xC0 #define OLED_NORMAL_H 0xA1 #define OLED_FLIP_H 0xA0 #define OLED_CONTRAST 0x81 #define OLED_SETCOMPINS 0xDA #define OLED_SETVCOMDETECT 0xDB #define OLED_CLOCKDIV 0xD5 #define OLED_SETMULTIPLEX 0xA8 #define OLED_COLUMNADDR 0x21 #define OLED_PAGEADDR 0x22 #define OLED_CHARGEPUMP 0x8D #define OLED_NORMALDISPLAY 0xA6 #define OLED_INVERTDISPLAY 0xA7 #define BUFSIZE_128x64 (128*64/8) #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_ADDR 0x3C const uint8_t _maxRow = 7; const uint8_t _maxY = SCREEN_HEIGHT - 1; const uint8_t _maxX = SCREEN_WIDTH - 1; // ========== I2C ========== #define I2C_FREQ 100000UL void i2c_begin(uint8_t address) { TWBR = ((F_CPU / I2C_FREQ) - 16) / 2; // Расчет предделителя для заданной частоты TWAR = (address << 1); // Установка адреса устройства } void i2c_endTransaction() { TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); // Отправка условия STOP } void i2c_beginTransmission(uint8_t address) { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Отправка условия START while (!(TWCR & (1 << TWINT))); // Ожидание завершения START TWDR = (address << 1); // Отправка адреса устройства TWCR = (1 << TWINT) | (1 << TWEN); // Отправка адреса while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи адреса } void i2c_write(uint8_t data) { TWDR = data; // Запись данных TWCR = (1 << TWINT) | (1 << TWEN); // Отправка данных while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи данных } // ========== Sender ========== uint8_t _writes = 0; void sendData(uint8_t data) { sendByteRaw(data); _writes++; if (_writes >= 16) { endTransm(); beginData(); } } void sendByteRaw(uint8_t data) { i2c_write(data); } void sendCommand(uint8_t cmd1) { beginOneCommand(); sendByteRaw(cmd1); endTransm(); } void sendCommand(uint8_t cmd1, uint8_t cmd2) { beginCommand(); sendByteRaw(cmd1); sendByteRaw(cmd2); endTransm(); } void setWindow(int x0, int y0, int x1, int y1) { beginCommand(); sendByteRaw(OLED_COLUMNADDR); sendByteRaw(constrain(x0, 0, _maxX)); sendByteRaw(constrain(x1, 0, _maxX)); sendByteRaw(OLED_PAGEADDR); sendByteRaw(constrain(y0, 0, _maxRow)); sendByteRaw(constrain(y1, 0, _maxRow)); endTransm(); } void beginData() { startTransm(); sendByteRaw(OLED_DATA_MODE); } void beginCommand() { startTransm(); sendByteRaw(OLED_COMMAND_MODE); } void beginOneCommand() { startTransm(); sendByteRaw(OLED_ONE_COMMAND_MODE); } void endTransm() { i2c_endTransaction(); _writes = 0; } void startTransm() { i2c_beginTransmission(OLED_ADDR); } void oled_init(){ i2c_begin(OLED_ADDR); beginCommand(); // 15 sendData(OLED_DISPLAY_OFF); sendData(OLED_CLOCKDIV); sendData(0x80); sendData(OLED_CHARGEPUMP); sendData(0x14); sendData(OLED_ADDRESSING_MODE); sendData(OLED_VERTICAL); sendData(OLED_NORMAL_H); sendData(OLED_NORMAL_V); sendData(OLED_CONTRAST); sendData(0x7F); sendData(OLED_SETVCOMDETECT); sendData(0x40); sendData(OLED_NORMALDISPLAY); sendData(OLED_DISPLAY_ON); // 15 endTransm(); beginCommand(); sendData(OLED_SETCOMPINS); sendData(OLED_HEIGHT_64); sendData(OLED_SETMULTIPLEX); sendData(OLED_64); endTransm(); } ISR(SPI_STC_vect) { char received = SPDR; data[index] = received; index++; } void setup() { Serial.begin(9600); SPI_SlaveInit(); oled_init(); oled.fill(0); oled.setScale(3); oled.home(); Serial.println(); Serial.println("Initialization "); } void SetCommand(char *data2, int length){ char command = data2[0]; // Отрезать 1 элемент от оставшихся Serial.print("\nReceived command: "); Serial.println(command, HEX); switch (command){ case 1: AllClear(&data2[1], length-1); break; case 2: SetPage(&data2[1], length-1); break; // case 6: // PrintMassive(&data2[1], length-1); // break; case 4: AddSymbol(&data2[1], length-1); break; case 5: DelSymbol(&data2[1], length-1); break; case 6: DrawPixel(&data2[1], length-1); PrintMassive(&data2[1], length-1); break; case 7: DrawLine(&data2[1], length-1); break; case 8: DrawCircle(&data2[1], length-1); break; case 9: DrawRectangle(&data2[1], length-1); break; } } void PrintMassive(uint8_t *symbols, int lenght){ Serial.print("Received Add: "); // oled.setScale(3); // масштаб текста (1..4) // oled.home(); // курсор в 0,0 // oled.print("Привет!"); for(int i = 0; i < lenght - 1; i++) { char str[3]; sprintf(str, "%01X", symbols[i]); Serial.print(str); Serial.print(" "); } } // Another // command 1 void AllClear(char *symbols, int lenght){ int param = symbols[0]; if (param == 1){ oled.fill(0); } else{ oled.fill(255); } } // command 2 void SetPage(char *symbols, int lenght){ int x = symbols[0]; int y = symbols[1]; oled.setCursor(x,y); } // command 4 void AddSymbol(char *symbols, int lenght) { for (int i = 0; i < lenght - 1; i++) { oled.print(symbols[i]); } } // command 5 void DelSymbol(char *symbols, int lenght) { for (int i = 0; i < lenght - 1; i++) { oled.print(symbols[i]); } } // command 6 void DrawPixel(char *symbols, int lenght){ int x = symbols[0]; int y = symbols[1]; int color = symbols[2]; oled.dot(x,y,color); } // command 7 void DrawLine(char *symbols, int lenght){ int x = symbols[0]; int y = symbols[1]; int x1 = symbols[2]; int y1 = symbols[3]; int color = symbols[4]; oled.line(x,y,x1,y1,color); } // command 8 void DrawCircle(char *symbols, int lenght){ int x = symbols[0]; int y = symbols[1]; int r = symbols[2]; int color = symbols[3]; oled.circle(x,y,r,color); } // command 9 void DrawRectangle(char *symbols, int lenght){ int x = symbols[0]; int y = symbols[1]; int x1 = symbols[2]; int y1 = symbols[3]; int color = symbols[4]; oled.rect(x,y,x1,y1,color); } // Функция для вычисления контрольной суммы XOR // char CRC8(char *data, int length) { // char crc = 0x00; // char poly = 0x07; // полином для CRC8 // for (int i = 0; i < length-2; i++) { // crc ^= data[i]; // XOR текущего байта с crc // for (int j = 0; j < length; j++) { // if (crc & 0x80) { // если старший бит crc равен 1 // crc = (crc << 1) ^ poly; // сдвигаем crc на 1 бит влево и XOR с полиномом // } else { // crc <<= 1; // иначе просто сдвигаем на 1 бит влево // } // } // } // return crc; // } // Вывод массива void arrayOut(uint8_t *arr, int size){ Serial.print("Array: "); for(int i = 0; i < size;i++){ char str[3]; sprintf(str, "%02X", arr[i]); Serial.print(str); Serial.print(" "); } Serial.println("."); } // Проверка массива на ноль // char checkArray(char *arr, int size) { // for (int i = 0; i < size; i++) { // if (arr[i] != 0) { // return 1; // } // } // return 0; // } // TODO: где то длина массива неправильно летит void loop() { if(PINB & (1 << 2)){ if(index > 0){ arrayOut(data, index); char sum = 0; sum = crc8(data, index-1); char checkNull = 0; char last_1 = data[index - 1]; Serial.println(sum, HEX); if (last_1 == sum){ Serial.println(); Serial.println("Старт вывода массивов"); Serial.println(sum, HEX); SetCommand(data, index); // oled.print(data[0]); Serial.println("Стоп вывода массивов"); index = 0; return; }else{ Serial.println("Nothing ..."); index = 0; } } } }