当前位置: 澳门新濠3559 > 操作系统 > 正文

TinyGUI的位图显示采用转换后的tinyBMP位图格式,—

时间:2019-12-21 19:57来源:操作系统
Microsoft .Net Micro Framework官方UI库为WPF,针对320*240的LCD而言,至少额外需要150K以上RAM才能基本运行,所以推出了轻量级的图形库TinyGUI。 彩屏显示使用之前修改好的ili9325的程序(lcd.c,lcd.

澳门新濠3559 1

Microsoft .Net Micro Framework 官方UI库为WPF,针对320*240的LCD而言,至少额外需要150K以上RAM才能基本运行,所以推出了轻量级的图形库TinyGUI。

彩屏显示使用之前修改好的ili9325的程序(lcd.c,lcd.h,gui.c,gui.h),在main.c中直接添加lcd_init()初始化函数,就可以使用lcd和gui中的绘图或者显示字符的函数了,不过需要注意要重定向printf输出到串口。

自己动手做个智能小车(6)

#include"stm32f10x.h"#include"./lcd/bsp_ili9341_lcd.h"#includestdio.hstaticvoidLCD_Test(void);staticvoidDelay(__IOuint32_tnCount);voidPrintf_Charater(void);intmain(void){ILI9341_Init();//LCD初始化USART_Config();while(1){LCD_Test();}}/*用于测试各种液晶的函数*/voidLCD_Test(void){/*演示显示变量*/staticuint8_ttestCNT=0;chardispBuff[100];testCNT++;LCD_SetFont(Font8x16);LCD_SetColors(RED,BLACK);ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);/*清屏,显示全黑*//********显示字符串示例*******/ILI9341_DispStringLine_EN(LINE(0),"BH3.2_2.8inchLCDpara:");ILI9341_DispStringLine_EN(LINE(1),"Imageresolution:240x320px");ILI9341_DispStringLine_EN(LINE(2),"ILI9341LCDdriver");ILI9341_DispStringLine_EN(LINE(3),"XPT2046TouchPaddriver");/********显示变量示例*******/LCD_SetFont(Font16x24);LCD_SetTextColor(GREEN);/*使用c标准库把变量转化成字符串*/sprintf(dispBuff,"Count:%d",testCNT);LCD_ClearLine(LINE(4));/*清除单行文字*//*然后显示该字符串即可,其它变量也是这样处理*/ILI9341_DispStringLine_EN(LINE(4),dispBuff);/*******显示图形示例******/LCD_SetFont(Font24x32);/*画直线*/LCD_ClearLine(LINE(4));/*清除单行文字*/LCD_SetTextColor(BLUE);ILI9341_DispStringLine_EN(LINE(4),"Drawline:");LCD_SetTextColor(RED);ILI9341_DrawLine(50,170,210,230);ILI9341_DrawLine(50,200,210,240);LCD_SetTextColor(GREEN);ILI9341_DrawLine(100,170,200,230);ILI9341_DrawLine(200,200,220,240);LCD_SetTextColor(BLUE);ILI9341_DrawLine(110,170,110,230);ILI9341_DrawLine(130,200,220,240);Delay(0xFFFFFF);ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);/*清屏,显示全黑*//*画矩形*/LCD_ClearLine(LINE(4));/*清除单行文字*/LCD_SetTextColor(BLUE);ILI9341_DispStringLine_EN(LINE(4),"DrawRect:");LCD_SetTextColor(RED);ILI9341_DrawRectangle(50,200,100,30,1);LCD_SetTextColor(GREEN);ILI9341_DrawRectangle(160,200,20,40,0);LCD_SetTextColor(BLUE);ILI9341_DrawRectangle(170,200,50,20,1);Delay(0xFFFFFF);ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);/*清屏,显示全黑*//*画圆*/LCD_ClearLine(LINE(4));/*清除单行文字*/LCD_SetTextColor(BLUE);ILI9341_DispStringLine_EN(LINE(4),"DrawCir:");LCD_SetTextColor(RED);ILI9341_DrawCircle(100,200,20,0);LCD_SetTextColor(GREEN);ILI9341_DrawCircle(100,200,10,1);LCD_SetTextColor(BLUE);ILI9341_DrawCircle(140,200,20,0);Delay(0xFFFFFF);ILI9341_Clear(0,16*8,LCD_X_LENGTH,LCD_Y_LENGTH-16*8);/*清屏,显示全黑*/}staticvoidDelay(__IOuint32_tnCount){for(;nCount!=0;nCount--);}

WPF支持标准BMP,JPG,GIF图片显示,从使用角度来看非常方便,但是由于嵌入式LCD大都为16bit显示(RGB565格式),无论是BMP还是JPG和GIF都需要进行颜色转换,此外后者还需要进行格式转换处理。以上操作,不仅导致运行速度慢,还需要一定的内存进行图形缓存。

IIC使用IO模拟,创建IIC初始化和读写函数

——给小车装个脸(显示屏)

TinyGUI的位图显示采用转换后的tinyBMP位图格式,其格式和LCD显存格式保持一致,由于图形转换工作通过工具YFTBConvert预先完成,所以在嵌入式系统上直接向显存拷贝,即可完成位图显示,所以运行速度极快。

ADX345的相关操作

查看器件 ID。ADXL345 的 ID 寄存器为 0x00

设置 ADXL345 存储数据的方式和通信方式。寄存器地址为:0x31。

设置数据的输出速率设置的是 BW_RATE 寄存器,地址为:0x2C。

设置测量模式和链接模式

设置不启用中断,设置 INT_ENABLE 寄存器,设置它不使用中断模式。

初始化偏移量,设置 OFSX 寄存器、OFSY 寄存器、OFSZ 寄存器。

1) 发送起始信号

