OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3497|回复: 11

12864 怎么在STemwin上移植

[复制链接]

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
发表于 2019-4-25 14:47:28 | 显示全部楼层 |阅读模式
30金钱
   自己写的打点函数,刷新很慢,不知道有时要几十分钟,说不行还是能显示,说行自己都不知道 什么时候能
   刷新 ,代码就不拿出来,怕害别人,各位大佬有成功在12864(ST920主控)移植STemwin吗

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-4-25 14:48:21 | 显示全部楼层
emwin 功能已经在原子开发板实现了,就差移植了
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-4-25 14:50:21 | 显示全部楼层
本来,我也想换块显示屏,但是我同学的毕设 ,要在焊洞洞板上,加之显示显示屏贵
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2015-10-27
在线时间
180 小时
发表于 2019-4-25 17:29:54 | 显示全部楼层
对12864屏幕不要直接操作,在STM2定义一个数组和12864的点阵对应起来。打点和读点直接操作数据,每次直接把整个数组写进12864。
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2015-10-27
在线时间
180 小时
发表于 2019-4-25 17:30:59 | 显示全部楼层

对12864屏幕不要直接操作,在STM2定义一个数组和12864的点阵对应起来。打点和读点直接操作数组,每次直接把整个数组写进12864。
volatile char LCD_DISPLAY_BUF[8][128];//LCD显示缓存
void Lcd_Display(void)
{
        uint8_t tmpi,tmpj;
        BSP_IO_L(LCDCS);//片选
        for (tmpi=0;tmpi<8;tmpi++)
        {
                Lcd_Setpos(0,tmpi);
                for (tmpj=0;tmpj<128;tmpj++)
                {
                        LcdDataWrite(LCD_DISPLAY_BUF[tmpi][tmpj]);
                }
        }
        BSP_IO_H(LCDCS);//片选
        memset((char *)LCD_DISPLAY_BUF,0,sizeof(LCD_DISPLAY_BUF));
}
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-4-25 19:08:46 | 显示全部楼层
g753388438 发表于 2019-4-25 17:30
对12864屏幕不要直接操作,在STM2定义一个数组和12864的点阵对应起来。打点和读点直接操作数组,每次直接 ...

你的想法是对的 ,只是我是每次打一个点和读一个点,但也差不多
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-4-25 19:11:04 | 显示全部楼层
说错了 我是在任意地方打一个点和读点
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-4-25 19:11:42 | 显示全部楼层
#include "12864.h"
#include "stm32f4xx.h"
#include "delay.h"
#include "stm32f4xx_gpio.h"
#include "stdio.h"
#include "string.h"
#include "stm32f4xx_adc.h"

//缓冲区
#define LCD_COLUMN_SIZE             8
#define LCD_ROW_SIZE                64
static unsigned short m_DisplayBuffer[LCD_COLUMN_SIZE][LCD_ROW_SIZE];
static void lcd_init_regdisRam(void);
//******发送一个字节数据*******//
void LCD12864_SendByte(u8 date) {
    u8 i;
    for( i=0 ; i<8 ; i++ )
    {
        SCLK = 0;
        delay_us(10);
        if(date & 0x80 )
        {
            SID = 1;
            delay_us(10);
        }
        else
        {
            SID = 0;
            delay_us(10);
        }
        date <<= 1;
        delay_us(10);
        SCLK = 1;
    }
    SCLK = 0;
    delay_us(10);
}


//******写数据*******//
void LCD12864_Writedata(u8 date) {
    CS = 1;
    LCD12864_SendByte(0xfa);          //写数据控制
    LCD12864_SendByte(0xf0&date);
    LCD12864_SendByte(0xf0&date<<4);
    delay_ms(10);
    CS = 0;
}

//写数据控制
void LCD12864_WriteCmd(u8 cmdcode) {
    CS = 1;
    LCD12864_SendByte(0xf8);            //写命令控制
    LCD12864_SendByte(0xf0&cmdcode);    //高位
    LCD12864_SendByte(0xf0&cmdcode<<4);  //低位
    delay_ms(10);
    CS = 0;
}

//设置显示位置
void LCD12864_pos(char x,char y) {
    u8 pos;
    switch(x)
    {
    case 1 :
        pos=0x80+y;
        break;
    case 2 :
        pos=0x90+y;
        break;
    case 3 :
        pos=0x88+y;
        break;
    case 4 :
        pos=0x98+y;
        break;
    }
    LCD12864_WriteCmd(pos);
}

