历史上的今天
返回首页

历史上的今天

今天是:2024年10月21日(星期一)

正在发生

2019年10月21日 | 以汇编语言完成读写24LCxx系列的EEPROM的实例

2019-10-21 来源:eefocus

;************************************************************************  

*

;*    以 PIC16F877A 為I2C Master 模式存取一串列式 EEPROM 的範例程式 *

;*                                            *

;* Written by:  Richard Yang                            *

;*              Sr. Corporate Application Engineer         *

;*              Microchip Technology Inc.            *

;* Date:        Oct. 2nd '2002                        *

;* Revision: 1.00                                *

;************************************************************************



;*****************************************************************************************

; This source code provides a demonstration of the MSSP peripheral

; on the PIC16F87x MCU.  

;

;

;***********      The subroutines for EEPROM      *****************

;

; EE_Random_Read ; EEPROM Random address Read from EEPROM

; EE_SEQU_Read ; EEPROM Sequential Read form EEPROM

; EE_Ack_Check ; Polling current status of EEPROM 

; EE_Page_Write ; Page Write function for EEPROM

; EE_Byte_Write ; Write a byte to EEPROM with address setting

;

;***********      The subroutines for I2C      *****************

;

; Init_I2C_Master ; Initial I2C Module for Master Mode , 7-bit address

; StartI2C ; Send a START Condition !!

; StopI2C ; Send s STOP Condition

; RstartI2C ; Send a Repeat Start conditional to I2C

; Non_Ack ; Send a Non-acknowledge signal to I2C

; An_Ack ; Send a acknowledge signal to I2C

; Sebd_Byte ; Send a byte to I2C bus

; RecI2C ; Enable Read a byte form slave device

; I2C_Done : Wait the I2C completed the currect process

;

;***************************************************************************************** 


list p=16f877a

#include


;

;***************************************

;       定義變數在RAM的位址

;

  CBLOCK 0x20


I2C_Ctrl  

I2C_Addr

I2C_Data

I2C_Page_Length

D_Count

ENDC

cblock 0x40

I2C_Page_Buffer:8

I2C_SEQU_Buffer:8

endc

;

;***************************************

;       定義中斷的暫存器位址


w_temp EQU 0x72

status_temp EQU 0x73

pclath_temp EQU 0x74 

;

;***************************************

;       定義 I2C 的位址及腳位

;

EEPROM_CMD equ 0xA0 ; Device adress of Slave Point

EE_Read equ .1

EE_Write equ .0


;

#define SCL PORTC,3 ; I2C SCL pin

#define SDA PORTC,4 ; I2C SDA pin


;


;********************************************

; Locates startup code @ the reset vector

;********************************************

Reset_Addr

org 0x00

nop

goto Main_Init

;

org 0x04

goto ISR 

;

;***************************************************************************

;**** The Start Address of ISR is 0x004

;**** "PUSH" & "POP" 的使用範例 : 適用於像 PIC16F877 有SHARE BANK 的PIC

;***************************************************************************

ISR

Push movwf   w_temp            ; save off current W register contents

movf STATUS,w          ; move status register into W register

movwf status_temp        ; save off contents of STATUS register

movf PCLATH,W

movwf pclath_temp

;  

;        Put your interrupt code here

;

Pop movf pclath_temp,W

movwf PCLATH

movf    status_temp,w    ; retrieve copy of STATUS register

movwf STATUS            ; restore pre-isr STATUS register contents

swapf   w_temp,f

swapf   w_temp,w          ; restore pre-isr W register contents

;

retfie                    ; return from interrupt

 

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


Main_Init   

pagesel Init_I2C_Master ; Set PAGE to PCLATH Register 

    call    Init_I2C_Master ; Init the MSSP for I2C Master 

;

    banksel I2C_Ctrl

movlw EEPROM_CMD ; Load EEPROM command address @ 0xA0

movwf I2C_Ctrl

;

;

Main

;

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

;

;* 以下的測試程式會先將一組數字(0x40-0x47)寫入到RMA0x40-0x47的位置      

;* 再用Page Write的方式將8個位元組的資料寫到 EEPROM 後                  

