k210单片机显示屏制作一个表盘

前言

主控采用k210单片机,屏幕为nt35310,采用image2lcd取模制作
哔哩哔哩视频

表盘处理

获取表盘图片

首先在网上获取一张比较好看的表盘图片

在这里插入图片描述
对图片进行处理,去除指针
在这里插入图片描述

转换c文件

这里使用image2lcd工具进行转换
在这里插入图片描述
点击保存转换为clock.h文件。
在这里插入图片描述

显示在屏幕上

在头文件中加入

#include  "clock.h"

定义一个show_time函数

void show_time()
{
    lcd_draw_picture_by_half(20,20,200,200,gImage_clock);

}

lcd_draw_picture_by_half为使用屏幕所带的显示图片函数,这时便可在屏幕上看到时钟。

旋转的指针

点(x,y)绕中心点(x0,y0)旋转后d°的坐标为
x1= x0+(x - x0)cos(dπ/180) - (y - y0)sin(dπ/180) ;
y1= y0+(x - x0)sin(dπ/180) + (y - y0)cos(dπ/180) ;
有了变换公式,我们便可以有指针变换前位置求出变换后位置,
然后从变换后到旋转中心做一条直线,即为时钟指针
定义一个时钟结构体

typedef struct _clock_time_
{   
    uint16_t middle_x;//表盘中点x
    uint16_t middle_y;//表盘中点y
    uint16_t hour_start[6];//时针起点x1,y1,x2,y2,x3,y3一共3个点
    uint16_t hour_end[6];//时针终点
    uint16_t minute_start[4];
    uint16_t minute_end[4];
    uint16_t second_start[2];
    uint16_t second_end[2];
}clock_info_t;
clock_info_t clock_info={
 100,100,{99,100,100,100,101,100},{100,60,100,60,100,60},
 {100,100,101,100},{100,50,100,50},{100,100},{100,40}
 };

由于k210的写点函数速度比较慢,采用dma将图片传输到内存中,对内存图片进行处理,然后进行刷屏。

double_t angle_covert(uint16_t angle)//角度转弧度
{
    double_t pi=3.14159265;
    return (pi*angle/180);
}
void rotate(int16_t mx,int16_t my, int16_t  x1,int16_t y1, int16_t * x,int16_t * y, uint16_t angle)//坐标变换函数
{

    *x=(int16_t)(mx+(x1-mx)*cos(angle_covert(angle))-(y1-mx)*sin(angle_covert(angle))) ;
    *y=(int16_t)(my+(x1-mx)*sin(angle_covert(angle))+(y1-mx)*cos(angle_covert(angle)));

}
void draw_line_ram(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t *str,uint16_t w,uint16_t color)//画直线函数
{
        uint16_t t;
    int xerr = 0, yerr = 0, delta_x, delta_y, distance;
    int incx, incy, uRow, uCol;
    delta_x = x2 - x1; 
    delta_y = y2 - y1;
    uRow = x1;
    uCol = y1;
    if (delta_x > 0)
        incx = 1; 
    else if (delta_x == 0)
        incx = 0; 
    else
    {
        incx = -1;
        delta_x = -delta_x;
    }
    if (delta_y > 0)
        incy = 1;
    else if (delta_y == 0)
        incy = 0; //ˮƽÏß
    else
    {
        incy = -1;
        delta_y = -delta_y;
    }
    if (delta_x > delta_y)
        distance = delta_x; 
    else
        distance = delta_y;
    for (t = 0; t <= distance + 1; t++) 
    {
        //lcd_draw_point(uRow, uCol, color); //如果使用的单片机写点速度较快,可以直接写入屏幕
        *(str+uRow+uCol*w)=color;//这里直接在内存中处理
        xerr += delta_x;
        yerr += delta_y;
        if (xerr > distance)
        {
            xerr -= distance;
            uRow += incx;
        }
        if (yerr > distance)
        {
            yerr -= distance;
            uCol += incy;
        }
    }

}
void write_hour(uint16_t ho,uint16_t color,uint32_t *mubiao)//画时针
{
            uint16_t hour_start[6];
            uint16_t hour_end[6];
            for(uint16_t i =0;i<3;i++)
            {
                ho=ho%12;
                uint16_t angle=ho*30;
                rotate(100,100,clock_info.hour_start[i*2],clock_info.hour_start[i*2+1],hour_start+i*2,hour_start+i*2+1,angle);
                rotate(100,100,clock_info.hour_end[i*2],clock_info.hour_end[i*2+1],hour_end+i*2,hour_end+i*2+1,angle);
            }
              for(uint16_t i =0;i<3;i++)
            draw_line_ram(hour_end[i*2],hour_end[i*2+1],hour_start[i*2],hour_start[i*2+1],mubiao,200,color);

}
void write_minute(uint16_t mi,uint16_t color,uint32_t *mubiao)//画分针
{
            uint16_t minute_start[4];
            uint16_t minute_end[4];

            for(uint16_t i =0;i<2;i++)
            {
                uint16_t angle=mi*6;
                rotate(100,100,clock_info.minute_start[i*2],clock_info.minute_start[i*2+1],minute_start+i*2,minute_start+i*2+1,angle);
                rotate(100,100,clock_info.minute_end[i*2],clock_info.minute_end[i*2+1],minute_end+i*2,minute_end+i*2+1,angle);
            }
              for(uint16_t i =0;i<2;i++)
            draw_line_ram(minute_start[i*2],minute_start[i*2+1],minute_end[i*2],minute_end[i*2+1],mubiao,200,color);
}
void write_second(uint16_t sc,uint16_t color,uint32_t *mubiao)//画秒针
{
     uint16_t second_start[2];
     uint16_t second_end[2];
     uint16_t angle=sc*6;
    rotate(100,100,clock_info.second_end[0],clock_info.second_end[1],second_end,second_end+1,angle);
      draw_line_ram(second_end[0],second_end[1],100,100,mubiao,200,color);
}

接下来便是主函数

        while(1)
       {
        dmac_wait_idle ( SYSCTL_DMA_CHANNEL_1 );
       dmac_set_single_mode ( SYSCTL_DMA_CHANNEL_1 , (uint32_t)gImage_clock,  mubiao , DMAC_ADDR_INCREMENT,DMAC_ADDR_INCREMENT , DMAC_MSIZE_4 , DMAC_TRANS_WIDTH_32 , 80000/4);             
        dmac_wait_done ( SYSCTL_DMA_CHANNEL_1);
          get_date_time();//获取时间
        write_hour(h,RED,mubiao);//画时针
        write_minute(m,GREEN,mubiao);
        write_second(s,BLUE,mubiao);
         lcd_draw_picture_by_half(20,20,200, 200,  mubiao);//刷屏
       
       }  



发布了4 篇原创文章 · 获赞 1 · 访问量 173

猜你喜欢

转载自blog.csdn.net/qq_33862616/article/details/105593054