摘要

本设计由桥式压力传感器将重力转换成电压信号,然后通过HX711进行放大和模数转换成数字信号传送给STC89C52进行数字信号处理,以等价转换成重力并显示出来,同时具有计价功能,具有功能多、功耗低、系统设计简单、使用方便直观、速度快、测量准确、自动化程度高等特点。

**关键词:**电子秤、压力传感器、HX711、单片机

目录

1 设计分析 1

1.1设计任务 1

1.2 设计要求 1

2 方案比较与选择 1

2.1压力传感器的论证与选择 1

2.2 A/D 转换模块的选取 1

2.3 单片机模块的论证与选取 2

2.4系统总体框图 2

3 原理及参数分析 3

3.1 全桥差动压力传感器 3

3.2 HX711A/D转化器 4

3.2.1 转换原理 4

3.2.2 A/D值反向转换重力值的参数计算 4

4 硬件模块设计 5

4.1 12864液晶显示电路 5

4.2 HX711电路设计 5

4.3 报警电路设计 6

4.4 按键电路设计 6

5 软件模块设计 6

5.1 程序功能 6

5.2 程序流程图 7

6 系统测试 7

6.1 测试方法 7

6.2 测试仪器设备 8

6.3 测试问题及解决方法 8

6.4 测试结果 8

7 结论 9

参考文献 9

附录 10

附录I元器件清单 10

附录II原理图及PCB图 10

原理图 10

PCB图 11

附录III作品实物图 12

附录IV程序代码 13

1 设计分析

1.1设计任务

本设计要求制作一个以电阻应变片为称重传感器的简易电子秤,电子秤的结构如图所示。铁质悬臂梁固定在支架上,支架高度不大于40cm,支架及秤盘的形状与材质不限。悬臂梁上粘贴电阻应变片作为称重传感器。

图1. 1

python 简易电子秤 简易电子秤电路_传感器

1.2 设计要求

(1)电子秤可以数字显示被称物体的重量,单位克(g)。

(2)电子秤称重范围5.00g~500g;重量小于50g,称重误差小于0.5g;重量在50g及以上,称重误差小于1g。

(3)电子秤可以设置单价(元/克),可计算物品金额并实现金额累加 。

(4)电子秤具有去皮功能,去皮范围不超过100g。

(5)其他。

2 方案比较与选择

2.1压力传感器的论证与选择

方案一:采用惠更斯电桥,当电阻应变片承受载荷产生变形时,其阻值将发生变化。从而使电桥失去平衡,产生相应的差动信号,但其线性度不理想。

方案二:采用全桥电路,此电路对压力的灵敏度比惠更斯电桥增加一倍以上,测量的精度将更加准确,线性度更好。还具有机械滞后小、横向效应小以及体积小的特点。

通过上述两种方案比较,全桥差动压力传感器符合设计要求,称重范围为0~5Kg,满足题目要求的5g~500g的测量范围。

2.2 A/D 转换模块的选取

方案一:采用分立元件构成的仪用放大电路对电阻应变式传感器输出的模拟信号进行放大,然后外接高精度的A/D模块将模拟信号转换成数字信号送给单片机进行处理。

方案二:采用集成芯片HX711,其内部PGA和24位A/D,放大倍数可以在128和64两档中选择,24位的精度足够准确的分辨出题设中1g的精度变化要求。

通过比较,方案二的电路具有简单且高效的特点,节省了很多电路的调试时间而且降低了实物制作的面积,所以,本设计采用方案二。

2.3 单片机模块的论证与选取

方案一:采用最常见的51单片机作为主控芯片,其主频范围在11~32MHz范围内可选择,同时具有32个I/O口,完全满足I/O口的使用,价格合适,便于设计整体电路。

方案二:采用STM32F407,主频最高能达到160Mhz,具有较多的I/O口,能够进行更多的控制。

通过比较,方案二的功能更强。但考虑到价格等情况,本设计最终选取方案一。

2.4系统总体框图

系统总体框图:如图2.1如所示。

图2. 1

