#include <avr/interrupt.h> #include <avr/io.h> #include <string.h> #include <util/delay.h> #include "spi_master.h" #include "func.h" #include <stdlib.h> #define MAX_DIGITS 12 #define F_CPU 16000000UL #define DELAY_MS 2000 void output_on_display(struct calculator *calc) { char buffer[32]; 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); transmit_num(calc->num1, buffer); 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); transmit_num(calc->num1, buffer); 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); transmit_num(calc->num2, buffer); 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); transmit_num(calc->num1, buffer); 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); transmit_num(calc->num2, buffer); // ðåçóëüòàò 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); transmit_num(calc->result, buffer); break; } default: display_all_clear(0, buffer); } } void transmit_num(long number, char *buffer) { char number_buffer[MAX_DIGITS]; char mapped_digits[MAX_DIGITS]; ltoa(number, number_buffer, 10); map_digits(mapped_digits, number_buffer, strlen(number_buffer)); size_t b_size = display_add_simbol(mapped_digits, strlen(number_buffer), buffer); SPI_MasterTransmit(buffer, b_size); } 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; }