51单片机模拟spi串行接口程序
基于SPI总线的51单片机多机互连编程技术

关 键 词 :单 片 机 ; UART; P SI 中 图分 类 号 :TP 1 34 文 献 标 识 码 :A
Co mu c ton Pr r m m ig Tec n q e Be we u t M CU s n SPI m n a i og a n h i u t en M li — Ba ed o 鲞
图 1 S 工 作 方 式 PI
图 1中 , M0S ( se ta d Sa e n I Ma tr0u n lv rI )和 MI 0 S
L a g , a j n i n ' P nQi z Qi u
( 1. Sc olo m put rSce c ho fCo e i n e,Sha gu n U nie st o a v r iy,Sha gu n 51 0 o a 2 00, i a; Ch n
2 Op ia a i g Me s r n n r l c n q eI s i t fS a g a ) . t l c Gr t a u e a d Co to n Te h i u n t u e o h o u n t
mu ia in i t r a e ,a d i i p r iu a l o i h s e d c mm u ia in b t e CU. tt e wo k mo e i v r i e e tfo t e nc t efc o n n t s a t lry f rh g — p e o c n c to e we n M Bu h r d s e y d f r n r m h f
串行 接 口, 而且 还 有 S IIC 总线 等 串行 接 口 。S I 口是 一 种 高速 串行 通 信 接 口, 别 适 合 于 单 片机 之 间 的 高速 通 信 , P、 P接 特 但 其 工作 方 式较 之 传 统 的 UAR 串行 通 信 方 式 有 很 大 的 不 同 。本 文 给 出 S I 口基 础 上 的 各 种 串行 通 信 工 作 方 式 配 T P接
单片机模拟SPI程序

单片机模拟SPI程序单片机模拟SPI程序分类: C/C++IO口模拟SPI通信C51程序 /************************** 文件所用资源1.端口:P0.4,P0.5,P0.6,P0.72.调用delay_ms函数**************************//*************************模拟SPI接口I/O定义*************************/sbit spi_cs=P0^1;sbit spi_di=P0^2;sbit spi_clk=P0^3;sbit spi_do=P0^4;/*******************************向SPI器件写入一个字节数据*******************************/void spi_write(unsigned char spi_dat){unsigned char i;spi_cs=0;for (i=0;i<8;i++){spi_clk=0;if((spi_dat & 0x80)==0x80)spi_di=1;else spi_di=0;spi_clk=1;spi_dat=(spi_dat<<1);}spi_cs=1;}/******************************** 从SPI器件读出一个字节数据********************************/ unsigned char spi_read(){unsigned char i,spi_dat;spi_cs=0;for (i=0;i<8;i++){spi_clk=0;spi_dat=(spi_dat<<1);spi_clk=1;if(spi_do==1)spi_dat|=0x01; else spi_dat&=~0x01;}spi_cs=1;return spi_dat;}其实光模拟来说,就时序问题,读取和写入一个字节的时序。
51单片机模拟spi串行接口程序

51 单片机模拟spi 串行接口程序51 单片机模拟spi 串行接口程序,在keilc51 下编写sbit CS=P3A5;sbit CLK= P"5;sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val){unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // write if(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val){unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // write if(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5; sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // writeif(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit DataI=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPI_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // writeif(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // writeif(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;DataI=0; // write if(val&0x80) DataI=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;Datal=0; // writeif(val&0x80) Datal=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;Datal=0; // writeif(val&0x80) Datal=1;val<<=1;CLK=1;if(DataO)val|=1; // readCLK=0;return val;}sbit CLK= P1A5;sbit Datal=P1A7;sbit DataO=P1A6;#define SD_Disable() CS=1 // 片选关#define SD_Enable() CS=0 // 片选开unsigned char SPl_TransferByte(unsigned char val) { unsigned char BitCounter;for(BitCounter=8; BiCounter!=0; BitCounter--){ CLK=0;Datal=0; // writeif(val&0x80) Datal=1;val<<=1;CLK=1;if(DataO)val|=1; // read}CLK=0;return val;。
单片机开发 SPI串行外设接口实验(1)