//清屏
void LCD_clean(void) {
    LCD12864_WriteCmd(0x30);
    delay_ms(10);
    LCD12864_WriteCmd(0x01);
    delay_ms(10);
}

void LCD_init(void)
{
    GPIO_InitTypeDef    GPIO_InitStruct;
   
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
        GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_1 | GPIO_Pin_3 | GPIO_Pin_5;
        GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_OUT;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD,&GPIO_InitStruct);

    LCD12864_WriteCmd(0x30); //选择基本指令集
    delay_ms(10);
    LCD12864_WriteCmd(0x0c); //开显示(无游标、不反白)
    delay_ms(10);
    LCD12864_WriteCmd(0x01); //清除显示,并且设定地址指针为00H
    delay_ms(10);
    LCD12864_WriteCmd(0x06); //游标的移动方向及指定显示的移位
    delay_ms(10);
    LCD_clean();
       
   lcd_init_regdisRam();
}


void Display(char *q) {
    while( *q != '\0' )
    {
        LCD12864_Writedata(*q++);
        delay_ms(10);
    }
}

void LCD12864_Display(char x, char y, char *str)
{
    LCD12864_pos(x,y);
    Display(str);

}

char* str_insert(char *src,char dest)
{
    char len,*p=src;
    u8 i;
    len=strlen(src);
    for( i=len-1; i>=dest; i--)
    {
        src[i+1]=src[i];
    }
    src[dest]=0x2e;
    src[len+1]='\0';
    return p;
}

void LCD12864_Clear(void)
{
        unsigned char i,j;
        LCD12864_WriteCmd(0x34);
        for(i=0;i<32;i++)
        {
       
                LCD12864_WriteCmd(0x80+i);
                LCD12864_WriteCmd(0x80);
                for(j=0;j<16;j++) LCD12864_Writedata(0x00);
        }
        for(i=0;i<32;i++)
        {
                LCD12864_WriteCmd(0x80+i);
                LCD12864_WriteCmd(0x88);
                for(j=0;j<16;j++) LCD12864_Writedata(0x00);
        }
        LCD12864_WriteCmd(0x36);
        LCD12864_WriteCmd(0x30);
}

//--------------------------------------------------------------------------------------------
//绘图函数集

//读取RAM显示值
static void lcd_init_regdisRam(void)
{
    for(int nColumn = 0; nColumn < LCD_COLUMN_SIZE ; nColumn++)
    {
        for(int nRow = 0; nRow < LCD_ROW_SIZE ; nRow++)
        {
            m_DisplayBuffer[nColumn][nRow] = 0x0000;
        }
    }
}
//这里采用MCU缓冲区
unsigned short lcd_Get_RegDisRam(unsigned char row ,unsigned char block)
{
    if(block < 8)
    {
        return m_DisplayBuffer[block][row];
    }
    else
    {
        return m_DisplayBuffer[block % 8][32 + row];
    }
}

void lcd_Set_RegDisRam(unsigned char row ,unsigned char block ,unsigned short data)
{
    if(block < 8)
    {
        m_DisplayBuffer[block][row] = data;
    }
    else
    {
        m_DisplayBuffer[block % 8][32 + row] = data;
    }
}

//绘图显示ON
void lcd_Graphics_On(void)
{
    LCD12864_WriteCmd(0x36);
    LCD12864_WriteCmd(0x30);
}

//绘图显示OFF
void lcd_Graphics_Off(void)
{
    LCD12864_WriteCmd(0x34);
}

//设定CGRAM地址
void lcd_Set_CGRAM_Address(unsigned char addressX ,unsigned char addressY)
{
    //先设定列地址AC6~AC0
    LCD12864_WriteCmd(0x80 | (addressX & 0x7F));
    //再设定行地址AC3~AC0
    LCD12864_WriteCmd(0x80 | (addressY & 0x0F));
}


//绘制
void lcd_Graphics(unsigned char addressX ,unsigned char addressY ,unsigned short data)
{
    lcd_Graphics_Off();
    lcd_Set_CGRAM_Address(addressX ,addressY);
    LCD12864_WriteCmd(data >> 8);
    LCD12864_Writedata(data & 0xFF);
    lcd_Graphics_On();
}

