实验报告
学生学院 自动化学院 专业班别 电气 姓 名 学 号 指导教师 老师
(20xx年)
《电子系统可靠性设计技术》
一、实验目的与要求
实验验证高频噪声模拟发生器产生的暂态传导干扰对电子设备电源线和数据线的干扰作用。综合分析电源抗干扰滤波器原理并通过实验验证电源抗干扰滤波器的作用。
二、主要仪器设备和材料
1、高频噪声模拟发生器
2、脉冲群电容耦合夹
3、电源抗干扰滤波器
4、单片机实验系统
三、实验方案
系统连线图如下:
实验步骤
1、将高频噪声模拟发生器产生的暂态传导干扰通过脉冲群电容耦合夹耦合到单片机实验系统的电源线上,然后进行下面操作:
1)调节干扰输出幅度、2)调节干扰输出频率
分别观察干扰的影响情况(按系统受影响但能自动恢复、系统受影响不能自动恢复两种严酷等级分类)。
1
3、将电源抗干扰滤波器接入单片机实验系统的电源入口。
4、将高频噪声模拟发生器产生的暂态传导干扰通过脉冲群电容耦合夹耦合到单片机实验系统的电源线上,然后进行下面操作:
1)调节干扰输出幅度、2)调节干扰输出频率
首先将干扰输出幅度和干扰输出频率调节到上一个实验中的系统受影响不能自动恢复时的数值上,观察系统是否受影响。然后再进一步增大干扰输出幅度,分别观察干扰的影响情况(按系统受影响但能自动恢复、系统受影响不能自动恢复两种严酷等级分类)。
四、实验结果和数据处理
实验结果是:
20*lg(1.85/0.75) = 7.95dB
五、结论
有了滤波器后,系统受干扰能力增强。
六、思考题、问题与讨论
思考题1:本实验中,高频噪声模拟发生器产生的干扰是怎样施加到受干扰对象上去的?
答:通过电容耦合夹耦合到单片机实验系统的电源线上。
思考题2:比较单片机实验系统接入电源抗干扰滤波器前后受EMI噪声干扰影响的情况,并扼要分析电源抗干扰滤波器工作原理。
答:电源抗干扰滤波器原理图如下:它是一种无源低通滤波器,它无衰减地将交流电传输到电源,而大大衰减随交流电传入的EMI噪声,同时又能有效地抑电源设备产生的EMI噪声,阻止它们进入交流电网干扰其它电子设备
单相交流电网电源抗干扰滤波器的基本结构如图1所示,它是由集中参数元件组成的四端无源网络,主要使用的元件是共模电感线圈L1,L2,差模电感L3,L4,以及共模电容CY1,CY2,和差模电容CX。若将此滤波器网络放在电源的输入端,则L1与CY1及L2与CY2分别构成交流进线上两对独立端口之间的低通滤波器,可衰减 2
交流进线上存在的共模干扰噪声,阻止它们进入电源设备。共模电感线圈用来衰减交流进线上的共模噪声,其中L1和L2一般是在闭合磁路的铁氧体上同向卷绕相同匝数,接入电路后在L1,L2两个线圈内交流电流产生的磁通相互抵消,不致使磁芯引起磁饱和,又使这两个线圈的电感值在共模状态下较大,且保持不变。 差模电感线圈L3,L4与差模电容器CX构成交流进线独立端口间的一个低通滤波器,用来抑制交流进线上的差模干扰信号,防止电源设备受其干扰。
3
第二篇:20xx年参加电子设计 单片机最小系统实验报告
单片机最小系统
一、 摘要:
单片机最小系统设计主要在STC89C52单片机上扩展I/O口,用ZLG7290芯片扩展键盘和8段数码管显示接口,用TLC5615和TLC1549芯片进行数/模间转换,液晶连接单片机I/O口。软件编程控制数码管显示、液晶显示、数/模间转换。
二、 关键字:
STC89C52、TLC5615、TLC1549、ZLG7290、按键、LED、LCD、8段数码管。
1
目录
1. 设计 ………………………………………………………………………… 3 1.1 主要芯片简介 ………………………………………………………… 3
1.1.1 ZLG7290芯片 ………………………………………………
1.1.2 TLC5615芯片 ……………………………………………
1.1.3 TLC1549芯片 ……………………………………………
1.2 目的要求 …………………………………………………………… 3
1.2.1 目的 ……………………………………………………… 4
1.2.2 任务 ……………………………………………………… 4
2. 系统原理 ………………………………………………………………… 4
2.1 电源 ……………………………………………………… 4
2.2 复位及时钟电路 ………………………………………… 4
2.3 八段数码显示管 ………………………………………… 5
2.4 液晶显示电路 …………………………………………… 5
2.5 按键电路 ………………………………………………… 6
2.6 AD/DA转换电路 …………………………………………
3. 具体步骤 …………………………………………………………………
4. 设计总结 …………………………………………………………………
5. 软件设计 …………………………………………………………………
6. 参考文献 ……………………………………………………………………附录1 材料清单
2
1.设计
1.1主要芯片简介
1.1.1 ZLG7290
1. 直接驱动 8位共阴式数码管(1 英寸以下)或 64只独立的 LED;
2. 能够管理多达 64 只按键,自动消除抖动,其中有 8 只可以作为功能键使用;
3. 段电流可达 20mA,位电流可达 100mA以上;
4. 利用功率电路可以方便地驱动 1 英寸以上的大型数码管;
5. 具有闪烁、段点亮、段熄灭、功能键、连击键计数等强大功能;
6. 提供有10种数字和21种字母的译码显示功能, 或者直接向显示缓存写入显示数据;
7. 不接数码管而仅使用键盘管理功能时,工作电流可降至 1mA;
8. 与微控制器之间采用 I2C串行总线接口,只需两根信号线,节省 I/O资源;
9. 工作电压范围:+3.3~5.5V;
10. 工作温度范围:-40~+85℃;
11. 封装:DIP-24(窄体) ,SOP-24。
1.1.2 TLC5615
TLC5615是一个串行10位DAC芯片。只需要3根串行总线就可以完成10位数
据的串行输入,易于和工业标准的微控制器或微处理器接口,适用于电池供电的
测试仪表、移动电话,也适用于数字的失调与增益调整以及工业控制场合。其主
要特点如下:
1、单5V电源工作
2、3线串行接口
3、高阻抗基准输入端
4、DAC输出的最大电压为2倍的基准输入电压
5、上电时内部自动复位
6、微功耗,最大功耗为1.75mW
7、转换速率快,更新速率为1.21MHZ
1.1.3 TLC1549
TLC1549是一个具有串行控制、连续逐渐逼近型的模数转换器,它采用两个差
分基准电压高阻输入和一个三态输出构成三态接口。
1、电源电压范围:-0.5V…6V
2、125摄氏度输入电压范围:-0.3…VCC+0.3V
3、输出电压范围:-0.3…VCC+0.3V
4、正基准电压:VCC+0.1V
5、负基准电压:-0.1V
6、峰值输入电流:+20mA或-20mA
7、峰值总输入电流:+30mA或-30mA
1.2 目的要求
1.2.1 目的:
通过对单片机最小系统的研究, 掌握单片机各引脚功能,理解单片机工作过程及原理,以及与各种外部扩展器件的连接,能够自己运用单片机来解决实际问题。
1.2.2 任务:
根据单片机最小系统的连接说明图,完成单片机最小系统的焊接以及调试。掌握keil 等单片机相关软件的使用。理解小系统的工作原理,掌握实际运用单片机小系统。
3
2. 系统原理
电路是由电源、复位电路、八段数码管显示电路、按键及LED电路、LCD电路、AD/DA转换电路等部分组成。
2.1 电源
5V电源电路图
2.2 复位及时钟电路
复位及时钟电路图
复位电路由按键复位和上电复位两部分组成。STC89系列单片机为高电平复位,通常在复位引脚RST上连接一个电容到VCC,再连接一个电阻到GND,由此形成一个RC充放电回路保证单片机在上电时RST脚上有足够时间的高电平进行复位,随后回归到低电平进入正常工作状态,这个电阻和电容的典型值为8.2K和10uF。
STC89C52RC使用12MHz的晶体振荡器作为振荡源,由于单片机内部带有振荡电路,所以外部只要连接一个晶振和两个电容即可,电容容量一般在15pF至50pF之间。 4
2.3 八段数码显示管
数码管电路图
电路包含两个共阴8段数码管显示器,使用动态扫描方式驱动。共阴极作为位选有PNP三极管驱动连接ZLG7290的SEG(A…G),八位段选在通过220Ω限流后连接在ZLG7290的Dig(0…7)上。由于数码管是共阴的,所以当驱动信号为1时对应的数码管才点亮。
2.4 液晶显示电路
液晶电路
5
电路采用12864液晶显示器,液晶的D(0…7)数据线连接在单片机的P0口上。RS、WR、LCDEN、RD连接在P1.2、P1.3、P1.4、P1.5上
2.5 按键电路
按键电路图
4个独立按键使用10K电阻上拉后连接到单片机的P3.2-P3.5口。按键没有按下时口线上因为上拉而呈现高电平,当某个按键按下时对应口线会被连接到GND而变成低电平。
另外由于LED的反向截止特性以及按键上拉较弱,P2口及P3.2-P3.5口亦可以兼做通用IO口使用,用来连接外部器件。MCS51 Lite板上也提供了插针方便连接。
2.6 AD/DA转换器
AD/DA转换器电路图
OUTPUT为模拟数据输出引脚,SCLK为读写时钟输入,INPUT是数据输入引脚,DOUT为输入输出引脚。CS为芯片使能。
3. 具体步骤
3.1 先按照说明书的器件规格要求,找到每个位置对应的具体器件,特别是电阻和三极管的大小,单片机等各个芯片的缺口要与板子对应。
6
3.2 按照对应的器件把器件牢固的焊接到板子对应的焊盘上,要注意不要让针脚脱落。
3.3 使用单片机编程软件keil 编写调试所用的程序,比如数码管、AD/DA转换、液晶显示。
3.4 检测完所有模块没有问题就说明单片机最小系统制作完成,然后撰写课程设计报告。
六、 设计总结
单片机最小系统经过我们一段时间的焊接、调试,终于能够达到预定的功能,虽然只是简单的焊接和调试,但从中我们也接触了不少的关于单片机的知识。此次课程设计让我对单片机有了初步的认识,能够了解单片机工作的模式和具体过程,明白了怎样利用单片机来设计满足自己设定功能的作品,怎样利用单片机来控制系统。同时,这也让我了解到怎样进行单片机编程。还有就是通过具体焊接过程掌握了焊接的技巧,锻炼了自己的焊接能力。掌握了这些就可以在大学期间利用单片机最小系统来拓展功能,制作自己想做的东西,对科研立项等活动有很大的帮助作用。
七、 软件设计
/*I2C.h
标准80C51单片机模拟I2C总线的主机程序头文件 Copyright (c) 2005,广州周立功单片机发展有限公司 All rights reserved. 本程序仅供学习参考,不提供任何可靠性方面的担保;请勿用于商业目的*/ #ifndef _I2C_H_
#define _I2C_H_
#include <reg52.h>
//模拟I2C总线的引脚定义
sbit I2C_SCL = P1^1;
sbit I2C_SDA = P1^0;
//定义I2C总线时钟的延时值,要根据实际情况修改,取值1~255
//SCL信号周期约为(I2C_DELAY_VALUE*4+15)个机器周期
#define I2C_DELAY_VALUE 12
//定义I2C总线停止后在下一次开始之前的等待时间,取值1~65535
//等待时间约为(I2C_STOP_WAIT_VALUE*8)个机器周期
//对于多数器件取值为1即可;但对于某些器件来说,较长的延时是必须的 #define I2C_STOP_WAIT_VALUE 120
7
//I2C总线初始化,使总线处于空闲状态
void I2C_Init();
//I2C总线综合发送函数,向从机发送多个字节的数据
bit I2C_Puts
(
);
//I2C总线综合接收函数,从从机接收多个字节的数据
bit I2C_Gets
(
);
#endif //_I2C_H_
/*ZLG7290.h
数码管显示与键盘管理芯片ZLG7290的标准80C51驱动程序头文件 Copyright (c) 2005,广州周立功单片机发展有限公司 All rights reserved. 本程序仅供学习参考,不提供任何可靠性方面的担保;请勿用于商业目的*/ unsigned char SlaveAddr, unsigned int SubAddr, unsigned char SubMod, char *dat, unsigned int Size unsigned char SlaveAddr, unsigned int SubAddr, unsigned char SubMod, char *dat, unsigned int Size #ifndef _ZLG7290_H_
#define _ZLG7290_H_
8
#include <reg52.h>
//ZLG7290中断请求信号的引脚定义 sbit ZLG7290_pinINT = P3^2;
//定义ZLG7290在I2C总线协议中的从机地址 //这是7位纯地址,不含读写位 #define ZLG7290_I2C_ADDR 0x38
//定义ZLG7290内部寄存器地址(子地址) #define ZLG7290_SystemReg #define ZLG7290_Key
0x00 0x01 0x02
//系统寄存器 //键值寄存器 //连击次数寄存器
//功能键寄存器 //命令缓冲区起始地址 //命令缓冲区0 //命令缓冲区1 //闪烁控制寄存器 //扫描位数寄存器 //显示缓存起始地址 //显示缓存0 //显示缓存1 //显示缓存2 //显示缓存3 //显示缓存4 //显示缓存5 //显示缓存6 //显示缓存7
#define ZLG7290_RepeatCnt
#define ZLG7290_FunctionKey #define ZLG7290_CmdBuf #define ZLG7290_CmdBuf0 #define ZLG7290_CmdBuf1 #define ZLG7290_FlashOnOff #define ZLG7290_ScanNum #define ZLG7290_DpRam
0x03 0x07 0x07 0x08 0x0C 0x0D 0x10 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17
#define ZLG7290_DpRam0 #define ZLG7290_DpRam1 #define ZLG7290_DpRam2 #define ZLG7290_DpRam3 #define ZLG7290_DpRam4 #define ZLG7290_DpRam5 #define ZLG7290_DpRam6 #define ZLG7290_DpRam7
//向ZLG7290的某个内部寄存器写入数据
bit ZLG7290_WriteReg(unsigned char RegAddr, char dat); //从ZLG7290的某个内部寄存器读出数据
bit ZLG7290_ReadReg(unsigned char RegAddr, char *dat); //向ZLG7290发送控制命令
9
bit ZLG7290_cmd(char cmd0, char cmd1);
//段寻址,单独点亮或熄灭数码管(或LED)中的某一段
bit ZLG7290_SegOnOff(char seg, bit b);
//下载数据并译码
bit ZLG7290_Download(char addr, bit dp, bit flash, char dat); //闪烁控制指令(Fn应当是字节型)
//Fn的8个位分别控制数码管的8个位是否闪烁,0-不闪烁,1-闪烁 #define ZLG7290_Flash(Fn) ZLG7290_cmd(0x70,(Fn))
#endif //_ZLG7290_H_
#ifndef _TLC5615_H_
#define _TLC5615_H_
#include <reg52.h>
sbit cs = P1^2; //片选
sbit clk = P1^3; //时钟
sbit din = P1^4; //数据入口
//sbit dout = P3^5; //数据出口
extern void DA_Conver(unsigned int DAValue);
extern void delayda();
#endif
#ifndef _TLC1549_H_
#define _TLC1549_H_
sbit AD_CS = P1^7;
sbit AD_DAT = P1^6;
sbit AD_CLK = P1^5;
10
extern void TLC1549();
#endif
/*ZLG7290.c
数码管显示与键盘管理芯片ZLG7290的标准80C51驱动程序C文件 Copyright (c) 2005,广州周立功单片机发展有限公司 All rights reserved. 本程序仅供学习参考,不提供任何可靠性方面的担保;请勿用于商业目的*/ #include "I2C.h"
#include "ZLG7290.h"
/*函数:ZLG7290_WriteReg()
功能:向ZLG7290的某个内部寄存器写入数据
参数:
RegAddr:ZLG7290的内部寄存器地址 dat:要写入的数据
返回:
0:正常 1:访问ZLG7290时出现异常
*/bit ZLG7290_WriteReg(unsigned char RegAddr, char dat)
{
}
/*函数:ZLG7290_ReadReg()
功能:从ZLG7290的某个内部寄存器读出数据
参数:
bit b; b = I2C_Puts(ZLG7290_I2C_ADDR,RegAddr,1,&dat,1); return b; RegAddr:ZLG7290的内部寄存器地址 11
*dat:保存读出的数据
返回:
0:正常 1:访问ZLG7290时出现异常
*/bit ZLG7290_ReadReg(unsigned char RegAddr, char *dat) {
}
/*函数:ZLG7290_cmd()
功能:向ZLG7290发送控制命令
参数:
cmd0:写入CmdBuf0寄存器的命令字(第1字节) cmd1:写入CmdBuf1寄存器的命令字(第2字节) bit b; b = I2C_Gets(ZLG7290_I2C_ADDR,RegAddr,1,dat,1); return b; 返回:
0:正常 1:访问ZLG7290时出现异常
*/bit ZLG7290_cmd(char cmd0, char cmd1)
{
}
/*函数:ZLG7290_SegOnOff()
功能:段寻址,单独点亮或熄灭数码管(或LED)中的某一段 参数:
12 bit b; char buf[2]; buf[0] = cmd0; buf[1] = cmd1; b = I2C_Puts(ZLG7290_I2C_ADDR,ZLG7290_CmdBuf,1,buf,2); return b;
seg:取值0~63,表示数码管(或LED)的段号 b:0表示熄灭,1表示点亮
返回:
0:正常 1:访问ZLG7290时出现异常
说明:
在每一位数码管中,段号顺序按照“a,b,c,d,e,f,g,dp”进行 */bit ZLG7290_SegOnOff(char seg, bit b)
{
}
/*函数:ZLG7290_Download()
功能:下载数据并译码
参数:
addr:取值0~7,显示缓存DpRam0~DpRam7的编号 dp:是否点亮该位的小数点,0-熄灭,1-点亮 flash:控制该位是否闪烁,0-不闪烁,1-闪烁 dat:取值0~31,表示要显示的数据 char cmd; cmd = seg & 0x3F; if ( b ) cmd |= 0x80; return ZLG7290_cmd(0x01,cmd);
返回:
0:正常 1:访问ZLG7290时出现异常
说明:
显示数据具体的译码方式请参见ZLG7290的数据手册 */bit ZLG7290_Download(char addr, bit dp, bit flash, char dat) {
char cmd0; char cmd1; 13
}
/*
*/
cmd0 = addr & 0x0F; cmd0 |= 0x60; cmd1 = dat & 0x1F; if ( dp ) cmd1 |= 0x80; if ( flash ) cmd1 |= 0x40; return ZLG7290_cmd(cmd0,cmd1); I2C.c 标准80C51单片机模拟I2C总线的主机程序 Copyright (c) 2005,广州周立功单片机发展有限公司 All rights reserved. 本程序仅供学习参考,不提供任何可靠性方面的担保;请勿用于商业目的
#include "I2C.h"
//定义延时变量,用于宏I2C_Delay() unsigned char data I2C_Delay_t;
/*
宏定义:I2C_Delay()
功能:延时,模拟I2C总线专用 */
#define I2C_Delay()\
{\
I2C_Delay_t = (I2C_DELAY_VALUE);\ while ( --I2C_Delay_t != 0 );\ 14
}
/*
函数:I2C_Init()
功能:I2C总线初始化,使总线处于空闲状态
说明:在main()函数的开始处,通常应当要执行一次本函数 */
void I2C_Init()
{
}
/*
函数:I2C_Start()
功能:产生I2C总线的起始状态
说明:
*/
void I2C_Start()
{
I2C_SCL = 1; I2C_Delay(); I2C_SDA = 1; I2C_Delay(); SCL处于高电平期间,当SDA出现下降沿时启动I2C总线 不论SDA和SCL处于什么电平状态,本函数总能正确产生起始状态 本函数也可以用来产生重复起始状态 本函数执行后,I2C总线处于忙状态 I2C_SDA = 1; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); 15
I2C_SDA = 0;
I2C_Delay();
I2C_SCL = 0;
I2C_Delay();
}
/*
函数:I2C_Write()
功能:向I2C总线写1个字节的数据 参数:
dat:要写到总线上的数据 */
void I2C_Write(char dat)
{
unsigned char t = 8;
do
{
I2C_SDA = (bit)(dat & 0x80); dat <<= 1;
I2C_SCL = 1;
I2C_Delay();
I2C_SCL = 0;
I2C_Delay();
} while ( --t != 0 );
}
/*
函数:I2C_Read()
功能:从从机读取1个字节的数据 返回:读取的一个字节数据
16
*/
char I2C_Read() {
}
/*
函数:I2C_GetAck() 功能:读取从机应答位 返回:
0:从机应答 1:从机非应答 char dat; unsigned char t = 8; I2C_SDA = 1; //在读取数据之前,要把SDA拉高 do { I2C_SCL = 1; I2C_Delay(); dat <<= 1; if ( I2C_SDA ) dat |= 0x01; I2C_SCL = 0; I2C_Delay(); } while ( --t != 0 ); return dat; 说明:
*/
bit I2C_GetAck() {
17 从机在收到每个字节的数据后,要产生应答位 从机在收到最后1个字节的数据后,一般要产生非应答位
}
/* bit ack; I2C_SDA = 1; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); ack = I2C_SDA; I2C_SCL = 0; I2C_Delay(); return ack;
函数:I2C_PutAck()
功能:主机产生应答位或非应答位
参数:
ack=0:主机产生应答位 ack=1:主机产生非应答位
说明:
主机在接收完每一个字节的数据后,都应当产生应答位 主机在接收完最后一个字节的数据后,应当产生非应答位 */void I2C_PutAck(bit ack)
{
}
18 I2C_SDA = ack; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); I2C_SCL = 0; I2C_Delay();
/*函数:I2C_Stop()
功能:产生I2C总线的停止状态
说明:
SCL处于高电平期间,当SDA出现上升沿时停止I2C总线 不论SDA和SCL处于什么电平状态,本函数总能正确产生停止状态 本函数执行后,I2C总线处于空闲状态
*/void I2C_Stop()
{
}
/*函数:I2C_Puts()
功能:I2C总线综合发送函数,向从机发送多个字节的数据 参数:
SlaveAddr:从机地址(7位纯地址,不含读写位) SubAddr:从机的子地址 SubMod:子地址模式,0-无子地址,1-单字节子地址,2-双字节子地址 *dat:要发送的数据 Size:数据的字节数 unsigned int t = I2C_STOP_WAIT_VALUE; I2C_SDA = 0; I2C_Delay(); I2C_SCL = 1; I2C_Delay(); I2C_SDA = 1; I2C_Delay(); while ( --t != 0 ); //在下一次产生Start之前,要加一定的延时
返回:
0:发送成功 1:在发送过程中出现异常
说明:
19
本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址 当从机没有子地址时,参数SubAddr任意,而SubMod应当为0 */bit I2C_Puts
(
unsigned char SlaveAddr,
unsigned int SubAddr,
unsigned char SubMod,
char *dat,
unsigned int Size
)
{
//定义临时变量
unsigned char i;
char a[3];
//检查长度
if ( Size == 0 ) return 0;
//准备从机地址
a[0] = (SlaveAddr << 1);
//检查子地址模式
if ( SubMod > 2 ) SubMod = 2;
//确定子地址
switch ( SubMod )
{
case 0:
break;
case 1:
a[1] = (char)(SubAddr);
break;
case 2:
a[1] = (char)(SubAddr >> 8);
20
a[2] = (char)(SubAddr); break; default: } break;
//发送从机地址,接着发送子地址(如果有子地址的话) SubMod++;
I2C_Start();
for ( i=0; i<SubMod; i++ )
{
I2C_Write(a[i]);
if ( I2C_GetAck() )
{
I2C_Stop();
return 1;
}
}
//发送数据
do
{
I2C_Write(*dat++);
if ( I2C_GetAck() ) break;
} while ( --Size != 0 );
//发送完毕,停止I2C总线,并返回结果
I2C_Stop();
if ( Size == 0 )
{
return 0;
}
else
21
}
{ } return 1;
/*函数:I2C_Gets()
功能:I2C总线综合接收函数,从从机接收多个字节的数据 参数:
SlaveAddr:从机地址(7位纯地址,不含读写位) SubAddr:从机的子地址 SubMod:子地址模式,0-无子地址,1-单字节子地址,2-双字节子地址 *dat:保存接收到的数据 Size:数据的字节数
返回:
0:接收成功 1:在接收过程中出现异常
说明:
本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址 当从机没有子地址时,参数SubAddr任意,而SubMod应当为0 */bit I2C_Gets
(
)
{
//定义临时变量
unsigned char SlaveAddr, unsigned int SubAddr, unsigned char SubMod, char *dat, unsigned int Size unsigned char i; 22
char a[3];
//检查长度
if ( Size == 0 ) return 0;
//准备从机地址
a[0] = (SlaveAddr << 1);
//检查子地址模式
if ( SubMod > 2 ) SubMod = 2;
//如果是有子地址的从机,则要先发送从机地址和子地址
if ( SubMod != 0 ) { //确定子地址 if ( SubMod == 1 ) { } else { } a[1] = (char)(SubAddr >> 8); a[2] = (char)(SubAddr); a[1] = (char)(SubAddr); //发送从机地址,接着发送子地址 SubMod++; I2C_Start(); for ( i=0; i<SubMod; i++ ) { I2C_Write(a[i]); if ( I2C_GetAck() ) { I2C_Stop(); return 1; 23
} } }
//这里的I2C_Start()对于有子地址的从机是重复起始状态 //对于无子地址的从机则是正常的起始状态
I2C_Start();
//发送从机地址
I2C_Write(a[0]+1);
if ( I2C_GetAck() )
{
I2C_Stop();
return 1;
}
//接收数据
for (;;)
{
*dat++ = I2C_Read();
if ( --Size == 0 )
{
I2C_PutAck(1);
break;
}
I2C_PutAck(0);
}
//接收完毕,停止I2C总线,并返回结果
I2C_Stop();
return 0;
}
24
#include<reg52.h>
#include <intrins.h>
#include "I2C.h"
#include "ZLG7290.h"
#include "tlc5615.h"
#include "tlc1549.h"
#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
#define LCD_data P0
#define CLEAR_SCREEN 0x01 //清屏指令:清屏且AC值为00H
#define AC_INIT 0x02 //将AC设置为00H。且游标移到原点位置
#define CURSE_ADD 0x06 //设定游标移到方向及图像整体移动方向(默认游标右移,图像整体不动)
#define FUN_MODE 0x30 //工作模式:8位基本指令集
#define DISPLAY_ON 0x0c //显示开,显示游标,且游标位置反白
#define DISPLAY_OFF 0x08 //显示关
#define CURSE_DIR 0x14 //游标向右移动:AC=AC+1
#define SET_CG_AC 0x40 //设置AC,范围为:00H~3FH
#define SET_DD_AC 0x80
#define FUN_MODEK 0x36 //扩展指令集,8位指令
#define X1address 0x80 //上半屏X轴起始地址
#define X2address 0x88 //下半屏X轴起始地址
#define Yaddress 0x80 //Y轴起始地址
extern unsigned int AD_Temp;
volatile bit FlagINT = 0;
sbit LCD_RS = P2^4; //寄存器选择输入
sbit LCD_RW = P2^5; //液晶读/写控制
sbit LCD_EN = P2^6;
25
uchar IRDIS[2];
uchar IRCOM[4];
void delay0(uchar x); //x*0.14MS
void dataconv();
void lcd_pos(uchar X,uchar Y);
uchar i=100;
unsigned char KeyValue;
unsigned char RepeatCnt;
unsigned char FnKeyValue;
uchar flat;
uint A1,A2,A3,A4;
uint n;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar idata shuma[8]={0};
uchar datetime[8];
uchar code towday[6]={"今天是"};
uchar code caiyangshuju[13]={"采样的数据是:"};
uchar code nian[2]={"年"};
uchar code yue[2]={"月"};
uchar code ri[2]={"日"};
uchar code shuzi[10]={'0','1','2','3','4','5','6','7','8','9'};
uchar idata nianyueri[4][16];
uchar code photo1[]={
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,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, 26
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,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,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,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,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,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,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,0x00,0x00,0x00, };
uchar code photo2[]={
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, 27
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,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,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,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,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,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,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,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 28
};
/*******************************************************************/ /* */ /*读显示数据到LCD_data */ /*RS=H,RW=H,E=高脉冲,D0-D7=数据。 */ /* */ /*******************************************************************/ unsigned char LcdRdata(void)
{
unsigned char LcdData;
LCD_data=0xff;
LCD_RW=1;
LCD_RS=1;
LCD_EN=1;
delay0(50);
LcdData =LCD_data;
LCD_EN=0;
return (LcdData);
}
void delaym(int ms)
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++) { _nop_(); _nop_(); 29
} _nop_(); _nop_(); } }
void delay(uchar i)
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P0&0x80);
LCD_EN = 0;
return(result);
}
/*******************************************************************/ /* */ /*写指令数据到LCD */ /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */ /* */ /*******************************************************************/ void lcd_wcmd(uchar cmd)
{
30
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
/*******************************************************************/ /* */ /*写显示数据到LCD */ /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */ /* */ /*******************************************************************/ void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
31
/**************************************************************** 函数名称:Display_photo(uchar *hz)显示自定义图形,分上下半屏来写
****************************************************************/
Display_photo1(uchar code *img1) //写上半屏图形数据函数 {
int i,j;
for(i=0;i<32;i++)
{ lcd_wcmd(FUN_MODEK);
delay(1);
lcd_wcmd(Yaddress+i);
一
delay(1);
lcd_wcmd(X1address);
delay(1);
for(j=0;j<8;j++)
{
lcd_wdat(img1[i*16+j*2]);
行,即16*8位数据
lcd_busy();
lcd_wdat(img1[i*16+j*2+1]);
lcd_busy();
}
}
}
Display_photo2(uchar code *img2)
{
int i,j;
for(i=0;i<32;i++)
//上半屏32行 //扩展指令,开绘图显示 //先写垂直地址,即Y地址,不能自动加 //再写水平地址,即X地址 //连续写入2个字节的数据,一共8次,为一 //写下半屏图形数据 //下半屏32行 32
{
lcd_wcmd(Yaddress+i); //先写垂直地址,即Y地址,不能自动加一
delay(1);
lcd_wcmd(X2address); //再写水平地址,即X地址
delay(1);
for(j=0;j<8;j++) //连续写入2个字节的数据,一共8次,为一行,即16*8位数据
{
lcd_wdat(img2[i*16+j*2]);
lcd_busy();
lcd_wdat(img2[i*16+j*2+1]);
lcd_busy();
}
}
}
/****************************************************************/ /*******************************************************************/ /* */ /* LCD初始化设定 */ /* */ /*******************************************************************/ void lcd_init()
{
// LCD_PSB = 1; //并口方式
lcd_wcmd(0x34); //扩充指令操作
33
delaym(5);
lcd_wcmd(0x30); //基本指令操作
delaym(5);
lcd_wcmd(0x0C); //显示开,关光标
delaym(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delaym(5);
}
/*********************************************************/ /*
*/ */ EA = 0; IT0 = 1; //负边沿触发中断 EX0 = 1; EA = 1; //允许外部中断 /* 主程序
/* */ /*********************************************************/ void displayled(uchar dis[4][16])
{
uchar i;
delaym(10); //延时
/* wela=0;
dula=0; */
lcd_init(); //初始化LCD
lcd_pos(0,0); //设置显示位置为第一行的第1个字符 i = 0;
while(dis[0][i] != '\0')
{ //显示字符
lcd_wdat(dis[0][i]);
34
i++;
}
lcd_pos(1,0); //设置显示位置为第二行的第1个字符
i = 0;
while(dis[1][i] != '\0')
{
lcd_wdat(dis[1][i]); //显示字符
i++;
}
lcd_pos(2,0); //设置显示位置为第三行的第1个字符
i = 0;
while(dis[2][i] != '\0')
{
lcd_wdat(dis[2][i]); //显示字符
i++;
}
lcd_pos(3,0); //设置显示位置为第四行的第1个字符
i = 0;
while(dis[3][i] != '\0')
{
lcd_wdat(dis[3][i]); //显示字符
i++;
}
}
void GUI_Point(unsigned char x,unsigned char y,unsigned char color)
{
unsigned char x_Dyte,x_byte; //定义列地址的字节位,及在字节中的哪1位 unsigned char y_Dyte,y_byte; //定义为上下两个屏(取值为0,1),行地址(取值为0~31)
unsigned char GDRAM_hbit,GDRAM_lbit;
35
lcd_wcmd(0x36); //扩展指令命令
/***X,Y坐标互换,即普通的X,Y坐标***/
x_Dyte=y/16; //计算在16个字节中的哪一个
x_byte=y&0x0f; //计算在该字节中的哪一位
y_Dyte=x/32; //0为上半屏,1为下半屏
y_byte=x&0x1f; //计算在0~31当中的哪一行
lcd_wcmd(0x80+y_byte); //设定行地址(y坐标),即是垂直地址
lcd_wcmd(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏,即是水平地址
LcdRdata(); //预读取数据
GDRAM_hbit=LcdRdata(); //读取当前显示高8位数据
GDRAM_lbit=LcdRdata(); //读取当前显示低8位数据
//delay(10);
lcd_wcmd(0x80+y_byte); //设定行地址(y坐标)
lcd_wcmd(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏
//delay(10);
lcd_wcmd(0x08);
if(x_byte<8) //判断其在高8位,还是在低8位
{
if(color==1)
{
lcd_wdat(GDRAM_hbit|(0x01<<(7-x_byte))); //置位GDRAM区高8位数据中相应的点
}
else
lcd_wdat(GDRAM_hbit&(~(0x01<<(7-x_byte)))); //清除GDRAM区高8 36
位数据中相应的点
lcd_wdat(GDRAM_lbit); //显示GDRAM区低8位数据
}
else
{
lcd_wdat(GDRAM_hbit);
if(color==1)
lcd_wdat(GDRAM_lbit|(0x01<<(15-x_byte))); //置位GDRAM区高8位数据中相应的点
else
lcd_wdat(GDRAM_lbit&(~(0x01<<(15-x_byte))));//清除GDRAM区高8位数据中相应的点
}
lcd_wcmd(0x0C);
lcd_wcmd(0x30); //恢复到基本指令集
}
void displaypicture()
{
uchar n,m; lcd_init(); lcd_wcmd(0x01); //清除LCD的显示内容 delay(10); lcd_wcmd(0x0c); Display_photo1(photo1); //显示上半屏数据 Display_photo2(photo2); { for (m=0;m<8;m++) { for(n=0;n<8;n++)
37
} { } { } { } { } GUI_Point(8,m+16*n,1); for(n=0;n<8;n++) for (m=0;m<8;m++) { } GUI_Point(24,m+16*n+8,1); for(n=1;n<16;n++) for (m=0;m<16;m++) { } GUI_Point(8+m,8*n,1); for(n=0;n<8;n++) for (m=0;m<8;m++) { } GUI_Point(56-n,16*m+n,1); for(n=0;n<8;n++) for (m=0;m<8;m++) { } 38 GUI_Point(48+n,16*m+n+8,1);
}
}
/*********************************************************/ /*
*/ */ /* 延时x*0.14ms子程序
/* */ /*********************************************************/
void delay0(uchar x) //x*0.14MS
{
uchar i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
/*********************************************************/ /* */ /* 设定显示位置 */ /* */ /*********************************************************/ void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if (X==0)
{X=0x80;}
else if (X==1)
{X=0x90;}
39
else if (X==2)
{X=0x88;}
else if (X==3)
{X=0x98;}
pos = X+Y ;
lcd_wcmd(pos); //显示地址 }
/*
函数:DispValue()
功能:显示100以内的数值 参数:
*/
void display0()
{
}
void ClearAll()
{
}
40 x:显示位置,取值0~6 dat:要显示的数据,取值0~99 uchar i; for (i=0;i<8;i++) { } ZLG7290_Download(i,0,0,shuma[i]); unsigned char x; for ( x=0; x<8; x++ ) { } ZLG7290_Download(x,0,0,31);
void INT0_SVC() interrupt 0 {
}
jianpan()
{
FlagINT = 1; if ( FlagINT ) { //清除中断标志 //如果有键按下 FlagINT = 0; //读取键值、连击计数器值、功能键值 ZLG7290_ReadReg(ZLG7290_Key,&KeyValue); ZLG7290_ReadReg(ZLG7290_RepeatCnt,&RepeatCnt); ZLG7290_ReadReg(ZLG7290_FunctionKey,&FnKeyValue); switch(KeyValue) { case 0x02:KeyValue=0x00;break; case 0x03:KeyValue=0x01;break; case 0x04:KeyValue=0x02;break; case 0x05:KeyValue=0x03;break; case 0x0A:KeyValue=0x04;break; case 0x0B:KeyValue=0x05;break; case 0x0C:KeyValue=0x06;break; case 0x0D:KeyValue=0x07;break; case 0x12:KeyValue=0x08;break; case 0x13:KeyValue=0x09;break; case 0x14:KeyValue=0x0A;break; case 0x15:KeyValue=0x0B;break; case 0x1A:KeyValue=0x0C;break; case 0x1B:KeyValue=0x0D;break; 41
} } case 0x1C:KeyValue=0x0E;break; case 0x1D:KeyValue=0x0F;break; default :KeyValue=0x00;break; } delay(1);
void save_date(uchar *dre,uchar *date) {
}
void shumaguan()
{
}
void cleardata(uchar dis[4][16]) {
42 uchar n=0; while (n<8) { *dre=*date; } date++; dre++; n++; if(n==-1) { } shuma[n]=KeyValue; ZLG7290_Download(n,0,0,shuma[n]); n--; n=7;
} uchar x,y; for (x=0;x<4;x++) for (y=0;y<16;y++) dis[x][y]='\0';
void main() {
uchar x; ClearAll(); lcd_init(); lcd_wcmd(0x01); //清除LCD的显示内容 delay(10); lcd_wcmd(0x0c); Display_photo1(photo1); //显示上半屏数据 Display_photo2(photo2); n=7; display0(); while(1) { KeyValue=16; jianpan(); switch(KeyValue) { case 0: case 1: case 2: case 3: case 4: case 5: 43
case 6: case 7: case 8: case 9: shumaguan(); break; case 10: save_date(datetime,shuma); break; case 11: TLC1549(); delay(1200); TLC1549(); A1=AD_Temp/1000; A2=AD_Temp%1000; A3=A2%100; A2=A2/100; A4=A3%10; A3=A3/10; cleardata(nianyueri); for (x=0;x<13;x++) nianyueri[0][x]=caiyangshuju[x]; nianyueri[1][0]=shuzi[A1]; nianyueri[1][1]=shuzi[A2]; nianyueri[1][2]=shuzi[A3]; nianyueri[1][3]=shuzi[A4]; displayled(nianyueri); break; case 12: DA_Conver(AD_Temp); 44
break; case 13: cleardata(nianyueri); for (x=0;x<6;x++) nianyueri[0][x]=towday[x]; nianyueri[1][0]=shuzi[datetime[7]]; nianyueri[1][1]=shuzi[datetime[6]]; nianyueri[1][2]=shuzi[datetime[5]]; nianyueri[1][3]=shuzi[datetime[4]]; nianyueri[1][4]=nian[0]; nianyueri[1][5]=nian[1]; nianyueri[2][0]=shuzi[datetime[3]]; nianyueri[2][1]=shuzi[datetime[2]]; nianyueri[2][2]=yue[0]; nianyueri[2][3]=yue[1]; nianyueri[2][4]=shuzi[datetime[1]]; nianyueri[2][5]=shuzi[datetime[0]]; nianyueri[2][6]=yue[0]; nianyueri[2][7]=yue[1]; displayled(nianyueri); break; case 14: displaypicture(); break; case 15: ClearAll(); for (x=0;x<8;x++) { shuma[x]=0; datetime[x]=0; 45
}
} } } n=7; AD_Temp=0; cleardata(nianyueri); lcd_init(); lcd_wcmd(0x01); //清除LCD的显示内容 delay(10); lcd_wcmd(0x0c); Display_photo1(photo1); //显示上半屏数据 Display_photo2(photo2); break; default : break;
#include <reg52.h>
#include "TLC5615.h"
void delayda()
{
int i = 5;
while(i--);
}
//--------------------------------------------------
// 函数名称: DA_Conver
// 函数功能: DA转换
// 入口参数: 要转换的数字量,最多输出参考电压的 46
// 2倍,如可采用MC1403等参考电源
// 出口参数: 无
//--------------------------------------------------
void DA_Conver(unsigned int DAValue)
{
unsigned char i;
DAValue <<= 6;
cs = 0; // 片选DA芯片
clk = 0; // 在以下12个时钟周期内,每当在上升沿的
// 数据被锁存,形成DA输出。在前10个时钟
for(i = 0; i < 12; i++) // 内输入的是10位DA数据,后两个时钟周期
{ // 为填充字节。
din = (bit)(DAValue & 0x8000); //
clk = 1; //
DAValue <<= 1; //
clk = 0;
}
cs = 1; // CS的上升沿和下降沿只有在clk为低的时候
clk = 0; // 才有效
}
#include <reg52.h>
#include <intrins.h>
#include "tlc1549.h"
47
unsigned int AD_Temp,Temp,TempA; unsigned char AD_i;
void TLC1549() //111111 {
TempA=0;
Temp=0;
AD_CS = 1;
AD_CLK = 1;
AD_DAT = 1;
AD_CS = 0;
// DelayMS(10);
_nop_();
for(AD_i=0;AD_i<2;AD_i++) {
AD_CLK =0;
_nop_();
if(AD_DAT)
{ Temp+=0x01;}
Temp =Temp<<1;
AD_CLK=1;
_nop_();
}
for(AD_i=0;AD_i<8;AD_i++) {
AD_CLK =0;
_nop_();
if(AD_DAT)
{ TempA+=0x01; }
TempA =TempA<<1;
48
} AD_CLK =1; _nop_();
AD_CLK =0;
AD_CS =0;
AD_Temp= Temp*256+TempA;
}
6、参考文献
单片机实用技术,清华大学出版社; 单片机KEIL CX51应用开发技术,人民邮电出版社; 单片机C语言,北京航空航天大学出版社;
附录1 材料清单
49
50
51