terminal/MASTER.ino

280 lines
7.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <avr/interrupt.h>
#include <avr/io.h>
#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;
}