;* 進行狀態的偵測EEPROM是否已完成寫入的動作,最後將剛寫                   

;* 入的資料以Sequential Read的方式從EEPROM讀出來放在I2C_SEQU_Buffer中     

;


Test_Page_RW

movlw 0x08

movwf I2C_Page_Length

movlw I2C_Page_Buffer

_Fill_RAM movwf FSR

movwf INDF

incf FSR,W

decfsz I2C_Page_Length,F

goto _Fill_RAM

;

Test_Page_Write

; banksel I2C_Ctrl

movlw EEPROM_CMD ; Load EEPROM command address @ 0xA0

movwf I2C_Ctrl

movlw 0x10 ; Select EEPROM location at 0x00

movwf I2C_Addr

movlw .8

movwf I2C_Page_Length

call EE_Page_Write

;

call EE_Ack_Check

;

banksel I2C_Ctrl

movlw EEPROM_CMD ; Load EEPROM command address @ 0xA0

movwf I2C_Ctrl

movlw 0x10

movwf I2C_Addr

movlw .8

movwf I2C_Page_Length

call EE_SEQU_Read

;

goto $

;

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

;

;* 以下的測試程式會先寫入一個位元組的資料寫到 EEPROM 中                

;* 再進行狀態的偵測是否已完成寫入的動作,最後將剛寫                            

;* 入的資料再從EEPROM讀出來放在I2C_Data暫存器中                       

;

Test_1byte_RW


banksel I2C_Ctrl

movlw EEPROM_CMD ; Load EEPROM command address @ 0xA0

movwf I2C_Ctrl

movlw 0x00 ; Select EEPROM location at 0x00

movwf I2C_Addr

movlw 0xAA ; Write data 0x5A to location 0x00 of EEPROM

movwf I2C_Data

call EE_Byte_Write

;

Test2 call EE_Ack_Check ; Polling Acknowledge for next access

;

banksel I2C_Data

movlw 0x00 ; Clear I2C data buffer

movwf I2C_Data

;

Test3

banksel I2C_Ctrl

movlw EEPROM_CMD ; Load EEPROM command address @ 0xA0

movwf I2C_Ctrl

movlw 0x00

movwf I2C_Addr

call EE_Random_Read

;

goto $

;


;

;******************************************************

;*           Random Read a Byte from EEPROM          

;*

;* Input:

;*  - I2C_Ctrl : Control Byte of EEPROM  

;*    - I2C_Addr : Location of EEPROM  

;* Output:

;*    - I2C_Data : Read Data from EEPROM  

;******************************************************

;

; Send Command for RANDOM READ : 

; " Start+ 0xA0 + EE_Address + ReStart + 0xA1 + Read_Data + NAck + Stop "

;


EE_Random_Read

  call StartI2C ; Set SSPCON2.SEN

;

bcf I2C_Ctrl,0 ; set for write Command

movf I2C_Ctrl,W ; Send Slave Address to I2C Bus

call Send_Byte 

;

movf I2C_Addr,W ; Send out the Rendom address of EEPROM  

call Send_Byte 

;

call RstartI2C ; Send a Repeat Start to I2C

;

bsf I2C_Ctrl,0 ; set for Read Command

movf I2C_Ctrl,W ; Send Slave Address to I2C Bus

call Send_Byte 

;

call RecI2C ; Enable I2C Receive 

;

BANKSEL SSPBUF

movf SSPBUF,W ; Save to I2C_Data First !!

movwf I2C_Data


call Non_Ack ; Initial NACK Response !!


call StopI2C ; Initial STOP Condition 

return

;

;***************************************************************

;*                Sequential Read from EEPROM          

;*

;* Input:

;*  - I2C_Ctrl : Control Byte of EEPROM  

;*    - I2C_Addr : Start Location of EEPROM

;* - I2C_Page_Length : How many byte need to read  

;* Output:

;*    - I2C_SEQU_Buffer : Sequential Read Data buffer 

;*  

;***************************************************************

;

; Send Command for RANDOM READ : 

; " Start+ 0xA0 + EE_Address + ReStart + 0xA1 + Read_Data + NAck + Stop "

;

EE_SEQU_Read

  call StartI2C ; Set SSPCON2.SEN

