打印

【转】STM32 + RT Thread OS 学习笔记[三]

[复制链接]
1818|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sunmeat|  楼主 | 2015-1-22 09:10 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
RTGUI

据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块。如果要移植到其它OS,估计难度较大。目前还处于Alpha状态,最终将会包含进RT-Thread中,成为其中的标准组件。


沙发
sunmeat|  楼主 | 2015-1-22 09:12 | 只看该作者
1、  RTGUI下载
当前,要获取包含RTGUI的源码,需要到SVN库里去拉。
因此,需要先安装SVN客户端。比较简单的就是命令行,当然你也可以其它选择。
这里使用Apache Subversion command line tools,下载地址:http://www.visualsvn.com/downloads/

使用特权

评论回复
板凳
sunmeat|  楼主 | 2015-1-22 09:13 | 只看该作者
下载文件是一个压缩包,解压到任意目录即可。
RT-Thread SVN源码浏览

使用特权

评论回复
地板
sunmeat|  楼主 | 2015-1-22 09:14 | 只看该作者
打开cmd窗口,进入上面解压缩目录,运行下面的命令:
svn checkout http://rt-thread.googlecode.com/svn/tags/rtt_1_1_1\mcu\rtt111
这样就把rtt_1_1_1这个版本下载到根目录下的 mcu\rtt111中。



注1:由于众所周知的原因,从googlecode下载有点困难,建议使用***等方式。

注2:下载的bsp目录,实际只需要simulator(模拟器)和stm32f10x(奋斗板V3对应),其它的都可以删除或转移到其它目录。

使用特权

评论回复
5
sunmeat|  楼主 | 2015-1-22 09:15 | 只看该作者
2、  项目生成
与之前一样,修改rtconfig.h,打开RT_USING_RTGUI选项;

运行命令:scons –target=mdk4 –s
打开生成的项目文件,可以看到已经包含了RTGUI。

使用特权

评论回复
6
sunmeat|  楼主 | 2015-1-22 09:17 | 只看该作者
3、  LCD驱动(SSD1963)
a)      这是重新下载的源码,所以对LED的定义,还需要按之前章节所述,修改相应代码。
b)      编译
在驱动未完成前,examples和calibration.c(由文件名看应该是触摸屏校准程序)都可以不要。从项目中移除(remove)组gui_examples以及文件calibration.c,重新编译,成功。

使用特权

评论回复
7
sunmeat|  楼主 | 2015-1-22 09:17 | 只看该作者
c)      驱动代码
默认状态下,包含了ssd1289这个驱动文件,我们要参照它来写一个ssd1963的驱动。
代码:
ssd1963.c
#include <rtthread.h>
#include "stm32f10x.h"

// 分辨率(H:0-479 V:0-271)
unsigned int  HDP=479;
unsigned int  VDP=271;

unsigned int  HT=531;
unsigned int  HPS=43;
unsigned int  LPS=8;
unsigned char HPW=1;

unsigned int  VT=288;
unsigned int  VPS=12;
unsigned int  FPS=4;
unsigned char VPW=10;

#define Bank1_LCD_D    ((uint32_t)0x60020000)    //disp Data ram
#define Bank1_LCD_C    ((uint32_t)0x60000000)     //disp Reg ram

void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

void LCD_WR_REG(u16 index)
{
*(__IO uint16_t *) (Bank1_LCD_C)= index;
}

u16 LCD_RD_DAT(void)
{
u16 a=0;
a=*(__IO uint16_t *) (Bank1_LCD_D);
return(a);
}

void LCD_WR_DAT(u16 val)
{  
*(__IO uint16_t *) (Bank1_LCD_D)= val;      
}

void _set_window(u16 x1, u16 y1, u16 x2, u16 y2)
{
LCD_WR_REG(0x002A);
         LCD_WR_DAT(x1>>8);      
         LCD_WR_DAT(x1&0x00ff);
         LCD_WR_DAT(x2>>8);
         LCD_WR_DAT(x2&0x00ff);
         LCD_WR_REG(0x002b);
         LCD_WR_DAT(y1>>8);
         LCD_WR_DAT(y1&0x00ff);
         LCD_WR_DAT(y2>>8);
         LCD_WR_DAT(y2&0x00ff);
}