python 简易电子秤 简易电子秤电路_传感器_02

系统原理:该系统通过全桥差动压力传感器将被测物体重量的非电信号转化为电信号,然后通过A/D转换器HX711转为数字量送给单片机处理,最终在液晶上显示出相应的被测物体重量。当被测物体的重量超出称重范围时,蜂鸣器发出鸣叫进行报警。此外,本设计通过键盘控制可实现计价功能,使电子秤更人性化。

3 原理及参数分析

3.1 全桥差动压力传感器

原理图:如图3.2所示

图3. 2

python 简易电子秤 简易电子秤电路_原理图_03


python 简易电子秤 简易电子秤电路_嵌入式_04

原理分析:电阻应变式传感器将被测量的力,通过它产生的金属弹性形变转换成电阻变化。

设有一根电阻丝,它在未受力时的原始电阻值为:

(3.8)

式中 :ρ为电阻丝的电阻率;l为电阻丝的长度;S为电阻丝的面积。

当电桥后接放大器时,放大器的输入阻抗很高,远大于电桥输出电阻,把电桥输出端看成开路,电桥输出为:

(3.9)

应变片工作室,其电阻变化为∆R,此时有不平衡的电压输出:

(3.10)

设桥臂比n=R2/R1,由于电桥平衡时有R4/R3=R2/R1 ,通常∆R1
﹤﹤R1,略去分母中的∆R1/R1。可得:

(3.11)

电桥灵敏度定义为,可得单臂工作应变片的电桥电压灵敏度为:

(3.12)

当n=1时,由式(3.11)得

(3.13)

(3.14)

式(3.14)表明,当电源电压U及电阻相对值一定时,电桥的输出电压及电压灵敏度将于各臂阻值大小无关。

python 简易电子秤 简易电子秤电路_原理图_05

3.2 HX711A/D转化器

3.2.1 转换原理

HX711内部原理图:如图3.1所示

python 简易电子秤 简易电子秤电路_嵌入式_06

HX711特性及功能:它是一款专门为高精度电子秤而设计的24位A/D转换器芯片,片内集成低噪声可编程放大器,可选增益有64和128,片内稳压电路可以直接向外部传感器和芯片内部A/D转换器提供电源,并且同步抑制50Hz和60Hz的电源干扰。

图3. 1

3.2.2 A/D值反向转换重力值的参数计算

输出电压与激励电压的关系:满量程输出电压=激励电压×灵敏1.0mV/V,即:如果供电电压是5V
,灵敏度是2.0mV/V,则:输出电压的满量程10mV。相当于有10kg 重力产生10mV 的电压。

假设重力为 xkg(x<10kg),测量出来的A/D值为y。在5V 的供电电压下10kg
的传感器最大输出电压是5v×2mV/V=10.0mV,则发送给 A/D 模块的电压为

x kg×10.0mV/10kg=0.1A mV (3.1)

经过128倍增益后为:

128×0.1x=12.8AmV (3.2)

转换为24bit 数字信号为:

12.0mV×224/5V=40265.3184 x (3.3)

所以

y =40265.3184 x/100 =402.653184 x (3.4)

因此得出

xy/402.653184 (3.5)

kg≈y/4.03 g (3.6)

4 硬件模块设计

4.1 12864液晶显示电路

显示电路:如图4.1所示。

12864LCD内部构成及功能:它是一种图形点阵液晶显示器,它主要由行驱动器/列驱动器128×64全点阵液晶显示器组成。可完成图形显示,也可以显示8×4个(16×16
点阵)汉字或者显示16×4个(8×16点阵)ASCII码。低电压低功耗是其显著特点。

图4. 1

python 简易电子秤 简易电子秤电路_原理图_07

4.2 HX711电路设计

在电路上预留四个排插插座,以便接入HX711传感器模块。其与单片机接口P1.0和P1.1两个引脚,外接+5V电压。

电路接口图:如图4.2所示。

图4. 2

python 简易电子秤 简易电子秤电路_传感器_08

4.3 报警电路设计

