linux SPI操作LCD12864液晶
液晶型号为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液晶相关推荐
- Arduino UNO通过SPI串行方式驱动LCD12864液晶屏
LCD12864液晶屏简介 LCD12864带中文字库图形点阵式液晶显示器,可配合各种单片机可完成中文汉字.英文字符和图形显示,可构成全中文人机交互图形界面,模块具有功耗低.显示内容丰富等特点而应用广 ...
- Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化
我们知道,SPI数据传输可以有两种方式:同步方式和异步方式.所谓同步方式是指数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到数据传输完成,函数才会返 ...
- linux spi屏驱动程序,65 linux spi设备驱动之spi LCD屏驱动
SPI的控制器驱动由平台设备与平台驱动来实现. 驱动后用spi_master对象来描述.在设备驱动中就可以通过函数spi_write, spi_read, spi_w8r16, spi_w8r8等函数 ...
- linux SPI分析
下面有两个大的模块: 一个是SPI总线驱动的分析 (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) SPI总线驱动分析 1 SPI概述 ...
- linux spi不使用框架,Linux spi驱动框架之执行流程
Linux spi驱动架构由三部分构成:SPI核心层.SPI控制器驱动层.和SPI设备驱动程序. 1.SPI核心层: SPI核心层是Linux的SPI核心部分,提供了核心数据结构的定义.SPI控制器驱 ...
- linux i2c adapter 增加设备_「正点原子Linux连载」第六十二章Linux SPI驱动实验(一)...
1)实验平台:正点原子Linux开发板 2)摘自<正点原子I.MX6U嵌入式Linux驱动开发指南>关注官方微信号公众号,获取更多资料:正点原子 第六十二章Linux SPI驱动实验 上一 ...
- Linux SPI设备驱动
实现了SPI OLED外设驱动,OLED型号为SH1106. 1.主机驱动与外设驱动分离 Linux中的I2C.SPI.USB等总线驱动,都采用了主机(控制器)驱动与外设(设备)驱动分离的思想.主机端 ...
- Linux spi驱动分析(四)----SPI设备驱动(W25Q32BV)
一.W25Q32BV芯片简介 W25X是一系列SPI接口Flash芯片的简称,它采用SPI接口和CPU通信,本文使用的W25Q32BV容量为32M,具体特性如下: 1.1.基本特性 该芯片最大支持10 ...
- Linux spi驱动分析----SPI设备驱动(W25Q32BV)
转载地址:http://blog.chinaunix.net/uid-25445243-id-4026974.html 一.W25Q32BV芯片简介 W25X是一系列SPI接口Flash芯片的简称,它 ...
- Linux spi驱动框架之执行流程-nuc970-att7022
转载地址:http://blog.csdn.net/chenliang0224/article/details/51236499 Linux spi驱动架构由三部分构成:SPI核心层.SPI控制器驱动 ...
最新文章
- 直接法 matlab,解线性方程组直接方法matlab用法.doc
- mysql dba 试题_MySQL DBA面试题总结
- bs4 CSS选择器
- Composer update 问题: Could not authenticate against github.com
- java哈希_Java如何采用哈希码实现分类(以员工分配为例)
- 重启docker容器命令
- BZOJ 2761: [JLOI2011]不重复数字( )
- tomcat原理详解和请求过程(涉及网卡、套接字等)
- 动态规划法---python实现
- 河北科怡档案管理系统连接服务器,档案信息管理系统web端使用说明.docx
- Linux安装命令_rpm
- 计算机安全原理与实践第3版PDF,windows安全原理与技术.pdf
- kali 2.0修改gnome登陆界面背景图片
- 【Web技术】1118- 图片防盗链的实现既然如此简单
- 【电子学会】2020年12月图形化四级 -- 加减法混合运算器
- eigen库疑难杂症大合集
- python彼岸图网爬取1200像素预览图
- 如何屏蔽网站不需要的蜘蛛
- android base64转pdf文件的展示
- 短沟道效应 窄宽度效应 short channel effects narrow width effects