1)发送一字节数据WR_BYTE
该子程序是向虚拟的IIC总显得数据线SDA上发送一字节数据的操作。调用该子程序前,将要发送的数据送入A中。
还是先汇编,然后c代码:
;-----------------------------------------------------------------
;发送字节子程序
;字节数据放入ACC
;每发送一个字节筪掉用一次CACK(检测应答子程序),取应答位
WR_BYTE:
MOVR0,#08H;8位数据长度送R0
W_LP:
RLCA;发送数据左移,使发送位入c
JCW_R1;判读发送1,还是发送0,发送1,转入W_R1
SJMPW_R0;发送0转入W_R0
W_LP1:
DJNZR0,W_LP
NOP
RET
W_R1: ;发送1
SETBSDA
NOP
SETBSCL
NOP
NOP
NOP
NOP
NOP
CLRSCL
SJMPW_LP1
W_R0: ;发送0
CLRSDA
NOP
SETBSCL
NOP
NOP
NOP
NOP
NOP
CLRSCL
SJMPW_LP1
//----------------------------------------------------------------------
//写一个字节函数
void send_byte(uchar c)
{
uchar bit_cnt;
for(bit_cnt=0;bit_cnt<8;bit_cnt++)//循环传送8位
{
if((c< //取当前发送位
sda=1;
else
sda=0;
_nop_();
scl=1;//发送到数据线上
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
}
}
2)接收一字节数据RD_BYTE(这个的汇编感觉并不肯定,有可能有错~~
,当然c语言还是没问题的,呵呵)
;----------------------------------------------------------------------
;读取字节子程序
;读出的值再ACC中
;每取一个字节要发送一个应达或者非应答信号(要知道你读取就成了从机,就要发送一个信号告诉主机)
RD_BYTE:
MOVR0,#08H;8位数据长度
R_LP:
SETBSDA;置SDA为输入方式
NOP
CLRSCL;置时钟线为低电平,准备接收数据
NOP
NOP
NOP
NOP
NOP
SETBSCL
NOP
MOVC,SDA;读取数据位
RLCA;进行数据位的处理
NOP
DJNZR0,R_LP;没有到8位,再来一次
RET
//------------------------------------------------------------------------
//接收一个字节函数
//返回接收的8位数据
uchar rec_byte()
{
uchar temp;
uchar bit_cnt;
temp=0;
sda=1; //置数据线为输入方式
for(bit_cnt=0;bit_cnt<8;bit_cnt++)
{
_nop_();
scl=0; //置时钟线为低电平,准备接收数据
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=1;
_nop_();
_nop_();
temp<<=1;
if(sda==1)//接收当前数据位,接收内容放入temp中
temp+=1;
_nop_();
_nop_();
}
scl=0;
_nop_();
_nop_();
return(temp);
}
3)向被控器件发送n个字节数据子程序MCU_WRN_BYTE
;-----------------------------------------------------------------------
;向器件指定地址写入N个数据
;入口参数:器件从地质SLA,器件子地址SUBA、发送数据缓冲区MTD、发送字节数NUMBYTE
;占用:A,R0,R1,R3,CY
MCU_WRN_BYTE:
MOVA,NUM_BYTE
MOVR3,A
LCALLSTART;启动总线
MOVA,SLA
LCALLWR_BYTE;发送器件地址
LCALLCACK
JNBACK,RET_WRN
MOVA,SUBA;指定子地址,并发送
LCALLWR_BYTE
LCALLCACK
MOVR1,#MTD
WRN_DA:
MOVA,@R1
LCALLWR_BYTE;开始写入数据
LCALLCACK
JNBACK,MCU_WRN_BYTE
INCR1
DJNZR3,WRN_DA;判断写完没有
RET_WRN:
LCALLSTOP
RET
评论