最近想用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*/
|