From 5fe0a6d3e49ee70e849dc1580014b5bdbe118743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=91=D0=B0=D1=82?= =?UTF-8?q?=D1=83=D1=85=D1=82=D0=B8=D0=BD?= Date: Sat, 3 Jun 2023 19:11:52 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BF=D0=BE=20?= =?UTF-8?q?SPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spi_master.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++++ spi_master.h | 20 ++++ 2 files changed, 305 insertions(+) create mode 100644 spi_master.c create mode 100644 spi_master.h diff --git a/spi_master.c b/spi_master.c new file mode 100644 index 0000000..ea220b7 --- /dev/null +++ b/spi_master.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include "spi_master.h" +#include "func.h" + +#define MAX_DIGITS 11 +#define F_CPU 16000000UL +#define DELAY_MS 3000 + +void output_on_display(struct calculator *calc) +{ + char buffer[8]; + switch (calc->state) + { + case NUMBER_FIRST: + { + size_t b_size = display_all_clear(0, buffer); + SPI_MasterTransmit(buffer, b_size); + + b_size = display_set_page(0x01, buffer); + SPI_MasterTransmit(buffer, b_size); + + int size = count_digits(calc->num1); + char mapped_digits[size]; + prepare_data(mapped_digits, calc->num1, size); + b_size = display_add_simbol(mapped_digits, size, buffer); + SPI_MasterTransmit(buffer, b_size); + + break; + } + case NUMBER_SECOND: + { + size_t b_size = display_all_clear(0, buffer); + SPI_MasterTransmit(buffer, b_size); + + b_size = display_set_page(0x01, buffer); + SPI_MasterTransmit(buffer, b_size); + + int size = count_digits(calc->num1); + char mapped_digits[size]; + prepare_data(mapped_digits, calc->num1, size); + b_size = display_add_simbol(mapped_digits, size, buffer); + SPI_MasterTransmit(buffer, b_size); + + char symbol[] = {0x01}; + // операция + switch (calc->operation) + { + case NO_OP: + break; + case ADD: + symbol[0] = 0x04; + break; + case SUB: + symbol[0] = 0x06; + break; + case DIV: + symbol[0] = 0x08; + break; + case MUL: + symbol[0] = 0x03; + break; + } + + b_size = display_add_simbol(symbol, 1, buffer); + SPI_MasterTransmit(buffer, b_size); + + b_size = display_set_page(0x02, buffer); + SPI_MasterTransmit(buffer, b_size); + + size = count_digits(calc->num2); + char mapped_digits1[size]; + prepare_data(mapped_digits1, calc->num2, size); + b_size = display_add_simbol(mapped_digits1, size, buffer); + SPI_MasterTransmit(buffer, b_size); + break; + } + case RESULT: + { + size_t b_size = display_all_clear(0, buffer); + SPI_MasterTransmit(buffer, b_size); + + b_size = display_set_page(0x01, buffer); + SPI_MasterTransmit(buffer, b_size); + + int size = count_digits(calc->num1); + char mapped_digits[size]; + prepare_data(mapped_digits, calc->num1, size); + b_size = display_add_simbol(mapped_digits, size, buffer); + SPI_MasterTransmit(buffer, b_size); + + char symbol[] = {0x01}; + // операция + switch (calc->operation) + { + case NO_OP: + break; + case ADD: + symbol[0] = 0x04; + break; + case SUB: + symbol[0] = 0x06; + break; + case DIV: + symbol[0] = 0x08; + break; + case MUL: + symbol[0] = 0x03; + break; + } + + b_size = display_add_simbol(symbol, 1, buffer); + SPI_MasterTransmit(buffer, b_size); + + b_size = display_set_page(0x02, buffer); + SPI_MasterTransmit(buffer, b_size); + + size = count_digits(calc->num2); + char mapped_digits1[size]; + prepare_data(mapped_digits1, calc->num2, size); + b_size = display_add_simbol(mapped_digits1, size, buffer); + SPI_MasterTransmit(buffer, b_size); + + // линия + + + // результат + b_size = display_set_page(0x03, buffer); + SPI_MasterTransmit(buffer, b_size); + + symbol[0] = 0x15; + b_size = display_add_simbol(symbol, 1, buffer); + SPI_MasterTransmit(buffer, b_size); + + size = count_digits(calc->result); + char mapped_digits2[size]; + prepare_data(mapped_digits2, calc->result, size); + b_size = display_add_simbol(mapped_digits2, size, buffer); + SPI_MasterTransmit(buffer, b_size); + + break; + } + default: + display_all_clear(0, 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 << SPR1); + + 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))) + { + // ожидание завершения передачи + } + } + SPI_PORTX |= (1 << SPI_SS); + _delay_ms(DELAY_MS); +} + +char crc8(char *data, int len) { + char crc = 0x00; + while (len--) { + crc ^= *data++; + for (int i = 0; i < 8; i++) { + if (crc & 0x80) { + crc = (crc << 1) ^ 0x07; + } else { + crc <<= 1; + } + } + } + return crc; +} + +//очищение экранa +size_t display_all_clear(char color, char *buffer) +{ + buffer[0] = 0x01; + buffer[1] = color; + buffer[2] = crc8(buffer, 2); + return 3; +} + +//выбор точки +size_t display_set_page(char point, char *buffer) +{ + buffer[0] = 0x02; + buffer[1] = point; + buffer[2] = crc8(buffer, 2); + return 3; +} + +//добавление нового символа и его параметров +size_t display_add_simbol(char *str, size_t str_len, char *buffer) +{ + size_t idx = 0; + buffer[idx] = 0x03; + idx++; + for (int i = 0; i < str_len; i++) + { + buffer[idx] = str[i]; + idx++; + } + buffer[idx] = crc8(buffer, idx); + idx++; + return idx; +} + +//удаление символа и его параметров +size_t display_del_simbol(char number, char *buffer) +{ + buffer[0] = 0x04; + buffer[1] = number; + buffer[2] = crc8(buffer, 2); + return 3; +} + +//закрашивание пикселя +size_t display_draw_pixel(char x, char y, char color, uint8_t *buffer) +{ + buffer[0] = 0x05; + buffer[1] = x; + buffer[2] = y; + buffer[3] = color; + buffer[4] = crc8(buffer, 4); + return 5; +} + +//рисует линию +size_t display_draw_line(char x1, char y1, char x2, char y2, char color, char *buffer) +{ + buffer[0] = 0x06; + buffer[1] = x1; + buffer[2] = y1; + buffer[3] = x2; + buffer[4] = y2; + buffer[5] = color; + buffer[6] = crc8(buffer, 6); + return 7; +} + +//рисует круг +size_t display_draw_circle(char x, char y, char r, char color, uint8_t *buffer) +{ + buffer[0] = 0x07; + buffer[1] = x; + buffer[2] = y; + buffer[3] = r; + buffer[4] = color; + buffer[5] = crc8(buffer, 5); + return 6; +} + +//рисует прямоугольник +size_t display_draw_rectangle(char x, char y, char height, char width, char color, uint8_t *buffer) +{ + buffer[0] = 0x08; + buffer[1] = x; + buffer[2] = y; + buffer[3] = height; + buffer[4] = width; + buffer[5] = color; + buffer[6] = crc8(buffer, 6); + return 7; +} + + diff --git a/spi_master.h b/spi_master.h new file mode 100644 index 0000000..3826c9b --- /dev/null +++ b/spi_master.h @@ -0,0 +1,20 @@ +#define SPI_PORTX PORTB +#define SPI_DDRX DDRB +#define SPI_MISO 4 +#define SPI_MOSI 3 +#define SPI_SCK 5 +#define SPI_SS 2 + +#include "calculator.h" + +void output_on_display(struct calculator *calc); +void SPI_MasterInit(void); +void SPI_MasterTransmit(char *buffer, size_t length); +void transmit_first_num(struct calculator *calc, char *buffer); +void transmit_second_num(struct calculator *calc, char *buffer); +void transmit_result(struct calculator *calc, char *buffer, char *symblo); +size_t display_all_clear(char color, char *buffer); +size_t display_add_simbol(char *str, size_t str_len, char *buffer); +size_t display_draw_line(char x1, char y1, char x2, char y2, char color, char *buffer); +size_t display_del_simbol(char number, char *buffer); +size_t display_set_page(char point, char *buffer);