本讲主要内容
1.SPI介绍 2.SPI配置步骤 3.硬件设计 4.软件设计
1.SPI介绍
1.1 SPI简介 SPI的全称是"Serial Peripheral Interface",意为串行外围接
口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主 要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处 理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的 通信总线,并且在芯片的管脚上只占用四根线。
// Initialize SPI FIFO registers SpiaRegs.SPIFFTX.all=0xE040;//使能 FIFO,清除发送中断 SpiaRegs.SPIFFRX.all=0x204f;//使能 FIFO 接收 16 级深度 SpiaRegs.SPIFFCT.all=0x0;//清除 FIFO 计数器 SpiaRegs.SPICCR.all =0x000F;//复位 SPI,上升沿发送,下降沿 接收,16位数据 SpiaRegs.SPICTL.all =0x0006;// 无相位延时,主模式 SpiaRegs.SPIBRR =0x007F;//确定 SPICLK SpiaRegs.SPICCR.all =0x009F;//自测模式并从复位状态释放 SpiaRegs.SPIPRI.bit.FREE = 1;//自由运行
3.硬件设计
本实验使用到硬件资源如下: (1)D1 指示灯 (2)RS232 模块 (3)SPI
4.软件设计
本章所要实现的功能是:使用 SPI 实现数据的自发自收,通过串 口将收发的数据输出显示,并且 D1 指示灯闪烁,指示系统运行状 态。程序框架如下: (1)初始化 SPI 相关参数,开启 SPI 自测功能 (2)编写 SPI 收发函数 (3)编写主函数
SPI总线在51系列单片机系统中的实现(一)

