226 lines
5.4 KiB
C++
226 lines
5.4 KiB
C++
#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,
|
||
ADD,
|
||
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[];
|
||
size_t size_buffer;
|
||
switch (state) {
|
||
case NUMBER_FIRST:
|
||
display_all_clear( 0, &buffer[0]);
|
||
SPI_MasterTransmit(&buffer[0], size_buffer);
|
||
displ1ay_add_simbol( , , &buffer[0]);
|
||
SPI_MasterTransmit(&buffer[0], 1);
|
||
break;
|
||
case NUMBER_SECOND:
|
||
display_all_clear();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
break;
|
||
case RESULT:
|
||
display_all_clear();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_draw_line();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
display_add_simbol();
|
||
SPI_MasterTransmit(&buffer[0], )
|
||
break;
|
||
default:
|
||
display_all_clear();
|
||
}
|
||
}
|
||
|
||
|
||
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) {
|
||
buffer[0] = 0x01;
|
||
buffer[1] = color;
|
||
buffer[2] = crc8(&buffer[0], 2);
|
||
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;
|
||
}
|