初级会员
- 积分
- 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);
}
}
|
|