找回密码
 立即注册
查看: 97|回复: 8

8H4K64TLCD驱动LCD屏无法点亮,新手求助各位帅哥大神

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-09 21:27:39
已绑定手机

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 7 天前 | 显示全部楼层 |阅读模式

请问各位大佬,我是想把测的数据在LCD上面显示,但是显示模块始终显示不了。
(求助各位帮帮忙指点一下,万分感谢)
单片机型号是STC8H4K64TLCD

单片机连线

单片机连线

LCD屏幕用的是汉昇的HS12864B03,ks0107和ks0108
[url=]C2939935_LCD显示屏_HS1286 ...[/url]

LCD屏连线

LCD屏连线

刚开始网上说是对比度的问题,我就在V0,VEE,GND加了电位器调电压。拿万用表测的V0电压。

测的V0

测的V0

没有调电位器之前

没有调电位器之前

因为不怎么会,就把代码全部写到一起去了,是因为代码不对的原因吗。
我看网上说屏幕如果没有字库的话要用pctolcd2002取模,我又再代码里加了取的模。
代码倒是没有报错了,可是总感觉是代码的问题。
因为lcd接线这些都是对着连好的。实在是不知道该怎么去排查问题出在哪儿了,希望大神们能够帮忙看看,再次谢过

  1. <blockquote>#include <STC8H.H>    // STC8H系列头文件
复制代码


test.zip

97.89 KB, 下载次数: 5

单独弄的lcd代码

C2939935_LCD显示屏_HS12864B03_规格书_WJ77310.PDF

400.92 KB, 下载次数: 5

LCD规格书

STC8H.zip

151.25 KB, 下载次数: 6

测试仪的代码

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-09 21:27:39
已绑定手机

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 7 天前 | 显示全部楼层
#include <STC8H.H>    // STC8H系列头文件
#include <intrins.h>   // 延时函数需要
#include <stdio.h>     // 用于sprintf函数
#include <math.h>      // log10函数需要
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
// ------ 新增宏定义 ------
#define RELAY_PORT0 0   // 控制K1-K8的端口
#define RELAY_PORT4 1   // 控制K9-K16的端口
#define OPAMP_SINGLE 0  // 运放类型
#define OPAMP_DUAL   1
#define OPAMP_QUAD   2

// ADS1115 I2C地址(ADDR接地为0x48,接VCC为0x49)
#define ADS1115_ADDR 0x48
// LCD引脚定义
sbit LCD_E = P3^2;    // 使能信号
sbit LCD_DI = P3^3;   // 数据/指令选择
sbit LCD_CS1 = P3^4;  // 左半屏片选
sbit LCD_CS2 = P3^5;  // 右半屏片选
sbit LCD_RST = P3^6;  // 复位
sbit LCD_RW = P3^7;   // 读写选择

