找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 927|回复: 1
打印 上一主题 下一主题
收起左侧

12864移植到STM32F7上面时,读取GDRAM问题

[复制链接]
跳转到指定楼层
楼主
ID:458679 发表于 2020-7-15 14:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近想用12864完成任意位置打点. 需要用到读取GDRAM的功能.在实现了写入后读取出现了问题.
读取数据在00c以下都是正确的高于0x0c就是锁定为0x0c;不知道哪儿有问题,请大家帮助!谢谢
//////12864.c

    void LCD_GPIO_Init(void)
    {
        //打开时钟;
        Lcd_12864_RS_CLK();
        Lcd_12864_RW_CLK();
        Lcd_12864_E_CLK();
        
        //GPIO定义
        
        /*Lcd RS引脚定义*/
        GPIO_Init_LCD.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_Init_LCD.Pull = GPIO_NOPULL;
        GPIO_Init_LCD.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_Init_LCD.Pin  = GPIO_PIN_2;
        
        HAL_GPIO_Init(Lcd_12864_RS_PORT,&GPIO_Init_LCD);
        
        /*Lcd RW引脚定义*/
        GPIO_Init_LCD.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_Init_LCD.Pull = GPIO_NOPULL;
        GPIO_Init_LCD.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_Init_LCD.Pin  = GPIO_PIN_8;
        
        HAL_GPIO_Init(Lcd_12864_RW_PORT,&GPIO_Init_LCD);
        
        /*Lcd E引脚定义*/
        GPIO_Init_LCD.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_Init_LCD.Pull = GPIO_NOPULL;
        GPIO_Init_LCD.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_Init_LCD.Pin  = GPIO_PIN_11;
        
        HAL_GPIO_Init(Lcd_12864_E_PORT,&GPIO_Init_LCD);
        
        
    }
   
    /****************GPIO_DATA_Read********************/
    /*
        将GPIO_DATA脚设置为Read模式
    */
   
    static  void Lcd_GPIO_DATA_Input_Mode(void)
    {
        Lcd_12864_DATA_CLK();
        GPIO_Init_LCD.Mode = GPIO_MODE_INPUT;//设置模式为输入模式;
        GPIO_Init_LCD.Pin = GPIO_PIN_All;//全部16脚;
        GPIO_Init_LCD.Pull = GPIO_PULLUP;
      HAL_GPIO_Init(Lcd_12864_DATA_PORT, &GPIO_Init_LCD);

        GPIOC->BSRR = 0xff;
    }

        /****************GPIO_DATA_Write********************/
    /*
        将GPIO_DATA脚设置为输出模式
    */
   
    static  void Lcd_GPIO_DATA_Output_Mode(void)
    {
        Lcd_12864_DATA_CLK();
        GPIO_Init_LCD.Mode = GPIO_MODE_OUTPUT_PP;//设置模式为输入模式;
        GPIO_Init_LCD.Pin = GPIO_PIN_All;//全部16脚;
        GPIO_Init_LCD.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_Init_LCD.Pull = GPIO_PULLUP;

        HAL_GPIO_Init(Lcd_12864_DATA_PORT,&GPIO_Init_LCD);
        
        GPIOC->BSRR = 0xff;
    }

   
   
   
    /****************LCD忙检测********************/
    /*
        RS = 0
        RW = 1
    返回DATA 8 bit : BF AC AC AC AC AC AC AC;BF = 1表示忙; AC为计数器值   
    */
static    void Lcd_Check_Busy(void)
{
    uint8_t status;
    Lcd_RS_0;
    Lcd_RW_1;
     Lcd_E_0;
    GPIOC->ODR = 0xff;
    do
    {
        Lcd_E_1;
        Delay_ms(2);
        Lcd_GPIO_DATA_Input_Mode();
        status = (uint8_t)(GPIOC->IDR);
        Lcd_GPIO_DATA_Output_Mode();
        Lcd_E_0;
    }while(status & 0x80);
}
/*********************LCD写入指令***************************/
/*描述:串口发送指令到12864
*    RS=0;
    RW=0;
*/

void Lcd_WriteCmd(uint8_t Cmd )
{
    Lcd_Check_Busy();
   
    Lcd_RS_0;
    Lcd_RW_0;
   
    Lcd_E_0;   
    GPIOC->ODR = Cmd;
    Lcd_E_1;
    Delay_ms(5);
    Lcd_E_0;
}


/*********************LCD写入数据***************************/
/*描述:串口发送指令到12864
*RS = 1
RW = 0;
*
*/

