功能: 实现MSP430口线模拟I2C总线协议与24C04通信. *
* 描述: 主系统工作时钟为12MHz,I2C工作时钟频率为1MHz.给某地址写入一个数据 *
* 再读出来,如写入前和读出后的数据一致,则P1.0输出高电平,否则输出低电 *
* 平. *
* /|\ /|\ *
* MSP430x22x4 10k 10k ATMEL 24c04 *
* master | | slave *
* --------------------------- | | ---------- *
* -|XIN P3.1/UCB0SDA|<-|----+>|SDA | *
* 32kHz | | | | | *
* -|XOUT | | | | *
* | P3.2/UCB0SCL|<-+-----> |SCL | *
* | | | | *
* -------------------------- ---------- *
* *
* 作者: Singel *
* 时间: 2008年10月17日22时35分 *
* 此例在 IAR Embedded Workbench IDE for MSP430 v3.42a 调试通过 . *
********************************************************************************************/
功能: 实现MSP430口线模拟I2C总线协议与24C04通信. * * 描述: 主系统工作时钟为12MHz,I2C工作时钟频率为1MHz.给某地址写入一个数据 * * 再读出来,如写入前和读出后的数据一致,则P1.0输出高电平,否则输出低电 * * 平. * * /|\ /|\ * * MSP430x22x4 10k 10k ATMEL 24c04 * * master | | slave * * --------------------------- | | ---------- * * -|XIN P3./UCB0SDA|<-|----+>|SDA | * * 32kHz | | | | | * * -|XOUT | | | | * * | P3./UCB0SCL|<-+-----> |SCL | * * | | | | * * -------------------------- ---------- * * * * 作者: Singel * * 时间: 2008年10月17日22时35分 * * 此例在 IAR Embedded Workbench IDE for MSP430 v3.42a 调试通过 . * ********************************************************************************************/ #include <MSP430x22x4.h> #define SlaveWriteAddress 0xa0 #define SlaveReadAddress 0xa1 #define OwnAddress 0xee #define I2CSDA BIT1 #define I2CSCL BIT2 #define I2CSDA_SET_1 P3OUT |= I2CSDA #define I2CSDA_SET_0 P3OUT &=~ I2CSDA #define I2CSCL_SET_1 P3OUT |= I2CSCL #define I2CSCL_SET_0 P3OUT &=~ I2CSCL #define I2CSDA_INPUT_IN P3IN&I2CSDA unsigned char READI2CBUF; void delay5us( void ) { unsigned ; while(count--); } void Delay_MS( unsigned int m ) { unsigned int i,j; ;i<m;i++) ;j<;j++); } void Setting_System_Clock_For_On_Chip_RC( char Frequency ) { switch (Frequency) { :DCOCTL = BCSCTL1 = CALBC1_1MHZ;break; :DCOCTL = BCSCTL1 = CALBC1_8MHZ;break; :DCOCTL = BCSCTL1 = CALBC1_12MHZ;break; :DCOCTL = BCSCTL1 = CALBC1_16MHZ;break; } } void I2C_Pins_DIR_Setting ( unsigned char SDADIR ) { P3DIR |= I2CSDA + I2CSCL; ) { P3DIR &=~ I2CSDA; P3OUT &=~ I2CSDA; } } void Engender_I2C_start_signal(void) { I2CSCL_SET_1; delay5us(); I2CSDA_SET_1; delay5us(); I2CSDA_SET_0; delay5us(); } void Engender_I2C_stop_signal(void) { I2CSDA_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); I2CSDA_SET_1; delay5us(); } void Engender_I2C_ack_signal(void) { I2CSCL_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); I2CSCL_SET_0; delay5us(); } void Engender_I2C_noack_signal(void) { I2CSDA_SET_1; delay5us(); I2CSCL_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); I2CSCL_SET_0; delay5us(); } void WRITE_BYTE_TO_24C04( unsigned char BytEDAta ) { unsigned char count; ;count<;count++) { I2CSCL_SET_0; delay5us(); if(BytEDAta&0x80)I2CSDA_SET_1; else I2CSDA_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); BytEDAta<<=; } } unsigned char READ_BYTE_TO_24C04( void ) { unsigned ; I2CSCL_SET_0; ;count<;count++) { readbyte=readbyte<<; I2CSCL_SET_1; delay5us(); if(I2CSDA_INPUT_IN)readbyte=readbyte|0x01; else readbyte=readbyte&0xfe; delay5us(); I2CSCL_SET_0; delay5us(); } I2CSCL_SET_0; return readbyte; } void WRITE_DATA_TO_24C04( unsigned char Address,unsigned char Date ) { Setting_System_Clock_For_On_Chip_RC(); I2C_Pins_DIR_Setting(); Engender_I2C_start_signal(); WRITE_BYTE_TO_24C04(SlaveWriteAddress); Engender_I2C_ack_signal(); WRITE_BYTE_TO_24C04(Address); Engender_I2C_ack_signal(); WRITE_BYTE_TO_24C04(Date); Engender_I2C_ack_signal(); Engender_I2C_stop_signal(); Delay_MS(); I2CSCL_SET_0; I2CSDA_SET_0; Setting_System_Clock_For_On_Chip_RC(); } unsigned char READ_DATA_FROM_24C04( unsigned char Address ) { unsigned char readdate; Setting_System_Clock_For_On_Chip_RC(); I2C_Pins_DIR_Setting(); Engender_I2C_start_signal(); WRITE_BYTE_TO_24C04(SlaveWriteAddress); Engender_I2C_ack_signal(); WRITE_BYTE_TO_24C04(Address); Engender_I2C_ack_signal(); Delay_MS(); Engender_I2C_start_signal(); WRITE_BYTE_TO_24C04(SlaveReadAddress); I2C_Pins_DIR_Setting(); Engender_I2C_ack_signal(); readdate=READ_BYTE_TO_24C04(); I2C_Pins_DIR_Setting(); Engender_I2C_noack_signal(); Engender_I2C_stop_signal(); I2CSCL_SET_0; I2CSDA_SET_0; Setting_System_Clock_For_On_Chip_RC(); return (readdate); } void main( void ) { unsigned char Data=0x59; WDTCTL = WDTPW+WDTHOLD; Setting_System_Clock_For_On_Chip_RC(); P1DIR |= BIT0; ) { WRITE_DATA_TO_24C04(0X00,Data); READI2CBUF=READ_DATA_FROM_24C04(0x00); if(Data == READI2CBUF) { P1OUT |= BIT0; } else { P1OUT &=~ BIT0; } Delay_MS(); } }
通过微处理器I/O口模拟I2C总线对AT24C进行读写之前应注意一下两个问题:
一、微处理器的两个模拟I/O口在和SDA,SCL连接时必须使用上拉电阻。
一、I2C总线空闲的时候,两条信号线应该维持高电平。否则,上拉电阻上会有耗电。特别是在上电过程中,I/O线上电平也应保持在高电平状态。也就是说:当Master的I2C使用的是I/O软件模拟时,一定要保证该两个I/O上电默认均为输入(或高阻)或者输出高电平,切不可默认为输出低电平。I/O默认为输入时,可以通过外部上拉电阻将I2C信号线拉至高电平。
该程序通过调试,可以直接应用,程序如下:
/*********************************************************************************************** * 文 件 名 : AT24C256.S43.C * 功能描述 : I/O模拟I2C时序读写AT24CXX(支持字节写、页写、字节读、顺序读) * 作 者 : 梦回大唐 * 创建日期 : 2011-4-18 * 版 本 : Version1.0 *************************************************************************************************/ #include <msp430x16x.h> #define SDA_IN P5DIR &=~BIT0 // P5.0 IN #define SDA_OUT P5DIR |=BIT0 // P5.0 OUT #define SDA_LOW P5OUT &=~BIT0 // sda=0 #define SDA_HIGH P5OUT |=BIT0 // sda=1 #define SCL_IN P5DIR &=~BIT1 // P5.1 IN #define SCL_OUT P5DIR |=BIT1 // P5.1 OUT #define SCL_LOW P5OUT &=~BIT1 #define SCL_HIGH P5OUT |=BIT1 #define W_EEPROM_LENGH 14 #define TURE 1 #define FALSE 0 #define AckError 0x55 #define OutOfRang 0xaa #define OutOfAddr 0xbb unsigned ,,,,,,,,,,,,,}; unsigned char x[W_EEPROM_LENGH]; void i2c_delay(unsigned char us); void i2c_delay_ms(unsigned char ms); void i2c_start(); void i2c_stop(void); void i2c_SendAck(void); void i2c_SendNoAck(void); unsigned char i2c_check_ACK(void); void i2c_SendByte(unsigned char data); unsigned char i2c_RevByte(void); unsigned char EEPROM_ByteWrite(unsigned int addr,unsigned char data); unsigned char EEPROM_RandomRead(unsigned int addr); unsigned char EEPROM_SequentialRead(unsigned int addr,unsigned int n,unsigned char* p); unsigned int EEPROM_PageWrite(unsigned int page,unsigned char* p,unsigned char n); void i2c_delay(unsigned char us) { unsigned char tmp; while(us--) { ;tmp<;tmp++) { _NOP(); } } } void i2c_delay_ms(unsigned char ms) { unsigned int tmp; while(ms--) { ;tmp<;tmp++) { _NOP(); } } } void i2c_start(void) { SDA_OUT; i2c_delay(); SDA_HIGH; i2c_delay(); SCL_HIGH; i2c_delay(); SDA_LOW; i2c_delay(); SCL_LOW; i2c_delay(); } void i2c_stop(void) { SDA_OUT; SDA_LOW; i2c_delay(); SCL_HIGH; i2c_delay(); SDA_LOW; i2c_delay(); SDA_HIGH; } void i2c_SendAck(void) { SDA_OUT; SDA_LOW; i2c_delay(); SCL_LOW; i2c_delay(); SCL_HIGH; i2c_delay(); SCL_LOW; SDA_HIGH; } void i2c_SendNoAck(void) { SDA_OUT; SDA_HIGH; i2c_delay(); SCL_LOW; i2c_delay(); SCL_HIGH; i2c_delay(); SCL_LOW; } unsigned char i2c_check_ACK(void) { unsigned char AckStatus; SDA_IN; SCL_HIGH; i2c_delay(); if(P5IN & 0x01) { AckStatus = FALSE; } else { AckStatus = TURE; } SCL_LOW; i2c_delay(); SDA_OUT; return AckStatus; } void i2c_SendByte(unsigned char data) { unsigned char tmp; SDA_OUT; ;tmp<;tmp++) { if(data & 0x80) { SDA_HIGH; } else { SDA_LOW; } i2c_delay(); SCL_HIGH; i2c_delay(); SCL_LOW; i2c_delay(); data <<= ; } i2c_delay(); } unsigned char i2c_RevByte(void) { unsigned char tmp; unsigned ; SDA_IN; SCL_LOW; i2c_delay(); ;tmp<;tmp++) { SCL_HIGH; i2c_delay(); DATA <<= ; if(P5IN & 0x01) { DATA |= 0x01; } else { DATA &= 0xfe; } SCL_LOW; } SDA_OUT; return DATA; } unsigned char EEPROM_ByteWrite(unsigned int addr,unsigned char data) { unsigned char Dev_addr; //设备地址 unsigned char AddrLow; unsigned char AddrHigh; AddrLow = (unsigned char)addr; AddrHigh = (unsigned ); Dev_addr = ); i2c_start(); i2c_SendByte(Dev_addr); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_SendByte(AddrHigh); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_SendByte(AddrLow); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_SendByte(data); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_stop(); i2c_delay_ms(); ; } unsigned char EEPROM_RandomRead(unsigned int addr) { unsigned char Dev_addr; //设备地址 unsigned char AddrLow; unsigned char AddrHigh; unsigned char tmp; AddrLow = (unsigned char)addr; AddrHigh = (unsigned ); Dev_addr = ); i2c_start(); i2c_SendByte(Dev_addr); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_delay_ms(); i2c_SendByte(AddrHigh); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_SendByte(AddrLow); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_delay_ms(); i2c_start(); Dev_addr = ); i2c_SendByte(Dev_addr); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_delay_ms(); tmp = i2c_RevByte(); i2c_SendNoAck(); i2c_stop(); i2c_delay(); return tmp; } unsigned int EEPROM_PageWrite(unsigned int page,unsigned char* p,unsigned char n) { unsigned char Dev_addr; unsigned char AddrLow; unsigned char AddrHigh; unsigned int tmp; )|(page > )) //根据读写的设备而变更为适合的页数和每页字节数 { return OutOfRang; } tmp = ((unsigned ; //得出页首地址 AddrLow = (unsigned char)tmp; AddrHigh = (unsigned ); Dev_addr = ); i2c_start(); i2c_SendByte(Dev_addr); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_delay_ms(); i2c_SendByte(AddrHigh); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_SendByte(AddrLow); if(i2c_check_ACK() == FALSE) { return AckError; } while(n--) { i2c_SendByte(*p++); if(i2c_check_ACK() == FALSE) { return AckError; } } i2c_stop(); i2c_delay_ms(); ; } unsigned char EEPROM_SequentialRead(unsigned int addr,unsigned int n,unsigned char* p) { unsigned char Dev_addr; //设备地址 unsigned char AddrLow; unsigned char AddrHigh; - addr)) //检查预写入地址是否有效 { return OutOfAddr; } AddrLow = (unsigned char)addr; AddrHigh = (unsigned ); Dev_addr = ); i2c_start(); i2c_SendByte(Dev_addr); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_delay_ms(); i2c_SendByte(AddrHigh); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_SendByte(AddrLow); if(i2c_check_ACK() == FALSE) { return AckError; } i2c_delay_ms(); i2c_start(); Dev_addr = ); i2c_SendByte(Dev_addr); if(i2c_check_ACK() == FALSE) { return AckError; } while(n--) { *p = i2c_RevByte(); p++; if(n) i2c_SendAck(); else i2c_SendNoAck(); } i2c_stop(); ; } main() { //unsigned char tt,tt1; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer DCOCTL = 0X73; BCSCTL1= 0X87; // 设置时钟频率4.00MHz P5DIR |=0X03; P5OUT |=0X03; //EEPROM_ByteWrite(0x0,12); //tt=EEPROM_RandomRead(0x0); //tt1=tt; EEPROM_PageWrite(,dat,); EEPROM_SequentialRead(,,x); }
MSP430的IO口模拟I2C总线对AT24C25进行读写程序的更多相关文章
-
C51 I2C接口驱动,IO口模拟I2C(主+从)
Master.asm ;/*------------------------------------------------------------------*/ ;/* --- STC MCU I ...
-
【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)
版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...
-
stm32 普通IO口模拟串口通信
普通IO口模拟串口通信 串口通信协议 串口传输 默认 波特率9600 1起始位 1停止位 其他0 数据位是8位(注意图上的给错了). 传输时,从起始位开始,从一个数据的低位(LSB)开始发送,如图从左 ...
-
模拟I2C协议学习点滴之原理框架
I2C是一种串行总线协议. 目前几种常用的串行总线有UART.SPI和I2C协议.UART协议的总线只有两条,发送(Transmit:TX)和接收(Receive:RX),没有时钟信号,这就要求两位数 ...
-
51单片机GPIO口模拟串口通信
51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于: 分类: 深入C语言(20) 作者同 ...
-
STM32F10x_模拟I2C读写EEPROM
Ⅰ.写在前面 说到IIC,大家都应该不会陌生,我们初学单片机的时候或多或少都知道或了解过,甚至使用I2C控制过器件.但是,有多少人真正去深入理解,或者深入研究过I2C通信协议呢? 1.我们有必要学习I ...
-
STM32F4XX中断方式通过IO模拟I2C总线Master模式
STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址 的器件,无法做到中断方式完成读写大部分I2C器件.同 ...
-
lpc1788IO口模拟IIC
#ifndef __MYIIC_H_ #define __MYIIC_H_ #include "common.h" #include "delay.h" #in ...
-
单片机小白学步系列(二十) IO口原理
IO口操作是单片机实践中最基本最重要的一个知识,本篇花了比較长的篇幅介绍IO口的原理. 也是查阅了不少资料,确保内容正确无误,花了非常长时间写的. IO口原理原本须要涉及非常多深入的知识,而这里尽最大 ...
随机推荐
-
Windows Server 2008 R2 域控服务器运行nslookup命令默认服务器显示 UnKnown
一.问题: 域控服务器DOS窗口运行nslookup命令提示如下: 二.原因分析: 主要原因在于域控服务器的DNS服务器没有设置反向查找区域,计算机名称是通过IP地址反向查找到域控服务器的计算机名称. ...
-
JS刷新父窗口的几种方式
浮层内嵌iframe及frame集合窗口,刷新父页面的多种方法 <script language=JavaScript> parent.location.reload(); ...
-
svn学习笔记(2)操作----还原,重命名,冲突处理,权限配置等
1.查看某个文件的所有版本信息 2.版本还原,还原到之前的某一个版本 通过show log查看 查看某个文件的所有版本后,可以在这些版本之间*切换 3.文件改名 文件改名字给我们一个教训: 如:in ...
-
apk文件分析原则
如果在dex生成的jar文件里没有发现关键内容的话,就要注意jar里面的native函数以及loadlibrary操作,从而可以判断出加载了哪些so,调用了什么函数.就不会出现判断不出是不是加载了某s ...
-
shadow dom 隔离代码 封装
Shadow DOM是指浏览器的一种能力,它允许在文档(document)渲染时插入一棵DOM元素子树,但是这棵子树不在主DOM树中. Shadow DOM 解决了 DOM 树的封装问题. ...
-
iOS ----------要学习的地方(链接整理)
1.http://www.cocoachina.com/special/xcode/ 2.http://blog.csdn.net/a416863220/article/details/4111387 ...
-
Welcom to Swift
1.第一个程序 import Foundation println(“hello world”) 2.常用数据类型 int/UInt/Double/Float/Bool/String/Array/Di ...
-
JDBC 和连接池
1 JDBC概述 Java DataBase Connectivity,Java数据库连接,一种执行SQL的Java API,为多种关系数据库提供统一访问规范,由一组Java语言编写的类和接口组成.数 ...
-
luogu P1052 过河
传送门 容易想到设\(f_i\)表示走到坐标\(i\)的最少走过的石子数 但是这题数据范围很大,,, 不过一次可以走的步数范围是1-10,石子个数最多100个,所以中间会有很多多出来的没石子的路,可以 ...
-
20155302 Exp2 后门原理与实践
20155302<网络对抗>后门原理与实践 实验要求 1.使用netcat获取主机操作Shell,cron启动 (0.5分) 2.使用socat获取主机操作Shell, 任务计划启动 (0 ...