// 全局变量存储测量值(XDATA区)
xdata float Vos = 0.0f;
xdata float IB = 0.0f;
xdata float Vo1 = 0.0f;
xdata float Vo1_prime = 0.0f;
xdata float Aol = 0.0f;
xdata float PSRR = 0.0f;
xdata float VoMax = 0.0f;
// ------ 新增全局变量 ------
xdata u8 OpampType = 0; // 当前运放类型(默认单运放)
bit RST_Flag = 0;       // 复位标志
unsigned char code ASCII_FONT[95][16] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",0*/
{0x00,0x00,0x10,0x00,0x0C,0x00,0x02,0x00,0x10,0x00,0x0C,0x00,0x02,0x00,0x00,0x00},/*""",1*/
{0x00,0x00,0x40,0x04,0xC0,0x3F,0x78,0x04,0x40,0x04,0xC0,0x3F,0x78,0x04,0x00,0x00},/*"#",2*/
{0x00,0x00,0x70,0x18,0x88,0x20,0x88,0x20,0xFC,0xFF,0x08,0x21,0x30,0x1E,0x00,0x00},/*"$",3*/
{0xF0,0x00,0x08,0x31,0xF0,0x0C,0x80,0x03,0x60,0x1E,0x18,0x21,0x00,0x1E,0x00,0x00},/*"%",4*/
{0x00,0x1E,0xF0,0x21,0x08,0x23,0x88,0x2C,0x70,0x19,0x00,0x27,0x00,0x21,0x00,0x10},/*"&",5*/
{0x00,0x00,0x12,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",6*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0x18,0x18,0x04,0x20,0x02,0x40,0x00,0x00},/*"(",7*/
{0x00,0x00,0x02,0x40,0x04,0x20,0x18,0x18,0xE0,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*")",8*/
{0x40,0x02,0x40,0x02,0x80,0x01,0xF0,0x0F,0x80,0x01,0x40,0x02,0x40,0x02,0x00,0x00},/*"*",9*/
{0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0xE0,0x0F,0x00,0x01,0x00,0x01,0x00,0x01},/*"+",10*/
{0x00,0x00,0x00,0x90,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",11*/
{0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00},/*"-",12*/
{0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",13*/
{0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x07,0xC0,0x00,0x38,0x00,0x04,0x00,0x00,0x00},/*"/",14*/
{0x00,0x00,0xE0,0x0F,0x10,0x10,0x08,0x20,0x08,0x20,0x10,0x10,0xE0,0x0F,0x00,0x00},/*"0",15*/
{0x00,0x00,0x00,0x00,0x10,0x20,0x10,0x20,0xF8,0x3F,0x00,0x20,0x00,0x20,0x00,0x00},/*"1",16*/
{0x00,0x00,0x70,0x30,0x08,0x28,0x08,0x24,0x08,0x22,0x08,0x21,0xF0,0x30,0x00,0x00},/*"2",17*/
{0x00,0x00,0x30,0x18,0x08,0x20,0x08,0x21,0x08,0x21,0x88,0x22,0x70,0x1C,0x00,0x00},/*"3",18*/
{0x00,0x00,0x00,0x06,0x80,0x05,0x40,0x24,0x30,0x24,0xF8,0x3F,0x00,0x24,0x00,0x24},/*"4",19*/
{0x00,0x00,0xF8,0x19,0x88,0x20,0x88,0x20,0x88,0x20,0x08,0x11,0x08,0x0E,0x00,0x00},/*"5",20*/
{0x00,0x00,0xE0,0x0F,0x10,0x11,0x88,0x20,0x88,0x20,0x90,0x20,0x00,0x1F,0x00,0x00},/*"6",21*/
{0x00,0x00,0x18,0x00,0x08,0x00,0x08,0x3E,0x88,0x01,0x68,0x00,0x18,0x00,0x00,0x00},/*"7",22*/
{0x00,0x00,0x70,0x1C,0x88,0x22,0x08,0x21,0x08,0x21,0x88,0x22,0x70,0x1C,0x00,0x00},/*"8",23*/
{0x00,0x00,0xF0,0x01,0x08,0x12,0x08,0x22,0x08,0x22,0x10,0x11,0xE0,0x0F,0x00,0x00},/*"9",24*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0xC0,0x30,0x00,0x00,0x00,0x00,0x00,0x00},/*":",25*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",26*/
{0x00,0x00,0x00,0x01,0x80,0x02,0x40,0x04,0x20,0x08,0x10,0x10,0x08,0x20,0x00,0x00},/*"<",27*/
{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"=",28*/
{0x00,0x00,0x08,0x20,0x10,0x10,0x20,0x08,0x40,0x04,0x80,0x02,0x00,0x01,0x00,0x00},/*">",29*/
{0x00,0x00,0x70,0x00,0x48,0x00,0x08,0x30,0x08,0x37,0x88,0x00,0x70,0x00,0x00,0x00},/*"?",30*/
{0xC0,0x07,0x30,0x18,0xC8,0x27,0x28,0x28,0xE8,0x2F,0x10,0x28,0xE0,0x17,0x00,0x00},/*"@",31*/
{0x00,0x20,0x00,0x3C,0xC0,0x23,0x38,0x02,0xE0,0x02,0x00,0x27,0x00,0x38,0x00,0x20},/*"A",32*/
{0x08,0x20,0xF8,0x3F,0x88,0x20,0x88,0x20,0x88,0x20,0x70,0x11,0x00,0x0E,0x00,0x00},/*"B",33*/
{0xC0,0x07,0x30,0x18,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x10,0x38,0x08,0x00,0x00},/*"C",34*/
{0x08,0x20,0xF8,0x3F,0x08,0x20,0x08,0x20,0x08,0x20,0x10,0x10,0xE0,0x0F,0x00,0x00},/*"D",35*/
{0x08,0x20,0xF8,0x3F,0x88,0x20,0x88,0x20,0xE8,0x23,0x08,0x20,0x10,0x18,0x00,0x00},/*"E",36*/
{0x08,0x20,0xF8,0x3F,0x88,0x20,0x88,0x00,0xE8,0x03,0x08,0x00,0x10,0x00,0x00,0x00},/*"F",37*/
{0xC0,0x07,0x30,0x18,0x08,0x20,0x08,0x20,0x08,0x22,0x38,0x1E,0x00,0x02,0x00,0x00},/*"G",38*/
{0x08,0x20,0xF8,0x3F,0x08,0x21,0x00,0x01,0x00,0x01,0x08,0x21,0xF8,0x3F,0x08,0x20},/*"H",39*/
{0x00,0x00,0x08,0x20,0x08,0x20,0xF8,0x3F,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00},/*"I",40*/
{0x00,0xC0,0x00,0x80,0x08,0x80,0x08,0x80,0xF8,0x7F,0x08,0x00,0x08,0x00,0x00,0x00},/*"J",41*/
{0x08,0x20,0xF8,0x3F,0x88,0x20,0xC0,0x01,0x28,0x26,0x18,0x38,0x08,0x20,0x00,0x00},/*"K",42*/
{0x08,0x20,0xF8,0x3F,0x08,0x20,0x00,0x20,0x00,0x20,0x00,0x20,0x00,0x30,0x00,0x00},/*"L",43*/
{0x08,0x20,0xF8,0x3F,0xF8,0x01,0x00,0x3E,0xF8,0x01,0xF8,0x3F,0x08,0x20,0x00,0x00},/*"M",44*/
{0x08,0x20,0xF8,0x3F,0x30,0x20,0xC0,0x00,0x00,0x07,0x08,0x18,0xF8,0x3F,0x08,0x00},/*"N",45*/
{0xE0,0x0F,0x10,0x10,0x08,0x20,0x08,0x20,0x08,0x20,0x10,0x10,0xE0,0x0F,0x00,0x00},/*"O",46*/
{0x08,0x20,0xF8,0x3F,0x08,0x21,0x08,0x01,0x08,0x01,0x08,0x01,0xF0,0x00,0x00,0x00},/*"P",47*/
{0xE0,0x0F,0x10,0x10,0x08,0x28,0x08,0x28,0x08,0x30,0x10,0x50,0xE0,0x4F,0x00,0x00},/*"Q",48*/
{0x08,0x20,0xF8,0x3F,0x88,0x20,0x88,0x00,0x88,0x03,0x88,0x0C,0x70,0x30,0x00,0x20},/*"R",49*/
{0x00,0x00,0x70,0x38,0x88,0x20,0x08,0x21,0x08,0x21,0x08,0x22,0x38,0x1C,0x00,0x00},/*"S",50*/
{0x18,0x00,0x08,0x00,0x08,0x20,0xF8,0x3F,0x08,0x20,0x08,0x00,0x18,0x00,0x00,0x00},/*"T",51*/
{0x08,0x00,0xF8,0x1F,0x08,0x20,0x00,0x20,0x00,0x20,0x08,0x20,0xF8,0x1F,0x08,0x00},/*"U",52*/
{0x08,0x00,0x78,0x00,0x88,0x07,0x00,0x38,0x00,0x0E,0xC8,0x01,0x38,0x00,0x08,0x00},/*"V",53*/
{0x08,0x00,0xF8,0x03,0x00,0x3E,0xF8,0x01,0x00,0x3E,0xF8,0x03,0x08,0x00,0x00,0x00},/*"W",54*/
{0x08,0x20,0x18,0x30,0x68,0x2C,0x80,0x03,0x80,0x03,0x68,0x2C,0x18,0x30,0x08,0x20},/*"X",55*/
{0x08,0x00,0x38,0x00,0xC8,0x20,0x00,0x3F,0xC8,0x20,0x38,0x00,0x08,0x00,0x00,0x00},/*"Y",56*/
{0x10,0x20,0x08,0x38,0x08,0x26,0x08,0x21,0xC8,0x20,0x38,0x20,0x08,0x18,0x00,0x00},/*"Z",57*/
{0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x02,0x40,0x02,0x40,0x02,0x40,0x00,0x00},/*"[",58*/
{0x00,0x00,0x04,0x00,0x38,0x00,0xC0,0x01,0x00,0x06,0x00,0x38,0x00,0xC0,0x00,0x00},/*"\",59*/
{0x00,0x00,0x02,0x40,0x02,0x40,0x02,0x40,0xFE,0x7F,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",60*/
{0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00},/*"^",61*/
{0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"_",62*/
{0x00,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",63*/
{0x00,0x00,0x00,0x19,0x80,0x24,0x80,0x24,0x80,0x12,0x00,0x3F,0x00,0x20,0x00,0x00},/*"a",64*/
{0x10,0x00,0xF0,0x3F,0x00,0x11,0x80,0x20,0x80,0x20,0x00,0x11,0x00,0x0E,0x00,0x00},/*"b",65*/
{0x00,0x00,0x00,0x0E,0x00,0x11,0x80,0x20,0x80,0x20,0x80,0x20,0x00,0x11,0x00,0x00},/*"c",66*/
{0x00,0x00,0x00,0x1F,0x80,0x20,0x80,0x20,0x80,0x20,0x90,0x10,0xF0,0x3F,0x00,0x20},/*"d",67*/
{0x00,0x00,0x00,0x1F,0x80,0x24,0x80,0x24,0x80,0x24,0x80,0x24,0x00,0x17,0x00,0x00},/*"e",68*/
{0x00,0x00,0x80,0x20,0x80,0x20,0xE0,0x3F,0x90,0x20,0x90,0x20,0x20,0x00,0x00,0x00},/*"f",69*/
{0x00,0x00,0x00,0x6B,0x80,0x94,0x80,0x94,0x80,0x94,0x80,0x93,0x80,0x60,0x00,0x00},/*"g",70*/
{0x10,0x20,0xF0,0x3F,0x00,0x21,0x80,0x00,0x80,0x00,0x80,0x20,0x00,0x3F,0x00,0x20},/*"h",71*/
{0x00,0x00,0x80,0x20,0x98,0x20,0x98,0x3F,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00},/*"i",72*/
{0x00,0x00,0x00,0xC0,0x00,0x80,0x80,0x80,0x98,0x80,0x98,0x7F,0x00,0x00,0x00,0x00},/*"j",73*/
{0x10,0x20,0xF0,0x3F,0x00,0x24,0x00,0x06,0x80,0x29,0x80,0x30,0x80,0x20,0x00,0x00},/*"k",74*/
{0x00,0x00,0x10,0x20,0x10,0x20,0xF8,0x3F,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00},/*"l",75*/
{0x80,0x20,0x80,0x3F,0x80,0x20,0x80,0x00,0x80,0x3F,0x80,0x20,0x80,0x00,0x00,0x3F},/*"m",76*/
{0x80,0x20,0x80,0x3F,0x00,0x21,0x80,0x00,0x80,0x00,0x80,0x20,0x00,0x3F,0x00,0x20},/*"n",77*/
{0x00,0x00,0x00,0x1F,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x20,0x00,0x1F,0x00,0x00},/*"o",78*/
{0x80,0x80,0x80,0xFF,0x00,0x91,0x80,0x20,0x80,0x20,0x00,0x11,0x00,0x0E,0x00,0x00},/*"p",79*/
{0x00,0x00,0x00,0x0E,0x00,0x11,0x80,0x20,0x80,0x20,0x00,0x91,0x80,0xFF,0x00,0x80},/*"q",80*/
{0x80,0x20,0x80,0x20,0x80,0x3F,0x00,0x21,0x80,0x20,0x80,0x00,0x80,0x01,0x00,0x00},/*"r",81*/
{0x00,0x00,0x00,0x33,0x80,0x24,0x80,0x24,0x80,0x24,0x80,0x24,0x80,0x19,0x00,0x00},/*"s",82*/
{0x00,0x00,0x80,0x00,0x80,0x00,0xE0,0x1F,0x80,0x20,0x80,0x20,0x00,0x10,0x00,0x00},/*"t",83*/
{0x80,0x00,0x80,0x1F,0x00,0x20,0x00,0x20,0x00,0x20,0x80,0x10,0x80,0x3F,0x00,0x20},/*"u",84*/
{0x80,0x00,0x80,0x03,0x80,0x0C,0x00,0x30,0x80,0x0C,0x80,0x03,0x80,0x00,0x00,0x00},/*"v",85*/
{0x80,0x01,0x80,0x0E,0x00,0x30,0x80,0x0C,0x80,0x07,0x00,0x38,0x80,0x06,0x80,0x01},/*"w",86*/
{0x00,0x00,0x80,0x20,0x80,0x31,0x80,0x0E,0x00,0x2E,0x80,0x31,0x80,0x20,0x00,0x00},/*"x",87*/
{0x80,0x00,0x80,0x81,0x80,0x86,0x00,0x78,0x00,0x18,0x80,0x06,0x80,0x01,0x80,0x00},/*"y",88*/
{0x00,0x00,0x80,0x21,0x80,0x30,0x80,0x2C,0x80,0x22,0x80,0x21,0x80,0x30,0x00,0x00},/*"z",89*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFC,0x3E,0x02,0x40,0x02,0x40},/*"{",90*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",91*/
{0x02,0x40,0x02,0x40,0xFC,0x3E,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",92*/
{0x00,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x00,0x00},/*"~",93*/


};

/*********************
函数声明
*********************/
void Delay1ms(u16 n);
void I2C_Init();
void ADS1115_Write(u8 reg, u16 value);
u16 ADS1115_Read(u8 reg);
void LCD_WriteCmd(u8 cmd);
void LCD_Writevalue(u8 dat);
void LCD_Init();
void LCD_Clear();
void LCD_ShowStr(u8 x, u8 y, u8 *str);
void MeasureVos();
void MeasureIB();
void MeasureAol();
void MeasurePSRR();
void MeasureVoMax();
void DisplayResults();
void I2C_Ack(u8 ack);
u8 I2C_RecvByte(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(u8 dat);
void RelayControl(u8 port, u8 state);  // 修改继电器控制函数
void CheckButtons();                   // 新增按键检测函数

/*********************
主函数
*********************/
void main()
{
    // 初始化部分
        // 初始化时强制关闭所有继电器
    P0 = 0x00;
    P4 = 0x00;
            // 新增端口初始化
    P0M0 = 0xFF;  // P0推挽输出(驱动K1-K8)
    P0M1 = 0x00;
    P5M0 = 0x00;  // P5.4准双向(RST按键)
    P5M1 = 0x00;
   
    P4M0 = 0xFF;  // P4推挽输出模式(驱动继电器)
    P4M1 = 0x00;
    P7M0 = 0x00; // P7.0准双向(按键输入)
    P7M1 = 0x00;
   
    I2C_Init();   // 初始化I2C
    LCD_Init();   // 初始化LCD
    LCD_Clear();  // 清屏
   
    while(1)
    {
        CheckButtons(); // 新增按键检测
        
        if(RST_Flag) {  // 处理复位
            LCD_Clear();
            Vos = IB = Aol = PSRR = VoMax = 0;
            RelayControl(RELAY_PORT0, 0x00);
            RelayControl(RELAY_PORT4, 0x00);
            RST_Flag = 0;
        }
        
        // 原按键S1检测修改为复合功能
        if(P70 == 0)
        {
            Delay1ms(20);
            if(P70 == 0)
            {
                // 根据运放类型执行测试
                switch(OpampType) {
                    case OPAMP_SINGLE:
                MeasureVos();  // 单运放测试
                MeasureIB();
                MeasureAol();
                MeasurePSRR();
                MeasureVoMax();
                        break;
                    case OPAMP_DUAL:
                MeasureVos();  
                MeasureIB();
                MeasureAol();
                MeasurePSRR();
                MeasureVoMax();// 双运放测试流程
                        break;
                    case OPAMP_QUAD:
                MeasureVos();  
                MeasureIB();
                MeasureAol();
                MeasurePSRR();
                MeasureVoMax();// 四运放测试流程(需补充)
                        break;
                }
                DisplayResults();
                while(P70 == 0);
            }
        }
    }
}
/*********************
新增按键检测函数
*********************/
static bit S2_Last = 1;  // 移出函数外声明
static bit RST_Last = 1;

void CheckButtons()
{
    // 检测运放类型切换按键(S2)
    if(P71 == 0 && S2_Last) {
        Delay1ms(50);
        if(P71 == 0) {
            if(++OpampType > 2)
                                                        OpampType = 0;
            // 根据运放类型设置基础继电器
            switch(OpampType) {
                case OPAMP_SINGLE:
                    RelayControl(RELAY_PORT0, 0x01);
                    break;
                case OPAMP_DUAL:
                    RelayControl(RELAY_PORT0, 0x03);
                    break;
                case OPAMP_QUAD:
                    RelayControl(RELAY_PORT0, 0xFF);
                    break;
            }
        }
        while(P71 == 0);
    }
    S2_Last = P71;

    // 检测RST按键(P5.4)
    if(P54 == 0 && RST_Last) {
        Delay1ms(50);
        if(P54 == 0) RST_Flag = 1;
        while(P54 == 0);
    }
    RST_Last = P54;
}
/*********************
修改后的继电器控制函数
参数:port-0控制P0(K1-K8),1控制P4(K9-K16)
*********************/
void RelayControl(u8 port, u8 state) {
    if(port == RELAY_PORT0) {
        P0 = state;  // 控制K1-K8
    } else {
        P4 = state;  // 控制K9-K16
    }
    Delay1ms(200);   // 增加200ms延时,防止抖动
}
/*********************
测量Vos(状态1)
*********************/
void MeasureVos()
{
    // 状态1:闭合K9,K10,K14(P4.0, P4.1, P4.5)
    RelayControl(RELAY_PORT4, 0x23); // 二进制00100011(低8位)
   
    Delay1ms(1000); // 延时1秒
   
    // 读取AIN1(Vo1)电压
    ADS1115_Write(0x01, 0xD283); // 配置AIN1单端,4.096V量程
    Delay1ms(10);
    Vo1 = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 计算Vos
    Vos = Vo1 / 501.0;
   
    // 继电器复位(全部断开)
    RelayControl(RELAY_PORT4, 0x00);
}

/*********************
测量IB(状态2)
*********************/
void MeasureIB()
{
    // 第一次测量:闭合K9,K14(P4.0, P4.5)
    RelayControl(RELAY_PORT4, 0x21); // 00100001
    Delay1ms(500);
    ADS1115_Write(0x01, 0xD283);
    Delay1ms(10);
    Vo1 = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 第二次测量:闭合K10,K14(P4.1, P4.5)
    RelayControl(RELAY_PORT4, 0x22); // 00100010
    Delay1ms(500);
    ADS1115_Write(0x01, 0xD283);
    Delay1ms(10);
    Vo1_prime = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 计算IB
    IB = (Vo1_prime - Vo1) / (2 * 50000.0 * 501.0); // 结果单位是安培
   
    // 继电器复位
    RelayControl(RELAY_PORT4, 0x00);
}
/*********************
状态3:测量开环增益Aol
*********************/
void MeasureAol()
{
    float vo1_aol, vo1_aol_prime;
   
    // 第一次测量:K9,10,13,14闭合(P4.0,1,4,5)
    RelayControl(RELAY_PORT4, 0x33); // 00110011
    Delay1ms(1000);     // 稳定时间
    ADS1115_Write(0x01, 0xD283); // 读取AIN1
    vo1_aol = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 第二次测量:K9,10,13,14,15,16闭合(添加P4.6,7)
    RelayControl(RELAY_PORT4, 0xF3); // 11110011
    Delay1ms(1000);
    ADS1115_Write(0x01, 0xD283);
    vo1_aol_prime = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 计算Aol(避免除零错误)
    if(fabs(vo1_aol_prime - vo1_aol) > 0.001) {
        Aol = 501.0 * 12.0 / (vo1_aol_prime - vo1_aol);
    }
else {
        Aol = 0;
    }
   
    RelayControl(RELAY_PORT4, 0x00); // 断开所有
}

/*********************
状态4:测量电源抑制比PSRR
*********************/
void MeasurePSRR()
{
    float vo1_psrr, vo1_psrr_prime;
   
    // 第一次测量:K9,10,13,14闭合(同状态3首次)
    RelayControl(RELAY_PORT4, 0x33);
    Delay1ms(1000);
    ADS1115_Write(0x01, 0xD283);
    vo1_psrr = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 第二次测量:K9,10,11,12,13,14闭合(添加P4.2,3)
    RelayControl(RELAY_PORT4, 0x3F); // 00111111
    Delay1ms(1000);
    ADS1115_Write(0x01, 0xD283);
    vo1_psrr_prime = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    // 计算PSRR(12-5=7V变化量)
    PSRR = (1.0/501.0) * (vo1_psrr - vo1_psrr_prime) / (2.0 * 7.0);
   
    RelayControl(RELAY_PORT4, 0x00);
}

/*********************
状态5:测量VoMax
*********************/
void MeasureVoMax()
{
    // 闭合K9,10,13,14,15,16(同状态3第二次)
    RelayControl(RELAY_PORT4, 0xF3);
    Delay1ms(1000);
   
    // 读取AIN3(Vo2)
    ADS1115_Write(0x01, 0xE283); // 配置AIN3单端
    VoMax = (float)ADS1115_Read(0x00) * 4.096 / 32768.0;
   
    RelayControl(RELAY_PORT4, 0x00);
}

/*********************
I2C初始化
*********************/
void I2C_Init() {
    // STC8H的I2C配置(使用官方推荐配置)
               
    I2CMSST = 0xFF; // 延长SCL高电平时间(进一步降速)
  
    I2CCFG = 0xE0;  // 使能I2C,时钟分频
    I2CMSAUX = 0x00;
    I2CMSCR = 0x00;// 主模式控制寄存器初始化
   
    // 配置P1.0和P1.1为开漏模式
    P1M0 &= ~0x03;  // P1.0/P1.1开漏
    P1M1 |= 0x03;
          P1PU |= 0x03;   // 启用P1.0和P1.1的内部弱上拉(关键修改!)

}
/*********************
ADS1115写寄存器
*********************/
void ADS1115_Write(u8 reg, u16 value)
{
    I2C_Start();
    I2C_SendByte(ADS1115_ADDR<<1); // 写操作
    I2C_SendByte(reg);
    I2C_SendByte(value >> 8);     // 高字节
    I2C_SendByte(value & 0xFF);   // 低字节
    I2C_Stop();
}

/*********************
ADS1115读寄存器
*********************/
u16 ADS1115_Read(u8 reg)
{
    u16 result;
    I2C_Start();
    I2C_SendByte(ADS1115_ADDR<<1); // 写操作
    I2C_SendByte(reg);
    I2C_Start();
    I2C_SendByte((ADS1115_ADDR<<1)|1); // 读操作
    result = I2C_RecvByte() << 8;
    I2C_Ack(1);
    result |= I2C_RecvByte();
    I2C_Ack(0);
    I2C_Stop();
    return result;
}
/*********************
LCD显示字符串函数
参数:x-列坐标(0-127), y-行坐标(0-7), str-字符串
*********************/
void LCD_ShowStr(u8 x, u8 y, u8 *str) {
    u8 page = y / 8;    // 计算页地址
    u8 col = x % 64;    // 列地址(每半屏64列)
   
    // 选择左/右半屏
    if(x < 64) {
        LCD_CS1 = 0;
        LCD_CS2 = 1;
    } else {
        LCD_CS1 = 1;
        LCD_CS2 = 0;
        col = x - 64;   // 右半屏列地址
    }
   
    // 设置地址
    LCD_WriteCmd(0xB8 | page); // 页地址
    LCD_WriteCmd(0x40 | col);  // 列地址
   
    // 写入字符串数据
    while(*str) {
        LCD_Writevalue(*str++);
    }
}
/*********************
LCD基础函数
*********************/

void LCD_WriteCmd(u8 cmd) {
    LCD_DI = 0;   // 命令模式
    LCD_RW = 0;   // 写操作
    P2 = cmd;     // 命令数据
    LCD_E = 1;
    Delay1ms(1);  // 增加延时确保脉冲宽度
    LCD_E = 0;
    Delay1ms(1);
}
void LCD_Writevalue(u8 dat)
{
    LCD_DI = 1;   // 数据模式
    LCD_RW = 0;
    P2 = dat;
    LCD_E = 1;
    Delay1ms(1);  // 增加延时确保脉冲宽度
    LCD_E = 0;
    Delay1ms(1);
}

void LCD_Init() {
    LCD_RST = 0;
    Delay1ms(100);
    LCD_RST = 1;
    LCD_CS1 = 1;
    LCD_CS2 = 1;
   
    // 初始化指令序列
    LCD_WriteCmd(0x3F);    // 显示开
    LCD_WriteCmd(0xC0);    // 起始行设为第0行
    LCD_WriteCmd(0xB8 | 0); // 设置页地址为0(第一页)
    LCD_WriteCmd(0x40 | 0); // 设置列地址为0
          LCD_Clear();         // 清屏
}
void LCD_Clear()
{
    u16 i;
    LCD_CS1 = 0; LCD_CS2 = 1; // 清左半屏
    for(i=0; i<512; i++) LCD_Writevalue(0x00);
    LCD_CS1 = 1; LCD_CS2 = 0; // 清右半屏
    for(i=0; i<512; i++) LCD_Writevalue(0x00);
    LCD_CS1 = 1; LCD_CS2 = 1;
}

/*********************
显示测量结果
*********************/
void DisplayResults()
{
    char buf[32];
    const char *OpampTypeStr[] = {"Single"," Dual "," Quad "};
   
    // 显示运放类型
    sprintf(buf, "OP:%s", OpampTypeStr[OpampType]);
    LCD_ShowStr(64, 6, buf);
   

    // 第一列显示主要参数
          // 统一显示格式模板:
    // %[占位][宽度][.精度][单位]
    // Vos显示为mV,保留3位小数
    sprintf(buf, "Vos:%7.3fmV", Vos*1000);
    LCD_ShowStr(0, 0, buf);
   
    // IB显示为nA,保留2位小数
    sprintf(buf, "IB:%8.2fnA", IB*1e9);
    LCD_ShowStr(0, 1, buf);
    // Aol显示为dB,保留1位小数
    sprintf(buf, "Aol:%7.1fdB", 20*log10(fabs(Aol)));
    LCD_ShowStr(0, 2, buf);
    // PSRR显示为dB,保留1位小数
    sprintf(buf, "PSRR:%6.1fdB", 20*log10(fabs(PSRR)));
    LCD_ShowStr(0, 3, buf);
   
    // VoMax显示为V,保留3位小数
    sprintf(buf, "VoMax:%6.3fV", VoMax);
    LCD_ShowStr(0, 4, buf);
   
    // 第二列显示原始电压(右半屏)
    // 调整X坐标为64(假设12864屏分左右半屏)
    sprintf(buf, "Vo1:%6.3fV", Vo1);
    LCD_ShowStr(64, 0, buf);
   
    sprintf(buf, "Vo1':%5.3fV", Vo1_prime);
    LCD_ShowStr(64, 1, buf);
    }

/*********************
通用延时函数
*********************/
void Delay1ms(u16 n)
{
    u16 i,j;
    for(i=n; i>0; i--)
        for(j=830; j>0; j--);
}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:464
  • 最近打卡:2025-06-12 06:01:31
已绑定手机

79

主题

5108

回帖

9076

积分

超级版主

DebugLab

积分
9076
发表于 4 天前 | 显示全部楼层
只用过ST7920、AIP31020(兼容)有字库的12864
KS0108是无字库的,看程序中也是有字库相关程序的,应该没有用错型号的问题,手头没有KS0108测试
建议先用逻辑分析仪测量一下接口处是否有信号,先判断一下是否是软件的问题
初始化时序要严格按照数据手册编写,注意复位和延时,太快的速度会导致初始化异常
没看到打开EAXFR,初始化先打开EAXFR
新手必读:
https://www.stcaimcu.com/thread-16535-1-1.html
ST7920、AIP31020(兼容)串口程序:
https://www.stcaimcu.com/thread-5660-1-1.html
ST7920、AIP31020(兼容)并口程序:

  1. #define                Bus_12864                P2
  2. #define                LCD12864_RST        P03
  3. #define         LCD12864_PSB        P04
  4. #define         LCD12864_E                P05
  5. #define         LCD12864_RW                P06
  6. #define         LCD12864_RS                P07
  7. #define                Command                                                                                        0
  8. #define                Data                                                                                        1
  9. #define                Setting_Basic_Instruction_Set                                        0x30
  10. #define                Setting_Extended_Instruction_Set_Drawing_Off        0x34
  11. #define                Setting_Extended_Instruction_Set_Drawing_On                0x36
  12. #define                Clear_Display                                                                        0x01
  13. #define                Entry_Mode_Cursor_Left                                                        0x04
  14. #define                Entry_Mode_Entire_Right                                                        0x05
  15. #define                Entry_Mode_Cursor_Right                                                        0x06
  16. #define                Entry_Mode_Entire_Left                                                        0x07
  17. #define                Display_Off                                                                                0x08
  18. #define                Display_On_Cursor_Off_Inverse_Off                                0x0c
  19. #define                Display_On_Cursor_Off_Inverse_On                                0x0d
  20. #define                Display_On_Cursor_On_Inverse_Off                                0x0e
  21. #define                Display_On_Cursor_On_Inverse_On                                        0x0f
  22. #define                Cursor_Move_Left                                                                0x10
  23. #define                Cursor_Move_Right                                                                0x14
  24. #define                Display_Move_Left                                                                0x18
  25. #define                Display_Move_Right                                                                0x1c
复制代码
  1. /*----------------------------清空GDRAM----------------------------*/
  2. void Clear_GDRAM(void)
  3. {
  4.         unsigned char i,j,k;
  5.         LCD12864_Write(Setting_Extended_Instruction_Set_Drawing_Off,Command);
  6.         k=0x80;
  7.         for(i=0;i<32;i++)
  8.         {
  9.                 LCD12864_Write(k++,Command);
  10.                 LCD12864_Write(0x80,Command);
  11.                 for(j=0;j<16;j++)
  12.                 {
  13.                         LCD12864_Write(0x00,Data);
  14.                 }
  15.         }
  16.         k=0x80;
  17.         for(i=0;i<32;i++)
  18.         {
  19.                 LCD12864_Write(k++,Command);
  20.                 LCD12864_Write(0x88,Command);
  21.                 for(j=0;j<16;j++)
  22.                 {
  23.                         LCD12864_Write(0x00,Data);
  24.                 }
  25.         }
  26.         LCD12864_Write(Setting_Extended_Instruction_Set_Drawing_On,Command);
  27. }
  28. /*----------------------------指定位置显示光标----------------------------*/
  29. void Draw_GDRAM_Cursor(unsigned char x,unsigned char y)
  30. {
  31.         unsigned char i,j,k,l;
  32.         LCD12864_Write(Setting_Extended_Instruction_Set_Drawing_Off,Command);
  33.         switch(y)
  34.         {
  35.                 case 0:
  36.                         k=0x80;
  37.                         l=0x80;
  38.                         break;
  39.                 case 1:
  40.                         k=0x90;
  41.                         l=0x80;
  42.                         break;
  43.                 case 2:
  44.                         k=0x80;
  45.                         l=0x88;
  46.                         break;
  47.                 case 3:
  48.                         k=0x90;
  49.                         l=0x88;
  50.                         break;
  51.         }
  52.         for(i=0;i<16;i++)
  53.         {
  54.                 LCD12864_Write(k++,Command);
  55.                 LCD12864_Write(l+x/2,Command);
  56.                 for(j=0;j<1;j++)
  57.                 {
  58.                         if(x%2==1)
  59.                                 LCD12864_Write(0x00,Data);
  60.                         LCD12864_Write(0xff,Data);
  61.                 }
  62.         }
  63.         LCD12864_Write(Setting_Extended_Instruction_Set_Drawing_On,Command);
  64. }
  65. /*----------------------------整页显示字符----------------------------*/
  66. void Display_Text(unsigned char code *addr)
  67. {
  68.         unsigned char i;
  69.         LCD12864_Write(Setting_Basic_Instruction_Set,Command);
  70.         LCD12864_Write(0x80,Command);        //设置DDRAM地址
  71.         Delay_10us();
  72.         for(i=0;i<16;i++)
  73.         {
  74.                 LCD12864_Write(*addr,Data);
  75.                 addr++;
  76.         }
  77.         LCD12864_Write(0x90,Command);        //设置DDRAM地址
  78.         Delay_10us();
  79.         for(i=0;i<16;i++)
  80.         {
  81.                 LCD12864_Write(*addr,Data);
  82.                 addr++;
  83.         }
  84.         LCD12864_Write(0x88,Command);        //设置DDRAM地址
  85.         Delay_10us();
  86.         for(i=0;i<16;i++)
  87.         {
  88.                   LCD12864_Write(*addr,Data);
  89.                 addr++;
  90.         }
  91.         LCD12864_Write(0x98,Command);        //设置DDRAM地址
  92.         Delay_10us();
  93.         for(i=0;i<16;i++)
  94.         {
  95.                 LCD12864_Write(*addr,Data);
  96.                 addr++;
  97.         }
  98. }
  99. /*----------------------------指定位置显示字符----------------------------*/
  100. void Display_Data(unsigned char x,unsigned char y,unsigned char Data1,unsigned char Data2)
  101. {
  102.         LCD12864_Write(Setting_Basic_Instruction_Set,Command);
  103.         switch(y)
  104.         {
  105.                 case 0:
  106.                         LCD12864_Write(0x80+x,Command);        //设置DDRAM地址
  107.                         Delay_10us();
  108.                         LCD12864_Write(Data1,Data);
  109.                         LCD12864_Write(Data2,Data);
  110.                         break;
  111.                 case 1:
  112.                         LCD12864_Write(0x90+x,Command);        //设置DDRAM地址
  113.                         Delay_10us();
  114.                         LCD12864_Write(Data1,Data);
  115.                         LCD12864_Write(Data2,Data);
  116.                         break;
  117.                 case 2:
  118.                         LCD12864_Write(0x88+x,Command);        //设置DDRAM地址
  119.                         Delay_10us();
  120.                         LCD12864_Write(Data1,Data);
  121.                         LCD12864_Write(Data2,Data);
  122.                         break;
  123.                 case 3:
  124.                         LCD12864_Write(0x98+x,Command);        //设置DDRAM地址
  125.                         Delay_10us();
  126.                         LCD12864_Write(Data1,Data);
  127.                         LCD12864_Write(Data2,Data);
  128.                         break;
  129.         }
  130. }
  131. /*----------------------------初始化LCD12864----------------------------*/
  132. void LCD12864_Init(void)
  133. {
  134.         LCD12864_PSB=1;                        //设置为8bit并口工作模式
  135.         Delay_10ms();
  136.         Delay_10ms();
  137.         Delay_10ms();
  138.         Delay_10ms();                        //延时40ms
  139.         LCD12864_Write(Setting_Basic_Instruction_Set,Command);                //设置基本指令集
  140.         Delay_x10us(10);                //延时100us
  141.         LCD12864_Write(Setting_Basic_Instruction_Set,Command);                //设置基本指令集
  142.         Delay_x10us(4);                        //延时40us
  143.         LCD12864_Write(Display_Off,Command);                                                //显示光标闪烁完全关闭
  144.         Delay_x10us(10);                //延时100us
  145.         LCD12864_Write(Clear_Display,Command);                                                //清除显示
  146.         Delay_10ms();                        //10mS延时
  147.         LCD12864_Write(Entry_Mode_Cursor_Right,Command);                        //光标右移模式
  148.         Delay_x10us(10);                //延时100us
  149.         LCD12864_Write(Display_On_Cursor_Off_Inverse_Off,Command);        //开显示,无光标,光标不闪烁
  150.         Delay_x10us(10);                //延时100us
  151.         Clear_GDRAM();                        //清空GDRAM
  152.         Delay_x10us(10);                //延时100us
  153. }
复制代码


DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:95
  • 最近打卡:2025-06-12 08:58:25

733

主题

1万

回帖

1万

积分

管理员

积分
16461
发表于 3 天前 | 显示全部楼层
这个不需要专门的 STC8H4K64TLCD, 用STC8H8K64U就够了,还有 USB直接下载/通信
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-09 21:27:39
已绑定手机

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 3 天前 | 显示全部楼层
Debu*** 发表于 2025-6-8 15:58
只用过ST7920、AIP31020(兼容)有字库的12864
KS0108是无字库的,看程序中也是有字库相关程序的,应该没有 ...

好的谢谢大佬,初始化要先打开EAXFR,这个可能导致显示不成功吗请问

点评

没打开EAXFR不能操作XFR,如果需要使用XFR但没打开EAXFR就会异常  详情 回复 发表于 前天 09:40
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-06-09 21:27:39
已绑定手机

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 3 天前 | 显示全部楼层
神*** 发表于 2025-6-9 08:40
这个不需要专门的 STC8H4K64TLCD, 用STC8H8K64U就够了,还有 USB直接下载/通信

当时选的时候没有细想
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:65
  • 最近打卡:2025-06-12 08:25:56
已绑定手机

17

主题

472

回帖

1333

积分

金牌会员

积分
1333
发表于 前天 08:37 | 显示全部楼层
VEE不能悬空吧
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:464
  • 最近打卡:2025-06-12 06:01:31
已绑定手机

79

主题

5108

回帖

9076

积分

超级版主

DebugLab

积分
9076
发表于 前天 09:40 | 显示全部楼层
blrs*** 发表于 2025-6-9 22:54
好的谢谢大佬,初始化要先打开EAXFR,这个可能导致显示不成功吗请问

没打开EAXFR不能操作XFR,如果需要使用XFR但没打开EAXFR就会异常
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:431
  • 最近打卡:2025-06-12 08:54:04

28

主题

335

回帖

2876

积分

荣誉版主

积分
2876
发表于 前天 11:19 | 显示全部楼层
通过你给出的驱动代码,不太能确定你用的驱动代码是不是兼容KS0108的,或者你用的这个屏幕是不是兼容KS0108。
从屏幕引脚图上看,20个脚的顺序倒是跟KS0108的一致。

首先,你的驱动代码里,数据接口的引脚P2,
在STC8H.zip里的没有进行配置,不能对其读写操作;
在test.zip里配置成了推挽模式,这样就不能读取屏幕的反馈了。

然后是发送命令和发送数据的函数里,没有对屏幕状态的等待,估计不符合屏幕驱动的时序。
在屏幕工作的时候,数据引脚最高位的忙状态是1,空闲状态是0.只有在空闲状态时才可以进行其他操作。
尝试添加了ReadBusy函数,读取P2.7的状态,while( P2 & 0x80 ); 等待空闲,
然后简单的清屏和点亮全屏之类的函数就可以工作了。

另外原程序大概是89c52之类的改写的,驱动里的us延时函数只是1个nop,有些短。
在STC8H这类单片机上即便在很慢的速度下运行,也时常会数据混乱,显示乱码。

显示字符之类其他函数看起来比较花眼,总感觉不是KS0108的控制写法。估计也都要对应修改。


=======================================
这是我自己写的KS0108的STC8H的驱动,你对照看一下,判断你的屏幕是否兼容KS0108。
20240308_1LCD12864_KS0108_8H.rar (25.4 KB, 下载次数: 0)

下面是这个驱动在KS0108屏幕上的运行效果(单片机速度不能选太高,比如40MHz的时候偶尔也会出乱码,或者继续加长LCD驱动的延时):




能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-12 18:09 , Processed in 0.376471 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表