最新日志

发表于:2008-5-13 23:30:47
标签:无标签

0

USB转串口(CH340)原理图及PCB

点击下载(CH340)原理图及PCB

点击下载CH340,CH341,CH375中文资料

有兴趣的下啊!共同分享!

点击此处查看原文 >>

系统分类: 接口电路   |    用户分类:    |    来源: 原创

评论(0) | 阅读(613)
发表于:2008-5-12 12:51:28
标签:无标签

0

C++ 串行通信控件

点击下载(串行通信控件代码)

在C++ builder中做一个串行通信控件,实现与单片机的串行通信,希望对你有用,共同分享下。

附在C++ builder中生成exe文件并释放后可在没安装C++ builder的电脑上运行方法:

程序编译通过之后,选择Project-->Options  -build Project完成后按照以下步骤进行便可生成可在任意电脑上运行的可执行文件。

打开Project-->Options  
  在Project-Options-Packages里UnCheck掉"Build   with   runtime   packages"。  
  在Project-Options-Linker里UnCheck掉"Use   dynamic   RTL"。  
  在Project-Options-Linker里UnCheck掉"Don't   generate   state   files"。  
  在Project-Options-Compile里按一下"Release"按钮。  
  在Project-Options-CodeGuard里UnCheck掉"CodeGuard"。

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 整理

评论(3) | 阅读(158)
发表于:2008-5-12 12:40:44
标签:无标签

0

超声波测距电路及测试程序

点击下载超声波测距程序

点击下载超声波测距电路

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 原创

评论(0) | 阅读(270)
发表于:2008-4-10 23:53:46
标签:无标签

0

红外脉搏测量电路(附输出波形图)

点击开大图点击开大图点击开大图点击下载

 

自己调试过的一个红外脉搏测量电路,红外型号是TIR2001对管 共同分享下

点击此处查看原文 >>

系统分类: 消费电子   |    用户分类:    |    来源: 原创

评论(2) | 阅读(489)
发表于:2008-3-22 16:18:24
标签:无标签

1

一些电子基础知识

点击下载学过了,温习下

点击此处查看原文 >>

系统分类: 电子制造   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(285)
发表于:2008-3-22 16:14:06
标签:无标签

0

C与汇编混合编程

C51与汇编混合编程详解
来源:全民业务网 作者:不详

C51和汇编混合编程(1)-C语言中嵌入汇编

1、在 C 文件中要嵌入汇编代码片以如下方式加入汇编代码:
#pragma ASM
; Assembler Code Here
#pragma ENDASM

2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”
和“Assemble SRC File”,使检查框由灰色变成黑色(有效)状态;

3、根据选择的编译模式,把相应的库文件(如 Small 模式时,是 Keil\C51\Lib\C51S.Lib)加入工程中, 该文件必须作为工程的最
后文件;

4、编译,即可生成目标代码。

来个实例吧:
#i nclude <reg51.h>
void main(void)
{
P2=1;
#pragma asm
    MOV R7,#10
DEL:MOV R6,#20
    DJNZ R6,$
    DJNZ R7,DEL
#pragma endasm
P2=0;
}

C51和汇编混合编程(2)-无参数传递的函数调用


C51调用汇编函数
1.无参数传递的函数调用
先来个例子:其中example.c和example.a51为项目中的两个文件
***********************example.c***********************************************
extern void delay100();

main()
{delay100;}
***********************example.a51***********************************************
?PR?DELAY100 SEGMENT CODE; //  在程序存储区中定义段
PUBLIC DELAY100;    //声明函数
RSEG ?PR?DELAY100;    //函数可被连接器放置在任何地方

DELAY100:
  MOV R7,#10
DEL:     
  MOV R6,#20
  DJNZ R6,$
  DJNZ R7,DEL
  RET
END

在example.c文件中,先声明外部函数,然后直接在main中调用即可。
在example.a51中,
?PR?DELAY100 SEGMENT CODE;  作用是在程序存储区中定义段,DELAY100为段名,?PR?表示段位于程序存储区内
PUBLIC DELAY100;    作用是声明函数为公共函数
RSEG ?PR?DELAY100;    表示函数可被连接器放置在任何地方,RSEG是段名的属性
段名的开头为PR,是为了和C51内部命名转换兼容,命名转换规律如下:
CODE -?PR?
XDATA-?XD
DATA-?DT
BIT-?BI
PDATA-?PD

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(3) | 阅读(305)
发表于:2007-11-13 17:54:35
标签:无标签