报警指示电路:如图4.3所示。

python 简易电子秤 简易电子秤电路_原理图_09

报警指示原理分析:报警指示电路是由PNP三极管8050驱动蜂鸣器实现的,单片机I0口控制三极管的基极,当单片机的I0口输出为低电平时,三极管导通,蜂鸣器的正极与电源接通,蜂鸣器通电发出报警声,当单片机I0口输出高电平时,三极管截止,蜂鸣器停止报警。

4.4 按键电路设计

按键电路功能主要包括:物品单价设置、复位及去皮测量。其中数字0~9为两位单价设置。键值15为其复位设置。键值13为去皮测量。

图4. 4

python 简易电子秤 简易电子秤电路_单片机_10

5 软件模块设计

5.1 程序功能

在系统通电后,主程序首先完成系统初始化,其中包括系统变量定义和给系统变量赋初值等,然后调用A/D采集函数,将A/D采集模块输出的24位二进制串行数据转化为十进制,接着进行调零和定标,最后分离出四位十进制数据的千位、百位、十位和个位,调用液晶显示函数,将对应的数值送到对应的液晶上进行显示。

5.2 程序流程图

系统主函数流程图如图3-1所示。

图5. 1

python 简易电子秤 简易电子秤电路_嵌入式_11

6 系统测试

6.1 测试方法

按照电路图输入到输出依次焊接,焊接一级则调试一级,焊接两级则进行级联调试,直到整机焊接与调试完成。

图6. 1

python 简易电子秤 简易电子秤电路_嵌入式_12

具体测试为:

(1)精度测试:用
2个1kg的砝码、1个2kg的砝码和1个0.5kg的砝码分别组合来测试本次设计的电子秤的精度。根据显示出来的示重和砝码重量的结果判断是否有偏差,再根据偏差的多少来确定本作品的精度。

(2)计价测试:分别放入不同重量的物体和输入不同的单价,观测是否能准确的得出总价。

(3)去皮测试:先放入一个重物作为“皮”,再按下“去皮按键”,然后将重物置于电子秤上,观察是否能够准确的测出后加重物的重量。

6.2 测试仪器设备

测试条件与设备如表6.1所示:

表6. 1 测试仪器设备

设备名称

型号

功能

电子天平

BT457

参考测量

万用表

VC9807A+

检测电流

基准砝码

电子秤标准砝码

提供重量

6.3 测试问题及解决方法

(1)因接线松动导致模块不工作和程序不运行。解决办法:更换为正常模块,制作专用的牢固接线来代替杜邦线。

(2)显示重量和实际重量不成线性关系。解决办法:对程序数据进行调整,再对数据进行精度测试,直到测量数据呈线性关系。

(3)数据精度不够。解决办法:修改程序数据,直到达到指标要求。

6.4 测试结果

测试结果如表6.2所示:

表6. 2 测试数据

实际重量/g

测量显示/g

绝对误差/g

相对误差/%

3.30

3.43

0.13

-0.96

10.10

10.23

0.13

-0.99

17.70

17.81

0.11

-0.99

27.80

27.89

0.09

-1.00

31.10

31.22

0.12

-1.00

40.50

40.67

0.17

-1.00

50.00

50.07

0.07

-1.00

90.60

90.50

-0.10

-1.00

182.00

182.04

0.04

-1.00

231.60

231.69

0.09

-1.00

281.60

281.62

0.02

-1.00

373.10

373.20

0.10

-1.00

451.20

451.19

-0.01

-1.00

501.20

501.16

-0.04

-1.00

682.90

682.96

0.06

-1.00

774.30

774.31

0.01

-1.00

871.10

871.06

-0.04

-1.00

1105.80

1105.72

-0.08

-1.00

从表中可以得到:

(1)当侧重物体小于50g时,其误差为±(0.05~0.2)g;

(2)当侧重物体不小于50g时,其误差为±(0.01~0.1)g。

7 结论

经过整体测试,本设计的简易电子秤完全符合设计要求。

