

struct Cursor_Data
{
enum Object id; //идентификатор объекта
int8_t y; //координаты верхнего левого угла курсора
int8_t x; //координаты верхнего левого угла курсора
int8_t height; //высота курсора
int8_t width; //ширина курсора
uint8_t to_redraw; //флаг "отрисовать"
//параметры для раскадровки
uint32_t count_frame; //счетчик кадров
uint32_t max_count_frame; //максимальное количество кадров - если применимо
uint32_t period_frame; //"скорость" изменения кадров в периодах тика метода проверки объектов 
// первая линия
float angle = -(PI/2) + angle_by_frame * cur_struct->count_frame; //угол линии
float angle_corner = atan(cur_struct->height / cur_struct->width); //тригонометрический угол для угла прямоугольника курсора
if(angle >= -angle_corner && angle <= angle_corner)
{//начало линии на левой границе прямоугольника курсора
x = cur_struct->x;
y = y_c - tan(angle) * cur_struct->width/2.0;
}
if(angle > angle_corner)
{//начало линии на верхней границе прямоугольника курсора
y = cur_struct->y;
x = x_c - tan(PI/2 - angle) * cur_struct->height/2.0;
}
if(angle < -angle_corner)
{//начало линии на нижней границе прямоугольника курсора
y = cur_struct->y + cur_struct->height;
x = x_c - tan(PI/2 + angle) * cur_struct->height/2.0;
}
//ветки
ssd1331_draw_line( x, y , x_c + (x_c - x), y_c + (y_c - y) , Color); //первая ветка 
//проверяем наступило ли событие раскадровки объекта
if(count_check % Cursor_->period_frame ==0)
{ //наступило время сменить кадр
Cursor_->Draw_Cursor(Cursor_, 1); //очистка старого места курсора
check_draw_obj_by_cursor(Object, num_objs, Cursor_); //для объектов, которые перекрывались курсором ставим флаг безусловной перерисовки
if(Cursor_->count_frame< Cursor_->max_count_frame-1)
Cursor_->count_frame++; //следующий кадр для отрисовки
else
Cursor_->count_frame=0; //следующий кадр для отрисовки
Cursor_->to_redraw = 1; // нужно потом перерисовать курсор в новом месте
} 

1. Рисуем все примитивы в один буфер памяти
2. Перебрасываем графический индикатор одной транзакцией:

//мультибайтная передача данных в графический экран
void _sendMultiData(uint8_t* data, uint16_t count)
{
__SSD1331_DC_SET();
__SSD1331_CS_CLR();
HAL_SPI_Transmit(get_hspi1(), data, count, 100);
__SSD1331_CS_SET();
} 
//копирование данных из буфера в графический индикатор
void SSD1331_UpdateScreen(void)
{
//set column point
ssd1331_write_byte(SET_COLUMN_ADDRESS, SSD1331_CMD);
ssd1331_write_byte(0, SSD1331_CMD);
ssd1331_write_byte(OLED_WIDTH-1, SSD1331_CMD);
//set row point
ssd1331_write_byte(SET_ROW_ADDRESS, SSD1331_CMD);
ssd1331_write_byte(0, SSD1331_CMD);
ssd1331_write_byte(OLED_HEIGHT-1, SSD1331_CMD);
_sendMultiData((uint8_t*)SSD1331_Buffer, OLED_WIDTH*OLED_HEIGHT*2);
} 
| Стартуем! |
| Дальше |
| Проверить |
| Узнать результат |
| Дальше |
| Проверить |
| Узнать результат |
| Дальше |
| Проверить |
| Узнать результат |
| Пройти еще раз |
| Пройти еще раз |
| Пройти еще раз |