2) 发送 I2C 写器件地址

3) 等待应答

4) 发送 I2C 要读的寄存器地址

5) 等待应答

6) 发送起始信号

TinyGUI的位图显示采用转换后的tinyBMP位图格式,——给小车装个脸澳门新濠3559:(显示屏)。7) 发送 I2C 读器件地址

8) 等待应答

9) 接收返回数据

10) 发送结束信号

1) 发送起始信号

2) 发送 I2C 写器件地址

3) 等待应答

4) 发送要写入的寄存器地址

5) 等待应答

6) 发送要写入的数据

7) 等待应答

8) 发送结束信号

注意读到的为8位,需要改成16位

uint8_t readValue[6];

|

*xValue = (readValue[1] << 8) + readValue[0];

*yValue = (readValue[3] << 8) + readValue[2];

*zValue = (readValue[5] << 8) + readValue[4];

现在轮子可以由程序控制了,但总感觉少点啥,程序在跑,但不知道里面的情况,就象一台电脑没有显示器一样。所以我们也来组小车安装个小显示器。

第一个版本的库,不支持模拟器显示,这样用户在测试新应用时,必须借助实际的开发板才能看到实际的运行效果,这大大影响了用户的体验,所以重新设计了代码,让模拟器也能支持TinyGUI库的运行。

STM32CubeMX配置

澳门新濠3559 2

需要添加得到文件

lcd

void LCD_Init;

void LCD_DisplayOn;

void LCD_DisplayOff;

void LCD_Clear(uint16_t Color);

void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);

void LCD_DrawPoint(uint16_t x,uint16_t y);//画点

uint16_t LCD_ReadPoint(uint16_t x,uint16_t y); //读点

void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd);

void LCD_DrawPoint_16Bit(uint16_t color);

uint16_t LCD_RD_DATA;//读取LCD数据

void LCD_WriteReg(uint16_t LCD_Reg, uint16_t LCD_RegValue);

void LCD_WR_DATA(uint16_t data);

uint16_t LCD_ReadReg(uint8_t LCD_Reg);

void LCD_WriteRAM_Prepare;

void LCD_WriteRAM(uint16_t RGB_Code);

uint16_t LCD_ReadRAM;

uint16_t LCD_BGR2RGB(uint16_t c);

void LCD_SetParam;

gui

void GUI_DrawPoint(uint16_t x,uint16_t y,uint16_t color);

void LCD_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint16_t color);

void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

void Draw_Circle(uint16_t x0,uint16_t y0,uint16_t fc,uint8_t r);

