lcd彩屏画点画线和画圆 嵌入式开发

学习记录:调用TFTLCD液晶屏 显示器属于计算机的I/O设备,即输入输出设备。它是一种将特定电子信息输出到屏幕上再反射到人眼的显示工具。常见的有CRT显示器、液晶显示器、LED点阵显示器及OLED显示器。液晶显示器,简称LCD(LiquidCrystalDisplay),相对于上一代CRT显示器(阴极射线管显示器),LCD显示器具有功耗低、体积小、承载的信息量大及不伤眼的优点,因而它成为了现在的主流电子显示设备,其中包括电视、电脑显示器、手机屏幕及各种嵌入式设备的显示器。本液晶屏内部包含有一个。... 阅读详情

  转载于 : http://blog.youkuaiyun.com/p1126500468/article/details/50428613

亲测可行,觉得很有意义,拿过来以备以后用

  

 //-----------画点函数。参数:坐标,颜色-------------------
void draw_point(int x, int y, int clor)
{
    fb[y*480 + x] = clor;
}

//-------------画圆函数。参数:圆心,半径,颜色----------
//        画1/8圆 然后其他7/8对称画
//          ---------------->X
//          |(0,0)   0
//          |     7     1
//          |    6       2
//          |     5     3
//       (Y)V        4
//
//      L = x^2 + y^2 - r^2
void draw_circle(int x, int y, int r, int color)
{
    int a, b, num;
    a = 0;
    b = r;
    while(2 * b * b >= r * r)          // 1/8圆即可
    {
        draw_point(x + a, y - b,color); // 0~1
        draw_point(x - a, y - b,color); // 0~7
        draw_point(x - a, y + b,color); // 4~5
        draw_point(x + a, y + b,color); // 4~3

        draw_point(x + b, y + a,color); // 2~3
        draw_point(x + b, y - a,color); // 2~1
        draw_point(x - b, y - a,color); // 6~7
        draw_point(x - b, y + a,color); // 6~5
        
        a++;
        num = (a * a + b * b) - r*r;
        if(num > 0)
        {
            b--;
            a--;
        }
    }
}

//-----------画线。参数:起始坐标,终点坐标,颜色--------
void draw_line(int x1,int y1,int x2,int y2,int color)
{
    int dx,dy,e;
    dx=x2-x1; 
    dy=y2-y1;
    if(dx>=0)
    {
        if(dy >= 0) // dy>=0
        {
            if(dx>=dy) // 1/8 octant
            {
                e=dy-dx/2;
                while(x1<=x2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){y1+=1;e-=dx;}   
                    x1+=1;
                    e+=dy;
                }
            }
            else        // 2/8 octant
            {
                e=dx-dy/2;
                while(y1<=y2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){x1+=1;e-=dy;}   
                    y1+=1;
                    e+=dx;
                }
            }
        }
        else           // dy<0
        {
            dy=-dy;   // dy=abs(dy)
            if(dx>=dy) // 8/8 octant
            {
                e=dy-dx/2;
                while(x1<=x2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){y1-=1;e-=dx;}   
                    x1+=1;
                    e+=dy;
                }
            }
            else        // 7/8 octant
            {
                e=dx-dy/2;
                while(y1>=y2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){x1+=1;e-=dy;}   
                    y1-=1;
                    e+=dx;
                }
            }
        }   
    }
    else //dx<0
    {
        dx=-dx;     //dx=abs(dx)
        if(dy >= 0) // dy>=0
        {
            if(dx>=dy) // 4/8 octant
            {
                e=dy-dx/2;
                while(x1>=x2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){y1+=1;e-=dx;}   
                    x1-=1;
                    e+=dy;
                }
            }
            else        // 3/8 octant
            {
                e=dx-dy/2;
                while(y1<=y2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){x1-=1;e-=dy;}   
                    y1+=1;
                    e+=dx;
                }
            }
        }
        else           // dy<0
        {
            dy=-dy;   // dy=abs(dy)
            if(dx>=dy) // 5/8 octant
            {
                e=dy-dx/2;
                while(x1>=x2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){y1-=1;e-=dx;}   
                    x1-=1;
                    e+=dy;
                }
            }
            else        // 6/8 octant
            {
                e=dx-dy/2;
                while(y1>=y2)
                {
                    draw_point(x1,y1,color);
                    if(e>0){x1-=1;e-=dy;}   
                    y1-=1;
                    e+=dx;
                }
            }
        }   
    }
}

