#include #include #define SPI_PORTX PORTB #define SPI_DDRX DDRB #define SPI_MISO 4 #define SPI_MOSI 3 #define SPI_SCK 5 #define SPI_SS 2 enum calculator_state { NUMBER_FIRST, NUMBER_SECOND, RESULT }; enum calculator_op { NO_OP, //0 ADD, // 1 SUB, DIV, MUL }; struct calculator { // 1 число int num1; // 2 число int num2; // 3 операция enum calculator_op operation; // 4 результат double result; // 5 состояние атомата enum calculator_state state; }; void output_on_display(struct calculator * calc) { char buffer[8]; switch (state) { case NUMBER_FIRST: size_t b_size = display_all_clear(0, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); //первое число char[12] string_num; itoa(calc.num1, &string_num, 10); b_size = display_add_simbol(&string_num, strlen(string_num), &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case NUMBER_SECOND: size_t b_size = display_all_clear(0, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); //первое число b_size = display_add_simbol(&string_num, strlen(string_num), &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); // операция switch (calc.operation) { case NO_OP: break; case ADD: b_size = display_add_simbol("+", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case SUB: b_size = display_add_simbol("-", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case DIV: b_size = display_add_simbol("/", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case MUL: b_size = display_add_simbol("*", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; } // второе число char[12] string_num; itoa(calc.num2, &string_num, 10); b_size = display_add_simbol(&string_num, strlen(string_num), &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case RESULT: size_t b_size = display_all_clear(0, size_buffer); SPI_MasterTransmit(&buffer[0], b_size); // первое число b_size = display_add_simbol(&string_num, strlen(string_num), &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); // операция switch (calc.operation) { case NO_OP: break; case ADD: b_size = display_add_simbol("+", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case SUB: b_size = display_add_simbol("-", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case DIV: b_size = display_add_simbol("/", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; case MUL: b_size = display_add_simbol("*", 1, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; } // второе число b_size = display_add_simbol(&string_num, strlen(string_num), &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); // линия b_size = display_draw_line( , , , , 0, &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); // результат char[12] string_num; itoa(calc.result, &string_num, 10); b_size = display_add_simbol(&string_num, strlen(string_num), &buffer[0]); SPI_MasterTransmit(&buffer[0], b_size); break; default: display_all_clear(0, size_buffer); } } void SPI_MasterInit(void) { /* Настройка MOSI и SCK как выход, все остальные сигналы как вход: */ SPI_DDRX = (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS) | (0 << SPI_MISO); /* Разрешить работу SPI, режим Master, установить скорость тактов fck/16: */ SPCR = (1 << SPE) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (1 << SPR0); SPI_PORTX |= (1 << SPI_SS); } void SPI_MasterTransmit(char* buffer, size_t length) { SPI_PORTX &= ~(1 << SPI_SS); for (int i = 0; i < length; i++ ) { SPDR = buffer[i]; while (!(SPSR & (1 << SPIF))); Serial.println("Transmitede"); delay(2000); } SPI_PORTX |= (1 << SPI_SS); } byte crc8(byte *data, int length) { byte crc = 0x00; byte poly = 0x07; //полином для CRC 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 setup() { SPI_MasterInit(); Serial.begin(9600); Serial.println("Arduino 1 starded"); } void loop() { char buffer[] = {'a', 't', 'g', '1', 0}; for (int y = 5; y < 21; y++) { // buffer[0] = 0x06; // buffer[1] = 3; // buffer[2] = y; // buffer[3] = 0x01; // buffer[4] = crc8(&buffer[0], 4); SPI_MasterTransmit(&buffer[0], 5); } } //очищение экранa size_t display_all_clear(char color, uint8_t* buffer, size_t *size_b) { buffer[0] = 0x01; buffer[1] = color; buffer[2] = crc8(&buffer[0], 2); // int a[17]; // size_t n = sizeof(a) / sizeof(a[0]); return 3; } //выбор точки size_t display_set_page(char point, uint8_t* buffer) { buffer[0] = 0x02; buffer[1] = point; buffer[2] = crc8(&buffer[0], 2); return 3; } //добавление нового символа и его параметров size_t display_add_simbol(char* str, size_t str_len, uint8_t* buffer) { size_t idx; buffer[idx] = 0x04; idx++; for (int i = 0; i < str_len; i++) { buffer[idx] = str; idx++; } buffer[idx] = crc8(&buffer[0], idx); idx++; return idx; } //удаление символа и его параметров size_t display_del_simbol(char number, uint8_t* buffer) { buffer[0] = 0x05; buffer[1] = number; buffer[2] = crc8(&buffer[0], 2); return 3; } //закрашивание пикселя size_t display_draw_pixel(char x, char y, char color, uint8_t* buffer) { buffer[0] = 0x06; buffer[1] = x; buffer[2] = y; buffer[3] = color; buffer[4] = crc8(&buffer[0], 4); return 5; } //рисует линию size_t display_draw_line(char x1, char y1, char x2, char y2, char color, uint8_t* buffer) { buffer[0] = 0x07; buffer[1] = x1; buffer[2] = y1; buffer[3] = x2; buffer[4] = y2; buffer[5] = color; buffer[6] = crc8(&buffer[0], 6); return 7; } //рисует круг size_t display_draw_circle(char x, char y, char r, char color, uint8_t* buffer) { buffer[0] = 0x08; buffer[1] = x; buffer[2] = y; buffer[3] = r; buffer[4] = color; buffer[5] = crc8(&buffer[0], 5); return 6; } //рисует прямоугольник size_t display_draw_rectangle(char x, char y, char height, char width, char color, uint8_t* buffer) { buffer[0] = 0x09; buffer[1] = x; buffer[2] = y; buffer[3] = height; buffer[4] = widht; buffer[5] = color; buffer[6] = crc8(&buffer[0], 6); return 7; }