void LCD_ShowChar(uint16_t x,uint16_t y,uint16_t fc, uint16_t bc, uint8_t num,uint8_t size,uint8_t mode);

void LCD_ShowNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t size);

void LCD_Show2Num(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint8_t size,uint8_t mode);

void LCD_ShowString(uint16_t x,uint16_t y,uint8_t size,uint8_t *p,uint8_t mode);

void GUI_DrawFont16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s,uint8_t mode);

void GUI_DrawFont24(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s,uint8_t mode);

void GUI_DrawFont32(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s,uint8_t mode);

void Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *str,uint8_t size,uint8_t mode);

iic

void IIC_Config;

void IIC_Start;

void IIC_Stop;

void IIC_SendData(uint8_t dat);

uint8_t IIC_ReceiveData(uint8_t ack);

int8_t IIC_WaitAck;

adx345

在mian函数中添加显示最终结果的程序,注意将获得的变量存入数组中,这样就可以使用原有函数显示变量了。

澳门新濠3559 3

选什么屏呢,对于小的屏幕,就当然是比较流程的1602LCD了:

在《TinyGUI绘图示例》中我们介绍过TinyGUI的使用,当时的库还只能在开发板中运行,现在同样的示例代码,我们让其在模拟器中运行,示例代码如下:

澳门新濠3559 4

public static void Main()

1602字符型LCD专门用于显示数字、字母、图形符号和少量的自定义符号。这类显示器的LCD控制器、点阵驱动器、字符存储器等做在一块板上,再与液晶屏一起组成一个显示模块,这类显示器的安装和使用非常简单。

{

目前字符型LCD常用的有16字行、16字X2行、20字X2行、20字X4行等液晶模块,型号通常用XXX1602、XXX1604、X2002、XXX2004等其中为厂家商标名称16代表液晶每行可以显示16个字符,02代表共有2行,也就是说这个液晶一共可以显示32字符。

    uint[] colors = new uint[]{Color.Black, Color.Red,Color.Green, Color.Orange,Color.Yellow, Color.Brown,Color.Purple, Color.Gray,

如何连接呢,比较容易,连接图如下:

                            Color.DarkGray, Color.LightGray,Color.Blue, Color.Magenta,Color.Cyan, Color.White,Color.LightGreen};

澳门新濠3559 5

 

图中,

    Graphics.Clear(Color.Blue);

第1脚:vss为地电源,

    int x, y, width, height, c;

第2脚:VDD接5V正电源"

    long index = 0;

第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生"鬼影",使用时可以通过一个10K的电位器调整对此度,

    HardwareProvider hwp = new HardwareProvider();

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器"

    int lcd_width,lcd_height,lcd_bitsPerPixel,lcd_orientationDeg;

第5脚;R/W,为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/V共同为低电平时可以写入指令或者显示地址,当RS为低电平R/w为高电平时可以读忙信号,当RS为高电平R/w为低电平时可以写入数据,

    hwp.GetLCDMetrics(out lcd_width, out lcd_height, out lcd_bitsPerPixel, out lcd_orientationDeg);           

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

    int Graphics_Width = lcd_width - 1;

第7~14脚:DO—D7为8位双向数据线,实际过程中,为了减少接口的使用(多留些给以后扩展用),所以我们采用4根线的(即用D0~D3),就是一个8位数据通过4根线传输2次。

    int Graphics_Height = lcd_height - 1;

第15脚:背光源正极,

    Random rnd = new Random();

第16脚:背光源负极。

    while (true)

 

    {

小车中连接后的效果如下:

        x = rnd.Next(Graphics_Width);

澳门新濠3559 6

        width = rnd.Next(Graphics_Width - x);

 

        y = rnd.Next(Graphics_Height);

好了,连接好了硬件后,就开始软件了,为了方便管理,代码增加一个LCD.c类:

        height = rnd.Next(Graphics_Height - y);

澳门新濠3559 7

        c = rnd.Next(colors.Length - 1);

同时,为了方便调用,对外,我们提供两个函数:

        switch (index % 3)

LcdInitiate() 用于对液晶片初步化;

        {

Print(字符串) 用于将字符串显示在屏上,跟C语言习惯相似。

            case 0:

 

                if (rnd.Next(10) > 5)

好了,上代码:

                    Graphics.DrawRectangle(x, y, width, height, colors[c]);

 

                else

 

                    Graphics.FillRectangle(x, y, width, height, colors[c]);

/*******************************************************************

                break;

* LCD.c 描述:

            case 1:

* LCD1602可以分为8位和4位控制方式,8位控制方式是用D0-D7数据线

                if (rnd.Next(10) > 5)

* 来传送控制命令及数据。4位控制方式是用D4-D7数据线来传送控制命令

                    Graphics.DrawEllipse(x, y, width, height, colors[c]);

* 及数据。使用4位数据线做控制时,需要分两次来传送,先送出高4位数

                else

* 据,再送出低4位数据。可以节省单片机的4根端口线。

                    Graphics.FillEllipse(x, y, width, height, colors[c]);

*

                break;

*******************************************************************/

            case 2:

#include "common.h"

                Graphics.DrawLine(x, y, rnd.Next(Graphics_Width), rnd.Next(Graphics_Height), colors[c]);

 

                break;

sfr LCD_Data = 0x80; //P0 显示接入P0口的高4位 P4 P5 P6 P7

        }

sbit LCD_RS=P0^3; //寄存器选择位,将RS位定义为P2.0引脚

        Graphics.FillRectangle(0, Graphics_Height-19, Graphics_Width, 19, Color.White);

sbit LCD_BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚

        Graphics.DrawString(2, Graphics_Height-17, (index++).ToString(), Color.Blue);

sbit LCD_RW=P2^6; //读写选择位,将RW位定义为P2.1引脚

        Thread.Sleep(50);

sbit LCD_EN=P2^7; //使能信号位,将E位定义为P2.2引脚

    }

 

}