SPI总线在51系列单片机系统中的实现(一)摘要:MCS51系列、MCS96系列等单片机由于都不带SPI串行总线接口而限制了其在SPI总线接口器件的使用。
文中介绍了SPI串行总线的特征和时序,并以串行E2PROM为例,给出了在51系列单片机上利用I/O口线实现SPI串行总线接口的方法和软件设计程序。
关键词:单片机SPI串行总线总线接口1引言SPI(SerialPeripheralInterface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。
外围设置FLASHRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。
SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOST和低电平有效的从机选择线SS(有的SPI接口芯片带有中断信号线INT或INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。
由于SPI系统总线一共只需3~4位数据线和控制即可实现与具有SPI总线接口功能的各种I/O器件进行接口,而扩展并行总线则需要8根数据线、8~16位地址线、2~3位控制线,因此,采用SPI总线接口可以简化电路设计,节省很多常规电路中的接口器件和I/O口线,提高设计的可靠性。
由此可见,在MCS51系列等不具有SPI接口的单片机组成的智能仪器和工业测控系统中,当传输速度要求不是太高时,使用SPI总线可以增加应用系统接口器件的种类,提高应用系统的性能。
2SPI总线的组成利用SPI总线可在软件的控制下构成各种系统。
如1个主MCU和几个从MCU、几个从MCU相互连接构成多主机系统(分布式系统)、1个主MCU和1个或几个从I/O设备所构成的各种系统等。
在大多数应用场合,可使用1个MCU作为控机来控制数据,并向1个或几个从外围器件传送该数据。
51模拟SPI接口[1]
![51模拟SPI接口[1]](https://img.taocdn.com/s3/m/e5b5a8393968011ca3009195.png)
51模拟SPI接口在MCS51系列单片机中的实现方法对于不带SPI串行总线接口的MCS51系列单片机来说,可以使用软件来模拟SPI的操作,包括串行时钟、数据输入和数据输出。
对于不同的串行接口外围芯片,它们的时钟时序是不同的。
对于在SCK的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件,一般应将其串行时钟输出口P1.1的初始状态设置为1,而在允许接口后再置P1.1为0。
这样,MCU 在输出1位SCK时钟的同时,将使接口芯片串行左移,从而输出1位数据至MCS51单片机的P1.3口(模拟MCU的MISO线),此后再置P1.1为1,使MCS51系列单片机从P1.0(模拟MCU的MOSI线)输出1位数据(先为高位)至串行接口芯片。
至此,模拟1位数据输入输出便宣告完成。
此后再置P1.1为0,模拟下1位数据的输入输出……,依此循环8次,即可完成1次通过SPI总线传输8位数据的操作。
对于在SCK的下降沿输入数据和上升沿输出数据的器件,则应取串行时钟输出的初始状态为0,即在接口芯片允许时,先置P1.1为1,以便外围接口芯片输出1位数据(MCU接收1位数据),之后再置时钟为0,使外围接口芯片接收1位数据(MCU发送1位数据),从而完成1位数据的传送。
图2所示为MCS51系列单片机与存储器X25F008(E2PROM)的硬件连接图,有关X25F008的详细资料可参考有关文献〔1〕。
图2中,P1.0模拟MCU的数据输出端(MOSI),P1.1模拟SPI的SCK输出端,P1.2模拟SPI的从机选择端,P1.3模拟SPI的数据输入端(MISO)。
下面介绍用MCS51单片机的汇编语言模拟SPI串行输入、串行输出和串行输入/输出的3个子程序。
实际上,这些子程序也适用于在串行时钟的上升沿输入和下降沿输出的其它各种串行外围接口芯片(如A/D转换芯片、网络控制器芯片、LED显示驱动芯片等)。
对于下降沿输入、上升沿输出的各种串行外围接口芯片,只要改变P1.1的输出电平顺序,即先置P1.1为低电平,之后再次置P1.1为高电平,再置P1.1为低电平……,则这些子程序也同样适用。
51单片机教程:单片机串行口通信程序设计

51单片机教程:单片机串行口通信程序设计1.串行口方式0应用编程 8051单片机串行口方式0为移位寄存器方式,外接一个串入并出的移位寄存器,就能扩展一个并行口。
单片机串行口通信程序设计硬件连接图例:用8051单片机串行口外接CD4094扩展8位并行输出口,如图所示,8位并行口的各位都接一个发光二极管,要求发光管呈流水灯状态。
串行口方式0的数据传送可采用中断方式,也可采用查询方式,无论哪种方式,都要借助于TI或RI标志。
串行发送时,能靠TI置位(发完一帧数据后)引起中断申请,在中断服务程序中发送下一帧数据,或者通过查询TI的状态,只要TI为0就继续查询,TI为1就结束查询,发送下一帧数据。
在串行接收时,则由RI引起中断或对RI查询来确定何时接收下一帧数据。
无论采用什么方式,在开始通信之前,都要先对控制寄存器SCON进行初始化。
在方式0中将,将00H送SCON就能了。
单片机串行口通信程序设计列子ORG 2000HSTART: MOV SCON,#00H ;置串行口工作方式0MOV A,#80H ;最高位灯先亮CLR P1.0 ;关闭并行输出(避象传输过程中,各LED的暗红现象) OUT0: MOV SBUF,A ;开始串行输出OUT1: JNB TI,OUT1 ;输出完否CLR TI ;完了,清TI标志,以备下次发送SETB P1.0 ;打开并行口输出ACALL DELAY ;延时一段时间RR A ;循环右移CLR P1.0 ;关闭并行输出JMP OUT0 ;循环说明:DELAY延时子程序能用前面我们讲P1口流水灯时用的延时子程序,这里就不给出了。
二、串行口异步通信org 0000HAJMP STARTORG 30HSTART:mov SP,#5fh ;mov TMOD,#20h ;T1: 工作模式2mov PCON,#80h ;SMOD=1mov TH1,#0FDH ;初始化波特率(参见表)mov SCON,#50h ;Standard UART settingsMOV R0,#0AAH ;准备送出的数SETB REN ;允许接收SETB TR1 ;T1开始工作WAIT:MOV A,R0CPL AMOV R0,AMOV SBUF,ALCALL DELAYJBC TI,WAIT1 ;如果TI等于1,则清TI并转WAIT1AJMP WAITWAIT1: JBC RI,READ ;如果RI等于1,则清RI并转READAJMP WAIT1READ:MOV A,SBUF ;将取得的数送P1口MOV P1,ALJMP WAITDELAY: ;延时子程序MOV R7,#0ffHDJNZ R7,$RETEND将程序编译通过,写入芯片,插入实验板,用通读电缆将实验板与主机的串行口相连就能实验了。
51单片机模拟串口通讯

论坛新老朋友们。
祝大家新年快乐。
在新的一年开始的时候,给大家一点小小的玩意。
工程师经常碰到需要多个串口通信的时候,而低端单片机大多只有一个串行口,甚至没有串口。
这时候无论是选择高端芯片,还是更改系统设计都是比较麻烦的事。
我把以前搞的用普通I/O口模拟串行口通讯的程序拿出来,供大家参考,希望各位兄弟轻点拍砖。
基本原理:我们模拟的是串行口方式1.就是最普通的方式。
一个起始位、8个数据位、一个停止位。
模拟串行口最关键的就是要计算出每个位的时间。
以波特率9600为例,每秒发9 600个位,每个位就是1/9600秒,约104个微秒。
我们需要做一个精确的延时,延时时间+对IO口置位的时间=104微秒。
起始位是低状态,再延时一个位的时间。
停止位是高状态,也是一个位的时间。
数据位是8个位,发送时低位先发出去,接收时先接低位。
了解这些以后,做个IO模拟串口的程序,就是很容易的事。
我们开始。
先上简单原理图:就一个MAX232芯片,没什么好说的,一看就明白。
使用单片机普通I/ O口,232数据输入端使用51单片机P3.2口(外部中断1口,接到普通口上也可以,模拟中断方式的串行口会有用。
呵呵)。
数据输出为P0.4(随便哪个口都行)。
下面这个程序,您只需吧P0.4 和P3.2 当成串口直接使用即可,经过测试完全没有问题.2、底层函数代码如下:sbit TXD1 = P0^4; //定义模拟输出脚sbit RXD1 = P3^2; //定义模拟输入脚bdata unsigned char SBUF1; //定义一个位操作变量sbit SBUF1_bit0 = SBUF1^0;sbit SBUF1_bit1 = SBUF1^1;sbit SBUF1_bit2 = SBUF1^2;sbit SBUF1_bit3 = SBUF1^3;sbit SBUF1_bit4 = SBUF1^4;sbit SBUF1_bit5 = SBUF1^5;sbit SBUF1_bit6 = SBUF1^6;sbit SBUF1_bit7 = SBUF1^7;void delay_bps() {unsigned char i; for (i = 0; i < 29; i++); _nop_(); _nop_();} //波特率9600 模拟一个9600波特率unsigned char getchar2() //模拟接收一个字节数据{while (RXD1);_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); delay_bps();SBUF1_bit0 = RXD1; //0delay_bps();SBUF1_bit1 = RXD1; //1delay_bps();SBUF1_bit2 = RXD1; //2delay_bps();SBUF1_bit3 = RXD1; //3delay_bps();SBUF1_bit4 = RXD1; //4delay_bps();SBUF1_bit5 = RXD1; //5delay_bps();SBUF1_bit6 = RXD1; //6delay_bps();SBUF1_bit7 = RXD1; //7delay_bps();return(SBUF1) ; //返回读取的数据}void putchar2(unsigned char input) //模拟发送一个字节数据{SBUF1 = input;TXD1 = 0; //起始位delay_bps();TXD1 = SBUF1_bit0; //0delay_bps();TXD1 = SBUF1_bit1; //1delay_bps();TXD1 = SBUF1_bit2; //2delay_bps();TXD1 = SBUF1_bit3; //3delay_bps();TXD1 = SBUF1_bit4; //4delay_bps();TXD1 = SBUF1_bit5; //5delay_bps();TXD1 = SBUF1_bit6; //6delay_bps();TXD1 = SBUF1_bit7; //7delay_bps();TXD1 = 1; //停止位delay_bps();}3、实现串行通讯。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbiபைடு நூலகம் DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
51单片机模拟spi串行接口程序
51单片机模拟spi串行接口程序,在keilc51下编写
sbit CS=P3^5;
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;