void _set_cursor(u16 x,u16 y)
{
_set_window(x, y, HDP, VDP);
}

void lcd_set_pixel(const char* pixel, int x, int y)
{
_set_cursor(x, y);
LCD_WR_REG(0x2c);
LCD_WR_DAT(*(rt_uint16_t*)pixel);
}

void lcd_get_pixel(char* pixel, int x, int y)
{
_set_cursor(x, y);
LCD_WR_REG(0x2e);
*(rt_uint16_t*)pixel = LCD_RD_DAT();
}

void lcd_draw_hline(const char* pixel, int x1, int x2, int y)
{
_set_cursor(x1, y);
LCD_WR_REG(0x2c);
    while (x1 < x2)
    {
        LCD_WR_DAT(*(rt_uint16_t*)pixel);
        x1++;
    }
}

void lcd_draw_vline(const char* pixel, int x, int y1, int y2)
{
_set_window(x, y1, x, y2);
LCD_WR_REG(0x2c);
    while (y1 < y2)
    {
        LCD_WR_DAT(*(rt_uint16_t*)pixel);
        y1++;
    }
}

void lcd_blit_line(const char* pixels, int x, int y, rt_size_t size)
{
rt_uint16_t *ptr;
ptr = (rt_uint16_t*)pixels;

_set_cursor(x, y);
LCD_WR_REG(0x2c);
    while (size)
    {
        LCD_WR_DAT(*ptr ++);
           size --;
    }
}

void lcd_clear()
{                  
    int w = HDP + 1, h = VDP + 1;
_set_cursor(0, 0);
LCD_WR_REG(0x2c);
    while (w--)
    {
        while(h--)
        {
            LCD_WR_DAT(0xffff);
        }
           h = VDP + 1;
    }
}

void LCD_INIT(void)
{
GPIO_ResetBits(GPIOE, GPIO_Pin_1);
    Delay(0xAFFFF);                                         
    GPIO_SetBits(GPIOE, GPIO_Pin_1 );                          
Delay(0xAFFFF);

    LCD_WR_REG(0x00E2);                 // PLL=10*36/3=120M
LCD_WR_DAT(0x0023);          //N=0x36 for 6.5M, 0x23 for 10M crystal
LCD_WR_DAT(0x0002);
LCD_WR_DAT(0x0004);
LCD_WR_REG(0x00E0);        
LCD_WR_DAT(0x0001);
Delay(0xAFFF);
LCD_WR_REG(0x00E0);
LCD_WR_DAT(0x0003);              
Delay(0xAFFF);
LCD_WR_REG(0x0001);      
Delay(0xAFFF);
LCD_WR_REG(0x00E6);              //PLL setting for PCLK, depends on resolution
LCD_WR_DAT(0x0001);
LCD_WR_DAT(0x0033);
LCD_WR_DAT(0x0032);

LCD_WR_REG(0x00B0);              //module
LCD_WR_DAT(0x0000);
LCD_WR_DAT(0x0000);
LCD_WR_DAT((HDP>>8)&0X00FF);  //Set HDP
LCD_WR_DAT(HDP&0X00FF);
    LCD_WR_DAT((VDP>>8)&0X00FF);  //Set VDP
LCD_WR_DAT(VDP&0X00FF);
    LCD_WR_DAT(0x0000);

LCD_WR_REG(0x00B4);      //HSYNC
LCD_WR_DAT((HT>>8)&0X00FF);  //Set HT
LCD_WR_DAT(HT&0X00FF);
LCD_WR_DAT((HPS>>8)&0X00FF);  //Set HPS
LCD_WR_DAT(HPS&0X00FF);
LCD_WR_DAT(HPW);                       //Set HPW
LCD_WR_DAT((LPS>>8)&0X00FF);  //Set HPS
LCD_WR_DAT(LPS&0X00FF);
LCD_WR_DAT(0x0000);

LCD_WR_REG(0x00B6);      //VSYNC
LCD_WR_DAT((VT>>8)&0X00FF);   //Set VT
LCD_WR_DAT(VT&0X00FF);
LCD_WR_DAT((VPS>>8)&0X00FF);  //Set VPS
LCD_WR_DAT(VPS&0X00FF);
LCD_WR_DAT(VPW);                       //Set VPW
LCD_WR_DAT((FPS>>8)&0X00FF);  //Set FPS
LCD_WR_DAT(FPS&0X00FF);

LCD_WR_REG(0x00BA);
LCD_WR_DAT(0x000F);    //GPIO[3:0] out 1

LCD_WR_REG(0x00B8);
LCD_WR_DAT(0x0007);    //GPIO3=input, GPIO[2:0]=output
LCD_WR_DAT(0x0001);    //GPIO0 normal

LCD_WR_REG(0x0036);            //rotation
LCD_WR_DAT(0x0000);

LCD_WR_REG(0x00F0);             //16位  565 color module
LCD_WR_DAT(0x0003);

Delay(0xAFFF);

LCD_WR_REG(0x0029); //display on

LCD_WR_REG(0x00BE); //set PWM for B/L
LCD_WR_DAT(0x0006);
LCD_WR_DAT(0x0080);
LCD_WR_DAT(0x0001);
LCD_WR_DAT(0x00f0);
LCD_WR_DAT(0x0000);
LCD_WR_DAT(0x0000);

LCD_WR_REG(0x00d0);// backlight
LCD_WR_DAT(0x000d);
}