传感器好比人体“五官”的工程模拟物,它是一种能将特定被测量信息按一定规律转换成某种可用信号输出的器件或装置。本次设计中的简易电子秤就是在传感器的基础上设计而成的。

参考文献

[1]王建华,敬大德,曹少飞.基于双悬臂梁结构的应变测量传感器研究[J].传感技术学报,2005,18(3):5-8.

[2]陈杰,黄鸿.传感器与检测技术[M].北京:高等教育出版社,2002.

[3]陈杰,陈绿深.传感器与检测技术[M].北京:北京理工大学出版社,1987.

[4]王洪业,传感器技术[M].长沙:湖南科学出版社,1985.

[5]张毅刚.单片机原理及应用[M].北京:高等教育出版社,2003.

[6]周明德,蒋本珊.微机原理与接口技术(第2版)[M].北京:人民邮电出版社,2007.

[7]康华光.电子技术基础数字部分(第五版)[M].北京:高等教育出版社,2005.

[8]楼然苗.单片机课程设计指导[M].北京: 北京航空航天大学出版社,2007.

附录

附录I元器件清单

Part Type

Designator

Footprint

Part Type

Designator

Footprint

0.1u

C2

RA/D0.3

POWER ON

D2

DIODE-LIGHT

0.1uf

C3

RA/D0.3

POWER ON

S17

SW2

1K

R5

AXIAL0.3

RESET

K1

ANJIAN

1K

R10

AXIAL0.3

STC89C52

U2

DIP40

2SC8050

Q1

TO-92B

SW-PB

S16

ANJIAN

4.7K

R8

AXIAL0.3

SW-PB

S2

ANJIAN

10K

R3

AXIAL0.3

SW-PB

S6

ANJIAN

10K

R1

AXIAL0.3

SW-PB

S10

ANJIAN

10K

R2

AXIAL0.3

SW-PB

S14

ANJIAN

10K

R4

AXIAL0.3

SW-PB

S1

ANJIAN

11.0592

Y1

XTAL1

SW-PB

S5

ANJIAN

18

R7

AXIAL0.3

SW-PB

S9

ANJIAN

20p

C4

RA/D0.1

SW-PB

S13

ANJIAN

20p

C5

RA/D0.1

SW-PB

S4

ANJIAN

100u

C1

RB.1/.2

SW-PB

S8

ANJIAN

330

R6

AXIAL0.3

SW-PB

S12

ANJIAN

BUZZER

U1

BUZZER

SW-PB

S15

ANJIAN

CON2

J11

sip2

SW-PB

S3

ANJIAN

HX711

J2

SIP4

SW-PB

S7

ANJIAN

LIGHT

D1

DIODE-LIGHT

SW-PB

S11

ANJIAN

PAIZU

A1

sip9

TLX12864

J3

JLX12864G

POT2

R9

SIP3

附录II原理图及PCB图

原理图

python 简易电子秤 简易电子秤电路_单片机_13

PCB图

python 简易电子秤 简易电子秤电路_嵌入式_14

附录III作品实物图

python 简易电子秤 简易电子秤电路_传感器_15

附录IV程序代码

主程序

#include <reg52.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit buff=P1^2;
extern void display_GB2312_string(uchar page,uchar column,uchar *text);
extern void initial_lcd();
extern void clear_screen();
extern ulong ReA/DCount(void);
extern void get_weight();
extern void scankeyboard() ;
extern unsigned char key;
extern uint weight,temp;
extern delay4(unsigned char k);
extern delay(int n_ms);
extern le();
int pl=0;
uchar a[10]={" "};
uchar b[10]={" "};
uchar c[9]={" "};
uchar shuzi[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2e};
 //数字0-10//=main program=====
