主控采用k210单片机,屏幕为nt35310,采用image2lcd取模制作
哔哩哔哩视频
首先在网上获取一张比较好看的表盘图片
对图片进行处理,去除指针
这里使用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)
{
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);//刷屏
}