void GPIO_INIT(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC
                                                       | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF , ENABLE);
}

void FSMC_LCD_Init(void)
{
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;
  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);      

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;                              
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  
  GPIO_Init(GPIOD, &GPIO_InitStructure);   
  GPIO_SetBits(GPIOD, GPIO_Pin_13);                                 


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;               
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  
  GPIO_Init(GPIOE, &GPIO_InitStructure);

        

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
                                GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
                                GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
  GPIO_Init(GPIOD, &GPIO_InitStructure);


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
                                GPIO_Pin_15;
  GPIO_Init(GPIOE, &GPIO_InitStructure);




  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOD, &GPIO_InitStructure);


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  p.FSMC_AddressSetupTime = 0x02;
  p.FSMC_AddressHoldTime = 0x00;
  p.FSMC_DataSetupTime = 0x05;
  p.FSMC_BusTurnAroundDuration = 0x00;
  p.FSMC_CLKDivision = 0x00;
  p.FSMC_DataLatency = 0x00;
  p.FSMC_AccessMode = FSMC_AccessMode_B;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
  FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);


  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}


struct rt_device_graphic_ops ssd1963_ops =
{
lcd_set_pixel,
lcd_get_pixel,
lcd_draw_hline,
lcd_draw_vline,
lcd_blit_line
};

struct rt_device _lcd_device;
static rt_err_t lcd_init(rt_device_t dev)
{
return RT_EOK;
}

static rt_err_t lcd_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}

static rt_err_t lcd_close(rt_device_t dev)
{
return RT_EOK;
}

static rt_err_t lcd_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
switch (cmd)
{
case RTGRAPHIC_CTRL_GET_INFO:
           {
                    struct rt_device_graphic_info *info;

                    info = (struct rt_device_graphic_info*) args;
                    RT_ASSERT(info != RT_NULL);

                    info->bits_per_pixel = 16;
                    info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565P;
                    info->framebuffer = RT_NULL;
                    info->width = HDP + 1;
                    info->height = VDP + 1;
           }
           break;

case RTGRAPHIC_CTRL_RECT_UPDATE:
           /* nothong to be done */
           break;

default:
           break;
}

return RT_EOK;
}