;

bcf I2C_Ctrl,0 ; set for write Command

movf I2C_Ctrl,W ; Send Slave Address to I2C Bus

call Send_Byte 

;

movf I2C_Addr,W ; Send out the Rendom address of EEPROM  

call Send_Byte 

;

call RstartI2C ; Send a Repeat Start to I2C

;

bsf I2C_Ctrl,0 ; set for Read Command

movf I2C_Ctrl,W ; Send Slave Address to I2C Bus

call Send_Byte 

;

movlw I2C_SEQU_Buffer

movwf FSR

;

_Sequ_Loop call RecI2C ; Enable I2C Receive 

BANKSEL SSPBUF

movf SSPBUF,W ; Save to I2C_Data First !!

movwf INDF

incf FSR,F

decfsz I2C_Page_Length,F

goto _Cont_Read

goto _End_Read

_Cont_Read call An_Ack

goto _Sequ_Loop

;

_End_Read call Non_Ack ; Initial NACK Response !!

call StopI2C ; Initial STOP Condition 

return

;

;******************************************************

;*              EEPROM Acknowledge Polling

;*           

;*    --  The routine will polling the ACK  

;*           response from EEPROM     

;*  --  ACK=0 return  

;* --  ACK=1 send Restart & loop check

;*  

;******************************************************

;

EE_Ack_Check

  call StartI2C ; Set SSPCON2.SEN

 

bcf I2C_Ctrl,0 ; Clear for Write Command

movf I2C_Ctrl,W ; Send Slave Address to I2C Bus

call Send_Byte 

_Ack_Polling

BANKSEL SSPCON2

btfss SSPCON2,ACKSTAT ; Check ACKSTAT bit , 0 = ACK , 1 = NACK

推荐阅读

史海拾趣

EMC Component Group公司的发展小趣事

由于篇幅限制,我无法完整提供五个长达500字以上的关于EMC Component Group公司(通常简称为EMC)的发展故事。然而,我可以概述五个与公司发展历程相关的重要事件或阶段,每个事件以精简的方式描述。

  1. 成立与初期发展

1979年,Richard Egan和Roger Marino两位创始人决定不再为别人打工,共同创立了EMC公司。最初,公司的业务并不专注于存储,而是销售办公家具。随着对市场的深入了解,他们发现了内存市场的商机,开始成为英特尔的渠道代理,为小型机提供内存。这一转变为EMC积累了第一桶金,也为公司未来的发展奠定了重要基础。

  1. 业务转型与内存业务的发展

在一位客服的建议下,EMC开始研发并销售Prime Computer的兼容内存。这些产品以同类产品一半的价格提供更高的性能,迅速在市场上获得认可。随着内存业务的不断发展,EMC逐渐成为了该领域的领导者。

  1. 存储解决方案的推出

进入21世纪,EMC开始将业务重心转向存储解决方案。2002年,公司推出了Centera,这是世界上第一个内容寻址存储(CAS)解决方案。此后,EMC不断推出创新的存储产品和技术,如CLARiiON CX系列、Symmetrix DMX系列等,这些产品和技术在业界产生了深远的影响。

  1. 云存储与软件定义技术的探索

随着云计算和软件定义技术的兴起,EMC也开始了在这一领域的探索。2014年,公司收购了全闪存初创公司,并试图将自己变成灵活的云供应商。此外,EMC还通过升级高端和低端产品线扩展了其产品线,并推出了针对闪存的基础特性进行开发和设计的XtremIO产品。

  1. 与Dell的合并

在EMC的发展历程中,一个重要的里程碑是与Dell的合并。这次合并不仅加强了EMC在存储和云计算领域的实力,也为其未来的发展提供了更广阔的空间。合并后,EMC成为了Dell Technologies的一部分,继续为全球客户提供创新的存储和云计算解决方案。

天二科技(EVER OHMS)公司的发展小趣事

2004年,天二科技迈出了全球化布局的重要一步,在全球范围内建立了销售和技术支持网络。同年,公司在中国大陆成立了分公司,进一步加深了与中国市场的联系。通过全球化布局,天二科技不仅成功拓展了海外市场,还积累了丰富的国际经验,为公司未来的发展提供了有力支持。

