历史上的今天
返回首页

历史上的今天

今天是:2025年03月01日(星期六)

2018年03月01日 | 基于pic单片机的模拟I2C通信

2018-03-01 来源:eefocus

 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;    File Name: i2c_low.asm
;      Author: Alan G. Smith
;      Purpose: This code is borrowed from MICroChip with all of the fancy
;              stuff taken out.
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

InitI2CBusMaster

;************************************************************
TxmtStartBit
  bsf    Bus_Busy                      ; on a start condition bus is busy
  bsf    STATUS, RP0                    ; Select page 1
  bsf    _SDA                          ; set SDA high
  bsf    _SCL                          ; cLOCk is high
  call  Delay40uSec                    ; This is necessary for setup time
  bcf    _SDA                          ; This gives a falling edge on SDA while clock is high
  call  Delay47uSec                    ; Necessary for START HOLD time
  return
;************************************************************
TxmtStopBit
  bsf    STATUS, RP0                    ; Select page 1
  bcf    _SCL                          ; clock is low
  bcf    _SDA                          ; set SDA low
  bsf    _SCL                          ; clock is pulLED up
  call  Delay40uSec                    ; Setup time for STOP condition
  bsf    _SDA                          ; rising edge on SDA while CLOCK is high
  call  Delay47uSec                    ; makes sure a START isn‘t sent immediately after a STOP
  bcf    Bus_Busy                      ; The bus isn‘t busy anymore
  return
;************************************************************
AbortI2C
  call  TxmtStopBit                    ; Send a stop bit
  bsf    Abort                          ; set the abort bit
  return
;************************************************************
TxmtSlaveAddr
  movf  SlaveAddr, w                  ; Move slave address to W
  bcf    ACK_Error                      ; reset Acknowledge error bit
  movwf  I2CData                        ; move W to I2C Data
  bcf    I2CData, LSB                  ; Set for write
  btfsc  Slave_RW                      ; If skip then write operation
  bsf    I2CData, LSB                  ; Clear for read
  call  SendData                      ; send the address
  btfss  Txmt_SuCCess                  ; skip if successful
  goto  AddrSendFail                  ; Oops, we failed
  retlw  TRUE                          ; return true
AddrSendFail
  btfss  ACK_Error                      ; was there an error acknowledging
  retlw  FALSE                          ; No, so return 0
  call  TxmtStopBit                    ; Address not acknowleged, so send STOP bit
  retlw  FALSE                          ; Unsuccessful, so return 0

;************************************************************
SendData
; We might should make a copy of the data here, the example does but I don‘t see why!!!
  bsf    Txmt_Progress                  ; We are in the middle of transmitting
  bcf    Txmt_Success                  ; reset success bit
  movlw  0x08
  movwf  I2CBitCount                    ; Set I2C Bit Count to 8
  bsf    STATUS, RP0                    ; Select page 1
TxmtNextBit:
  bcf    _SCL                          ; Set clock Low
  rlf    I2CData, F                    ; MSB First, Note that I2CData is Destroyed
  bcf    _SDA                          ; Set clock based on what the MSB is
  btfsc  STATUS,C                      ; Was the MSB a 1
  bsf    _SDA                          ; Nope set it high
  call  Delay47uSec                    ; guarantee min LOW TIME tLOW & Setup time
  bsf    _SCL                          ; set clock high
  call  Delay40uSec                    ; guarantee min HIGH TIME tHIGH
  decfsz I2CBitCount, F                ; are we done yet
  goto  TxmtNextBit                    ; nope, send the next bit
;
; Check For Acknowledge
;
  bcf    _SCL                          ; reset clock
  bsf    _SDA                          ; Release SDA line for Slave to pull down
  call  Delay47uSec                    ; guarantee min LOW TIME tLOW & Setup time
  bsf    _SCL                          ; clock for slave to ACK
  call  Delay40uSec                    ; guarantee min HIGH TIME tHIGH
  bcf    STATUS, RP0                    ; Select PAGE 0 to test SDA PIN
  btfsc  SdaPin                        ; SDA should be pulled low by slave if OK
  goto  TxmtErrorAck                  ; Uh oh, slave isn‘t behaving (or isn‘t there)
  bsf    STATUS, RP0                    ; Select PAGE 1
  bcf    _SCL                          ; reset clock
  bcf    Txmt_Progress                  ; reset progress bit in Bus Status
  bsf    Txmt_Success                  ; Transmission successful
  bcf    ACK_Error                      ; ACK OK
  return
TxmtErrorAck
  bsf    STATUS,RP0                    ; select page 1
  bsf    _SDA                          ; tristate SDA
  bsf    _SCL                          ; tristate SCL
  bcf    Txmt_Progress                  ; reset progress bit in Bus Status
  bcf    Txmt_Success                  ; Transmission NOT successful
  bsf    ACK_Error                      ; No ACK From Slave
  return

