Files
QD4C-firmware/libraries/zf_device/zf_device_ips114.c
2023-12-11 21:45:06 +08:00

1077 lines
46 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*********************************************************************************************************************
* CH32V307VCT6 Opensourec Library 即CH32V307VCT6 开源库)是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
*
* 本文件是CH32V307VCT6 开源库的一部分
*
* CH32V307VCT6 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPLGNU General Public License即 GNU通用公共许可证的条款
* 即 GPL 的第3版即 GPL3.0)或(您选择的)任何后来的版本,重新发布和/或修改它
*
* 本开源库的发布是希望它能发挥作用,但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
*
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有,请参阅<https://www.gnu.org/licenses/>
*
* 额外注明:
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明(即本声明)
*
* 文件名称 zf_device_ips114
* 公司名称 成都逐飞科技有限公司
* 版本信息 查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境 MounRiver Studio V1.8.1
* 适用平台 CH32V307VCT6
* 店铺链接 https://seekfree.taobao.com/
*
* 修改记录
* 日期 作者 备注
* 2022-09-15 大W first version
********************************************************************************************************************/
/*********************************************************************************************************************
* 接线定义:
* ------------------------------------
* 模块管脚 单片机管脚
* SCL 查看 zf_device_ips114.h 中 IPS114_SCL_PIN 宏定义
* SDA 查看 zf_device_ips114.h 中 IPS114_SDA_PIN 宏定义
* RST 查看 zf_device_ips114.h 中 IPS114_RST_PIN 宏定义
* DC 查看 zf_device_ips114.h 中 IPS114_DC_PIN 宏定义
* CS 查看 zf_device_ips114.h 中 IPS114_CS_PIN 宏定义
* BLK 查看 zf_device_ips114.h 中 IPS114_BLK_PIN 宏定义
* VCC 3.3V电源
* GND 电源地
* 最大分辨率 135 * 240
* ------------------------------------
********************************************************************************************************************/
#include "zf_common_clock.h"
#include "zf_common_debug.h"
#include "zf_common_font.h"
#include "zf_common_function.h"
#include "zf_driver_delay.h"
#include "zf_driver_soft_spi.h"
#include "zf_driver_spi.h"
#include "zf_device_ips114.h"
static uint16 ips114_pencolor = IPS114_DEFAULT_PENCOLOR;
static uint16 ips114_bgcolor = IPS114_DEFAULT_BGCOLOR;
static ips114_dir_enum ips114_display_dir = IPS114_DEFAULT_DISPLAY_DIR;
static ips114_font_size_enum ips114_display_font = IPS114_DEFAULT_DISPLAY_FONT;
static uint8 ips114_x_max = 240;
static uint8 ips114_y_max = 135;
#if IPS114_USE_SOFT_SPI
static soft_spi_info_struct ips114_spi;
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 8bit 数据
// 参数说明 data 数据
// 返回参数 void
// 使用示例 ips114_write_8bit_data(dat);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_8bit_data(data) (soft_spi_write_8bit(&ips114_spi, (data)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 8bit 数据数组
// 参数说明 *data 数据
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 ips114_write_8bit_data_array(data, len);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_8bit_data_array(data, len) (soft_spi_write_8bit(&ips114_spi, (data), (len)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 16bit 数据
// 参数说明 data 数据
// 返回参数 void
// 使用示例 ips114_write_16bit_data(x1 + 52);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_16bit_data(data) (soft_spi_write_16bit(&ips114_spi, (data)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 16bit 数据数组
// 参数说明 *data 数据
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 ips114_write_16bit_data_array(data, len);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_16bit_data_array(data, len) (soft_spi_write_16bit_array(&ips114_spi, (data), (len)))
#else
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 8bit 数据
// 参数说明 data 数据
// 返回参数 void
// 使用示例 ips114_write_8bit_data(dat);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_8bit_data(data) (spi_write_8bit(IPS114_SPI, (data)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 8bit 数据数组
// 参数说明 *data 数据
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 ips114_write_8bit_data_array(data, len);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_8bit_data_array(data, len) (spi_write_8bit_array(IPS114_SPI, (data), (len)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 16bit 数据
// 参数说明 data 数据
// 返回参数 void
// 使用示例 ips114_write_16bit_data(x1 + 52);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_16bit_data(data) (spi_write_16bit(IPS114_SPI, (data)))
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 SPI 写 16bit 数据数组
// 参数说明 *data 数据
// 参数说明 len 数据长度
// 返回参数 void
// 使用示例 ips114_write_16bit_data_array(data, len);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
#define ips114_write_16bit_data_array(data, len) (spi_write_16bit_array(IPS114_SPI, (data), (len)))
#endif
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 写命令
// 参数说明 dat 数据
// 返回参数 void
// 使用示例 ips114_write_index(0x2a);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void ips114_write_index (const uint8 dat)
{
IPS114_DC(0);
ips114_write_8bit_data(dat);
IPS114_DC(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置显示区域
// 参数说明 x1 起始x轴坐标
// 参数说明 y1 起始y轴坐标
// 参数说明 x2 结束x轴坐标
// 参数说明 y2 结束y轴坐标
// 返回参数 void
// 使用示例 ips114_set_region(0, 0, ips114_x_max - 1, ips114_y_max - 1);
// 备注信息 内部调用
//-------------------------------------------------------------------------------------------------------------------
static void ips114_set_region (const uint16 x1, const uint16 y1, const uint16 x2, const uint16 y2)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
// 检查一下你的显示调用的函数 自己计算一下哪里超过了屏幕显示范围
zf_assert(x1 < ips114_x_max);
zf_assert(y1 < ips114_y_max);
zf_assert(x2 < ips114_x_max);
zf_assert(y2 < ips114_y_max);
switch(ips114_display_dir)
{
case IPS114_PORTAIT:
{
ips114_write_index(0x2a); // 列地址设置
ips114_write_16bit_data(x1 + 40);
ips114_write_16bit_data(x2 + 40);
ips114_write_index(0x2b); // 行地址设置
ips114_write_16bit_data(y1 + 52);
ips114_write_16bit_data(y2 + 52);
ips114_write_index(0x2c); // 储存器写
}break;
case IPS114_PORTAIT_180:
{
ips114_write_index(0x2a); // 列地址设置
ips114_write_16bit_data(x1 + 40);
ips114_write_16bit_data(x2 + 40);
ips114_write_index(0x2b); // 行地址设置
ips114_write_16bit_data(y1 + 53);
ips114_write_16bit_data(y2 + 53);
ips114_write_index(0x2c); // 储存器写
}break;
case IPS114_CROSSWISE:
{
ips114_write_index(0x2a); // 列地址设置
ips114_write_16bit_data(x1 + 52);
ips114_write_16bit_data(x2 + 52);
ips114_write_index(0x2b); // 行地址设置
ips114_write_16bit_data(y1 + 40);
ips114_write_16bit_data(y2 + 40);
ips114_write_index(0x2c); // 储存器写
}break;
case IPS114_CROSSWISE_180:
{
ips114_write_index(0x2a); // 列地址设置
ips114_write_16bit_data(x1 + 53);
ips114_write_16bit_data(x2 + 53);
ips114_write_index(0x2b); // 行地址设置
ips114_write_16bit_data(y1 + 40);
ips114_write_16bit_data(y2 + 40);
ips114_write_index(0x2c); // 储存器写
}break;
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 1.14寸 IPS 液晶显示DEBUG信息初始化
// 参数说明 void
// 返回参数 void
// 使用示例 ips114_debug_init();
// 备注信息 内部使用
//-------------------------------------------------------------------------------------------------------------------
static void ips114_debug_init (void)
{
debug_output_struct info;
debug_output_struct_init(&info);
info.type_index = 1;
info.display_x_max = ips114_x_max;
info.display_y_max = ips114_y_max;
switch(ips114_display_font)
{
case IPS114_6X8_FONT:
{
info.font_x_size = 6;
info.font_y_size = 8;
}break;
case IPS114_8X16_FONT:
{
info.font_x_size = 8;
info.font_y_size = 16;
}break;
case IPS114_16X16_FONT:
{
// 暂不支持
}break;
}
info.output_screen = ips114_show_string;
info.output_screen_clear = ips114_clear;
debug_output_init(&info);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 清屏函数
// 参数说明 void
// 返回参数 void
// 使用示例 ips114_clear();
// 备注信息 将屏幕清空成背景颜色
//-------------------------------------------------------------------------------------------------------------------
void ips114_clear (void)
{
uint16 color_buffer[ips114_x_max];
uint32 i = 0, j = 0;
IPS114_CS(0);
ips114_set_region(0, 0, ips114_x_max - 1, ips114_y_max - 1);
for(i = 0; i < ips114_x_max; i ++)
{
color_buffer[i] = ips114_bgcolor;
}
for (j = 0; j < ips114_y_max; j ++)
{
ips114_write_16bit_data_array(color_buffer, ips114_x_max);
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 屏幕填充函数
// 参数说明 color 颜色格式 RGB565 或者可以使用 zf_common_font.h 内 rgb565_color_enum 枚举值或者自行写入
// 返回参数 void
// 使用示例 ips114_full(RGB565_BLACK);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_full (const uint16 color)
{
uint16 color_buffer[ips114_x_max];
uint32 i = 0, j = 0;
IPS114_CS(0);
ips114_set_region(0, 0, ips114_x_max - 1, ips114_y_max - 1);
for(i = 0; i < ips114_x_max; i ++)
{
color_buffer[i] = color;
}
for (j = 0; j < ips114_y_max; j ++)
{
ips114_write_16bit_data_array(color_buffer, ips114_x_max);
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置显示方向
// 参数说明 dir 显示方向 参照 zf_device_ips114.h 内 ips114_dir_enum 枚举体定义
// 返回参数 void
// 使用示例 ips114_set_dir(IPS114_CROSSWISE);
// 备注信息 这个函数只有在初始化屏幕之前调用才生效
//-------------------------------------------------------------------------------------------------------------------
void ips114_set_dir (ips114_dir_enum dir)
{
ips114_display_dir = dir;
switch(ips114_display_dir)
{
case IPS114_PORTAIT:
case IPS114_PORTAIT_180:
{
ips114_x_max = 240;
ips114_y_max = 135;
}break;
case IPS114_CROSSWISE:
case IPS114_CROSSWISE_180:
{
ips114_x_max = 135;
ips114_y_max = 240;
}break;
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置显示字体
// 参数说明 dir 显示方向 参照 zf_device_ips114.h 内 ips114_font_size_enum 枚举体定义
// 返回参数 void
// 使用示例 ips114_set_font(IPS114_8x16_FONT);
// 备注信息 字体可以随时自由设置 设置后生效 后续显示就是新的字体大小
//-------------------------------------------------------------------------------------------------------------------
void ips114_set_font (ips114_font_size_enum font)
{
ips114_display_font = font;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置显示颜色
// 参数说明 pen 颜色格式 RGB565 或者可以使用 zf_common_font.h 内 rgb565_color_enum 枚举值或者自行写入
// 参数说明 bgcolor 颜色格式 RGB565 或者可以使用 zf_common_font.h 内 rgb565_color_enum 枚举值或者自行写入
// 返回参数 void
// 使用示例 ips114_set_color(RGB565_WHITE, RGB565_BLACK);
// 备注信息 字体颜色和背景颜色也可以随时自由设置 设置后生效
//-------------------------------------------------------------------------------------------------------------------
void ips114_set_color (const uint16 pen, const uint16 bgcolor)
{
ips114_pencolor = pen;
ips114_bgcolor = bgcolor;
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 画点
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 color 颜色格式 RGB565 或者可以使用 zf_common_font.h 内 rgb565_color_enum 枚举值或者自行写入
// 返回参数 void
// 使用示例 ips114_draw_point(0, 0, RGB565_RED); // 坐标 0,0 画一个红色的点
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_draw_point (uint16 x, uint16 y, const uint16 color)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
IPS114_CS(0);
ips114_set_region(x, y, x, y);
ips114_write_16bit_data(color);
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 画线
// 参数说明 x_start 坐标x方向的起点
// 参数说明 y_start 坐标y方向的起点
// 参数说明 x_end 坐标x方向的终点
// 参数说明 y_end 坐标y方向的终点
// 参数说明 color 颜色格式 RGB565 或者可以使用 zf_common_font.h 内 rgb565_color_enum 枚举值或者自行写入
// 返回参数 void
// 使用示例 ips114_draw_line(0, 0, 10, 10, RGB565_RED); // 坐标 0,0 到 10,10 画一条红色的线
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_draw_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x_start < ips114_x_max);
zf_assert(y_start < ips114_y_max);
zf_assert(x_end < ips114_x_max);
zf_assert(y_end < ips114_y_max);
int16 x_dir = (x_start < x_end ? 1 : -1);
int16 y_dir = (y_start < y_end ? 1 : -1);
float temp_rate = 0;
float temp_b = 0;
do
{
if(x_start != x_end)
{
temp_rate = (float)(y_start - y_end) / (float)(x_start - x_end);
temp_b = (float)y_start - (float)x_start * temp_rate;
}
else
{
while(y_start != y_end)
{
ips114_draw_point(x_start, y_start, color);
y_start += y_dir;
}
ips114_draw_point(x_start, y_start, color);
break;
}
if(func_abs(y_start - y_end) > func_abs(x_start - x_end))
{
while(y_start != y_end)
{
ips114_draw_point(x_start, y_start, color);
y_start += y_dir;
x_start = (int16)(((float)y_start - temp_b) / temp_rate);
}
ips114_draw_point(x_start, y_start, color);
}
else
{
while(x_start != x_end)
{
ips114_draw_point(x_start, y_start, color);
x_start += x_dir;
y_start = (int16)((float)x_start * temp_rate + temp_b);
}
ips114_draw_point(x_start, y_start, color);
}
}while(0);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示字符
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 dat 需要显示的字符
// 返回参数 void
// 使用示例 ips114_show_char(0, 0, 'x'); // 坐标 0,0 写一个字符 x
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_char (uint16 x, uint16 y, const char dat)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
uint8 i = 0, j = 0;
IPS114_CS(0);
switch(ips114_display_font)
{
case IPS114_6X8_FONT:
{
uint16 display_buffer[6*8];
ips114_set_region(x, y, x + 5, y + 7);
for(i = 0; 6 > i; i ++)
{
// 减 32 因为是取模是从空格开始取得 空格在 ascii 中序号是 32
uint8 temp_top = ascii_font_6x8[dat - 32][i];
for(j = 0; 8 > j; j ++)
{
if(temp_top & 0x01)
{
display_buffer[i + j * 6] = (ips114_pencolor);
}
else
{
display_buffer[i + j * 6] = (ips114_bgcolor);
}
temp_top >>= 1;
}
}
ips114_write_16bit_data_array(display_buffer, 6*8);
}break;
case IPS114_8X16_FONT:
{
uint16 display_buffer[8*16];
ips114_set_region(x, y, x + 7, y + 15);
for(i = 0; 8 > i; i ++)
{
uint8 temp_top = ascii_font_8x16[dat - 32][i];
uint8 temp_bottom = ascii_font_8x16[dat - 32][i + 8];
for(j = 0; 8 > j; j ++)
{
if(temp_top & 0x01)
{
display_buffer[i + j * 8] = (ips114_pencolor);
}
else
{
display_buffer[i + j * 8] = (ips114_bgcolor);
}
temp_top >>= 1;
}
for(j = 0; 8 > j; j ++)
{
if(temp_bottom & 0x01)
{
display_buffer[i + j * 8 + 4 * 16] = (ips114_pencolor);
}
else
{
display_buffer[i + j * 8 + 4 * 16] = (ips114_bgcolor);
}
temp_bottom >>= 1;
}
}
ips114_write_16bit_data_array(display_buffer, 8 * 16);
}break;
case IPS114_16X16_FONT:
{
// 暂不支持
}break;
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示字符串
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 dat 需要显示的字符串
// 返回参数 void
// 使用示例 ips114_show_string(0, 0, "seekfree");
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_string (uint16 x, uint16 y, const char dat[])
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
uint16 j = 0;
while('\0' != dat[j])
{
switch(ips114_display_font)
{
case IPS114_6X8_FONT: ips114_show_char(x + 6 * j, y, dat[j]); break;
case IPS114_8X16_FONT: ips114_show_char(x + 8 * j, y, dat[j]); break;
case IPS114_16X16_FONT: break; // 暂不支持
}
j ++;
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示32位有符号 (去除整数部分无效的0)
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 dat 需要显示的变量 数据类型 int32
// 参数说明 num 需要显示的位数 最高10位 不包含正负号
// 返回参数 void
// 使用示例 ips114_show_int(0, 0, x, 3); // x 可以为 int32 int16 int8 类型
// 备注信息 负数会显示一个 -’号
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_int (uint16 x, uint16 y, const int32 dat, uint8 num)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(0 < num);
zf_assert(10 >= num);
int32 dat_temp = dat;
int32 offset = 1;
char data_buffer[12];
memset(data_buffer, 0, 12);
memset(data_buffer, ' ', num + 1);
// 用来计算余数显示 123 显示 2 位则应该显示 23
if(10 > num)
{
for(; 0 < num; num --)
{
offset *= 10;
}
dat_temp %= offset;
}
func_int_to_str(data_buffer, dat_temp);
ips114_show_string(x, y, (const char *)&data_buffer);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示32位无符号 (去除整数部分无效的0)
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 dat 需要显示的变量 数据类型 uint32
// 参数说明 num 需要显示的位数 最高10位 不包含正负号
// 返回参数 void
// 使用示例 ips114_show_uint(0, 0, x, 3); // x 可以为 uint32 uint16 uint8 类型
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_uint (uint16 x, uint16 y, const uint32 dat, uint8 num)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(0 < num);
zf_assert(10 >= num);
uint32 dat_temp = dat;
int32 offset = 1;
char data_buffer[12];
memset(data_buffer, 0, 12);
memset(data_buffer, ' ', num);
// 用来计算余数显示 123 显示 2 位则应该显示 23
if(10 > num)
{
for(; 0 < num; num --)
{
offset *= 10;
}
dat_temp %= offset;
}
func_uint_to_str(data_buffer, dat_temp);
ips114_show_string(x, y, (const char *)&data_buffer);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示浮点数 (去除整数部分无效的0)
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 dat 需要显示的变量 数据类型 double
// 参数说明 num 整数位显示长度 最高8位
// 参数说明 pointnum 小数位显示长度 最高6位
// 返回参数 void
// 使用示例 ips114_show_float(0, 0, x, 2, 3); // 显示浮点数 整数显示 2 位 小数显示 3 位
// 备注信息 特别注意当发现小数部分显示的值与你写入的值不一样的时候,
// 可能是由于浮点数精度丢失问题导致的,这并不是显示函数的问题,
// 有关问题的详情,请自行百度学习 浮点数精度丢失问题。
// 负数会显示一个 -’号
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_float (uint16 x, uint16 y, const double dat, uint8 num, uint8 pointnum)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(0 < num);
zf_assert(8 >= num);
zf_assert(0 < pointnum);
zf_assert(6 >= pointnum);
double dat_temp = dat;
double offset = 1.0;
char data_buffer[17];
memset(data_buffer, 0, 17);
memset(data_buffer, ' ', num + pointnum + 2);
// 用来计算余数显示 123 显示 2 位则应该显示 23
for(; 0 < num; num --)
{
offset *= 10;
}
dat_temp = dat_temp - ((int)dat_temp / (int)offset) * offset;
func_double_to_str(data_buffer, dat_temp, pointnum);
ips114_show_string(x, y, data_buffer);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示二值图像 数据每八个点组成一个字节数据
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 *image 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 参数说明 dis_width 图像显示宽度 参数范围 [0, ips114_x_max]
// 参数说明 dis_height 图像显示高度 参数范围 [0, ips114_y_max]
// 返回参数 void
// 使用示例 ips114_show_binary_image(0, 0, ov7725_image_binary[0], OV7725_W, OV7725_H, OV7725_W, OV7725_H);
// 备注信息 用于显示小钻风的未解压的压缩二值化图像
// 这个函数不可以用来直接显示总钻风的未压缩的二值化图像
// 这个函数不可以用来直接显示总钻风的未压缩的二值化图像
// 这个函数不可以用来直接显示总钻风的未压缩的二值化图像
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_binary_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(NULL != image);
uint32 i = 0, j = 0;
uint8 temp = 0;
uint32 width_index = 0;
uint16 data_buffer[dis_width];
const uint8 *image_temp;
IPS114_CS(0);
ips114_set_region(x, y, x + dis_width - 1, y + dis_height - 1); // 设置显示区域
for(j = 0; j < dis_height; j ++)
{
image_temp = image + j * height / dis_height * width / 8; // 直接对 image 操作会 Hardfault 暂时不知道为什么
for(i = 0; i < dis_width; i ++)
{
width_index = i * width / dis_width;
temp = *(image_temp + width_index / 8); // 读取像素点
if(0x80 & (temp << (width_index % 8)))
{
data_buffer[i] = (RGB565_WHITE);
}
else
{
data_buffer[i] = (RGB565_BLACK);
}
}
ips114_write_16bit_data_array(data_buffer, dis_width);
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示 8bit 灰度图像 带二值化阈值
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 *image 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 参数说明 dis_width 图像显示宽度 参数范围 [0, ips114_x_max]
// 参数说明 dis_height 图像显示高度 参数范围 [0, ips114_y_max]
// 参数说明 threshold 二值化显示阈值 0-不开启二值化
// 返回参数 void
// 使用示例 ips114_show_gray_image(0, 0, mt9v03x_image[0], MT9V03X_W, MT9V03X_H, MT9V03X_W, MT9V03X_H, 0);
// 备注信息 用于显示总钻风的图像
// 如果要显示二值化图像 直接修改最后一个参数为需要的二值化阈值即可
// 如果要显示二值化图像 直接修改最后一个参数为需要的二值化阈值即可
// 如果要显示二值化图像 直接修改最后一个参数为需要的二值化阈值即可
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_gray_image (uint16 x, uint16 y, const uint8 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 threshold)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(NULL != image);
uint32 i = 0, j = 0;
uint16 color = 0,temp = 0;
uint16 data_buffer[dis_width];
const uint8 *image_temp;
IPS114_CS(0);
ips114_set_region(x, y, x + dis_width - 1, y + dis_height - 1); // 设置显示区域
for(j = 0; j < dis_height; j ++)
{
image_temp = image + j * height / dis_height * width; // 直接对 image 操作会 Hardfault 暂时不知道为什么
for(i = 0; i < dis_width; i ++)
{
temp = *(image_temp + i * width / dis_width); // 读取像素点
if(threshold == 0)
{
color = (0x001f & ((temp) >> 3)) << 11;
color = color | (((0x003f) & ((temp) >> 2)) << 5);
color = color | (0x001f & ((temp) >> 3));
data_buffer[i] = (color);
}
else if(temp < threshold)
{
data_buffer[i] = (RGB565_BLACK);
}
else
{
data_buffer[i] = (RGB565_WHITE);
}
}
ips114_write_16bit_data_array(data_buffer, dis_width);
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示 RGB565 彩色图像
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 *image 图像数组指针
// 参数说明 width 图像实际宽度
// 参数说明 height 图像实际高度
// 参数说明 dis_width 图像显示宽度 参数范围 [0, ips114_x_max]
// 参数说明 dis_height 图像显示高度 参数范围 [0, ips114_y_max]
// 参数说明 color_mode 色彩模式 0-低位在前 1-高位在前
// 返回参数 void
// 使用示例 ips114_show_rgb565_image(0, 0, scc8660_image[0], SCC8660_W, SCC8660_H, SCC8660_W, SCC8660_H, 1);
// 备注信息 用于显示凌瞳的 RGB565 的图像
// 如果要显示低位在前的其他 RGB565 图像 修改最后一个参数即可
// 如果要显示低位在前的其他 RGB565 图像 修改最后一个参数即可
// 如果要显示低位在前的其他 RGB565 图像 修改最后一个参数即可
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_rgb565_image (uint16 x, uint16 y, const uint16 *image, uint16 width, uint16 height, uint16 dis_width, uint16 dis_height, uint8 color_mode)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(NULL != image);
uint32 i = 0, j = 0;
uint16 data_buffer[dis_width];
const uint16 *image_temp;
IPS114_CS(0);
ips114_set_region(x, y, x + dis_width - 1, y + dis_height - 1); // 设置显示区域
for(j = 0; j < dis_height; j ++)
{
image_temp = image + j * height / dis_height * width; // 直接对 image 操作会 Hardfault 暂时不知道为什么
for(i = 0; i < dis_width; i ++)
{
data_buffer[i] = *(image_temp + i * width / dis_width); // 读取像素点
}
if(color_mode)
{
ips114_write_8bit_data_array((uint8 *)data_buffer, dis_width * 2);
}
else
{
ips114_write_16bit_data_array(data_buffer, dis_width);
}
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 IPS114 显示波形
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 *wave 波形数组指针
// 参数说明 width 波形实际宽度
// 参数说明 value_max 波形实际最大值
// 参数说明 dis_width 波形显示宽度 参数范围 [0, ips114_x_max]
// 参数说明 dis_value_max 波形显示最大值 参数范围 [0, ips114_y_max]
// 返回参数 void
// 使用示例 ips114_show_wave(56,35,data,128,64,128,64);
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_wave (uint16 x, uint16 y, const uint16 *wave, uint16 width, uint16 value_max, uint16 dis_width, uint16 dis_value_max)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(NULL != wave);
uint32 i = 0, j = 0;
uint32 width_index = 0, value_max_index = 0;
uint16 data_buffer[dis_width];
IPS114_CS(0);
ips114_set_region(x, y, x + dis_width - 1, y + dis_value_max - 1); // 设置显示区域
for(j = 0; j < dis_value_max; j ++)
{
for(i = 0; i < dis_width; i ++)
{
data_buffer[i] = (ips114_bgcolor);
}
ips114_write_16bit_data_array(data_buffer, dis_width);
}
IPS114_CS(1);
for(i = 0; i < dis_width; i ++)
{
width_index = i * width / dis_width;
value_max_index = *(wave + width_index) * (dis_value_max - 1) / value_max;
ips114_draw_point(i + x, (dis_value_max - 1) - value_max_index + y, ips114_pencolor);
}
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 汉字显示
// 参数说明 x 坐标x方向的起点 参数范围 [0, ips114_x_max-1]
// 参数说明 y 坐标y方向的起点 参数范围 [0, ips114_y_max-1]
// 参数说明 size 取模的时候设置的汉字字体大小 也就是一个汉字占用的点阵长宽为多少个点 取模的时候需要长宽是一样的
// 参数说明 *chinese_buffer 需要显示的汉字数组
// 参数说明 number 需要显示多少位
// 参数说明 color 颜色格式 RGB565 或者可以使用 zf_common_font.h 内 rgb565_color_enum 枚举值或者自行写入
// 返回参数 void
// 使用示例 ips114_show_chinese(0, 0, 16, chinese_test[0], 4, RGB565_RED);// 显示font文件里面的 示例
// 备注信息 使用PCtoLCD2002软件取模 阴码、逐行式、顺向 16*16
//-------------------------------------------------------------------------------------------------------------------
void ips114_show_chinese (uint16 x, uint16 y, uint8 size, const uint8 *chinese_buffer, uint8 number, const uint16 color)
{
// 如果程序在输出了断言信息 并且提示出错位置在这里
// 那么一般是屏幕显示的时候超过屏幕分辨率范围了
zf_assert(x < ips114_x_max);
zf_assert(y < ips114_y_max);
zf_assert(NULL != chinese_buffer);
int i = 0, j = 0, k = 0;
uint8 temp = 0, temp1 = 0, temp2 = 0;
const uint8 *p_data = chinese_buffer;
temp2 = size / 8;
IPS114_CS(0);
ips114_set_region(x, y, number * size - 1 + x, y + size - 1);
for(i = 0; i < size; i ++)
{
temp1 = number;
p_data = chinese_buffer + i * temp2;
while(temp1 --)
{
for(k = 0; k < temp2; k ++)
{
for(j = 8; 0 < j; j --)
{
temp = (*p_data >> (j - 1)) & 0x01;
if(temp)
{
ips114_write_16bit_data(color);
}
else
{
ips114_write_16bit_data(ips114_bgcolor);
}
}
p_data ++;
}
p_data = p_data - temp2 + temp2 * size;
}
}
IPS114_CS(1);
}
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 1.14寸 IPS液晶初始化
// 参数说明 void
// 返回参数 void
// 使用示例 ips114_init();
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
void ips114_init (void)
{
#if IPS114_USE_SOFT_SPI
soft_spi_init(&ips114_spi, 0, IPS114_SOFT_SPI_DELAY, IPS114_SCL_PIN, IPS114_SDA_PIN, SOFT_SPI_PIN_NULL, SOFT_SPI_PIN_NULL);
#else
spi_init(IPS114_SPI, SPI_MODE0, IPS114_SPI_SPEED, IPS114_SCL_PIN, IPS114_SDA_PIN, SPI_MISO_NULL, SPI_CS_NULL);
#endif
gpio_init(IPS114_DC_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
gpio_init(IPS114_RST_PIN, GPO, GPIO_LOW, GPO_PUSH_PULL);
gpio_init(IPS114_CS_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
gpio_init(IPS114_BLK_PIN, GPO, GPIO_HIGH, GPO_PUSH_PULL);
ips114_set_dir(ips114_display_dir);
ips114_set_color(ips114_pencolor, ips114_bgcolor);
IPS114_RST(0);
system_delay_ms(200);
IPS114_RST(1);
system_delay_ms(100);
IPS114_CS(0);
ips114_write_index(0x36);
system_delay_ms(100);
switch(ips114_display_dir)
{
case IPS114_PORTAIT: ips114_write_8bit_data(0xA0); break;
case IPS114_PORTAIT_180: ips114_write_8bit_data(0x70); break;
case IPS114_CROSSWISE: ips114_write_8bit_data(0x00); break;
case IPS114_CROSSWISE_180: ips114_write_8bit_data(0xC0); break;
}
ips114_write_index(0x3A);
ips114_write_8bit_data(0x05);
ips114_write_index(0xB2);
ips114_write_8bit_data(0x0C);
ips114_write_8bit_data(0x0C);
ips114_write_8bit_data(0x00);
ips114_write_8bit_data(0x33);
ips114_write_8bit_data(0x33);
ips114_write_index(0xB7);
ips114_write_8bit_data(0x35);
ips114_write_index(0xBB);
ips114_write_8bit_data(0x37);
ips114_write_index(0xC0);
ips114_write_8bit_data(0x2C);
ips114_write_index(0xC2);
ips114_write_8bit_data(0x01);
ips114_write_index(0xC3);
ips114_write_8bit_data(0x12);
ips114_write_index(0xC4);
ips114_write_8bit_data(0x20);
ips114_write_index(0xC6);
ips114_write_8bit_data(0x0F);
ips114_write_index(0xD0);
ips114_write_8bit_data(0xA4);
ips114_write_8bit_data(0xA1);
ips114_write_index(0xE0);
ips114_write_8bit_data(0xD0);
ips114_write_8bit_data(0x04);
ips114_write_8bit_data(0x0D);
ips114_write_8bit_data(0x11);
ips114_write_8bit_data(0x13);
ips114_write_8bit_data(0x2B);
ips114_write_8bit_data(0x3F);
ips114_write_8bit_data(0x54);
ips114_write_8bit_data(0x4C);
ips114_write_8bit_data(0x18);
ips114_write_8bit_data(0x0D);
ips114_write_8bit_data(0x0B);
ips114_write_8bit_data(0x1F);
ips114_write_8bit_data(0x23);
ips114_write_index(0xE1);
ips114_write_8bit_data(0xD0);
ips114_write_8bit_data(0x04);
ips114_write_8bit_data(0x0C);
ips114_write_8bit_data(0x11);
ips114_write_8bit_data(0x13);
ips114_write_8bit_data(0x2C);
ips114_write_8bit_data(0x3F);
ips114_write_8bit_data(0x44);
ips114_write_8bit_data(0x51);
ips114_write_8bit_data(0x2F);
ips114_write_8bit_data(0x1F);
ips114_write_8bit_data(0x1F);
ips114_write_8bit_data(0x20);
ips114_write_8bit_data(0x23);
ips114_write_index(0x21);
ips114_write_index(0x11);
system_delay_ms(120);
ips114_write_index(0x29);
IPS114_CS(1);
ips114_clear();
ips114_debug_init();
}