//获取GUI指定点对应的CGRAM位置
//addressX: 0~127
//addressY: 0~63
Location_t lcd_Get_Location(unsigned char addressX ,unsigned char addressY)
{
    Location_t location = {0 ,0};
    //
    unsigned char temp = addressX / 16;
    //
    if(addressY < 32)
    {
        location.Row = addressY % 32;
        location.Block = temp;
        location.OffsetX = addressX - (temp * 16);
    }
    else
    {
        location.Row = addressY % 32;
        location.Block = temp + 8;
        location.OffsetX = addressX - (temp * 16);
    }

    return location;
}

/*
* 函数描述: 设置像素点
* 输入参数:
*            nX        X位置
*            nY        Y位置
*           nValue 1:亮;0:灭
* 输出参数: 无
* 返回参数:
*            无
* 说    明:
*
*/
void lcd_SetPixel(unsigned int nX ,unsigned int nY ,int nValue)
{
    if(nX > 127)
        nX = 127;
    if(nY > 63)
        nY = 63;

    lcd_Graphics_Off();
    /*获取指定点对应的CGRAM位置*/
    Location_t location = lcd_Get_Location(nX ,nY);
    /*读取该CGRAM位置上的数据*/
    unsigned short RAMdata = lcd_Get_RegDisRam(location.Row ,location.Block);

    /*改变RAM数据*/
    if(nValue)
    {
        RAMdata |= 0x1 << (15 - location.OffsetX);
    }
    else
    {
        RAMdata &= ~(0x1 << (15 - location.OffsetX));
    }

    /*写回显存*/
    lcd_Set_RegDisRam(location.Row ,location.Block ,RAMdata);

    /*写入CGRAM*/
    lcd_Set_CGRAM_Address(location.Row ,location.Block);
    LCD12864_Writedata(RAMdata >> 8);
    LCD12864_Writedata(RAMdata & 0xFF);
    lcd_Graphics_On();
}

/*
* 函数描述: 获取像素点
* 输入参数:
*            nX        X位置
*            nY        Y位置
* 输出参数: 无
* 返回参数:
*            1:亮;0:灭
* 说    明:
*
*/
unsigned char lcd_GetPixel(unsigned int nX ,unsigned int nY)
{
    if(nX > 127)
        nX = 127;
    if(nY > 63)
        nY = 63;

    /*获取指定点对应的CGRAM位置*/
    Location_t location = lcd_Get_Location(nX ,nY);
    /*读取该CGRAM位置上的数据*/
    unsigned short RAMdata = lcd_Get_RegDisRam(location.Row ,location.Block);
    unsigned short data = 0x1 << (15 - location.OffsetX);
    /*改变RAM数据*/
    if(data & RAMdata)
    {
        return (1);
    }
    else
    {
        return (0);
    }
}
/*
* 函数描述: 绘制HL直线
* 输入参数:
*            nX        X位置
*            nY        Y位置
*           nValue  是否点亮
* 输出参数: 无
* 返回参数:
*            无
* 说    明:
*
*/
void lcd_drawHLline(int nX0 ,int nX1 ,int nY ,int nValue)
{

    if(nX1 > 127)
        nX1 = 127;
    if(nY > 63)
        nY = 63;

    unsigned short RAMdata = 0 ,Maskdata = 0;
    //获取起始/结束块
    Location_t StartLocation = lcd_Get_Location(nX0 ,nY);
    Location_t EndLocation = lcd_Get_Location(nX1 ,nY);
    //绘制
    for(int nBlock = StartLocation.Block; nBlock <= EndLocation.Block; nBlock++)
    {
        //获取数据
        RAMdata = lcd_Get_RegDisRam(StartLocation.Row ,nBlock);
        //获取遮掩层数据
        Maskdata = 0xFFFF;
        //裁剪遮掩层
        if(nBlock == StartLocation.Block)
        {
            Maskdata <<= StartLocation.OffsetX;
            Maskdata >>= StartLocation.OffsetX;
        }
        if(nBlock == EndLocation.Block)
        {
            Maskdata >>= (15 - EndLocation.OffsetX);
            Maskdata <<= (15 - EndLocation.OffsetX);
        }
        //实际效果
        if(nValue)
        {
            RAMdata |=  Maskdata;
        }
        else
        {
            RAMdata &=  ~Maskdata;
        }
        /*写回显存*/
        lcd_Set_RegDisRam(StartLocation.Row ,nBlock ,RAMdata);
        /*写入CGRAM*/
        lcd_Set_CGRAM_Address(StartLocation.Row ,nBlock);
        LCD12864_Writedata(RAMdata >> 8);
        LCD12864_Writedata(RAMdata & 0xFF);
    }
}