/*********************************************************

  在模拟器中运行的效果图如下(其实在官方模拟器中也可以运行)。

* 5us 延时子程序

  红牛模拟器下载:

*********************************************************/

 澳门新濠3559 8

void delayNOP()

 System.TinyGUI库的下载地址如下(包含文档和示例代码):

{

http://www.sky-walker.com.cn/MFRelease/library/System.TinyGUI.rar 

_nop_();

附:System.TinyGUI库函数说明

_nop_();

1.1 Clear

声明:void Clear(uint color)

参数:color– 清除后的背景色 (24bit RGB)

返回: 

说明: 以用指定颜色清除LCD显示。

_nop_();

1.2 SetPixel

声明:void SetPixel(int x,int y,uint color)

参数:x,y – 屏幕坐标

      color– 颜色

返回:

说明: 画点。

_nop_();

1.3 GetPixel

声明:uint GetPixel (int x,int y)

参数:x,y – 屏幕坐标

返回:指定坐标的颜色

说明:返回指定坐标的颜色,有些硬件不支持该函数。

_nop_();

1.4 DrawLine

声明:void DrawLine(int x1, int y1, int x2, int y2, uint color)

参数:x1,y1,x2,y2 – 屏幕坐标

color– 颜色

返回:

说明:画线。

}

1.5 DrawRectangle

声明:void DrawRectangle(int x, int y, int width, int height, uint color)

参数:x,y – 屏幕左上角坐标

      width,height – 宽,高

color– 颜色

返回:

说明:画空心矩形。

 

1.6 DrawEllipse

声明:void DrawEllipse(int x, int y, int width,int height, uint color)

参数:x,y – 屏幕左上角坐标

      width,height – 宽,高

color– 颜色

返回:

说明:画空心椭圆。