0

CH系列IC免费申请

网址:http://wch.cn/technique/index2.asp

该公司的态度相当的不错,有需要的朋友可以去申请一下

点击此处查看原文 >>

系统分类: 消费电子   |    用户分类: 无分类    |    来源: 原创

评论(2) | 阅读(476)
发表于:2007-11-13 17:50:19
标签:无标签

0

使用PROTEL画PCB板的一般心得

   
               
使用PROTELPCB板的一般心得


一、电路版设计的先期工作

1、利用原理图设计工具绘制原理图,并且生成对应的网络表当然,有些特殊情况下,如电路版比较简单,已经有了网络表等情况下也可以不进行原理图的设计,直接进入PCB设计系统,在PCB设计系统中,可以直接取用零件封装,人工生成网络表

2、手工更改网络表 将一些元件的固定用脚等原理图上没有的焊盘定义到与它相通的网络上,没任何物理连接的可定义到地或保护地等将一些原理图和PCB封装库中引脚名称不一致的器件引脚名称改成和PCB封装库中的一致,特别是二、三极管等

二、画出自己定义的非标准器件的封装库

建议将自己所画的器件都放入一个自己建立的PCB 库专用设计文件

柚肞CB设计环境和绘制印刷电路的版框含中间的镂空等

1、进入PCB系统后的第一步就是设置PCB设计环境,包括设置格点大小和类型,光标类型,版层参数,布线参数等等大多数参数都可以用系统默认值,而且这些参数经过设置之后,符合个人的习惯,以后无须再去修改

2、规划电路版,主要是确定电路版的边框,包括电路版的尺寸大小等等在需要放置固定孔的地方放上适当大小的焊盘对于3mm 的螺丝可用6.5~8mm 的外径和3.2~3.5mm 内径的焊盘对于标准板可从其它板或PCB izard 中调入

注意:在绘制电路版地边框前,一定要将当前层设置成Keep Out层,即禁止布线层

四、打开所有要用到的PCB 库文件后,调入网络表文件和修改零件封装

这一步是非常重要的一个环节,网络表是PCB自动布线的灵魂,也是原理图设计与印象电路版设计的接口,只有将网络表装入后,才能进行电路版的布线

在原理图设计的过程中,ERC检查不会涉及到零件的封装问题因此,原理图设计时,零件的封装可能被遗忘,在引进网络表时可以根据设计情况来修改或补充零件的封装

当然,可以直接在PCB内人工生成网络表,并且指定零件封装

五、布置零件封装的位置,也称零件布局

Protel99可以进行自动布局,也可以进行手动布局如果进行自动布局,运行"Tools"下面的"Auto Place",用这个命令,你需要有足够的耐心布线的关键是布局,多数设计者采用手动布局的形式用鼠标选中一个元件,按住鼠标左键不放,拖住这个元件到达目的地,放开左键,将该元件固定Protel99在布局方面新增加了一些技巧新的交互式布局选项包含自动选择和自动对齐使用自动选择方式可以很快地收集相似封装的元件,然后旋转、展开和整理成组,就可以移动到板上所需位置上了当简易的布局完成后,使用自动对齐方式整齐地展开或缩紧一组封装相似的元件

提示:在自动选择时,使用Shift+XYCtrl+XY可展开和缩紧选定组件的XY方向

注意:零件布局,应当从机械结构散热、电磁干扰、将来布线的方便性等方面综合考虑先布置与机械尺寸有关的器件,并锁定这些器件,然后是大的占位置的器件和电路的核心元件,再是外围的小元件

六、根据情况再作适当调整然后将全部器件锁定

假如板上空间允许则可在板上放上一些类似于实验板的布线区对于大板子,应在中间多加固定螺丝孔板上有重的器件或较大的接插件等受力器件边上也应加固定螺丝孔,有需要的话可在适当位置放上一些测试用焊盘,最好在原理图中就加上将过小的焊盘过孔改大,将所有固定螺丝孔焊盘的网络定义到地或保护地等

放好后用VIEW3D 功能察看一下实际效果,存盘

七、布线规则设置

布线规则是设置布线的各个规范(象使用层面、各组线宽、过孔间距、布线的拓朴结构等部分规则,可通过Design-Rules Menu 处从其它板导出后,再导入这块板)这个步骤不必每次都要设置,按个人的习惯,设定一次就可以