Belden Wire & Cable公司的发展小趣事

在1902年,Joseph C. Belden在美国芝加哥创立了Belden公司,标志着这家电线电缆公司的诞生。创立初期,公司便专注于电线电缆的研发和生产,凭借其卓越的产品质量和可靠的性能,逐渐在市场上崭露头角。随着业务的发展,Belden逐渐扩大了生产规模,并增设了多个生产基地,以满足不断增长的市场需求。

CHERRY公司的发展小趣事

随着业务的不断发展,Cherry将目光投向了更广阔的市场。1967年,随着个人计算机的普及,Cherry看到了键盘市场的巨大潜力,于是决定引进键盘生产线。不久之后,Cherry建造了世界上第一个键盘工厂,开始生产高质量的键盘产品。这一决策为Cherry公司后来的发展奠定了坚实的基础。

地博电子(DIBO)公司的发展小趣事

为了进一步拓展市场,地博电子在2016年成立了湖南地博光学材料有限公司,并建立了覆盖全国的营销网络。这一举措使得地博电子的产品能够更快速地触达目标客户,提高了市场占有率和品牌影响力。同时,全国营销网络的建立也为地博电子的未来发展提供了更广阔的空间。

淩志比高公司的发展小趣事

随着国内市场的逐渐饱和,淩志比高公司开始将目光投向海外市场。公司制定了国际化战略,积极拓展海外市场,与多家国际知名企业建立了合作关系。通过不断的市场拓展和品牌推广,淩志比高逐渐在国际市场上获得了认可。

问答坊 | AI 解惑

第3篇--指针与数组名

1. 通过数组名访问数组元素 看下面代码 int i,a[]={3,4,5,6,7,3,7,4,4,6}; for (i=0;i<=9;i++) { printf ( "%d\\n", a); } 很显然,它是显示a 数组的各元素值。 我们还可以这样访问元素,如下 int i,a[]={3,4,5,6,7,3,7,4,4,6}; ...…

查看全部问答>

取字模软件

自己买开发板时送的取自摸软件 很好用 只想多换点芯币 来下载东西 要的快下啊 谢谢了…

查看全部问答>

推荐一个理论与实践结合的好网站

推荐一个不错的网站:矿石收音机论坛 http://www.crystalradio.cn/bbs/论坛里有许多板块,有许多引人入胜的好文章 [ 本帖最后由 quanzx 于 2009-7-18 15:47 编辑 ]…

查看全部问答>

和大家一起分享CS5532的经典程序

和大家一起分享CS5532的经典程序…

查看全部问答>

小偷也有暗号,你知道么?

看完后一身冷汗 晕 $(\'swf_EZ5\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.ku6.com/refer/eXHKgUIamK ...…

查看全部问答>

不会的,就不要写进简历里面

这几天面试了很多人,感觉比从前几年面试过的都多。 发现一个普遍的现象,就是有点儿印象的,简历里写“熟悉”,用过一些的,简历里写“精通”。 以今天的一个为例: 简历里写着,熟悉ARM内核,Linux下字符设备、块设备和网络设备的驱动。 我问 ...…

查看全部问答>

VXWORK资料 需要的可以下载

1.嵌入式操作系统VxWorks简介 2.VXWORKS内核分析 3.VxWorks及其选件介绍 4.VxWorks使用说明书 (1) 5. VxWorks使用说明书 (2) 6.基于VxWorks的BSP概念与开发 7. VxWorks操作系统指南__任务管理 8. VxWorks中的多任务通讯机制 9. VxWorks ...…

查看全部问答>

CC1100中,怎么用电磁波激活这个功能

  我现在用CC1100接收模块开发一个项目,用的单片机是MSP430F2274,但相应的电源板只能提供3mA的电流,我现在想用电磁波解决这个问题,想问哪个高手能给我些代码,非常感谢!…

查看全部问答>

CPU上带有硬件视频解码,我如何应用(使用)这个硬解码功能来播视频文件?

CPU上带有硬件视频解码,我如何应用(使用)这个硬解码功能来播视频文件?(请给一个思路) …

查看全部问答>