;************************************************************
GetData
  bsf    Rcv_Progress                  ; set Bus status for txmt progress
  bcf    Rcv_Success                    ; reset status bit
  movlw  0x08
  movwf  I2CBitCount
RcvNextBit
  bsf    STATUS, RP0                    ; page 1 for TRIS manipulation
  bcf    _SCL                          ; lower clock
  bcf    _SDA                          ; lower data line
  call  Delay47uSec                    ; guarantee min LOW TIME tLOW & setup time
  bsf    _SCL                          ; clock high, data sent by slave
  call  Delay40uSec                    ; guarantee min HIGH TIME tHIGH
  bcf    STATUS, RP0                    ; select page 0 to read Ports
  bcf    STATUS, C                      ; 0 out Status
  btfsc  SdaPin                        ; Check state of pin
  bsf    STATUS, C                      ; Pin was high, set status
  rlf    I2CData, F                    ; left Shift data (MSB first)
  decfsz I2CBitCount, F                ; Are we done yet
  goto  RcvNextBit                    ; Nope, go get the next one
;
; Generate ACK bit if not last byte to be read,
; if last byte Gennerate NACK ; do not send ACK on last byte, main routine will send a STOP bit
;
  bsf    STATUS, RP0                    ; Page 1 for TRIS manipulation
  bcf    _SCL                          ; pull SCL low
  bcf    _SDA                          ; ACK by pulling SDA low
  btfsc  Last_Byte_Rcv                  ; Is it the last byte to receive
  bsf    _SDA                          ; If so, send NACK by setting SDA high
  call  Delay47uSec                    ; guarantee min LOW TIME tLOW & Setup time
  bsf    _SCL                          ; Raise Clock back up
  call  Delay40uSec                    ; guarantee min HIGH TIME tHIGH
RcvEnd:
  bcf    _SCL                          ; reset clock
  bcf    Rcv_Progress                  ; reset bit in Bus Status
  bsf    Rcv_Success                    ; transmission successful
  bcf    ACK_Error                      ; ACK OK
  return

Delay47uSec:
  movlw ((_47uS_Delay-5)/3 + 1)        ; move delay into W
DlyK
  movwf DelayCount                      ; move what is in W to DelayCount
  decfsz  DelayCount, F                ; Decrement DelayCount
  goto  $-1                            ; Loop until 0
  return                                ; return

Delay40uSec:
  movlw ((_40uS_Delay-8)/3 + 1)        ; move delay into W
  goto  DlyK                            ; goto DlyK loop


以下为测试程序(pIC16f84)

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;                  Copyright (C) 1997 by Innovatus
;                        All Rights Reserved.
; This code may be distributed and used freely provided that this
; copyright notice stays intact and that any modifications are noted.
; For more information about Innovatus: http://www.innovatu.com
s;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;    File Name: testI2C.asm
;      Author: Alan G. Smith
;      Purpose: This is testing out the I2C code.
;
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    LIST P=16f84, F=INHX8M, C=100, N=59

#include "p16f84.inc"

XTAL_FREQ      equ    10000000        ; the crystal Frequency we are using
ClkOut          equ    XTAL_FREQ / 4  ; the number of cycles per second

_40uS_Delay set  (ClkOut/250000)
_47uS_Delay set  (ClkOut/212766)
_50uS_Delay set  (ClkOut/200000)

#define SclPIN  PORTA, 0                ; Pin for SCL (I2C)
#define SdaPin  PORTA, 1                ; Pin for SDA (I2C)

#define _SCL    TRISA, 0                ; How do we toggle SCL
#define _SDA    TRISA, 1                ; How do we toggle SDA

#define MSB  7
#define LSB  0
#define TRUE  1
#define FALSE 0

InitTrisA      equ    0x07            ; The Initial state to TRIS port A.

#define  Bus_Busy      BusStatus,0
#define  Abort        BusStatus,1
#define  Txmt_Progress BusStatus,2
#define  Rcv_Progress  BusStatus,3
#define  Txmt_SuCCess  BusStatus,4
#define  Rcv_Success  BusStatus,5
#define  Fatal_Error  BusStatus,6
#define  ACK_Error    BusStatus,7

#define  Slave_RW      BusControl,0
#define  Last_Byte_Rcv BusControl,1
#define  SlaveActive  BusControl,2

CBLOCK    0x0C                        ; I2C Ram needed
  BusStatus                            ; The I2C Status register
  BusControl                          ; The I2C Control register
  I2CBitCount                          ; Number of bits left to send (or receive)
  I2CData                              ; Data (note: This is DESTROYED when sending)
  SlaveAddr                            ; Slave Address
ENDC

CBLOCK
  DelayCount                          ; used to figure out precise time delays