void main(void)
{
bit q=1;
unsigned long danjia,zongjia;
float zl,pl=0,pl2;
// uchar a1,b1,c1,w=0; //单价
uchar a2,b2,c2,a3,b3,c3,d3,e3,a4,b4,c4;
uint a1,b1,c1,w=0; //单价
// uint a3,b3,c3,d3,e3;//f3 ;
initial_lcd();
clear_screen();
buff=0;
delay(100);
le();
delay(800);
clear_screen();
while(1)
{
get_weight() ;
zl=weight;
// zl=zl/22*1.0168-64.77; //误差修正
// zl=zl/22*1.005-63.90; //误差修正 zl<50时候的修正 修正第一次
//修正第二次
// zl=(zl/22*1.005-64.13); //这个也行
// if(zl>230)
zl=(zl/22*1.00394297846527-64.10);
pl2=zl; //记录毛总
zl=zl-pl; //去皮操作
scankeyboard();
/* while(key!=16)
{
if(0<=key<10)
{
w++; //按键记录次数;往后面移动
if(w==4)
{
w=0;
a1=0;
b1=0;
c1=0;
}
switch(w)
{
case 1: a1=key; break;
case 2: b1=key; break;
case 3: c1=key; break;
default: break;
}
}
if(key==15) {a1=0;b1=0;c1=0;} //单价归零
if(key==13) {pl=pl2;} //案件控制去皮操作
key=16;
} */
if(key!=16)
{
switch(key)
{
case 0: w++; break;
case 1: w++; break;
case 2: w++; break;
case 3: w++; break;
case 4: w++; break;
case 5: w++; break;
case 6: w++; break;
case 7: w++; break;
case 8: w++; break;
case 9: w++; break;
case 13: pl=pl2; break; //案件控制去皮操作
case 15:a1=0;b1=0;c1=0; break; //单价归零
default: break;
// case 1:w++;
// case 1:w++;
}
if(w==4) //按键记录次数;往后面移动
{
w=0;
a1=0;
b1=0;
c1=0;
}
switch(w)
{
case 1: a1=key;
break;
case 2: b1=key;
break;
case 3: c1=key;
break;
default: break;
}
} key=16;
a3=(uint)zl/100%10;b3=(uint)zl/10%10;c3=(uint)zl%10,d3=(uint)(zl*10)%10;e3=(uint)(zl*100)%10;//f3=(uint)(zl*1000)%10;
 //取百位十位个位 d3,e3是取的小数点danjia=a1*100+b1*10+c1; //单价计算
zongjia=zl*danjia; //总价计算
a[0]=shuzi[a3];a[1]=shuzi[b3];a[2]=shuzi[c3];a[3]=shuzi[10];a[4]=shuzi[d3];a[5]=shuzi[e3];//a[6]=shuzi[f3];
 //重量b[0]=shuzi[a1];b[1]=shuzi[b1];b[2]=shuzi[10];b[3]=shuzi[c1]; //单价
c[0]=shuzi[zongjia/100000]; //总价
c[1]=shuzi[zongjia/10000%10];
c[2]=shuzi[zongjia/1000%10%10];
c[3]=shuzi[zongjia/100%10%10%10];
c[4]=shuzi[10]; //小数点
c[5]=shuzi[zongjia/10%10%10%10%10];
c[6]=shuzi[zongjia%10%10%10%10%10];
if((a2!=a1)|(b2!=b1)|(c2!=c1)|(a4!=a3)|(b4!=b3)|(c4!=c3)) // 去掉闪屏
{q=1;}
a2=a1;b2=b1;c2=c1;
a4=a3;b4=b3;c4=c3;
while(q)
{
display_GB2312_string(1,45,“电子秤”); //在第1 页,第1 列,显示一串16x16
 点阵汉字或8x16 的ASCII 字display_GB2312_string(3,1,“重量 : g”); //显示一串16x16 点阵汉字或8x16 的ASCII
 字.以下雷同display_GB2312_string(5,1,“单价 : 元/g”) ;
display_GB2312_string(7,1,“总价 : 元”);
display_GB2312_string(3,50,a);
display_GB2312_string(5,50,b);
display_GB2312_string(7,50,c);
q=0;
}
if(zl>1000) buff=1;
}
}
LCD12864显示程序
#include <reg52.H>
#include <intrins.h>
sbit lcd_sclk=P0^4; //接口定义:lcd_sclk 就是LCD 的SCLK
sbit lcd_sid=P0^3; //接口定义:lcd_sid 就是LCD 的SDA
sbit lcd_rs=P0^2; //接口定义:lcd_rs 就是LCD 的RS,也叫“CD”
sbit lcd_reset=P0^1; //接口定义:lcd_reset 就是LCD 的RESET
sbit lcd_cs1=P0^0; //接口定义:lcd_cs1 就是LCD 的CS1
sbit Rom_IN=P1^3; //字库IC 接口定义:Rom_IN 就是字库IC 的SI
sbit Rom_OUT=P1^4; //字库IC 接口定义:Rom_OUT 就是字库IC 的SO
sbit Rom_SCK=P1^5; //字库IC 接口定义:Rom_SCK 就是字库IC 的SCK
sbit Rom_CS=P1^6; //字库IC 接口定义Rom_CS 就是字库IC 的CS#
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar code jiong1[]={//-- 图片 :亚古兽,
//–
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
0x84,0x00,0x00,0x00,0x02,0x00,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x04,0x04,0x00,0x00,0x02,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xE7,
0xFE,0xC3,0xE2,0xF8,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x02,0x0C,0x00,0x00,0xF0,0xC6,0xC3,0xFF,0xFC,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,
0xCC,0xD8,0x10,0x50,0xD0,0x9C,0xD8,0x70,0x30,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x7F,0x7F,0x25,0x25,0xFF,0xFF,0x25,0x25,0x3F,0xFF,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x00,
0x07,0x1F,0x19,0x0F,0x00,0x30,0x08,0x68,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x60,0x68,0x08,0x72,0x0F,0x1B,0x1B,0x0F,0x07,0x2F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,
0x07,0x0F,0x0A,0x0A,0x0B,0x09,0x09,0x0B,0x0A,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x40,
0x82,0x02,0x0C,0x70,0x20,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0x40,0x40,0x20,0x10,0x0C,0x84,0xC0,0x20,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xC0,0xC0,0x40,0x40,0x40,0x40,0x40,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x80,0x88,0x88,0x88,0x88,0xC8,0xA8,0xB8,0x98,0x88,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
0x00,0x20,0x01,0x12,0x06,0x0C,0x39,0x73,0xE1,0xE2,0xE2,0xC2,0xC2,0xC2,0xC2,0xC2,
0xE2,0xE2,0xE2,0xE1,0x70,0x7C,0x76,0x22,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xC0,0x00,0x00,0x00,0x00,
0x00,0x80,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,
0xE7,0x77,0xD5,0x85,0xFD,0xFD,0x95,0x97,0x97,0x84,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x10,0x10,0x10,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,
0x00,0x00,0xC0,0xFE,0xC0,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x81,0x83,0x03,0x83,
0x83,0x01,0x01,0x00,0x00,0x00,0xC0,0xFC,0xE2,0xC0,0x80,0x01,0x04,0x00,0x08,0x00,
0x30,0x20,0x10,0x88,0xC0,0xC0,0xE2,0xE0,0xF0,0xF8,0xFC,0xFE,0xFE,0xFE,0xFE,0xFD,
0xFF,0xFF,0xEE,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x70,0xFF,0x03,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x03,0x3F,0xF1,0x03,0x06,0x06,0x0C,0x1C,
0x1C,0x1E,0x1F,0x1F,0x0F,0x0F,0x0F,0x0F,0x07,0x07,0x07,0x07,0x07,0x03,0x03,0x03,
0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x65,0x7D,0xFF,0x14,0x76,0x37,0x13,0xFA,0x12,0x77,0x67,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x20,0x80,0x00,0x00,0x00,0x00,0x10,
0xC0,0x01,0x0E,0xF0,0x00,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0x40,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
void delay(int n_ms)
{
int j,k;
for(j=0;j<n_ms;j++)
for(k=0;k<110;k++);
}
//短延时
void delay_us(int n_us)
{
int j,k;
for(j=0;j<n_us;j++)
for(k=0;k<1;k++);
}
//写指令到LCD 模块
void transfer_command_lcd(int data1)
{
char i;
lcd_cs1=0;
lcd_rs=0;
for(i=0;i<8;i++)
{
lcd_sclk=0;
//delay_us(10); //加少量延时
if(data1&0x80) lcd_sid=1;
else lcd_sid=0;
lcd_sclk=1;
//delay_us(10); //加少量延时
data1=data1<<=1;
}
lcd_cs1=1;
}
//写数据到LCD 模块
void transfer_data_lcd(int data1)
{
char i;
lcd_cs1=0;
lcd_rs=1;
for(i=0;i<8;i++)
{
lcd_sclk=0;
if(data1&0x80) lcd_sid=1;
else lcd_sid=0;
lcd_sclk=1;
data1=data1<<=1;
}
lcd_cs1=1;
}
//LCD 模块初始化
void initial_lcd()
{
lcd_reset=0; //低电平复位
delay(100);
lcd_reset=1; //复位完毕
delay(100);
transfer_command_lcd(0xe2); //软复位
delay(5);
transfer_command_lcd(0x2c); //升压步聚1
delay(50);
transfer_command_lcd(0x2e); //升压步聚2
delay(50);
transfer_command_lcd(0x2f); //升压步聚3
delay(5);
transfer_command_lcd(0x23); //粗调对比度,可设置范围0x20~0x27
transfer_command_lcd(0x81); //微调对比度
transfer_command_lcd(0x28); //微调对比度的值,可设置范围0x00~0x3f
transfer_command_lcd(0xa2); //1/9 偏压比(bias)
transfer_command_lcd(0xc8); //行扫描顺序:从上到下
transfer_command_lcd(0xa0); //列扫描顺序:从左到右
transfer_command_lcd(0x40); //起始行:第一行开始
transfer_command_lcd(0xaf); //开显示
}
void lcd_A/Ddress(uint page,uint column)
{
column=column-0x01;
transfer_command_lcd(0xb0+page-1); //设置页地址,每8 行为一页,全屏共64
 行,被分成8 页transfer_command_lcd(0x10+(column>>4&0x0f)); //设置列地址的高4 位
transfer_command_lcd(column&0x0f); //设置列地址的低4 位
}
//全屏清屏
void clear_screen()
{
unsigned char i,j;
for(i=0;i<9;i++)
{
transfer_command_lcd(0xb0+i);
transfer_command_lcd(0x10);
transfer_command_lcd(0x00);
for(j=0;j<132;j++)
{
transfer_data_lcd(0x00);
}
}

}

//送指令到晶联讯字库IC
void send_command_to_ROM( uchar datu )
{
uchar i;
for(i=0;i<8;i++ )
{
Rom_SCK=0;
delay_us(10);
if(datu&0x80)Rom_IN = 1;
else Rom_IN = 0;
datu = datu<<1;
Rom_SCK=1;
delay_us(10);
}
}
//从晶联讯字库IC 中取汉字或字符数据(1 个字节)
static uchar get_data_from_ROM( )
{
uchar i;
uchar ret_data=0;
for(i=0;i<8;i++)
{
Rom_OUT=1;
Rom_SCK=0;
//delay_us(1);
ret_data=ret_data<<1;
if( Rom_OUT )
ret_data=ret_data+1;
else
ret_data=ret_data+0;
Rom_SCK=1;
//delay_us(1);
}
return(ret_data);
}
//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_16x16(ulong fontA/Ddr,uchar page,uchar column)
{
uchar i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontA/Ddr&0xff0000)>>16); //地址的高8 位,共24 位
send_command_to_ROM((fontA/Ddr&0xff00)>>8); //地址的中8 位,共24 位
send_command_to_ROM(fontA/Ddr&0xff); //地址的低8 位,共24 位
for(j=0;j<2;j++)
{
lcd_A/Ddress(page+j,column);
for(i=0; i<16; i++ )
{
disp_data=get_data_from_ROM();
transfer_data_lcd(disp_data); //写数据到LCD,每写完1 字节的数据后列地址自动加1
}
}
Rom_CS=1;
}
//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_8x16(ulong fontA/Ddr,uchar page,uchar column)
{
uchar i,j,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontA/Ddr&0xff0000)>>16); //地址的高8 位,共24 位
send_command_to_ROM((fontA/Ddr&0xff00)>>8); //地址的中8 位,共24 位
send_command_to_ROM(fontA/Ddr&0xff); //地址的低8 位,共24 位
for(j=0;j<2;j++)
{
lcd_A/Ddress(page+j,column);
for(i=0; i<8; i++ )
{
disp_data=get_data_from_ROM();
transfer_data_lcd(disp_data); //写数据到LCD,每写完1 字节的数据后列地址自动加1
}
}
Rom_CS=1;
}
//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_5x8(ulong fontA/Ddr,uchar page,uchar column)
{
uchar i,disp_data;
Rom_CS = 0;
send_command_to_ROM(0x03);
send_command_to_ROM((fontA/Ddr&0xff0000)>>16); //地址的高8 位,共24 位
send_command_to_ROM((fontA/Ddr&0xff00)>>8); //地址的中8 位,共24 位
send_command_to_ROM(fontA/Ddr&0xff); //地址的低8 位,共24 位
lcd_A/Ddress(page,column);
for(i=0; i<5; i++ )
{
disp_data=get_data_from_ROM();
transfer_data_lcd(disp_data); //写数据到LCD,每写完1 字节的数据后列地址自动加1
}
Rom_CS=1;
}
//****************************************************************
ulong fontA/Ddr=0;
void display_GB2312_string(uchar page,uchar column,uchar *text)
{
uchar i= 0;
while((text[i]>0x00))
{
if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1))
{
//国标简体(GB2312)汉字在晶联讯字库IC 中的地址由以下公式来计算:
//A/Ddress = ((MSB - 0xB0) * 94 + (LSB - 0xA1)+ 846)*32+ BaseA/Dd;BaseA/Dd=0
//由于担心8 位单片机有乘法溢出问题,所以分三部取地址
fontA/Ddr = (text[i]- 0xb0)*94;
fontA/Ddr += (text[i+1]-0xa1)+846;
fontA/Ddr = (ulong)(fontA/Ddr*32);
get_and_write_16x16(fontA/Ddr,page,column);
 //从指定地址读出数据写到液晶屏指定(page,column)座标中i+=2;
column+=16;
}
else if(((text[i]>=0xa1) &&(text[i]<=0xa3))&&(text[i+1]>=0xa1))
{
//国标简体(GB2312)15x16 点的字符在晶联讯字库IC 中的地址由以下公式来计算:
//A/Ddress = ((MSB - 0xa1) * 94 + (LSB - 0xA1))*32+ BaseA/Dd;BaseA/Dd=0
//由于担心8 位单片机有乘法溢出问题,所以分三部取地址
fontA/Ddr = (text[i]- 0xa1)*94;
fontA/Ddr += (text[i+1]-0xa1);
fontA/Ddr = (ulong)(fontA/Ddr*32);
get_and_write_16x16(fontA/Ddr,page,column);
 //从指定地址读出数据写到液晶屏指定(page,column)座标中i+=2;
column+=16;
}
else if((text[i]>=0x20) &&(text[i]<=0x7e))
{
fontA/Ddr = (text[i]- 0x20);
fontA/Ddr = (unsigned long)(fontA/Ddr*16);
fontA/Ddr = (unsigned long)(fontA/Ddr+0x3cf80);
get_and_write_8x16(fontA/Ddr,page,column);
 //从指定地址读出数据写到液晶屏指定(page,column)座标中i+=1;
column+=8;
}
else
i++;
}
}
void display_128x64(uchar *dp)
{
uint i,j;
for(j=0;j<8;j++)
{
lcd_A/Ddress(j+1,1);
for (i=0;i<128;i++)
{
transfer_data_lcd(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
dp++;
}
}
}