Design-Rules 一般需要重新设置以下几点:

1、安全间距(Routing标签的Clearance Constraint)

它规定了板上不同网络的走线焊盘过孔等之间必须保持的距离一般板子可设为0.254mm,较空的板子可设为0.3mm,较密的贴片板子可设为0.2-0.22mm,极少数印板加工厂家的生产能力在0.1-0.15mm,假如能征得他们同意你就能设成此值0.1mm 以下是绝对禁止的

2、走线层面和方向(Routing标签的Routing Layers

此处可设置使用的走线层和每层的主要走线方向请注意贴片的单面板只用顶层,直插型的单面板只用底层,但是多层板的电源层不是在这里设置的(可以在Design-Layer Stack Manager中,点顶层或底层后,用Add Plane 添加,用鼠标左键双击后设置,点中本层后用Delete 删除),机械层也不是在这里设置的(可以在Design-Mechanical Layer 中选择所要用到的机械层,并选择是否可视和是否同时在单层显示模式下显示)

机械层1 一般用于画板子的边框;
   机械层3 一般用于画板子上的挡条等机械结构件;
   机械层4 一般用于画标尺和注释等,具体可自己用PCB Wizard 中导出一个PCAT结构的板子看一下

3、过孔形状(Routing标签的Routing Via Style

它规定了手工和自动布线时自动产生的过孔的内、外径,均分为最小、最大和首选值,其中首选值是最重要的,下同

4、走线线宽(Routing标签的Width Constraint

它规定了手工和自动布线时走线的宽度整个板范围的首选项一般取0.2-0.6mm,另添加一些网络或网络组(Net Class)的线宽设置,如地线、+5 伏电源线、交流电源输入线、功率输出线和电源组等网络组可以事先在Design-Netlist Manager中定义好,地线一般可选1mm 宽度,各种电源线一般可选0.5-1mm 宽度,印板上线宽和电流的关系大约是每毫米线宽允许通过1安培的电流,具体可参看有关资料当线径首选值太大使得SMD 焊盘在自动布线无法走通时,它会在进入到SMD 焊盘处自动缩小成最小宽度和焊盘的宽度之间的一段走线,其中Board 为对整个板的线宽约束,它的优先级最低,即布线时首先满足网络和网络组等的线宽约束条件

5、敷铜连接形状的设置(Manufacturing标签的Polygon Connect Style

建议用Relief Connect 方式导线宽度Conductor Width 0.3-0.5mm 4 根导线45 90

其余各项一般可用它原先的缺省值,而象布线的拓朴结构、电源层的间距和连接形状匹配的网络长度等项可根据需要设置

Tools-Preferences,其中Options 栏的Interactive Routing 处选Push Obstacle (遇到不同网络的走线时推挤其它的走线,Ignore Obstacle为穿过,Avoid Obstacle 为拦断)模式并选中Automatically Remove (自动删除多余的走线)Defaults 栏的Track Via 等也可改一下,一般不必去动它们

在不希望有走线的区域内放置FILL 填充层,如散热器和卧放的两脚晶振下方所在布线层,要上锡的在Top Bottom Solder 相应处放FILL

布线规则设置也是印刷电路版设计的关键之一,需要丰富的实践经验

八、自动布线和手工调整

1、点击菜单命令Auto Route/Setup 对自动布线功能进行设置

选中除了Add Testpoints 以外的所有项,特别是选中其中的Lock All Pre-Route 选项,Routing Grid 可选1mil 自动布线开始前PROTEL 会给你一个推荐值可不去理它或改为它的推荐值,此值越小板越容易100%布通,但布线难度和所花时间越大

2、点击菜单命令Auto Route/All 开始自动布线

假如不能完全布通则可手工继续完成或UNDO 一次(千万不要用撤消全部布线功能,它会删除所有的预布线和自由焊盘、过孔)后调整一下布局或布线规则,再重新布线完成后做一次DRC,有错则改正布局和布线过程中,若发现原理图有错则应及时更新原理图和网络表,手工更改网络表(同第一步),并重装网络表后再布

3、对布线进行手工初步调整

需加粗的地线、电源线、功率输出线等加粗,某几根绕得太多的线重布一下,消除部分不必要的过孔,再次用VIEW3D 功能察看实际效果手工调整中可选Tools-Density Map 查看布线密度,红色为最密,黄色次之,绿色为较松,看完后可按键盘上的End 键刷新屏幕红色部分一般应将走线调整得松一些,直到变成黄色或绿色

九、切换到单层显示模式下(点击菜单命令Tools/Preferences,选中对话框中Display栏的Single Layer Mode

将每个布线层的线拉整齐和美观手工调整时应经常做DRC,因为有时候有些线会断开而你可能会从它断开处中间走上好几根线,快完成时可将每个布线层单独打印出来,以方便改线时参考,其间也要经常用3D显示和密度图功能查看

最后取消单层显示模式,存盘

十、如果器件需要重新标注可点击菜单命令Tools/Re-Annotate 并选择好方向后,按OK

并回原理图中选Tools-Back Annotate 并选择好新生成的那个*.WAS 文件后,按OK 原理图中有些标号应重新拖放以求美观,全部调完并DRC 通过后,拖放所有丝印层的字符到合适位置

注意字符尽量不要放在元件下面或过孔焊盘上面对于过大的字符可适当缩小,DrillDrawing 层可按需放上一些坐标(Place-Coordinate)和尺寸((Place-Dimension

最后再放上印板名称、设计版本号、公司名称、文件首次加工日期、印板文件名、文件加工编号等信息(请参见第五步图中所示)并可用第三方提供的程序来加上图形和中文注释如BMP2PCB.EXE 和宏势公司ROTEL99 PROTEL99SE 专用PCB 汉字输入程序包中的FONT.EXE

十一、对所有过孔和焊盘补泪滴

补泪滴可增加它们的牢度,但会使板上的线变得较难看顺序按下键盘的S A 键(全选),再选择Tools-Teardrops,选中General 栏的前三个,并选Add Track 模式,如果你不需要把最终文件转为PROTEL DOS 版格式文件的话也可用其它模式,后按OK 完成后顺序按下键盘的X A 键(全部不选中)对于贴片和单面板一定要加

十二、放置覆铜区

将设计规则里的安全间距暂时改为0.5-1mm 并清除错误标记,选Place-Polygon Plane 在各布线层放置地线网络的覆铜(尽量用八角形,而不是用圆弧来包裹焊盘最终要转成DOS 格式文件的话,一定要选择用八角形)下图即为一个在顶层放置覆铜的设置举例:

设置完成后,再按OK 扭,画出需覆铜区域的边框,最后一条边可不画,直接按鼠标右键就可开始覆铜它缺省认为你的起点和终点之间始终用一条直线相连,电路频率较高时可选Grid Size Track Width 大,覆出网格线

相应放置其余几个布线层的覆铜,观察某一层上较大面积没有覆铜的地方,在其它层有覆铜处放一个过孔,双击覆铜区域内任一点并选择一个覆铜后,直接点OK,再点Yes 便可更新这个覆铜几个覆铜多次反复几次直到每个覆铜层都较满为止将设计规则里的安全间距改回原值

十三、最后再做一次DRC

选择其中Clearance Constraints Max/Min Width Constraints Short Circuit Constraints Un-Routed Nets Constraints 这几项,按Run DRC 钮,有错则改正全部正确后存盘

十四、对于支持PROTEL99SE 格式(PCB4.0)加工的厂家可在观看文档目录情况下,将这个文件导出为一个*.PCB 文件;对于支持PROTEL99 格式(PCB3.0)加工的厂家,可将文件另存为PCB 3.0 二进制文件,做DRC通过后不存盘退出在观看文档目录情况下,将这个文件导出为一个*.PCB 文件由于目前很大一部分厂家只能做DOS 下的PROTEL AUTOTRAX 画的板子,所以以下这几步是产生一个DOS PCB 文件必不可少的:

1、将所有机械层内容改到机械层1,在观看文档目录情况下,将网络表导出为*.NET 文件,在打开本PCB 文件观看的情况下,将PCB 导出为PROTEL PCB 2.8 ASCII FILE 格式的*.PCB 文件

2 、用PROTEL FOR WINDOWS PCB 2.8 打开PCB 文件,选择文件菜单中的另存为,并选择Autotrax 格式存成一个DOS 下可打开的文件

3、用DOS 下的PROTEL AUTOTRAX 打开这个文件个别字符串可能要重新拖放或调整大小上下放的全部两脚贴片元件可能会产生焊盘X-Y大小互换的情况,一个一个调整它们大的四列贴片IC 也会全部焊盘X-Y 互换,只能自动调整一半后,手工一个一个改,请随时存盘,这个过程中很容易产生人为错误PROTEL DOS 版可是没有UNDO 功能的假如你先前布了覆铜并选择了用圆弧来包裹焊盘,那么现在所有的网络基本上都已相连了,手工一个一个删除和修改这些圆弧是非常累的,所以前面推荐大家一定要用八角形来包裹焊盘这些都完成后,用前面导出的网络表作DRC Route 中的Separation Setup ,各项值应比WINDOWS 版下小一些,有错则改正,直到DRC 全部通过为止

也可直接生成GERBER 和钻孔文件交给厂家选File-CAM Manager Next>钮出来六个选项,Bom 为元器件清单表,DRC 为设计规则检查报告,Gerber 为光绘文件,NC Drill 为钻孔文件,Pick Place 为自动拾放文件,Test Points 为测试点报告选择Gerber 后按提示一步步往下做其中有些与生产工艺能力有关的参数需印板生产厂家提供直到按下Finish 为止在生成的Gerber Output 1 上按鼠标右键,选Insert NC Drill 加入钻孔文件,再按鼠标右键选Generate CAM Files 生成真正的输出文件,光绘文件可导出后用CAM350 打开并校验注意电源层是负片输出的

十五、发Email 或拷盘给加工厂家,注明板材料和厚度(做一般板子时,厚度为1.6mm,特大型板可用2mm,射频用微带板等一般在0.8-1mm 左右,并应该给出板子的介电常数等指标)、数量、加工时需特别注意之处等Email发出后两小时内打电话给厂家确认收到与否

十六、产生BOM 文件并导出后编辑成符合公司内部规定的格式

十七、将边框螺丝孔接插件等与机箱机械加工有关的部分(即先把其它不相关的部分选中后删除),导出为公制尺寸的AutoCAD R14 DWG 格式文件给机械设计人员

二十一、整理和打印各种文档如元器件清单、器件装配图(并应注上打印比例)、安装和接线说明等

点击此处查看原文 >>

系统分类: PCB   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(1289)
发表于:2007-8-11 21:33:20
标签:无标签

1

12864(CVAVR程序)

#include<mega16.h>
#include<delay.h>

#define uchar unsigned char

#define DB PORTB
#define RS PORTD.5
#define RW PORTD.6
#define E  PORTD.7

uchar check_busy(void);     
void Write_Command(uchar cmd);//写命令   
void Write_Data(uchar datacode);//写数据 
void Initial_LCD();  //初始化 
void Location_XY(uchar x,uchar y);//设置光标位置   
void Write_String(uchar *asc);  //写字符串
void Write_String_atXY(uchar x,uchar y,uchar string[]);//在(x,y)处写字符串

uchar str1[]="欢迎光临";
uchar str2[]="知己相惜";
uchar str3[]="携手共度";
uchar str4[]="GOOD LUCK";

void main()
{
  Initial_LCD();
  while(1)
  {
    Write_String_atXY(1,0,str1);
    delay_ms(100);
    Write_String_atXY(2,1,str2);
    delay_ms(100);
    Write_String_atXY(3,2,str3);
    delay_ms(100);
    Write_String_atXY(3,3,str4);
    delay_ms(100);
    Write_Command(0x01);
    delay_ms(100);
  }
}

/**************************************************************
功能:检查是否LCD忙碌
***************************************************************/
uchar check_busy(void)
{
    char r;
    DDRB = 0x00;       //端口B设为输入方式
    E="0";RS=0;RW=1;     //E=0(致能),RS=0(命令),RW=1(读)
    delay_us(2);       //液晶延时子程序
    E="1";
    delay_us(2);       //液晶延时子程序
    r = PINB & 0x80;   //读取lcd_data第八位
    E="0";
    DDRB="0xff";         //端口B设为输出方式
    return r;          //读取结果返回
}


/****************************************************************
功能:写命令到LCM
参数:cmdcode是要写入的命令
****************************************************************/
void Write_Command(uchar cmdcode)
{
  while(check_busy());
  RS="0";
  RW="0";
  E="0";
  delay_us(1);delay_us(1);
  E="1";
  DB="cmdcode";
  delay_us(1);delay_us(1);delay_us(1);
  E="0";
}

/****************************************************************
功能:写数据到LCM
参数:datacode是要写入的数据
****************************************************************/
void Write_Data(uchar datacode)
{
  while(check_busy());
  RS="1";
  RW="0";
  E="0";
  delay_us(1);delay_us(1);
  E="1";
  DB="datacode";
  delay_us(1);delay_us(1);delay_us(1);
  E="0";
}

/****************************************************************
功能:初始化LCD
****************************************************************/
void Initial_LCD(void)
{   
    DDRB = 0xff;       //端口B设为输出方式
    DDRD = 0xff;       //端口D设为输出方式
    Write_Command(0x38); //
    Write_Command(0x38); //
    Write_Command(0x38); //
    Write_Command(0x38); //
    Write_Command(0x08); //令显示器off
    Write_Command(0x01); //清除显示器
    Write_Command(0x06); //令LCD每接收到1Byte数据后,AC自动加1
    Write_Command(0x0C); //令光标,0x0c=不显示,0x0d=显示闪动.
}

/****************************************************************
功能:写一串字符到LCM
参数:datacode是要写入的数据
****************************************************************/
void Write_String(unsigned char *asc)
{
  while((*asc) != 0)   //判断字是否结束
    {
        Write_Data(*asc); //向lcd写入字符串
        asc++;           //移下一个字符
    }
}

/*==============设置坐标====================*/
void Location_XY(uchar x,uchar y)
{
  switch(y)
  {
    case 0:
      y="0x80";break;
    case 1:
      y="0x90";break;
    case 2:
     y="0x88";break;
    case 3:
      y="0x98";break;
    default:
      y="0x80";
  }
  x="x"&0x07;
  Write_Command(x+y);
}

/***********************************************************************
功能:在(x,y)处显示字符串string
************************************************************************/
void Write_String_atXY(uchar x,uchar y,uchar string[])
{
  Location_XY(x,y);
  Write_String(string);
}

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 原创

评论(0) | 阅读(895)
发表于:2007-8-11 17:28:48
标签:无标签

0

24C256/51单片机

#include "24c02.h" sbit SDA="P1"^3;                            //I2C总线数据

sbit SCL="P1"^2;                            //I2C总线时钟

void delay(void)      //延时子程序

{

 unsigned char i;

 for(i=0;i<1;i++);

}

//**************************************   将一个字节保存到EEROM   *****************************************

unsigned char Write_a_EEPROM_data(unsigned char device_addr,unsigned char data_addr,unsigned char w_data)

{

 unsigned char i,Device_Addr;

 //if(NO_2401)return 0xFF;

 delay();

 SDA=0;                          //产生一个起始位    

 delay();

 Device_Addr=device_addr;        //EEROM的地址暂存

 for(i=0;i<7;i++)                //输出设备地址

  {

   SCL=0;

   delay();

   SDA=device_addr&0x80;         //SDA上输出一位数据,高位在前

   device_addr<<=1;

   delay();

   SCL=1;

   delay();

  }

 SCL=0;

 delay();

 SDA=0;                          //SDA上输出0,表示写操作

 delay();

 SCL=1;

 delay();

 SCL=0;

 delay();

 SDA=1;                          //释放SDA线

 delay();

 SCL=1;

 delay();

 if(SDA){return 1;}               //如果设备未响应,则返回出错代码1

 for(i=0;i<8;i++)                //输出数据地址

  {

   SCL=0;

   delay();

   SDA=data_addr&0x80;           //SDA上输出一位数据,高位在前

   data_addr<<=1;      

   delay();

   SCL=1;

   delay();

   delay();

  } 

 SCL=0;

 delay();

 SDA=1;                          //释放SDA线

 delay();

 SCL=1;

 delay();

 if(SDA){return 2;}             //如果设备未响应,则返回出错代码2

 for(i=0;i<8;i++)                //输出要写入的数据

  {

   SCL=0;

   delay();

   SDA=w_data&0x80;               //SDA上输出一位数据,高位在前

   w_data<<=1;

   delay();

   SCL=1;

   delay();

  } 

 SCL=0;

 delay();

 SDA=1;                          //释放SDA线

 delay();

 SCL=1;

 delay();

 if(SDA){return 3;}               //如果设备未响应,则返回出错代码3

 SCL=0;

 delay();

 SDA=0;

 delay();

 SCL=1;

 delay();

 SDA=1;                         //产生一个停止位,停止操作

 for(i=0;i<250;i++)             //等待数据写入

  {

   delay();

  }

 for(i=0;i<250;i++)delay();