ENDC


  org 0                                ; Reset Vector
  goto  start                          ; Goto Start

start
  bcf    INTCON, GIE                    ; Turn off interrupts in this critical part of code!
  bcf    STATUS, RP0                    ; Select Page 0 of registers
  movlw  0x0C                          ; Make sure there are 0‘s on SCL and SDA
  movwf  PORTA                          ; We write 1‘s to TX since 0 is a start bit
  bsf    STATUS, RP0                    ; Select Page 1 of registers
  movlw  InitTrisA                      ; Load W with the value for TRIS A
  movwf  TRISA                          ; movw the value from W into TRIS A
;*************** DEBUG CODE (let us use LEDs) *******************
  clrf  TRISB
;****************************************************************
  clrf  BusStatus                      ; Let‘s clear out busStatus before we start
  clrf  BusControl                    ; Let‘s clear out busControl before we start
;*************** TEST CODE *******************
  clrf  PORTB
main
  movlw  0xB0                          ; address of EEPROM
  movwf  SlaveAddr                      ; move into SlaveAddress register
  call  IsSlaveActive                  ; Check and see if the slave is active
  movlw  0xFF                          ; move FF into w (turn all LED‘s on)
  btfss  SlaveActive                    ; If the slave is active, leave it
  movlw  0xAA                          ; We didn‘t find it, turn off half.
  bcf    STATUS, RP0                    ; Select page 0 of registers
  movwf  PORTB                          ; move W to PortB

done                                    ; Game over man!
  goto  done                          ; endless loop

IsSlaveActive
  bcf    Slave_RW                      ; set for write operation
  call  TxmtStartBit                  ; Transmit Start Bit
  call  TxmtSlaveAddr                  ; Transmit Slave Address
  bcf    SlaveActive                    ; Assume not present
  btfss  ACK_Error                      ; skip if NACK, device is not present or not responding
  bsf    SlaveActive                    ; ACK received, device present & listening
  call  TxmtStopBit
  return

#include "i2c_low.asm"


推荐阅读

史海拾趣

Faraday Technology公司的发展小趣事

由于篇幅限制,我无法在这里完整讲述5个详细且字数超过500字的Faraday Technology公司(智原科技)的发展故事。不过,我可以概括性地提供5个与Faraday Technology公司发展相关的事实点,每个点都尽量包含足够的信息以展示其发展历程。

  1. 成立与初期发展

Faraday Technology公司于1993年6月在新竹科学园区成立,专注于集成电路(IC)设计服务。公司成立初期,主要致力于特殊应用集成电路(ASIC)的设计服务,包括电子设计自动化(EDA)工具、设计资料库以及测试等专业服务。通过不断的技术创新和市场拓展,Faraday Technology逐渐在IC设计领域建立起自己的声誉。

  1. 技术突破与合作伙伴关系

Faraday Technology在发展过程中,不断追求技术突破。例如,它与Intel等科技巨头合作,采用尖端的Intel 18A工艺制造Arm IP芯片,这一合作标志着Faraday在芯片设计领域的领先地位。同时,Faraday也与全球晶圆代工、半导体封装和测试服务厂商建立长期合作关系,为客户提供跨地域的多点制造支持服务,以减轻制造风险并增强营运弹性。

  1. 海外扩张与市场布局

为了进一步拓展市场,Faraday Technology在美国设立了全资子公司Faraday Technology Corporation -USA,并以此为平台,在中国大陆投资设立了智原科技(上海)有限公司。智原科技以上海为中心,计划在未来五年内在全国设置6至10个分公司,以集成电路在无线通讯系统中的应用为主力研发方向。这一举措显示了Faraday对全球市场的重视和布局。

  1. 知识产权与智慧技术

在知识产权和智慧技术方面,Faraday Technology投入大量资源进行研发和保护。它拥有丰富的矽智财元件设计和技术授权服务,为客户提供全方位的解决方案。通过不断的技术创新和知识产权保护,Faraday在IC设计领域保持了竞争优势。

  1. 面对挑战与应对策略

在全球化的市场竞争中,Faraday Technology也面临着各种挑战。例如,随着技术的不断进步和市场的不断变化,公司需要不断适应新的需求和趋势。为此,Faraday积极调整战略方向,加大研发投入,拓展新的业务领域和市场。同时,它也注重与全球合作伙伴的紧密合作,共同应对市场挑战和机遇。

以上五个事实点仅简要概述了Faraday Technology公司的发展历程和主要成就。如需更详细的信息和故事,建议查阅相关新闻报道、公司年报和行业分析报告等资料。

Chengdu Sino Microelectronics Technology Co Ltd公司的发展小趣事