/*********************************************************

1.7 DrawImage

声明:void DrawImage(int x, int y, byte[] bytData)

参数:x,y – 屏幕左上角坐标

      bytData - TinyBMP格式的图像数据

返回:

说明:位图绘制(模拟器暂不支持)。

* 检查LCD忙状态

1.8 DrawImageEx

声明:void DrawImageEx (int x, int y, byte[] bytData,uint MaskColor)

参数:x,y – 屏幕左上角坐标

      bytData - TinyBMP格式的图像数据

MaskColor– 屏蔽色

返回:

说明:位图绘制(模拟器暂不支持)。

* lcd_busy为1时,忙,等待。

1.9 DrawString

声明:void DrawString (int x, int y,string s, uint color)

参数:x,y – 屏幕左上角坐标

      s – 字符串

color– 字体颜色

返回:

说明:绘制字体(暂时仅支持符号和西文字符)

* lcd-busy为0时,闲,可写指令与数据

1.10 FillRectangle

声明:void FillRectangle (int x, int y, int width, int height, uint color)

参数:x,y – 屏幕左上角坐标

      width,height – 宽,高

color– 填充色

返回:

说明:画填充矩形。

*********************************************************/

1.11 FillEllipse

声明:void FillEllipse (int x, int y, int width, int height, uint color)

参数:x,y – 屏幕左上角坐标

      width,height – 宽,高

color– 填充色

返回:

说明:画填充椭圆。

bit lcd_busy()

1.12 Print

声明:void Print(string str)

参数:str – LCD显示的字符串

返回:

说明:LCD信息输出(底层LCD_Printf函数的封装)。

{

1.13 SuspendLayout

声明:void SuspendLayout ()

参数:

返回:

说明:挂起LCD的输出显示。

bit result;

1.14 ResumeLayout

声明:void SuspendLayout ()

参数:

返回:

说明:恢复挂起的LCD输出显示。

MF快速参考: .NET Micro Framework 快速入门

MF中文讨论组:

【低价开发板】http://item.taobao.com/item.htm?id=7117999726

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

delayNOP();

result = LCD_BF;

LCD_EN = 0;

return(result);

}

 

/*********************************************************

* 写指令或数据

* start=0, 写入命令; start=1, 写入数据

*********************************************************/

 

void lcd_write(bit start, uchar in_data)

{

uchar Hdata,Ldata;

 

while(lcd_busy());

 

Hdata=in_data&0xf0; //取高四位

Ldata=(in_data<<4)&0xf0; //取低四位

 

if(start==0)

LCD_RS = 0; //写入命令

else

LCD_RS = 1; //写入数据

 

LCD_RW = 0;

LCD_EN = 0;

delayNOP();

 

//发送高四位

LCD_Data = LCD_Data & 0x0F;

LCD_Data = Hdata | LCD_Data;

 

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

delayNOP();

 

//发送低四位

LCD_Data = LCD_Data & 0x0F;

LCD_Data = Ldata | LCD_Data;

 

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

delayNOP();

}

 

/*************************************************************

* LCD初始化设定

*************************************************************/

void LcdInitiate()

{

Delay(15);

lcd_write(0,0x28); //16*2显示,5*7点阵,4位数据

Delay(5);

lcd_write(0,0x28);

Delay(5);

lcd_write(0,0x28);

 

Delay(5);

lcd_write(0,0x0c); //显示开,关光标

Delay(5);

lcd_write(0,0x06); //移动光标

Delay(5);

lcd_write(0,0x01); //清除LCD的显示内容

Delay(25); //延时

}

 

/**********************************************************

* 设定显示位置

**********************************************************/

void lcd_pos(uchar pos)

{

lcd_write(0,pos|0x80); //数据指针=80+地址变量

}

 

/**********************************************************

* 显示字符串

* 示例: print("Hello World!") print("aaarbbb")

**********************************************************/

void print(unsigned char *str)

{

unsigned char i;

lcd_write(0,0x01); //清除LCD的显示内容

Delay(10);

lcd_pos(0); // 设置显示位置为第一行的第1个字

i = 0;

while(*str != '') //''是数组结束标志

{

//超过一行时,另起一行

if (i == 16 || str[i] == 'r')

lcd_pos(0x40); //设置显示位置为第二行

 

if (*str == 'r')

{

i++;

str++;

continue;

}

 

lcd_write(1,*str);

i++;

str++;

}

}

 

有了这个显示函数(print),我们就很方便在主函数中调一下,比如print("Hello")之类的进行测试。 同时也可以将给小车的PWM值显示出来。

编辑:操作系统 本文来源:TinyGUI的位图显示采用转换后的tinyBMP位图格式,—

关键词: