老古开发网首页
导航:老古开发网首页文章索引文章分类单片机→[s3c9228汇编写的I2C及一字节除法]
| -文章搜索 - 最新文章 - |

s3c9228汇编写的I2C及一字节除法

发布时间:2006年6月26日 点击次数:1145
来源:   作者:
 

; /*EEPROM的读写*/
;本文件提供四个函数,对MEM(24C02)进行读写
;ReadMemByte
;ReadMemBlock
;WriteMemByte
;WriteMemBlock
;---------------------------------------------------------

;从EEPROM中读一个字节,函数返回值R15
;unsigned char ReadMemByte(unsigned char Addr)
;入口:R15
;出口:R15
;资源: R14,R15
;引用:供外部用作从MEM读1BYTE的函数

ReadMemByte: 
PUSH      R15   ;保存Addr堆栈
;StartI2C(0x51)
LD        R15,#0a0h
CALL      StartI2C
;写入地址并读出数所
POP       R15
CALL      WriteI2C             ;写地址
CALL      StopI2C
LD        R15,#0a1h
CALL      StartI2C               
LD        R12,#01h
CALL      ReadI2C  ;返回值R15
CALL      StopI2C
RET      
;---------------------------------------------------------
        
;从EEPROM中读Len个字节到Dst
;void ReadMemBlock(unsigned char Addr,unsigned char *Dst,unsigned char Len)
;入口:R15--Addr,R13--&Dst,R12--Len
;出口:
;资源: R14
;方法:
;               LD      R15,#E_Addr
;               LD      R13,#Var_Addr
;               LD      R12,#Len
;               CALL    ReadMemBlock            ;从NVRAM读
;引用:供外部用作从MEM读LEN个BYTE的函数

ReadMemBlock:
PUSH   R15   ;保存地址
LD        R15,#0a0h
CALL      StartI2C
POP   R15   ;恢复地址
CALL      WriteI2C
CALL      StopI2C
LD        R15,#0a1h
CALL      StartI2C                        
;读R12个数据
ReadMB_Loop: 
CALL      ReadI2C
LD   @R13,R15
INC   R13
DEC   R12
JR        NZ,ReadMB_Loop
CALL      StopI2C
OR      BTCON,#BIT1     ;WatchDog
RET      
;---------------------------------------------------------
;
;向EEPROM中写一个字节Sdata到Addr,函数返回值C为ACK是否正确
;bit WriteMemByte(unsigned char Addr,unsigned char SData)
;入口:R15--Addr,R13--Sdata
;出口:
;资源: R13,(R14,)R15
;引用:供外部用作向MEM写1BYTE的函数

WriteMemByte: 
PUSH   R15   ;暂存地址
OR        BTCON,#BIT1     ;WatchDog
LD        R15,#0a0h
CALL      StartI2C
POP   R15
CALL      WriteI2C  ;写入地址
LD        R15,R13
CALL      WriteI2C  ;写入数据
CALL      StopI2C
LD        R15,#10
CALL      Delay                               
RET
;---------------------------------------------------------
;
;向EEPROM中写Len个字节Sdata到Addr,函数返回值C为ACK是否正确
;bit WriteMemBlock(unsigned char Addr,unsigned char *Sdata,unsigned char Len)
;入口:R15--Addr,R13--&Sdata,R12--Len
;出口:
;资源: R12,R13,(R14,)R15
;               LD      R15,#E_Addr
;               LD      R13,#Var_Addr
;               LD      R12,#Len
;               CALL    WriteMemBlock   ;
;引用:供外部用作向MEM写LEN长度(BYTE)的函数

WriteMemBlock:
PUSH    R0
PUSH    R1
LD      R0,R15
LD      R1,R13
;写R12个数据
WriteMB_Loop:
LD        R15,R0
LD        R13,@R1
CALL      WriteMemByte        ;WriteI2C
INC       R0
INC       R1
DEC   R12
JR        NZ,WriteMB_Loop
POP       R1
POP       R0
RET      
;---------------------------------------------------------
;
;开始向设备0读或写作好准备
;void StartI2C(unsigned char Device)
;入口:R15
;出口:
;资源: R14,R5
;引用:本文件内的读、写函数

StartI2C:
AND P1CON,#03fh  ;SCL作为输入
OR P1PUR,#008h  ;SCL上拉使能
OR P1,#SCL   ;SCL = 1
OR P2CON,#040h  ;设SDA输出
OR P2PUR,#008h  ;SDA上拉使能,以便输入,但此时为输出
OR P2,#SDA   ;SDA = 1
;等设备释放总线
LD      R5,#0ffh
StartI2C_1:
DEC     R5
JR      Z,StartI2C_2
TM P1,#SCL
JR      Z,StartI2C_1
;开始对设备进行操作
StartI2C_2:     
OR      P1CON,#040h  ;SCL作为输出
AND     P1PUR,#0f7h  ;SCL禁止上拉
NOP
AND     P2,#~SDA  ;SDA = 0
NOP
AND     P1,#~SCL  ;SCL = 0
CALL WriteI2C
JR NC,StartI2C
RET

;---------------------------------------------------------

;从设备处得到ACK响应
;bit GetAckI2C(void)
;入口:
;出口:C
;资源:
;引用:本文件内的读、写函数