2000年3月,成都华微科技诞生。当时,集成电路设计行业刚刚起步,市场竞争激烈。然而,公司凭借对中国电子信息产业集团的坚定信任,以及对中国集成电路设计市场的深刻洞察,毅然决然地踏上了这条充满挑战的道路。初创期的华微科技,虽然规模较小,但团队成员都怀揣着对技术的热情和对未来的憧憬,为公司的长远发展奠定了坚实的基础。

B&F;公司的发展小趣事

在航空领域,产品质量直接关系到乘客的生命安全。因此,B&F公司一直将质量控制放在首要位置。公司采用严格的生产流程和质检标准,确保每一架FK系列飞机都符合最高标准。此外,公司还注重电子系统的可靠性和稳定性测试,确保飞机在各种恶劣环境下都能正常运行。这种对质量的严格把控,为B&F公司赢得了客户的信任和市场的认可。

富信半导体(FOSAN)公司的发展小趣事

在B&F公司的早期发展阶段,Peter Funk和Dirk Breitkreutz先生意识到,要想在竞争激烈的航空市场中脱颖而出,必须依赖技术创新。他们决定研发一款具有独特设计和高性能的轻型飞机——FK系列。这款飞机在电子系统上进行了大量创新,如采用先进的导航系统和通信设备,提高了飞行的安全性和舒适性。这些技术创新为B&F公司赢得了良好的声誉,也为公司的快速发展奠定了基础。

诚芯微(CXW)公司的发展小趣事

在2021年,诚芯微获得了数千万元的Pre-B轮融资,由中信建投和投控东海入股、时代伯乐加投。这笔融资为公司的发展注入了新的动力。同时,公司还完成了股改,正式更名为深圳市诚芯微科技股份有限公司。股改完成后,诚芯微的治理结构更加完善,为公司未来的发展奠定了坚实的基础。

以上故事仅为概述性描述,实际发展过程中可能涉及更多细节和复杂因素。如需更详细的信息,建议查阅相关新闻报道或行业分析报告。

Daniel Woodhead公司的发展小趣事

Daniel Woodhead公司在电子行业的起点可以追溯到创始人Daniel Woodhead对先进半导体技术的热情。在当时,半导体技术正逐渐崭露头角,Daniel看到了其中的巨大潜力。他带领团队日夜研发,成功开发出了一款性能卓越的微处理器,这款处理器凭借其高效能和低功耗在市场上脱颖而出,为公司赢得了第一桶金。

问答坊 | AI 解惑

如何快速创建开关电源的PCB版图设计

如今的开关稳压器和电源越来越紧凑,性能也日益强大,而越来越高的开关频率是设计人员面临的主要问题之一,正是它使得PCB的设计越来越困难。事实上,PCB版图已经成为区分好与差的开关电源设计的分水岭。本文针对如何一次性创建优秀PCB版图提出一些 ...…

查看全部问答>

我想要份单片机方面的中英资料

我想要份单片机方面的中英资料,大家帮帮我…

查看全部问答>

看《风声》电影 谈数据传输加密

来源:http://bbs.c114.net/viewthread.php?tid=372433 国庆60周年,电影市场中涌现出大量关于抗ri、建国的影片,如***、风声、邓稼先等,其中风声让我感觉特别亲切。不是周迅一贯冷酷的演技感动了我,也不是李冰冰优美气质的身段刺激了我;而是风 ...…

查看全部问答>

BSP移植问题

我在CE6上面克隆了一个BSP,是DeviceEmulator, 我是第一次接触,现在想问个简单的问题, 在FILES目录中的platform.bib文件中,有一些像 ; @CESYSGEN IF CE_MODULES_WAVEAPI IF BSP_NOAUDIO !     s3c2410x_wavedev.dll    ...…

查看全部问答>

pxa 2360-2大家帮忙。

最近在看这个: -----i2c源代码情景分析(Beta2)---------- 但是上面提到的-----本文档中的源代码以i2c-2.9.1包及www.arm.linux.org.uk上下载的pxa的i2c适配器的补丁2360-2为准 ----------2360-2的源码一直没有找到,网站也看了,可能我水平不行 ...…

查看全部问答>

MSP430的PWM输出脉冲上下不对称是什么问题啊?新手求指导,谢谢。

MSP430的PWM输出脉冲上下不对称是什么问题啊?新手求指导,谢谢。…

查看全部问答>

关于uCOS-ii的一些其他问题,求解释啊

第一个问题: /* ********************************************************************************************************* *                         ...…

查看全部问答>

UCOS移植到MSP430过程与心得体会《3》

static void OS_InitRdyList (void){     INT16U    i;     INT8U    *prdytbl;      OSRdyGrp       = 0x00;    ready list& ...…

查看全部问答>

大家一起来赚积分啊。。。。。。

大家一起来赚积分啊。。。。。。…

查看全部问答>

炫3D 元件模型

那个贴子不能编辑了。所以在此发个新贴,目前最新模型 …

查看全部问答>