液晶型号为JLX12864 COG液晶,资料网上有,linux下面通过SPI与IO控制,IO控制使用的是文件方式,SPI是开发板提供的驱动,这个SPI驱动应该每家提供的都不一样,需要自己去按照驱动文档操作,主要不通电就是底层的配置不一样。

//SPI.c这个是打开SPI驱动

/** SPI.c**  Created on: 2018年8月2日*      Author: cfan*/
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <termios.h>
#include "SPI.h"
#include <errno.h>    // 包含errno所需要的头文件
#include <string.h>   // 包含strerror所需要的头文件
#include "typedef.h"//SPI初始化
int SPI_Init(SPI_HANDLE *pHandle, const char *pSpiDeviceName)
{pHandle->fd = -1;if(pSpiDeviceName == NULL || pHandle==NULL || strlen(pSpiDeviceName)>SPI_DEVICE_NAME_MAX_LEN){printf("%s(%d)Check the input parameters!\r\n",__FILE__ , __LINE__);return -1;}strcpy(pHandle->SpiDeviceName, pSpiDeviceName);                  //记录串口设备名称//打开SPIpHandle->fd = open(pSpiDeviceName, O_RDWR|O_NOCTTY|O_NDELAY);      //读写独占方式打开SPIif (pHandle->fd < 0){//打印错误信息printf("Can't Open SPI(%s) : %s(%d)\n",pSpiDeviceName, strerror(errno), errno);return errno;}else{printf("Open SPI OK!\r\n");}return 0;
}

//spi.h

/** SPI.h**  Created on: 2018年8月2日*      Author: cfan*/#ifndef HARDWARE_SPI_H_
#define HARDWARE_SPI_H_
#include "termios.h"
#include "typedef.h"#define SPI_DEVICE_NAME_MAX_LEN   35  //SPI名称最大长度//SPI接口句柄
typedef struct
{int fd;char SpiDeviceName[SPI_DEVICE_NAME_MAX_LEN+1];     //SPI名称
}SPI_HANDLE;//SPI初始化
int SPI_Init(SPI_HANDLE *pHandle, const char *pSpiDeviceName);#endif /* HARDWARE_SPI_H_ */

//SPI驱动调用,这个是开发板提供的,各个厂家应该都不一样,需要自己去查询