// 区域填色函数
// 参数:开始列数,结束列数,开始行数,结束行数,颜色
void fill_fb(int start_x, int end_x, int start_y, int end_y, unsigned short val)
{
    int i, j;
    for(i = start_y; i < end_y; i++)
    {
        for(j = start_x; j < end_x; j++)
        {
            fb[i*480 + j] = val;
        }
    }
}
void clr_fb(void)
{
    int i, j;
    for(i = 0; i < 272; i++)
    {
        for(j = 0; j < 480; j++)
        {
            fb[i*480 + j] = 0;
        }
    }
}


下面先简要介绍常用的画圆算法(Bresenham算法),然后再具体阐述笔者对该算法的改进。

    一个圆,如果画出了圆上的某一点,那么可以利用对称性计算余下的七段圆弧:Plot(x,y),Plot(y,x),Plot(y,-x),Plot(x,-y),Plot(-x,-y),Plot(-y,-x),Plot(-y,x),Plot(-x,y)。

    1、Bresenham 画圆算法。Bresenham算法的主要思想是:以坐标原点(0,0)为圆心的圆可以通过0度到45°的弧计算得到,即x从0增加到半径,然后利用对称性计算余下的七段圆弧。当x从0增加到时,y从R递减到。

    设圆的半径为R,则圆的方程为:

    f(x,y)=(x+1)2+y2-R2=0                                   (1)

    假设当前列(x=xi列)中最接近圆弧的像素已经取为P(xi,yi),根据第二卦限1/8圆的走向,下一列(x=xi+1列)中最接近圆弧的像素只能在P的正右方点H(xi+1,yi)或右下方点L(xi+1,yi-1)中选择,如图1所示。Bresenham画圆算法采用点T(x,y)到圆心的距离平方与半径平方之差D(T)作为选择标准,即

    D(T)=(x+1)2+y2-R2                                         (2)

    通过比较H、L两点各自对实圆弧上点的距离大小,即根据误差大小来选取,具有最小误差的点为绘制点。根据公式(2)得:

    对H(xi+1,yi)点有:D(H)=(xi+1)2+yi2-R2;

    对L(xi+1,yi-1)点有:D(L)=(xi+1)2+(yi-1)2-R2;

    根据Bresenham画圆算法,则选择的标准是:

    如果|D(H)|<|D(L)|,那么下一点选取H(xi+1,yi);

    如果|D(H)|>|D(L)|,那么下一点选取L(xi+1,yi-1);

    如果|D(H)|=|D(L)|,那么下一点可以取L(xi+1,yi-1),也可以选取H(xi+1,yi),我们约定选取H(xi+1,yi)。

 

    图1  Bresenham画圆算法点的选取

    综合上述情况,得:

    当|D(H)|>|D(L)|时,选取L点(xi+1,yi-1)为绘制点坐标;

    当|D(H)|<|D(L)|时,选取H点(xi+1,yi)为绘制点坐标。

    然后将选取的点坐标作为当前坐标,重复上述过程直至xi=或者yi=为止,(xi,yi)的初始值为(0,R)。

    以上便是Bresenham算法的主要思想,但是上述算法是在一个假设下:以坐标原点(0,0)为圆心。该假设实际上只是为了方便算法的研究。但在实际嵌入式LCD显示设备中,往往圆心坐标不是(0,0)点,而是以左上角为(0,0)点,这样就使得在实际运用中,需要对这个算法做很大的改进。

    另外,如果完全按照Bresenham画圆算法,那么就会涉及到浮点运算,这使得嵌入式编程十分烦琐,因为本系统中所有数据都是整型的,因此在这方面也要作一定的改进。下面根据本系统中嵌入式硬件特点和数据结构得特点,对这个算法进行改进。

    2、改进的Bresenham画圆算法。先假设起始点为(R,0),令Pi=(xi,yi)为当前的一点,那么我们就需要在Ti=(xi,yi+1)和Si=(xi-1,yi+1)中选取一点,如图2所示。

 

    图2 嵌入式LCD画圆时点的选取

    设(xi-1/2+e,yi+1)为S和T之间圆上的点,e是S、T中点到圆上点的误差,带入圆的方程(1)得:

    f(xi-1/2+e,yi+1)=(xi-1/2+e)2+(yi+1)2-R2=f(xi-1/2,yi+1)+2(xi-1/2)e+e2=0   (3)

    在式(3)中,令

    di="f"(xi-1/2,yi+1)=-2(xi-1/2)e-e2                                    (4)

    如果e<0,那么di>0,因此选择S=(xi-1,yi+1),根据(3)与(4)得:

    di+1=f(xi-1-1/2,yi+1+1)=di-2(xi-1)+2(yi+1)+1=di+2(yi+1-xi+1)+1         (5)

    如果e30,那么di£0,因此选择T=(xi,yi+1),根据(3)与(4)得:

    di+1=f(xi-1/2,yi+1+1)=di+2yi+1+1                                  (6)

    起始点是(R,0)的时候,根据(4)得di的初始值d0就是:

    d0=f(R-1/2,0+1)=(R-1/2)2+1-R2=5/4-R=1-R(由于编程中所用数据类型均为整型,故取1-R)。

    综合上述情况,得:

    当选取S=(xi-1,yi+1)时,那么di+1=di+2(yi+1-xi+1)+1;

    当选取T=(xi,yi+1)时,那么di+1=di+2yi+1+1;

    然后将选取的点坐标作为当前坐标,重复上述过程直至x=y,而不是xi=或者yi=,这样就可以不用作浮点数计算了。

    本项目中的LCD像素为640×480点阵,并且数据是八位的,当横坐标和纵坐标超过255时,那么数据就不能一次传送成功,因此需要通过字节操作来设定高字节,然后再传送低字节。因此,每次画圆上的点时要传送的参数至少是六个,圆心坐标是四个(因为要考虑圆心坐标可能大于255,因此要对其圆心坐标设置高、低字节),另外两个是圆上的点相对于圆心的坐标,但是最后要画一个点,需要四个参数,即改进的画圆算法为六个参数输入,四个参数输出。

    用C语言在嵌入式LCD上实现改进的Bresenham画圆算法的部分代码如下:

    voidMidBresenhamcircle(int R) 

    {

    intx,y,d;

    x="0";y=R;d=1-R;       

    while(x<y)

    {circlePoint(x,y);  

     if(d<0)  d+=2*x+3;  

    

       else

            {d+=2*(x-y)+5;

              y--;

             }

              x++;

     delay(900000);

     } 


令附上一个比较有意义的帖子http://www.dzsc.com/dzbbs/20050531/2007651911609418.html



以上内容 均来源于海之遥的博客 

纯属自己学习之用,分享一下,仅供学习交流



画圆算法 实验平台: (codeblocks+openCV1.0) 画圆算法: 阅读详情

相关推荐

嵌入式LCD屏幕驱动开发全解析:从硬件连接到软件优化实战

LCD屏幕驱动是嵌入式系统开发中的基础且关键技术,它负责实现微控制器与显示设备之间的通信与控制。其核心原理在于通过特定的通信协议(如SPI、I2C或8080并行接口)和时序,将指令与像素数据准确传输至屏幕控制器。这项技术的价值在于为各类嵌入式设备提供了人机交互的可视化界面,是智能硬件、工业控制等领域的基石。在实际应用中,开发者需深入理解初始化序列、显存操作及性能优化方法。本文聚焦于TFT-LCD与OLED的驱动开发,详细剖析了通信协议选择、底层函数封装、显示算法实现以及常见花屏、性能瓶颈等问题的排查与解决策

weixin_34245749的博客 711

lcd彩屏画点画线和画圆 嵌入式开发

在lcd显示屏上的指定点画出直线,点,圆 本文源于 海之遥的博客 http://blog.sina.com.cn/atpx1989            亲测可行,觉得很有意义,拿过来以备以后用 //-----------画点函数。参数:坐标,颜色------------------- void draw_point(int x, int y, int clor) { fb[

ppeng的博客 2万+

蓝桥杯嵌入式实战指南:从CubeMX到LCD驱动的快速开发

本文详细介绍了蓝桥杯嵌入式比赛中使用STM32CubeMX和HAL库快速开发LCD驱动的实战指南。从CubeMX工程配置到LCD代码移植,再到常见问题排查与性能优化,帮助开发者高效完成嵌入式开发任务,特别适合蓝桥杯参赛选手参考。

weixin_28278377的博客 389

S3C2440裸机------LCD_画点线圆

目录 1.画点 2.画线、圆 1.画点 我们首先实现画点的函数, #include "lcd.h" /* 实现画点 */ /* 获得LCD参数 */ static unsigned int fb_base; static int xres, yres, bpp; void fb_get_lcd_params(void) { get_lcd_params(&fb_base, &xres, &yres, &bpp); } /* rgb: 0x00RRGGB

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 666

从零开始:使用Arduino与Adafruit库点亮ST7789驱动1.3寸TFT彩屏

SPI(串行外设接口)是嵌入式系统中广泛使用的高速同步串行通信协议,它通过主从架构和全双工通信实现设备间高效数据交换。其技术价值在于简化硬件连接、提升传输速率,特别适用于显示驱动、存储设备等场景。在嵌入式显示领域,SPI常用于驱动TFT液晶屏,如ST7789控制器驱动的屏幕,这类屏幕在物联网设备、可穿戴设备和智能家居中广泛应用。本文以Arduino平台为例,结合Adafruit图形库,详细解析如何通过SPI接口驱动1.3寸TFT彩屏,涵盖硬件连接、库函数调用和常见问题排查,帮助开发者快速实现屏幕初始化、文本

weixin_33725270的博客 367

STM32驱动LCD全流程解析:从硬件连接到图形库构建

在嵌入式系统开发中,显示技术是实现人机交互的关键环节。其核心原理是通过微控制器按照特定时序协议,将图像数据准确传输到显示设备的显存中,从而控制像素点的亮灭与色彩。这项技术的工程价值在于能够将传感器数据、系统状态等信息可视化,极大地提升了嵌入式设备的交互能力与用户体验。从智能家居面板、工业HMI到便携式医疗设备,显示驱动都是实现功能的基础。本文聚焦于基于STM32的LCD驱动开发,深入剖析硬件接口选型、通信时序控制、显存管理及图形算法等核心模块,并针对常见的花屏、时序不匹配等工程难题提供解决方案,帮助开发者构

weixin_34184561的博客 429

LPC1788的LCD接口驱动真彩屏

#ifndef __LCD_H_ #define __LCD_H_ #include "common.h" #include "debugserial.h" #include "delay.h" #include "sdram.h" #define White 0xFFFFFF #define Black 0x000000 #defi...

weixin_30336061的博客 653

从零玩转1.8寸TFT彩屏:基于ILI9163C与HyperDisplay库的嵌入式GUI实战

TFT液晶显示屏作为嵌入式系统中实现人机交互的核心组件,其工作原理是通过驱动芯片控制每个像素的红、绿、蓝子像素透光,混合生成丰富色彩。SPI通信协议因其简单高效,成为中小屏显控的主流接口,主控通过MOSI、SCLK及片选信号与驱动芯片交互。在嵌入式开发中,图形库能大幅简化底层操作,提升开发效率。本文聚焦于采用ILI9163C驱动芯片的1.8英寸TFT模块,详细解析其硬件接口定义、电源方案兼容性,并深入实践基于HyperDisplay图形库的软件驱动、图形绘制与缓冲区管理,为物联网设备状态显示、简易交互界面等

weixin_30509393的博客 456

树莓派Pico驱动1.44寸SPI彩屏:从ST7735S原理到实战优化

SPI(串行外设接口)是一种广泛应用于嵌入式系统的高速同步串行通信协议,通过主从架构和时钟同步机制实现全双工数据传输。其核心原理基于四线制(SCK、MOSI、MISO、CS)的时序控制,具有引脚少、速率高、协议简单的特点,成为微控制器连接显示屏、传感器等外设的主流方案。在嵌入式显示领域,SPI协议的技术价值在于能以较低硬件开销驱动彩色LCD,实现图形化人机交互。典型的应用场景包括物联网设备状态显示、便携式仪器仪表和微型游戏机等。本文以树莓派Pico驱动ST7735S芯片的1.44寸LCD为例,深入解析SPI

weixin_30633405的博客 322

RP2040驱动1.8寸SPI LCD:从底层时序到DMA双缓冲优化全解析

SPI(串行外设接口)是嵌入式系统中连接微控制器与外围设备(如传感器、存储器、显示屏)的经典同步串行通信协议。其工作原理基于主从架构,通过时钟线(SCK)、数据线(MOSI/MISO)和控制线(CS)实现全双工通信,核心在于精确的时序控制与模式配置。掌握SPI对于实现高效、稳定的外设驱动至关重要,尤其在需要高速数据传输的显示应用场景中。LCD(液晶显示器)作为最常见的人机交互界面,其驱动涉及初始化序列、色彩格式转换与显存管理。针对RP2040微控制器与1.8寸SPI LCD的组合,通过深入解析ST7735S

weixin_30838873的博客 373

ArduPy脚本化驱动Wio Terminal LCD:Python快速硬件开发实践

在嵌入式开发领域,Python因其简洁语法和快速迭代能力,正通过MicroPython及其衍生框架(如ArduPy)拓展到硬件编程场景。其核心原理在于将Python解释器移植到微控制器,通过高级脚本语言直接操作底层硬件寄存器,实现了无需编译、即写即跑的开发模式。这一技术价值在于极大降低了硬件交互的门槛,使开发者能专注于功能逻辑而非底层细节,特别适用于原型验证、教育演示和快速工具开发。在应用场景上,它广泛应用于物联网设备、数据可视化终端和交互式教学装置中。本文以Wio Terminal开发板为例,深入探讨了如

weixin_30437847的博客 328

【扩展】【程序】使用硬件SPI驱动1.3寸TFT彩屏

使用STM32F103C8T6驱动1.3寸TFT屏幕的驱动代码用法这里使用的开发板和屏幕都来自某宝店家大越创新。

u014483560的博客 2926

嵌入式GUI开发入门:emWin项目结构与硬件移植实战指南

在嵌入式系统开发中,图形用户界面(GUI)的实现是提升产品交互体验的关键技术。其核心原理在于通过高效的图形库将应用逻辑与底层硬件驱动解耦,从而在资源受限的微控制器(MCU)上实现流畅的视觉输出。这项技术的核心价值在于显著提升开发效率与代码可维护性,尤其适用于智能家居、工业HMI、医疗设备等对实时性及可靠性要求严苛的应用场景。本文以广泛应用的emWin嵌入式GUI库为例,深入剖析其推荐的项目目录结构与配置宏体系,并详解如何通过实现LCD_X硬件抽象层接口完成从模拟器到真实硬件的移植,为构建稳定、高效的嵌入式图

weixin_34093995的博客 263

Arduino串口屏入门:从显示文字到画图的全流程指南(附时钟案例代码)

本文提供了一份Arduino串口屏的完整入门指南,涵盖从硬件连接到软件编程的全流程。通过解析核心指令,详细讲解了如何显示文字、处理中文编码以及绘制基础图形,并附有一个综合性的模拟时钟案例代码,帮助开发者快速上手,为嵌入式项目添加图形化人机交互界面。

weixin_29172963的博客 194

2.0英寸TFT彩屏SPI模块ILI9225完整驱动与应用实战

为了摆脱第三方库依赖并提高灵活性,建议从零开始设计轻量级驱动库。以下是典型头文件结构设计:public:private:#endif逻辑分析:- 使用私有成员函数封装底层操作,增强封装性;和区分命令与数据通道(通过RS引脚控制);- 所有颜色均使用RGB565格式(16位),便于统一处理。该设计遵循“最小接口原则”,仅暴露必要功能,便于后期扩展绘图函数。

weixin_33308579的博客 945

彩色LCD画圆算法\TFT LCD 彩屏液晶驱动(二)-----画点、画线、画圆

彩色LCD画圆算法\TFT LCD 彩屏液晶驱动(二)-----画点、画线、画圆

STM32 I2C OLED驱动全解析:从硬件连接到图形显示实战

I2C(Inter-Integrated Circuit)是一种广泛应用于微控制器与低速外设通信的串行总线协议,以其简洁的两线制(SDA数据线和SCL时钟线)和主从架构,在资源受限的嵌入式系统中扮演着关键角色。其工作原理基于开漏输出和上拉电阻,通过地址寻址实现多设备管理,具备良好的可扩展性。这项技术的核心价值在于极大节省了微控制器的宝贵IO引脚,简化了硬件布线,是连接各类传感器、存储器和显示模块的理想选择。在嵌入式显示领域,基于SSD1306驱动芯片的OLED屏幕因其自发光、高对比度和极低功耗的特性,常通过

weixin_34192816的博客 293

STM32 OLED打点划线画圆 OLED电子罗盘 程序

1.划线的线段在 规定的圆内. 2.电子罗盘中指针斜率为东北天坐标系下 解算航向斜率slope

上一篇: 2017第八届蓝桥杯 05 杨辉三角(java)
下一篇: 2014第四届蓝桥杯 01 猜年龄(java)
mainn
博客等级 码龄10年 865粉丝 447原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值