void rt_hw_lcd_init(void)
{

/* register lcd device */
_lcd_device.type  = RT_Device_Class_Graphic;
_lcd_device.init  = lcd_init;
_lcd_device.open  = lcd_open;
_lcd_device.close = lcd_close;
_lcd_device.control = lcd_control;
_lcd_device.read  = RT_NULL;
_lcd_device.write = RT_NULL;

_lcd_device.user_data = &ssd1963_ops;
    GPIO_INIT();
    FSMC_LCD_Init();
    LCD_INIT();
    lcd_clear();

    /* register graphic device driver */
rt_device_register(&_lcd_device, "lcd",
           RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
}

使用特权

评论回复
8
sunmeat|  楼主 | 2015-1-22 09:18 | 只看该作者
这个文件中,直接被调用的只有一个函数:void rt_hw_lcd_init(void),执行完成后,在系统中注册了名为“lcd”的设备。
   _lcd_device.type  = RT_Device_Class_Graphic;
   _lcd_device.init  = lcd_init;
   _lcd_device.open  = lcd_open;
   _lcd_device.close = lcd_close;
   _lcd_device.control = lcd_control;
   _lcd_device.read  = RT_NULL;
   _lcd_device.write = RT_NULL;

使用特权

评论回复
9
sunmeat|  楼主 | 2015-1-22 09:18 | 只看该作者
这些是一个标准设备必须的函数,作为LCD显示设备,这里只有control是有用的,其它实际上是个空函数。
struct rt_device_graphic_ops ssd1963_ops =
{
         lcd_set_pixel,
         lcd_get_pixel,
         lcd_draw_hline,
         lcd_draw_vline,
         lcd_blit_line
};

void rt_hw_lcd_init(void)
{

         …………

         _lcd_device.user_data = &ssd1963_ops;
…………

使用特权

评论回复
10
sunmeat|  楼主 | 2015-1-22 09:19 | 只看该作者
d)      测试程序
测试程序分两个,一个是底层硬件画图函数测试,一个是RTGUI API测试。
lcd_hw_test.c
#include <rtthread.h>

extern const unsigned char* icon;

void lcd_hw_test(){
    char pixel[] = {0x00, 0xf8};
    int width, height = 59, i=5;
    unsigned char* p;
    char tmp[] = {0xff, 0xff};

    rt_device_t drv = rt_device_find("lcd");
    struct rt_device_graphic_ops* ops = ((struct rt_device_graphic_ops *)(drv->user_data));

    // hline
    while(i--)
    {
        ops->draw_hline(pixel, 0, 480, 50 + i);
    }

    // vline
    i = 5;
    while(i--)
    {
        ops->draw_vline(pixel, 80 + i, 0, 272);
    }

    // draw icon
    p = (unsigned char*)&icon;
    while(height--){
        ops->blit_line((char*)p, 200, 180 - height, 59);
        p += 59 * 2;
    }
   
    // copy icon
    width = height = 59;
    while(height--)
    {
        while(width--)
        {
            ops->get_pixel(tmp, 200 + width, 180 - height);
            ops->set_pixel(tmp, 290 + width,  180 - height);
        }
        width = 59;
    }
}

使用特权

评论回复
11
sunmeat|  楼主 | 2015-1-22 09:20 | 只看该作者
lcd_gui_test.c
#include <rtthread.h>

extern const unsigned char* icon;

void lcd_hw_test(){
    char pixel[] = {0x00, 0xf8};
    int width, height = 59, i=5;
    unsigned char* p;
    char tmp[] = {0xff, 0xff};

    rt_device_t drv = rt_device_find("lcd");
    struct rt_device_graphic_ops* ops = ((struct rt_device_graphic_ops *)(drv->user_data));

    // hline
    while(i--)
    {
        ops->draw_hline(pixel, 0, 480, 50 + i);
    }

    // vline
    i = 5;
    while(i--)
    {
        ops->draw_vline(pixel, 80 + i, 0, 272);
    }

    // draw icon
    p = (unsigned char*)&icon;
    while(height--){
        ops->blit_line((char*)p, 200, 180 - height, 59);
        p += 59 * 2;
    }
   
    // copy icon
    width = height = 59;
    while(height--)
    {
        while(width--)
        {
            ops->get_pixel(tmp, 200 + width, 180 - height);
            ops->set_pixel(tmp, 290 + width,  180 - height);
        }
        width = 59;
    }
}

使用特权

评论回复
12
sunmeat|  楼主 | 2015-1-22 09:24 | 只看该作者
d)      测试程序
测试程序分两个,一个是底层硬件画图函数测试,一个是RTGUI API测试。
lcd_hw_test.c
#include <rtthread.h>