GetAckI2C: 
AND   P2CON,#03fh  ;SDA为输入
OR        P1,#SCL  ;SCL = 1
NOP
TM   P2,#SDA
JR        Z,GetAckI2C_1
AND   P1,#~SCL  ;SCL = 0
RCF
RET      
GetAckI2C_1:   
AND   P1,#~SCL  ;SCL = 0
SCF
RET      
;---------------------------------------------------------;

;使设备停止
;void StopI2CA(void)
;入口:
;出口:R15
;资源: R14
;引用:本文件内的读、写函数

StopI2C:       
OR        P2CON,#040h   ;SDA输出 
AND       P2,#~SDA ;SDA = 0
NOP
OR        P1,#SCL ;SCL = 1
NOP
OR        P2,#SDA ;SDA = 1
NOP
AND       P1,#~SCL
AND       P2,#~SDA ;SDA = 0
RET      
;---------------------------------------------------------

;向设备写一个字节的命令或数据或地址,返回值C=1为成功
;bit WriteI2C(const unsigned char SendData)
;入口:R15
;出口:C
;资源: R14
;引用:本文件内的读、写函数

WriteI2C: 
LD        R14,#008h
AND       P2CON,#07fh
OR        P2CON,#040h           ;SDA输出 
;用R14作变量,进行一个字节的传送
WriteI2C_Loop: 
TM   R15,#080h
JR        Z,WriteI2C_1
OR        P2,#SDA  ;SDA = 1
JR        WriteI2C_2
WriteI2C_1: 
AND       P2,#~SDA  ;SDA = 0
NOP
WriteI2C_2: 
OR        P1,#SCL  ;SCL = 1
NOP
AND       P1,#~SCL  ;SCL = 0
RL        R15
DEC       R14
JR        NZ,WriteI2C_Loop
CALL      GetAckI2C
JR        NC,WriteI2C_Error
RET      
WriteI2C_Error: 
CALL      StopI2C
RET      
;---------------------------------------------------------
;
;从设备中读出一个字节,返回值R15;中间用到资源R14
;unsigned char ReadI2C(void)
;入口:
;出口:R15
;资源: R14
;引用:本文件内的读函数
ReadI2C:       
AND   P2CON,#03fh  ;SDA为输入
CLR       R15
LD        R14,#080h
ReadI2C_Loop: 
OR        P1,#SCL  ;SCL = 1
NOP
TM   P2,#SDA
JR        Z,ReadI2C_1
OR        R15,R14
ReadI2C_1: 
AND       P1,#~SCL  ;SCL = 0
RCF      
RRC       R14
JR        NZ,ReadI2C_Loop
CP        R12,#01h
JR        EQ,ReadI2C_2
OR        P2CON,#040h           ;SDA为输出状态
AND       P2,#~SDA
ReadI2C_2:     
OR        P1,#SCL
NOP
AND       P1,#~SCL
RET      
;---------------------------------------------------------
;一字节除以10
;入口:R15
;出口:R15,R13;  R15= R15/10,R13 = R15 %10
;次源: R13,R14,R15
ByteDiv10: 
LD        R14,#10
LD        R13,R15
CLR       R15
Div10_Loop: 
CP        R13,R14
JR        ULT,Div10_Exit
SUB       R13,R14
INC       R15
JR        T,Div10_Loop
Div10_Exit: 
RET   

; 2004.8 wyanxi


欢迎进入老古论坛进行讨论
[单片机] 相关文章:
基于WinCE的I2C驱动程序设计
简介:
基于WinCE的I2C驱动程序设计 作 者: 中国地质大学 王小芳 王典洪 陈飞 摘要: 将操作系统和相应硬件设备连接起来,编写联系硬件和软件的驱动程序至关重要。本文主要讨论在WinCE操作系统下,如何设计实现S3C2410芯片具有I2C接口的驱动程序;详细介绍WinCE下,流驱动程序的编写方法,同时将驱动通过Platform Builder编译进操作系统,最后用动态链接库的方式提供给用户使用。 关键词: WinCE 流驱动 I2C总线 驱动程序 引言   随着以计算机技术、通信技术和软件技术为核心的信息技术的迅速发展,嵌入式......

P89LPC932的几种ISP编程方法
[转载]C8051F020中的ADC应用要素
基于普通单片机的LIN协议实现方案
[转载]AT89C2051控制LMX2332的频率合成器
[转载]基于51单片机的数控电源设计
[转载]利用单片机串口实现多个LED的显示
[转载]Atmel单片机应用技巧
VFD应用初探[1]___键盘
基于ADμC812的温度检测系统的设计
 
下一个:[单片机]SPI总线
简介:
SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。 假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。 那么第一个上升沿来的时候 数据将会是sdo=1;寄存器=0101010x。下降沿到来的时候,sdi上的电平将所存到寄存器中去,那么这时寄存器=0101010sdi,这样在8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个spi时序。 &nbs......
 

上一个:[CPLD/FPGA]QuickLogic全球最低功耗FPGA产品PolarPro开始批量出货

老古开发网版权所有 2006年9月 asp.Net V2.0 设计:老古
页面缓存:10分钟 执行时间:31毫秒