#include "common.h"
#include "spi_enum.h"
#include "spidev.h"
#include <sys/ioctl.h>
#include "nano_pi_spi.h"
//开发板官方提供的SPI驱动接口#define SPI_MAX_SPEED 25000000     //最大时钟速度/*************************************************************************************************************************
*函数                 :   int setSPIWriteBitsPerWord(int spi_fd, int bits)
*功能                 :   设置每次读SPI设备的字长,单位是比特.
*参数                 :   spi_fd: SPI设备的文件描述符;bits: 字长,单位是比特
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :   虽然大部分SPI接口的字长是8或者16,仍然会有一些特殊的例子。需要说明的是,如果这个成员为零的话,默认使用8作为字长(ioctl SPI_IOC_WR_BITS_PER_WORD)
*************************************************************************************************************************/
int setSPIWriteBitsPerWord(int spi_fd, int bits)
{clearLastError();int ret = ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_WR_BITS_PER_WORD");}return ret;
}/*************************************************************************************************************************
*函数                 :   int setSPIReadBitsPerWord(int spi_fd, int bits)
*功能                 :   设置每次写SPI设备的字长,单位是比特
*参数                 :   spi_fd: SPI设备的文件描述符;bits: 字长,单位是比特
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :   虽然大部分SPI接口的字长是8或者16,仍然会有一些特殊的例子。需要说明的是,如果这个成员为零的话,默认使用8作为字长(ioctl SPI_IOC_WR_BITS_PER_WORD)
*************************************************************************************************************************/
int setSPIReadBitsPerWord(int spi_fd, int bits)
{int ret = ioctl(spi_fd, SPI_IOC_RD_BITS_PER_WORD, &bits);clearLastError();if (ret < 0) {setLastError("Can't ioctl SPI_IOC_RD_BITS_PER_WORD");}return ret;
}/*************************************************************************************************************************
*函数                 :   int setSPIBitOrder(int spi_fd, int order)
*功能                 :   设备SPI传输时是先传输低比特位还是高比特位
*参数                 :   spi_fd: SPI设备的文件描述符;order: 传SPIEnum.MSBFIRST或SPIEnum.LSBFIRST
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :   可选的参数有SPIEnum.MSBFIRST和SPIEnum.LSBFIRST
*************************************************************************************************************************/
int setSPIBitOrder(int spi_fd, int order)
{int ret;int spi_mode = 0;clearLastError();if(order == LSBFIRST) {spi_mode |=  SPI_LSB_FIRST;} else {spi_mode &= ~SPI_LSB_FIRST;}ret = ioctl(spi_fd, SPI_IOC_WR_MODE, &spi_mode);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_WR_MODE");return ret;}return ret;
}/*************************************************************************************************************************
*函数                 :   int setSPIMaxSpeed(int spi_fd, unsigned int spi_speed)
*功能                 :   设备SPI传输速度
*参数                 :   spi_fd: SPI设备的文件描述符;spi_speed: 速度(分频,越小速度越高)
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :
*************************************************************************************************************************/
int setSPIMaxSpeed(int spi_fd, unsigned int spi_speed)
{int ret;unsigned int realSpeed;clearLastError();if (spi_speed<0 || spi_speed>SPI_MAX_SPEED) {setLastError("invalid spi speed %d", spi_speed);}ret = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_WR_MAX_SPEED_HZ");return ret;}ret = ioctl(spi_fd, SPI_IOC_RD_MAX_SPEED_HZ, &realSpeed);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_RD_MAX_SPEED_HZ");return ret;}return ret;
}/*************************************************************************************************************************
*函数                 :   int setSPIDataMode(int spi_fd, int mode)
*功能                 :   设置SPI设备的模式
*参数                 :   spi_fd: SPI设备的文件描述符;mode: SPI设备的模式,可传入SPI_MODE0 ~ SPI_MODE3
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :
*************************************************************************************************************************/
int setSPIDataMode(int spi_fd, int mode)
{int ret;int spi_mode = 0;clearLastError();switch(mode) {case SPI_MODE0:spi_mode &= ~(SPI_CPHA|SPI_CPOL);break;case SPI_MODE1:spi_mode &= ~(SPI_CPOL);spi_mode |= (SPI_CPHA);break;case SPI_MODE2:spi_mode |= (SPI_CPOL);spi_mode &= ~(SPI_CPHA);break;case SPI_MODE3:spi_mode |= (SPI_CPHA|SPI_CPOL);break;default:setLastError("error SPIDataMode");return -1;}ret = ioctl(spi_fd, SPI_IOC_WR_MODE, &mode);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_WR_MODE");return ret;}ret = ioctl(spi_fd, SPI_IOC_RD_MODE, &mode);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_RD_MODE");return ret;}return ret;
}/*************************************************************************************************************************
*函数                 :   int SPItransferOneByte(int spi_fd, unsigned char byteData, int spi_delay, int spi_speed, int spi_bits)
*功能                 :   同时发送与接收一个字节的数据
*参数                 :   spi_fd: SPI设备的文件描述符;byteData:要写入SPI设备的数据;spi_delay:延时;spi_speed:传输速度;spi_bits:字长,单位是比特
*返回                 :   成功返回读到的数据,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :
*************************************************************************************************************************/
int SPItransferOneByte(int spi_fd , unsigned char byteData, int spi_delay, int spi_speed, int spi_bits)
{int ret;unsigned char tx[1] = {0};unsigned char rx[1] = {0};tx[0] = byteData;struct spi_ioc_transfer tr;tr.tx_buf = (unsigned long)tx;tr.rx_buf = (unsigned long)rx;tr.len = 1;tr.delay_usecs = spi_delay;tr.speed_hz = spi_speed;tr.bits_per_word = spi_bits;clearLastError();ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);if (ret < 0) {setLastError("Can't ioctl SPI_IOC_MESSAGE");return ret;}return rx[0];
}/*************************************************************************************************************************
*函数                 :   int SPItransferBytes(int spi_fd, unsigned char * writeData, int writeLen, unsigned char * readBuffer,
*函数                         int readLen, int spi_delay, int spi_speed, int spi_bits)
*功能                 :   同时发送与接收多个字节的数据
*参数                 :   spi_fd: SPI设备的文件描述符;writeData:要写入的数据;readBuff: 存放读取数据的缓冲区;spi_delay:延时;spi_speed:传输速度;spi_bits:字长,单位是比特
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :
*************************************************************************************************************************/
int SPItransferBytes(int spi_fd, unsigned char * writeData, int writeLen, unsigned char * readBuffer, int readLen, int spi_delay,int spi_speed, int spi_bits)
{unsigned int len = writeLen;if (len > readLen) {len = readLen;}unsigned char * pWriteData = writeData;unsigned char * pReadBuffer = readBuffer;struct spi_ioc_transfer tr;tr.tx_buf = (unsigned long)pWriteData;tr.rx_buf = (unsigned long)pReadBuffer;tr.len = len;tr.delay_usecs = spi_delay;tr.speed_hz = spi_speed;tr.bits_per_word = spi_bits;int ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);clearLastError();if (ret < 0) {setLastError("Can't ioctl SPI_IOC_MESSAGE");}return ret;
}/*************************************************************************************************************************
*函数                 :   int writeBytesToSPI(int spi_fd, unsigned char * writeData, int writeLen, int spi_delay, int spi_speed,
*函数                         int spi_bits)
*功能                 :   写多个字节的数据到SPI设 备
*参数                 :   spi_fd: SPI设备的文件描述符;writeData:要写入的数据;spi_delay:延时;spi_speed:传输速度;spi_bits:字长,单位是比特
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :
*************************************************************************************************************************/
int writeBytesToSPI(int spi_fd, unsigned char * writeData, int writeLen, int spi_delay, int spi_speed, int spi_bits)
{unsigned int len = writeLen;unsigned char * pWriteData = writeData;struct spi_ioc_transfer tr;tr.tx_buf = (unsigned long)pWriteData;tr.rx_buf = (unsigned long)0;tr.len = len;tr.delay_usecs = spi_delay;tr.speed_hz = spi_speed;tr.bits_per_word = spi_bits;int ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);clearLastError();if (ret < 0) {setLastError("Can't ioctl SPI_IOC_MESSAGE");}return ret;
}/*************************************************************************************************************************
*函数                 :   int readBytesFromSPI(int spi_fd, unsigned char * readBuffer, int readLen, int spi_delay, int spi_speed,
*函数                         int spi_bits)
*功能                 :   从SPI设备读取多个字节
*参数                 :   spi_fd: SPI设备的文件描述符;readBuff: 存放读取数据的缓冲区;readLen:读取长度(不能超过缓冲区大小)spi_delay:延时;spi_speed:传输速度;spi_bits:字长,单位是比特
*返回                 :   成功返回0,失败返回负数
*依赖                 :   无
*作者                 :   Friendly NanoPI-NEO(cp1300@139.com整理)
*时间                 :   2018-08-12
*最后修改时间 :   2018-08-12
*说明                 :
*************************************************************************************************************************/
int readBytesFromSPI(int spi_fd, unsigned char * readBuffer, int readLen, int spi_delay, int spi_speed, int spi_bits)
{unsigned int len = readLen;unsigned char * pReadBuffer = readBuffer;struct spi_ioc_transfer tr;tr.tx_buf = (unsigned long)0;tr.rx_buf = (unsigned long)pReadBuffer;tr.len = len;tr.delay_usecs = spi_delay;tr.speed_hz = spi_speed;tr.bits_per_word = spi_bits;int ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);clearLastError();if (ret < 0) {setLastError("Can't ioctl SPI_IOC_MESSAGE");}return ret;
}