extern const unsigned char* icon;

void lcd_hw_test(){
    char pixel[] = {0x00, 0xf8};
    int width, height = 59, i=5;
    unsigned char* p;
    char tmp[] = {0xff, 0xff};

    rt_device_t drv = rt_device_find("lcd");
    struct rt_device_graphic_ops* ops = ((struct rt_device_graphic_ops *)(drv->user_data));

    // hline
    while(i--)
    {
        ops->draw_hline(pixel, 0, 480, 50 + i);
    }

    // vline
    i = 5;
    while(i--)
    {
        ops->draw_vline(pixel, 80 + i, 0, 272);
    }

    // draw icon
    p = (unsigned char*)&icon;
    while(height--){
        ops->blit_line((char*)p, 200, 180 - height, 59);
        p += 59 * 2;
    }
   
    // copy icon
    width = height = 59;
    while(height--)
    {
        while(width--)
        {
            ops->get_pixel(tmp, 200 + width, 180 - height);
            ops->set_pixel(tmp, 290 + width,  180 - height);
        }
        width = 59;
    }
}

使用特权

评论回复
13
sunmeat|  楼主 | 2015-1-22 09:25 | 只看该作者
lcd_gui_test.c
代码很大,存入文档.rar (5.32 KB)
这两个测试文件的显示内容是一样的。
显示一条5个像素宽的横条与竖条,以及一个图标,再复制一份同样的图标。通过这些来测试基本的五个函数有没有按预期效果显示。

使用特权

评论回复
14
sunmeat|  楼主 | 2015-1-22 09:26 | 只看该作者
在application.c中添加测试代码:(L55-L59)

使用特权

评论回复
15
sunmeat|  楼主 | 2015-1-22 09:26 | 只看该作者
编译,下载,可以看到测试结果:

使用特权

评论回复
16
sunmeat|  楼主 | 2015-1-22 09:27 | 只看该作者
e)模拟器运行RTGUI
模拟器在目录bsp\simulator下,在开始之前,请阅读目录下的readme.txt。
使用命令:scons --target=vs –s 来创建Visaul C++ 2005的项目文件。
打开生成的project.vcproj。

使用特权

评论回复
17
sunmeat|  楼主 | 2015-1-22 09:28 | 只看该作者
将lcd_gui_test.c加入,再在application.c中添加测试代码(默认是运行贪吃蛇游戏);

使用特权

评论回复
18
sunmeat|  楼主 | 2015-1-22 09:28 | 只看该作者
修改project -> Drivers -> sdl_fb.c,让屏幕分辨率与开发板的一致。
运行后,就可以看到效果了(注:可能因调用低层代码,窗口没刷新,用其它窗口盖一下,再挪开,就可以看到上图了)

使用特权

评论回复
19
yinhaix| | 2015-6-2 17:36 | 只看该作者

使用特权

评论回复
20
vivilzb1985| | 2015-6-8 19:39 | 只看该作者
sunmeat 发表于 2015-1-22 09:14
打开cmd窗口,进入上面解压缩目录,运行下面的命令:
svn checkout http://rt-thread.googlecode.com/svn/t ...

这个资料非常给力的,介绍也很详细。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

208

主题

2132

帖子

13

粉丝