/*
* 函数描述: 绘制VH直线
* 输入参数:
*            nX        X位置
*            nY        Y位置
*           nValue  是否点亮
* 输出参数: 无
* 返回参数:
*            无
* 说    明:
*
*/
void lcd_drawVHline(int nX ,int nY0 ,int nY1 ,int nValue)
{
    if(nX > 127)
        nX = 127;
    if(nY1 > 63)
        nY1 = 63;

    //绘制
    for(int nY = nY0; nY <= nY1; nY++)
    {
        lcd_SetPixel(nX ,nY ,nValue);
    }
}


/*
* 函数描述: 刷新指定区域
* 输入参数:
*            nX        X位置
*            nY        Y位置
* 输出参数: 无
* 返回参数:
*            无
* 说    明:
*
*/
void lcd_refresh(int nX0 ,int nY0 ,int nXsize ,int nYsize)
{
    //将数据发送至LCD显示
    Location_t Startlocation ,Endlocation ,location;
    unsigned short RAMdata;
    int nIndex = 0;
    int nX1 ,nY1;
    /*限制大小*/
    if((nX0 + nXsize) > 127)
    {
        nX1 = 127;
    }
    else
    {
        nX1 = nX0 + nXsize;
    }

    if((nY0 + nYsize) > 63)
    {
        nY1 = 63;
    }
    else
    {
        nY1 = nY0 + nYsize;
    }
    /*获取列大小*/
    Startlocation = lcd_Get_Location(nX0 ,nY0);
    Endlocation = lcd_Get_Location(nX1 ,nY0);

    /*发送数据至显示器*/
    for(int nY = nY0; nY <= nY1; nY++)
    {
        /*获取显示区域*/
        location = lcd_Get_Location(nX0 ,nY);
        lcd_Set_CGRAM_Address(location.Row ,location.Block);
        nIndex = 0;
        for(int nCol = Startlocation.Block; nCol <= Endlocation.Block; nCol++)
        {
            RAMdata = lcd_Get_RegDisRam(location.Row ,location.Block + nIndex);
            /*写入CGRAM*/
            LCD12864_Writedata(RAMdata >> 8);
            LCD12864_Writedata(RAMdata & 0xFF);
            nIndex++;
        }
    }
}

/*
* 函数描述: 配置显存位
* 输入参数:
*            nX        X位置
*            nY        Y位置
* 输出参数: 无
* 返回参数:
*            无
* 说    明: 这里仅仅是更改显存数据,并未送至显示器!!
*
*/
void lcd_SetPixelIndex(int nX, int nY, int PixelIndex)
{
    if(nX > 127)
        nX = 127;
    if(nY > 63)
        nY = 63;
    /*获取指定点对应的CGRAM位置*/
    Location_t location = lcd_Get_Location(nX ,nY);
    /*读取该CGRAM位置上的数据*/
    unsigned short RAMdata = lcd_Get_RegDisRam(location.Row ,location.Block);

    /*改变RAM数据*/
    if(PixelIndex)
    {
        RAMdata |= 0x1 << (15 - location.OffsetX);
    }
    else
    {
        RAMdata &= ~(0x1 << (15 - location.OffsetX));
    }

    /*写回显存*/
    lcd_Set_RegDisRam(location.Row ,location.Block ,RAMdata);
}

/*
* 函数描述: 配置显存线
* 输入参数:
*            nX        X位置
*            nY        Y位置
* 输出参数: 无
* 返回参数:
*            无
* 说    明: 这里仅仅是更改显存数据,并未送至显示器!!
*
*/
void lcd_drawHLlineAF(int nX0 ,int nX1 ,int nY ,int nValue)
{
    if(nX1 > 127)
        nX1 = 127;
    if(nY > 64)
        nY = 64;

    unsigned short RAMdata = 0 ,Maskdata = 0;
    //获取起始/结束块
    Location_t StartLocation = lcd_Get_Location(nX0 ,nY);
    Location_t EndLocation = lcd_Get_Location(nX1 ,nY);
    //绘制
    for(int nBlock = StartLocation.Block; nBlock <= EndLocation.Block; nBlock++)
    {
        //获取数据
        RAMdata = lcd_Get_RegDisRam(StartLocation.Row ,nBlock);
        //获取遮掩层数据
        Maskdata = 0xFFFF;
        //裁剪遮掩层
        if(nBlock == StartLocation.Block)
        {
            Maskdata <<= StartLocation.OffsetX;
            Maskdata >>= StartLocation.OffsetX;
        }
        if(nBlock == EndLocation.Block)
        {
            Maskdata >>= (15 - EndLocation.OffsetX);
            Maskdata <<= (15 - EndLocation.OffsetX);
        }
        //实际效果
        if(nValue)
        {
            RAMdata |=  Maskdata;
        }
        else
        {
            RAMdata &=  ~Maskdata;
        }
        /*写回显存*/
        lcd_Set_RegDisRam(StartLocation.Row ,nBlock ,RAMdata);
    }
}