//JLX12864G.c 液晶硬件底层操作

/************************************************************************************************************** 文件名:     JLX12864G.c* 功能:        JLX12864G-0088 JLX12864G液晶驱动* 作者:       cp1300@139.com* 邮箱:        cp1300@139.com* 创建时间:  2012年5月30日20:40* 最后修改时间:2012年5月30日* 详细:     2016-02-01:增加获取显存函数
*************************************************************************************************************/
#include "ascii_8x16.h"
#include "JLX12864G.H"
#include <stdio.h>
#include "typedef.h"//字模取模方式:阴码,列行式,逆向(低位在前)//汉字支持
#define CHINESE_ENABLE      0#if LCD_BUFF_ENABLE        //使能了显存
//获取显存地址
//2016-02-01:增加获取显存函数
u8 *JLX12864G_GetGramBuff(JLX12864G_HANDLE *pHandle)
{return (u8 *)&pHandle->LCD_BUFF[0][0];
}#endif/*************************************************************************************************************************
* 函数            :   void JLX12864G_WriteCommand(JLX12864G_HANDLE *pHandle, u8 cmd)
* 功能            :   向JLX12864G写入一字节命令
* 参数            :   pHandle:句柄;cmd:命令
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120530
* 最后修改时间    :   2018-08-12
* 说明            :   RS=0,时钟上升沿数据有效,先发送高位
*************************************************************************************************************************/
void JLX12864G_WriteCommand(JLX12864G_HANDLE *pHandle, u8 cmd)
{pHandle->SetRS(0);              //RS=0pHandle->WriteData(&cmd, 1);  //发送数据pHandle->SetRS(1);             //RS=1
}/*************************************************************************************************************************
* 函数    :   static void JLX12864G_SetPageAdd(JLX12864G_HANDLE *pHandle, u8 PageAdd)
* 功能    :   设置光标页地址
* 参数    :   pHandle:句柄;PageAdd:页地址,0-7
* 返回    :   无
* 依赖    :   底层宏定义
* 作者    :   cp1300@139.com
* 时间    :   20120531
* 最后修改时间 : 20120531
* 说明    :   共64行,没8行为一页,共8页
*************************************************************************************************************************/
static void JLX12864G_SetPageAdd(JLX12864G_HANDLE *pHandle, u8 PageAdd)
{JLX12864G_WriteCommand(pHandle, 0xb0 + PageAdd);
}/*************************************************************************************************************************
* 函数    :   static void JLX12864G_SetLineAdd(JLX12864G_HANDLE *pHandle, u8 LineAdd)
* 功能    :   设置光标列地址
* 参数    :   pHandle:句柄;LineAdd:列地址,0-127
* 返回    :   无
* 依赖    :   底层宏定义
* 作者    :   cp1300@139.com
* 时间    :   20120531
* 最后修改时间 : 20120531
* 说明    :   共128列
*************************************************************************************************************************/
static void JLX12864G_SetLineAdd(JLX12864G_HANDLE *pHandle, u8 LineAdd)
{LineAdd += JLX12864G_X_OFFSET;JLX12864G_WriteCommand(pHandle, 0x10 + (LineAdd >> 4));     //列地址高4位JLX12864G_WriteCommand(pHandle, 0x00 + (LineAdd & 0x0f));  //列地址低4位
}/*************************************************************************************************************************
* 函数            :   void JLX12864G_ClearAll(JLX12864G_HANDLE *pHandle)
* 功能            :   JLX12864G液晶清屏
* 参数            :   pHandle:句柄;
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120530
* 最后修改时间    :   20120530
* 说明            :   无
*************************************************************************************************************************/
void JLX12864G_ClearAll(JLX12864G_HANDLE *pHandle)
{u8 i,j;u32 data = 0;for(i = 0;i < 9;i ++){JLX12864G_SetPageAdd(pHandle, i);JLX12864G_SetLineAdd(pHandle, 0);for(j = 0;j < 132/4;j ++){pHandle->WriteData((u8 *)&data, 4);}}
}/*************************************************************************************************************************
* 函数            :   void JLX12864G_FillAll(JLX12864G_HANDLE *pHandle)
* 功能            :   JLX12864G液晶填充
* 参数            :   pHandle:句柄;
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120530
* 最后修改时间    :   20120530
* 说明            :   无
*************************************************************************************************************************/
void JLX12864G_FillAll(JLX12864G_HANDLE *pHandle)
{u8 i,j;u32 data = 0xffffffff;for(i = 0;i < 9;i ++){JLX12864G_SetPageAdd(pHandle, i);JLX12864G_SetLineAdd(pHandle, 0);for(j = 0;j < 132/4;j ++){pHandle->WriteData((u8 *)&data, 4);}}
}/*************************************************************************************************************************
* 函数    :   void JLX12864G_ShowOneChar(JLX12864G_HANDLE *pHandle,u8 PageAdd,u8 LineAdd,u8 CHAR,u8 FontSize)
* 功能    :   在指定位置显示一个字符
* 参数    :   pHandle:句柄;PageAdd:页,0~7,共8页;L:0~127共128列,CHAR:需要显示的字符,FontSize:字体大小
* 返回    :   无
* 依赖    :   底层宏定义
* 作者    :   cp1300@139.com
* 时间    :   20120530
* 最后修改时间 : 20120530
* 说明    :   显示一个ASCII字符
*************************************************************************************************************************/
void JLX12864G_ShowOneChar(JLX12864G_HANDLE *pHandle,u8 PageAdd,u8 LineAdd,u8 CHAR,u8 FontSize)
{u8 i,j,k;const unsigned char *p;CHAR -= 32;if(CHAR > ASCII_MAX - 1)return;if(FontSize == 12)p = ASCII_8X12[CHAR];       //12号elsep = ASCII_8X16[CHAR];     //16号for(i = 0;i < 2;i ++){JLX12864G_SetPageAdd(pHandle, PageAdd + i);JLX12864G_SetLineAdd(pHandle, LineAdd);k = i * 8;pHandle->WriteData((u8 *)&p[k+j], 8);/*for(j = 0;j < 8;j ++){pHandle->WriteByteData(p[k+j]);}*/}
}/*************************************************************************************************************************
* 函数    :   void LCD_PrintfChar(JLX12864G_HANDLE *pHandle,u8 PageAdd,u8 LineAdd,const char *p,u8 FontSize)
* 功能    :   在指定位置显示字符串
* 参数    :   pHandle:句柄;PageAdd:页,0~7,共8页;L:0~127共128列;p:字符指针,FontSize:子大小;16或者12
* 返回    :   无
* 依赖    :   JLX12864G_ShowOneChar
* 作者    :   cp1300@139.com
* 时间    :   20120601
* 最后修改时间 : 20120601
* 说明    :   FontSize = 16或者 12
*************************************************************************************************************************/
void JLX12864G_PrintfChar(JLX12864G_HANDLE *pHandle,u8 PageAdd,u8 LineAdd,const char *p,u8 FontSize)
{while(*p != 0){JLX12864G_ShowOneChar(pHandle, PageAdd,LineAdd,*p,FontSize);p ++;LineAdd += 8;}
}/*************************************************************************************************************************
* 函数    :   void JLX12864G_SetConAdj(JLX12864G_HANDLE *pHandle,u8 cont)
* 功能    :   设置液晶的对比度
* 参数    :   pHandle:句柄;cont:对比度值
* 返回    :   无
* 依赖    :   底层宏定义
* 作者    :   cp1300@139.com
* 时间    :   2014-08-24
* 最后修改时间 : 2014-08-24
* 说明    :   需要先初始化LCD
*************************************************************************************************************************/
void JLX12864G_SetConAdj(JLX12864G_HANDLE *pHandle,u8 cont)
{if(cont < 25)cont = 25;if(cont > 60)cont = 60;JLX12864G_WriteCommand(pHandle, 0x81); /*微调对比度*/JLX12864G_WriteCommand(pHandle, cont); /*微调对比度的值,可设置范围0~63*/pHandle->LCD_Cont = cont;      //更新对比度
}/*************************************************************************************************************************
* 函数            :   void JLX12864G_Init(JLX12864G_HANDLE *pHandle,void (*WriteData)(u8 data,u8 len),        //写数据接口void (*SetRS)(u8 level),     //设置RS电平void (*SetRST)(u8 level),       //设置RST电平void (*DelayMS)(u8 ms),            //ms延时u8 LCDCont)
* 功能            :   初始化JLX12864G液晶
* 参数            :   pHandle:句柄;WriteByteData:写一字节函数;SetRS:设置RS电平;SetRST:设置RST电平;DelayMS:系统ms延时;LCDCont:对比度
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120530
* 最后修改时间    : 2018-08-12
* 说明            :   初始化JLX12864G液晶
*************************************************************************************************************************/
void JLX12864G_Init(JLX12864G_HANDLE *pHandle,void (*WriteData)(u8 *data,u8 len),       //写数据接口void (*SetRS)(u8 level),     //设置RS电平void (*SetRST)(u8 level),       //设置RST电平void (*DelayMS)(u8 ms),            //ms延时u8 LCDCont)
{if(pHandle == NULL){printf("JLX12864G:ERROR *pHandle is NULL!\r\n");return;}if(WriteData == NULL){printf("JLX12864G:ERROR *WriteData is NULL!\r\n");return;}if(SetRS == NULL){printf("JLX12864G:ERROR *SetRS is NULL!\r\n");return;}if(DelayMS == NULL){printf("JLX12864G:ERROR *DelayMS is NULL!\r\n");return;}pHandle->WriteData = WriteData;pHandle->SetRS = SetRS;pHandle->SetRST = SetRST;pHandle->DelayMS = DelayMS;if(pHandle->SetRST != NULL){pHandle->SetRST(0);//液晶复位开始pHandle->DelayMS(1);pHandle->SetRST(1);//液晶复位结束}pHandle->DelayMS(1);JLX12864G_WriteCommand(pHandle, 0xe2); /*软复位*/JLX12864G_WriteCommand(pHandle, 0x2c); /*升压步聚1*/JLX12864G_WriteCommand(pHandle, 0x2e); /*升压步聚2*/JLX12864G_WriteCommand(pHandle, 0x2f); /*升压步聚3*/JLX12864G_WriteCommand(pHandle, 0x23); /*粗调对比度,可设置范围20~27*/
//  JLX12864G_WriteCommand(0x81); /*微调对比度*/
//  JLX12864G_WriteCommand(0x30); /*微调对比度的值,可设置范围0~63*/JLX12864G_SetConAdj(pHandle, LCDCont);JLX12864G_WriteCommand(pHandle, 0xa2); /*1/9 偏压比(bias)*/
#if(LCD_ROTATE_180) //旋转180度显示JLX12864G_WriteCommand(pHandle, 0xc0); /*行扫描顺序:从下到上*/JLX12864G_WriteCommand(pHandle, 0xa1); /*列扫描顺序:从右到左*/
#elseJLX12864G_WriteCommand(pHandle, 0xc8); /*行扫描顺序:从上到下*/JLX12864G_WriteCommand(pHandle, 0xa0); /*列扫描顺序:从左到右*/
#endifJLX12864G_WriteCommand(pHandle, 0x40); //初始化显示行为0JLX12864G_WriteCommand(pHandle, 0xa4); //常规显示JLX12864G_WriteCommand(pHandle, 0xaf); /*开显示*/JLX12864G_ClearAll(pHandle);pHandle->LCD_Cont = LCDCont;//isPowerStatus = TRUE;  //上电完成
}/*************************************************************************************************************************
* 函数            :   void JLX12864G_GRAM_Up(JLX12864G_HANDLE *pHandle, u8 LCD_BUFF[8][128], u8 x1,u8 y1,u8 x2,u8 y2)
* 功能            :   更新显存至液晶
* 参数            :   pHandle:句柄;LCD_BUFF:显存地址;x1,y1:起始坐标;x2,y2:终点坐标
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120531
* 最后修改时间    :   2018-08-12
* 说明            :   y坐标会页对齐
*************************************************************************************************************************/
void JLX12864G_GRAM_Up(JLX12864G_HANDLE *pHandle, u8 LCD_BUFF[8][128], u8 x1,u8 y1,u8 x2,u8 y2)
{u8 i,j;if(x2 > 127) x2 = 127;y1 /= 8;  //计算页地址y2 /= 8;for(i = 0;i < (y2 - y1 + 1);i ++){JLX12864G_SetPageAdd(pHandle, y1 + i);   //写入页地址JLX12864G_SetLineAdd(pHandle, x1);       //写入行地址pHandle->WriteData(&LCD_BUFF[y1 + i][x1 + 0], (x2 - x1 + 1));/*for(j = 0;j < (x2 - x1 + 1);j ++){LCD12864_WriteData(pHandle, LCD_BUFF[y1 + i][x1 + j]);}*/}
}

//LCD12864.c 这个是个内存中的虚拟LCD,每次操作都在内存中操作,然后同步到实际LCD

/** LCD12864_Virtual.c* 虚拟LCD12864*  Created on: 2018年8月12日*      Author: cfan*/
#include "LCD12864.h"
#include "typedef.h"
#include "ASCII_8x16.h"
#include <stdio.h>
#include <string.h>/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_Init(LCD12864_HANDLE *pHandle)
* 功能            :   LCD12864显存模式初始化
* 参数            :   pHandle:句柄;
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120531
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_Init(LCD12864_HANDLE *pHandle)
{if(pHandle == NULL){printf("LCD12864:ERROR *pHandle is NULL!\r\n");return;}memset(pHandle->LCD_BUFF, 0, 8*128);
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_DrawPoint(LCD12864_HANDLE *pHandle, u8 x,u8 y)
* 功能            :   在显存里面指定位置画点
* 参数            :   pHandle:句柄;x:X坐标,0-127;y:y坐标,0-63
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120531
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_DrawPoint(LCD12864_HANDLE *pHandle, u8 x,u8 y)
{if(x > 127 || y > 63)return;pHandle->LCD_BUFF[y / 8][x] |= (1 << (y % 8));
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_ClearPoint(LCD12864_HANDLE *pHandle, u8 x,u8 y)
* 功能            :   擦除显存里面指定位置的点
* 参数            :   pHandle:句柄;x:X坐标,0-127;y:y坐标,0-63
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120531
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_ClearPoint(LCD12864_HANDLE *pHandle, u8 x, u8 y)
{if(x > 127 || y > 63)return;pHandle->LCD_BUFF[y / 8][x] &= ~(1 << (y % 8));
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_ClearAll(LCD12864_HANDLE *pHandle)
* 功能            :   清除全部显存
* 参数            :   pHandle:句柄;
* 返回            :   无
* 依赖            :   底层宏定义
* 作者            :   cp1300@139.com
* 时间            :   20120531
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_ClearAll(LCD12864_HANDLE *pHandle)
{u8 i,j;for(i = 0;i < 8;i ++){for(j = 0;j < 128;j ++){pHandle->LCD_BUFF[i][j] = 0x00;}}
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_ShowChar(LCD12864_HANDLE *pHandle, u8 x,u8 y,u8 CHAR,LCD12864_FONT_MODE FontMode)
* 功能            :   在指定位置显示一个指定大小的字符
* 参数            :   pHandle:句柄;x,y:显示开始坐标,p:汉子点阵缓冲区;FontMode:汉子显示模式,
* 返回            :   无
* 依赖            :   画点函数
* 作者            :   cp1300@139.com
* 时间            :   20120603
* 最后修改时间    :   2018-08-12
* 说明            :
*************************************************************************************************************************/
void LCD12864_GRAM_ShowChar(LCD12864_HANDLE *pHandle, u8 x,u8 y,u8 CHAR,LCD12864_FONT_MODE FontMode)
{u8 i,j;u8 FontSize = (u8)FontMode&0x0f;   //获取字体大小u8 *p;void (*DrawPoint)(LCD12864_HANDLE *pHandle, u8 i,u8 j);void (*ClearPoint)(LCD12864_HANDLE *pHandle, u8 i,u8 j);CHAR -= 32;if(CHAR > 95 - 1) //限制ASCII范围return;if(FontSize){FontSize = 12;p = (u8 *)ASCII_8X12[CHAR];        //12号}else{FontSize = 16;p = (u8 *)ASCII_8X16[CHAR];      //16号}if(FontMode & 0x40)   //反显{DrawPoint = LCD12864_GRAM_ClearPoint;ClearPoint =  LCD12864_GRAM_DrawPoint;}else //正常模式{ClearPoint =  LCD12864_GRAM_ClearPoint;DrawPoint =  LCD12864_GRAM_DrawPoint;}if(FontMode & 0x80)   //叠加显示{for(j = 0;j < 8;j ++){for(i = 0;i < 8;i ++){if(*p & (1 << i))(*DrawPoint)(pHandle, x + j,y + i);}p ++;}for(j = 0;j < 8;j ++){for(i = 0;i < FontSize - 8;i ++){if(*p & (1 << i))(*DrawPoint)(pHandle, x + j,y + 8 + i);}p ++;}}else  //非叠加显示{for(j = 0;j < 8;j ++){for(i = 0;i < 8;i ++){if(*p & (1 << i))(*DrawPoint)(pHandle, x + j,y + i);else(*ClearPoint)(pHandle, x + j,y + i);}p ++;}for(j = 0;j < 8;j ++){for(i = 0;i < FontSize - 8;i ++){if(*p & (1 << i))(*DrawPoint)(pHandle, x + j,y + 8 + i);else(*ClearPoint)(pHandle, x + j,y + 8 + i);}p ++;}}
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_Fill(LCD12864_HANDLE *pHandle, u16 xStart, u16 yStart, u16 xEnd, u16 yEnd)
* 功能            :   指定位置填充
* 参数            :   pHandle:句柄;范围
* 返回            :   无
* 依赖            :   底层函数
* 作者            :   cp1300@139.com
* 时间            :   20110920
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_Fill(LCD12864_HANDLE *pHandle, u16 xStart, u16 yStart, u16 xEnd, u16 yEnd)
{u16 i,j;for(i = xStart;i < xEnd; i ++){for(j = yStart;j < yEnd;j ++){LCD12864_GRAM_DrawPoint(pHandle,i,j);}}
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_Clear(LCD12864_HANDLE *pHandle, u16 xStart, u16 yStart, u16 xEnd, u16 yEnd)
* 功能            :   清除指定位置
* 参数            :   pHandle:句柄;范围
* 返回            :   无
* 依赖            :   底层函数
* 作者            :   cp1300@139.com
* 时间            :   20110920
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_Clear(LCD12864_HANDLE *pHandle, u16 xStart, u16 yStart, u16 xEnd, u16 yEnd)
{u16 i,j;for(i = xStart;i < xEnd; i ++){for(j = yStart;j < yEnd;j ++){LCD12864_GRAM_ClearPoint(pHandle,i,j);}}
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_DrawLine(LCD12864_HANDLE *pHandle,u16 x1, u16 y1, u16 x2, u16 y2)
* 功能            :   画线函数
* 参数            :   pHandle:句柄;起点终点坐标
* 返回            :   无
* 依赖            :   画点函数
* 作者            :   cp1300@139.com
* 时间            :   20110920
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_DrawLine(LCD12864_HANDLE *pHandle,u16 x1, u16 y1, u16 x2, u16 y2)
{u16 t;int xerr=0,yerr=0,delta_x,delta_y,distance;int incx,incy,uRow,uCol;//TFT_LCD_SetRamAddr(0,239,0,319);//设置显示窗口delta_x=x2-x1; //计算坐标增量delta_y=y2-y1;uRow=x1;uCol=y1;if(delta_x>0)incx=1; //设置单步方向else if(delta_x==0)incx=0;//垂直线else {incx=-1;delta_x=-delta_x;}if(delta_y>0)incy=1;else if(delta_y==0)incy=0;//水平线else{incy=-1;delta_y=-delta_y;}if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴else distance=delta_y;for(t=0;t<=distance+1;t++ )//画线输出{LCD12864_GRAM_DrawPoint(pHandle, uRow,uCol);//画点xerr+=delta_x ;yerr+=delta_y ;if(xerr>distance){xerr-=distance;uRow+=incx;}if(yerr>distance){yerr-=distance;uCol+=incy;}}
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_DrawRectangle(LCD12864_HANDLE *pHandle,u16 x1, u16 y1, u16 x2, u16 y2)
* 功能            :   在指定位置画一个矩形
* 参数            :   pHandle:句柄;多边形的两个坐标
* 返回            :   无
* 依赖            :   画线函数
* 作者            :   cp1300@139.com
* 时间            :   20110920
* 最后修改时间    :   2018-08-12
* 说明            :   无
*************************************************************************************************************************/
void LCD12864_GRAM_DrawRectangle(LCD12864_HANDLE *pHandle,u16 x1, u16 y1, u16 x2, u16 y2)
{LCD12864_GRAM_DrawLine(pHandle, x1,y1,x2,y1);LCD12864_GRAM_DrawLine(pHandle, x1,y1,x1,y2);LCD12864_GRAM_DrawLine(pHandle, x1,y2,x2,y2);LCD12864_GRAM_DrawLine(pHandle, x2,y1,x2,y2);
}/*************************************************************************************************************************
* 函数            :   void LCD12864_GRAM_ShowString(LCD12864_HANDLE *pHandle, u16 x,u16 y,const char *pStr,LCD12864_FONT_MODE Font_MODE)
* 功能            :   在显存指定位置显示字符串
* 参数            :   pHandle:句柄;x,y:显示开始坐标,pStr:字符串缓冲区;FontMode:显示模式,
* 返回            :   无
* 依赖            :   画点函数
* 作者            :   cp1300@139.com
* 时间            :   2014-08-20
* 最后修改时间    :   2018-08-12
* 说明            :
*************************************************************************************************************************/
void LCD12864_GRAM_ShowString(LCD12864_HANDLE *pHandle, u16 x,u16 y,const char *pStr,LCD12864_FONT_MODE Font_MODE)
{u8 Font_Size = Font_MODE & 0x0f;
#if CHINESE_ENABLEu8 buff[32];
#endifwhile(*pStr != 0){
#if CHINESE_ENABLEif(*pStr > 0x80)//汉字{FONT_GetFontLattice(buff, (u8*)pStr, ST16X16);    //获取汉字点阵LCD12864_GRAM_ShowChina(x,y,buff,Font_MODE);    //显示汉字pStr += 2;if(x > 127 - 16)  //自动换行{x = 0;y += 16;}else{x += 16;}}else //ASCII
#endif{LCD12864_GRAM_ShowChar(pHandle, x,y,*pStr,Font_MODE);pStr++;if(x > 127 - 8)  //自动换行{x = 0;y += Font_Size;}else{x += 8;}}}
}

//LCD12864.h

/** LCD12864_Virtual.h**  Created on: 2018年8月12日*      Author: cfan*/#ifndef PROGRAM_LCD_LCD12864_H_
#define PROGRAM_LCD_LCD12864_H_
#include "typedef.h"typedef enum
{FONT16_DEFAULT     = (0x80+16),  //16号,叠加显示FONT12_DEFAULT    = (0x80+12),  //12号,叠加显示FONT16_COVER  =  (16),       //16号,覆盖显示FONT12_COVER  =  (12),       //12号,覆盖显示FONT16_REVERSE    = (0x40+16),  //16号,反显显示FONT12_REVERSE    = (0x40+12),  //12号,反显显示
}LCD12864_FONT_MODE;//LCD12864 句柄
typedef struct
{u8 LCD_BUFF[8][128];//显存//void (*UpdateGRAM)(u8 LCD_BUFF[8][128], u8 x1,u8 y1,u8 x2,u8 y2);
}LCD12864_HANDLE;void LCD12864_GRAM_Init(LCD12864_HANDLE *pHandle);//LCD12864显存模式初始化
void LCD12864_GRAM_ShowString(LCD12864_HANDLE *pHandle, u16 x,u16 y,const char *pStr,LCD12864_FONT_MODE Font_MODE); //在显存指定位置显示字符串#endif /* PROGRAM_LCD_LCD12864_H_ */

//测试线程


//测试线程
void *func(void *arg)
{float ftemp = 0;char buff[64];SPI_Init(&SPI_Handle, "/dev/spidev0.0");          //打开SPI驱动setSPIReadBitsPerWord(SPI_Handle.fd, 8);           //8bit模式setSPIBitOrder(SPI_Handle.fd, MSBFIRST);            //高位在前//setSPIMaxSpeed(SPI_Handle.fd, 500);             //设备SPI传输速度 10KsetSPIDataMode(SPI_Handle.fd, SPI_MODE0);            //模式0if(initPinGPIO(BOARD_NANOPI_M1) < 0)                //初始化开发板型号{printf("error:gpio init error!\r\n");}exportGPIOPin(LCD_RST_PIN_INDEX);                    //导出IO文件 RST接口setGPIODirection(LCD_RST_PIN_INDEX,  GPIO_OUT);       //输出exportGPIOPin(LCD_RS_PIN_INDEX);                    //导出IO文件 RS接口setGPIODirection(LCD_RS_PIN_INDEX,  GPIO_OUT);     //输出//初始化JLX12864G硬件JLX12864G_Init(&mJLX12864G_Handle, JLX12864G_WriteData, JLX12864G_SetRS, JLX12864G_SetRST, JLX12864G_DelayMS, 40);LCD12864_GRAM_Init(&g_LCD12864_Handle);               //初始化虚拟LCD12864屏幕while(1){ftemp = GetCPU_Temp();                           //获取CPU温度sprintf(buff,"CPU TEMP:%.02f",ftemp);            //格式化字符串LCD12864_GRAM_ShowString(&g_LCD12864_Handle, 0 ,0, buff, FONT16_COVER);         //覆盖显示-将字符串在虚拟LCD12864中显示JLX12864G_GRAM_Up(&mJLX12864G_Handle, g_LCD12864_Handle.LCD_BUFF, 0,0,128,64); //更新显存到JLX12864Gsleep(3);}
}

示例代码:https://download.csdn.net/download/cp1300/10611732

linux SPI操作LCD12864液晶相关推荐

  1. Arduino UNO通过SPI串行方式驱动LCD12864液晶屏

    LCD12864液晶屏简介 LCD12864带中文字库图形点阵式液晶显示器,可配合各种单片机可完成中文汉字.英文字符和图形显示,可构成全中文人机交互图形界面,模块具有功耗低.显示内容丰富等特点而应用广 ...

  2. Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化

    我们知道,SPI数据传输可以有两种方式:同步方式和异步方式.所谓同步方式是指数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到数据传输完成,函数才会返 ...

  3. linux spi屏驱动程序,65 linux spi设备驱动之spi LCD屏驱动

    SPI的控制器驱动由平台设备与平台驱动来实现. 驱动后用spi_master对象来描述.在设备驱动中就可以通过函数spi_write, spi_read, spi_w8r16, spi_w8r8等函数 ...

  4. linux SPI分析

    下面有两个大的模块: 一个是SPI总线驱动的分析            (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) SPI总线驱动分析   1 SPI概述     ...

  5. linux spi不使用框架,Linux spi驱动框架之执行流程

    Linux spi驱动架构由三部分构成:SPI核心层.SPI控制器驱动层.和SPI设备驱动程序. 1.SPI核心层: SPI核心层是Linux的SPI核心部分,提供了核心数据结构的定义.SPI控制器驱 ...

  6. linux i2c adapter 增加设备_「正点原子Linux连载」第六十二章Linux SPI驱动实验(一)...

    1)实验平台:正点原子Linux开发板 2)摘自<正点原子I.MX6U嵌入式Linux驱动开发指南>关注官方微信号公众号,获取更多资料:正点原子 第六十二章Linux SPI驱动实验 上一 ...

  7. Linux SPI设备驱动

    实现了SPI OLED外设驱动,OLED型号为SH1106. 1.主机驱动与外设驱动分离 Linux中的I2C.SPI.USB等总线驱动,都采用了主机(控制器)驱动与外设(设备)驱动分离的思想.主机端 ...

  8. Linux spi驱动分析(四)----SPI设备驱动(W25Q32BV)

    一.W25Q32BV芯片简介 W25X是一系列SPI接口Flash芯片的简称,它采用SPI接口和CPU通信,本文使用的W25Q32BV容量为32M,具体特性如下: 1.1.基本特性 该芯片最大支持10 ...

  9. Linux spi驱动分析----SPI设备驱动(W25Q32BV)

    转载地址:http://blog.chinaunix.net/uid-25445243-id-4026974.html 一.W25Q32BV芯片简介 W25X是一系列SPI接口Flash芯片的简称,它 ...

  10. Linux spi驱动框架之执行流程-nuc970-att7022

    转载地址:http://blog.csdn.net/chenliang0224/article/details/51236499 Linux spi驱动架构由三部分构成:SPI核心层.SPI控制器驱动 ...

最新文章

  1. 直接法 matlab,解线性方程组直接方法matlab用法.doc
  2. mysql dba 试题_MySQL DBA面试题总结
  3. bs4 CSS选择器
  4. Composer update 问题: Could not authenticate against github.com
  5. java哈希_Java如何采用哈希码实现分类(以员工分配为例)
  6. 重启docker容器命令
  7. BZOJ 2761: [JLOI2011]不重复数字( )
  8. tomcat原理详解和请求过程(涉及网卡、套接字等)
  9. 动态规划法---python实现
  10. 河北科怡档案管理系统连接服务器,档案信息管理系统web端使用说明.docx
  11. Linux安装命令_rpm
  12. 计算机安全原理与实践第3版PDF,windows安全原理与技术.pdf
  13. kali 2.0修改gnome登陆界面背景图片
  14. 【Web技术】1118- 图片防盗链的实现既然如此简单
  15. 【电子学会】2020年12月图形化四级 -- 加减法混合运算器
  16. eigen库疑难杂症大合集
  17. python彼岸图网爬取1200像素预览图
  18. 如何屏蔽网站不需要的蜘蛛
  19. android base64转pdf文件的展示
  20. 短沟道效应 窄宽度效应 short channel effects narrow width effects

热门文章

  1. 易语言解析html实例,易语言完整示例(单设备)
  2. 指标权重确定方法之熵权法
  3. aiml java_AIML实现智能聊天机器人
  4. 批量修改字幕文件中的时间,c语言实现
  5. 截图上传录屏gif上传工具推荐
  6. comps电磁场模拟软件_电力系统仿真软件综述说课.ppt
  7. iOS 录音,播放并上传
  8. linux 下tar打包举例,Linux tar打包命令
  9. uni-app开发环境配置
  10. 32个Python爬虫项目含github链接