void Lcd_WriteData(uint8_t Data )
{
    Lcd_Check_Busy();
   
    Lcd_RS_1;
    Lcd_RW_0;
    Lcd_E_0;
   
    GPIOC->ODR = Data;
    Lcd_E_1;
    Delay_ms(1);
    Lcd_E_0;
}

/*********************LCD读取数据***************************/
/*描述:并口读取12864数据
*RS = 1
RW = 1;
*
*/

uint8_t Lcd_ReadData(void)
{
    uint16_t data_16=0x0000;
    uint8_t  data_8=0x00;
   
    Lcd_Check_Busy();
    Lcd_E_0;
    Lcd_RS_1;
    Lcd_RW_1;
    Delay_us(10);
    Lcd_E_1;
    Delay_us(200);
    Lcd_GPIO_DATA_Input_Mode();
    data_16 = GPIOC->IDR;
    Lcd_E_0;
    Lcd_GPIO_DATA_Output_Mode();
   
    data_8=(uint8_t)(data_16);
   
    return data_8;
}

/*********************LCD初始化***************************/
/*
*
*
*/

void Lcd_Init(void)
{
    Delay_ms(50);       //等待液晶自检(延时>40ms)
    Lcd_WriteCmd(0x30);        //功能设定:选择基本指令集
    Delay_us(150);//延时>100us
    Lcd_WriteCmd(0x30);        //功能设定:选择8bit数据流
    Delay_us(60);;    //延时>37us
  Lcd_WriteCmd(0x0c);        //开显示
    Delay_us(200);//;    //延时>100us
  Lcd_WriteCmd(0x01);        //清除显示,并且设定地址指针为00H
    Delay_ms(15);    //延时>10ms




void Clear_GDRAM(void)
{
    uint8_t i,j,k,lcd_x,lcd_y;
   
    lcd_x = 0x80;
    lcd_y    = 0x80;
   
  Lcd_CLose_Draw();
   
    for(i=0;i<2;i++) // 区分上下屏
    {
        for(j=0;j<32;j++)
        {
            Lcd_WriteCmd(lcd_y + j);//要被清除的Y坐标
            Lcd_WriteCmd(lcd_x);//要被清除的X坐标
            
            for(k=0;k<8;k++)
            {
                Lcd_WriteData(DUMY_Data);//写入高位
                Lcd_WriteData(DUMY_Data);//写入地位
            }
        }
        
        lcd_x = 0x88; // 将x指向下半屏
    }
    Lcd_OPEN_Draw();
}





/*******************LCD任意位置打点实验*************************/
/*通过坐标来写任意位置的数据*/
/*
X:表示X轴坐标
Y:表示Y轴坐标
x,y的值为头文件中的地址坐标值;
data_H,RAM的高8位;
data_L,RAM的低8位;
*/
void Lcd_GDRAM_DRAW(uint8_t x,uint8_t y,uint8_t data_H,uint8_t data_L)
{
    Lcd_CLose_Draw();
      if(y>Y_32)
        {
            y=y-Y_L_MASK;//确定下半屏y坐标
            x=X_O_L|x;//确定下半屏x坐标
            Lcd_WriteCmd(Y_O|y); //写入Y地址        20
            Lcd_WriteCmd(x); //写入X地址  20
            Lcd_WriteData(data_H);
            Lcd_WriteData(data_L);
        }
        else
        {
            x=X_O_H |x;
            Lcd_WriteCmd(Y_O|y); //写入Y地址        20
            Lcd_WriteCmd(x); //写入X地址  20
            Lcd_WriteData(data_H);
            Lcd_WriteData(data_L);
        }   
            Lcd_OPEN_Draw();
}


/******************LCD读取任意坐标数据*****************************/
/*
    通过输入形参X ,Y来读取GDRAM中的数据;
uint8_t x: 要读取的x轴坐标;
uint8_t y: 尧都区的y轴坐标;
*/

uint16_t Lcd_GDRAM_Read(uint8_t x,uint8_t y)
{
    uint16_t Data=0x0000;
    uint8_t RAM_data_H=0x00;
    uint8_t RAM_data_L=0x00;
    Lcd_WriteCmd(0x34);

      if(y>Y_32)
        {
            y=y-Y_L_MASK;//确定下半屏y坐标
            x=X_O_L|x;//确定下半屏x坐标
            Lcd_WriteCmd(Y_O|y); //写入Y地址        20
            Lcd_WriteCmd(x); //写入X地址  20
            
    Lcd_Check_Busy();
            RAM_data_H=Lcd_ReadData();//空读一次
            RAM_data_H=Lcd_ReadData();//读取高位
            RAM_data_L=Lcd_ReadData();//读取低位
        }
        else
        {
            x=X_O_H |x;
            Lcd_WriteCmd(Y_O|y); //写入Y地址        20
            Lcd_WriteCmd(x); //写入X地址  20
               
        Lcd_Check_Busy();            
         RAM_data_H=Lcd_ReadData();//空读一次
            RAM_data_H=Lcd_ReadData();//读取高位
            RAM_data_L=Lcd_ReadData();//读取低位
        }   
//    Lcd_WriteCmd(0x34);
        printf("\r\n RAM_data_H =:0x%x ----> done\r\n",RAM_data_H);
        printf("\r\n RAM_data_L =:0x%x ----> done\r\n",RAM_data_L);
        Data|=RAM_data_H;
        Data<<=8;
        Data|=RAM_data_L;
        return Data;
}


//////12864.h

#ifndef  __12864_H
#define  __12864_H

#include "stm32f7xx.h"

/*******引脚定义********/
/*12864串口通讯;
RS    片选信号        PH2
RW     数据串行口    PH8
E    时钟        PA11                        
DATA PC0-8*/
#define  Lcd_12864_RS_PORT            GPIOH
#define  Lcd_12864_RS_Pin                GPIO_PIN_2
#define  Lcd_12864_RS_CLK()            __HAL_RCC_GPIOH_CLK_ENABLE()


#define  Lcd_12864_RW_PORT            GPIOH
#define  Lcd_12864_RW_Pin                GPIO_PIN_8
#define  Lcd_12864_RW_CLK()            __HAL_RCC_GPIOH_CLK_ENABLE()

#define  Lcd_12864_E_PORT            GPIOA
#define  Lcd_12864_E_Pin            GPIO_PIN_11
#define  Lcd_12864_E_CLK()        __HAL_RCC_GPIOA_CLK_ENABLE()


#define  Lcd_12864_DATA_PORT  GPIOC
#define  Lcd_12864_DATA_CLK() __HAL_RCC_GPIOC_CLK_ENABLE()
/******模拟时序*********/
#define Lcd_RS_1                                HAL_GPIO_WritePin(Lcd_12864_RS_PORT,Lcd_12864_RS_Pin,GPIO_PIN_SET)
#define Lcd_RS_0                                HAL_GPIO_WritePin(Lcd_12864_RS_PORT,Lcd_12864_RS_Pin,GPIO_PIN_RESET)


#define Lcd_RW_1                                HAL_GPIO_WritePin(Lcd_12864_RW_PORT,Lcd_12864_RW_Pin,GPIO_PIN_SET)
#define Lcd_RW_0                                HAL_GPIO_WritePin(Lcd_12864_RW_PORT,Lcd_12864_RW_Pin,GPIO_PIN_RESET)


#define Lcd_E_1                                HAL_GPIO_WritePin(Lcd_12864_E_PORT,Lcd_12864_E_Pin,GPIO_PIN_SET)
#define Lcd_E_0                                HAL_GPIO_WritePin(Lcd_12864_E_PORT,Lcd_12864_E_Pin,GPIO_PIN_RESET)
/***********传输指令*************/
#define NORMAL_C    0x30//常规指令

#define CLOSE_DRAW    0x34//关闭绘图功能
#define OPEN_DRAW    0x36//打开绘图功能
#define DUMY_Data    0x00//打开绘图功能

/***********LCD坐标*************/
//上半屏
#define X_O_H  0x80 // x轴原点坐标
//下半屏
#define X_O_L  0x88 // x轴原点坐标

#define Y_O  0x80 // y轴原点坐标
#define Y_L_MASK 0x20// 计算下半屏地址的掩码
//x向
#define X_1  0x00 // 第一列;
#define X_2  0x01 // 第二列;
#define X_3  0x02 // 第三列;
#define X_4  0x03 // 第四列;
#define X_5  0x04 // 第五列;
#define X_6  0x05 // 第六列;
#define X_7  0x06 // 第七列;
#define X_8  0x07 // 第八列;

//上半屏
#define Y_1  0x00 // 第一行;
#define Y_2  0x01 // 第二行;
#define Y_3  0x02 // 第三行;
#define Y_4  0x03 // 第四行;
#define Y_5  0x04 // 第五行;
#define Y_6  0x05 // 第六行;
#define Y_7  0x06 // 第七行;
#define Y_8  0x07 // 第八行;
#define Y_9  0x08 // 第九行;
#define Y_10 0x09 // 第十行;
#define Y_11 0x0a // 第十一行;
#define Y_12 0x0b // 第十二行;
#define Y_13 0x0c // 第十三行;
#define Y_14 0x0d // 第十四行;
#define Y_15 0x0e // 第十五行;
#define Y_16 0x0f // 第十六行;
#define Y_17 0x10 // 第十七行;
#define Y_18 0x11 // 第十八行;
#define Y_19 0x12 // 第十九行;
#define Y_20 0x13 // 第二十行;
#define Y_21 0x14 // 第二十一行;
#define Y_22 0x15 // 第二十二行;
#define Y_23 0x16 // 第二十三行;
#define Y_24 0x17 // 第二十四行;
#define Y_25 0x18 // 第二十五行;
#define Y_26 0x19 // 第二十六行;
#define Y_27 0x1a // 第二十七行;
#define Y_28 0x1b // 第二十八行;
#define Y_29 0x1c // 第二十九行;
#define Y_30 0x1d // 第三十行;
#define Y_31 0x1e // 第三十一行;
#define Y_32 0x1f // 第三十二行;
//下半屏
#define Y_33  (0x00+Y_L_MASK) // 第一行;
#define Y_34  (0x01+Y_L_MASK) // 第二行;
#define Y_35  (0x02+Y_L_MASK) // 第三行;
#define Y_36  (0x03+Y_L_MASK) // 第四行;
#define Y_37  (0x04+Y_L_MASK) // 第五行;
#define Y_38  (0x05+Y_L_MASK) // 第六行;
#define Y_39  (0x06+Y_L_MASK) // 第七行;
#define Y_40  (0x07+Y_L_MASK) // 第八行;
#define Y_41  (0x08+Y_L_MASK) // 第九行;
#define Y_42  (0x09+Y_L_MASK) // 第十行;
#define Y_43  (0x0a+Y_L_MASK) // 第十一行;
#define Y_44  (0x0b+Y_L_MASK) // 第十二行;
#define Y_45  (0x0c+Y_L_MASK) // 第十三行;
#define Y_46  (0x0d+Y_L_MASK) // 第十四行;
#define Y_47  (0x0e+Y_L_MASK) // 第十五行;
#define Y_48  (0x0f+Y_L_MASK) // 第十六行;
#define Y_49  (0x10+Y_L_MASK) // 第十七行;
#define Y_50  (0x11+Y_L_MASK) // 第十八行;
#define Y_51  (0x12+Y_L_MASK) // 第十九行;
#define Y_52  (0x13+Y_L_MASK) // 第二十行;
#define Y_53  (0x14+Y_L_MASK) // 第二十一行;
#define Y_54  (0x15+Y_L_MASK) // 第二十二行;
#define Y_55  (0x16+Y_L_MASK) // 第二十三行;
#define Y_56  (0x17+Y_L_MASK) // 第二十四行;
#define Y_57  (0x18+Y_L_MASK) // 第二十五行;
#define Y_58  (0x19+Y_L_MASK) // 第二十六行;
#define Y_59  (0x1a+Y_L_MASK) // 第二十七行;
#define Y_60  (0x1b+Y_L_MASK) // 第二十八行;
#define Y_61  (0x1c+Y_L_MASK) // 第二十九行;
#define Y_62  (0x1d+Y_L_MASK) // 第三十行;
#define Y_63  (0x1e+Y_L_MASK) // 第三十一行;
#define Y_64  (0x1f+Y_L_MASK) // 第三十二行;


/************函数定义******/
//extern  void Delay_us(__IO uint32_t nTime);//systick
void LCD_GPIO_Init(void);//GPIO初始化函数;
void Lcd_Init(void);//12864初始化函数;
void LCD_Display_Words(uint8_t x,uint8_t y,uint8_t*str);//写入字符
void Clear_GDRAM(void);
extern void Delay_us(uint32_t nus);
extern void Delay_ms(uint16_t nms);
void Lcd_GDRAM_DRAW(uint8_t x,uint8_t y,uint8_t data_H,uint8_t data_L);

uint8_t Lcd_ReadData(void);
uint16_t Lcd_GDRAM_Read(uint8_t x,uint8_t y);

#endif/*__12864_H*/




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:776619 发表于 2022-5-20 20:46 | 只看该作者
Data|=RAM_data_H;
Data<<=8;
Data|=RAM_data_L;
不同长度的数据能做或等于的运算吗?
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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