回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-4-25 19:12:50 | 显示全部楼层
这是 源代码  不知道 为什么 显示一个hello world 要几十分钟
        delay_init(168);               //延时初始化
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //中断分组配置
        uart_init(115200);            //串口波特率设置
        LCD_init();
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC,ENABLE); //开启CRC时钟
       
        GUI_Init();
        GUI_SetBkColor(GUI_BLACK);
        GUI_Clear();
        GUI_SetColor(GUI_WHITE);
        GUI_SetFont(&GUI_Font24_ASCII);
        GUI_DispStringAt("Hello word", 0, 0);
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2015-10-27
在线时间
180 小时
发表于 2019-4-26 08:40:33 | 显示全部楼层
罗涛 发表于 2019-4-25 19:12
这是 源代码  不知道 为什么 显示一个hello world 要几十分钟
        delay_init(168);               //延时初始化
        N ...

首先你的屏幕缓存数组定义的大小就不对小了一半[mw_shl_code=c,true]volatile char LCD_DISPLAY_BUF[8][128];

void Lcd_Init(void)
{
        BSP_IO_L(LCDCS);//片选
        BSP_IO_L(LCDRES);//复位
        HAL_Delay(20);
        BSP_IO_H(LCDRES);//复位
       
//        LcdCommand(0xa0);
//        LcdCommand(0xc8);
//        LcdCommand(0xa2);
//        LcdCommand(0x40);
//        LcdCommand(0xa4);
//        LcdCommand(0x26);
//        LcdCommand(0x2c);

//        LcdCommand(0x2e);

//        LcdCommand(0x2f);

//        LcdCommand(0x25);        
//        LcdCommand(0x81);
//        LcdCommand(0x20);
//        LcdCommand(0xaf);

//        LcdCommand(0xad);
//        LcdCommand(0x00);

        LcdCommand(0xa0);
        LcdCommand(0xc8);
        LcdCommand(0xa2);
        LcdCommand(0x2f);
        LcdCommand(0x81);
        LcdCommand(0x29);
        LcdCommand(0x40);

        LcdCommand(0xaf);

        BSP_IO_H(LCDCS);//片选
       
        Lcd_Clear();//清屏
        Lcd_Clear1();
//        Set_BL(Para_Deploy.Sys_Deploy.BL);//点亮背光
        BSP_IO_L(LCDBL);//点亮背光
}
//写入数据
void Lcd_Display(void)
{
        uint8_t tmpi,tmpj;
        BSP_IO_L(LCDCS);//片选
        for (tmpi=0;tmpi<8;tmpi++)
        {
                Lcd_Setpos(0,tmpi);
                for (tmpj=0;tmpj<128;tmpj++)
                {
                        LcdDataWrite(LCD_DISPLAY_BUF[tmpi][tmpj]);
                }
        }
        BSP_IO_H(LCDCS);//片选
        memset((char *)LCD_DISPLAY_BUF,0,sizeof(LCD_DISPLAY_BUF));
}
static void Lcd_Draw_Point(uint8_t x,uint8_t y)
{       
        LCD_DISPLAY_BUF[y/8][x] |= (0x01<<(y%8));
}

[/mw_shl_code]
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2015-10-27
在线时间
180 小时
发表于 2019-4-26 08:42:56 | 显示全部楼层
每次打完点都要调用 Lcd_Display 这个函数。将数据送到屏幕。你的读点参照我的打点函数自己改改。
我以前用的没有用到读点,每次给屏幕送完数据后都会把数组清空,然后从新打点操作
回复

使用道具 举报

5

主题

106

帖子

0

精华

高级会员

Rank: 4

积分
756
金钱
756
注册时间
2015-10-27
在线时间
180 小时
发表于 2019-4-26 08:46:05 | 显示全部楼层
我最终调用的时候是两个函数
360截图18720115142110.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 23:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表