MSP430的IO口模拟I2C总线对AT24C25进行读写程序
功能: 实现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口原理原本须要涉及非常多深入的知识,而这里尽最大 ...
随机推荐
- Java语言基础(五)
Java语言基础(五) 一.浮点数 浮点数就是小数,其标准是IEEE 754,用指数和尾数表示 例如30000=3*10000=3*10^4 其中4是指数,3是尾数 Java中,浮点数有float ...
- Objective-C--@property,@synthesize关键字介绍
Objective-C–@property,@synthesize关键字介绍 转载:http://www.cnblogs.com/QM80/p/3576282.html /** 注意:由@proper ...
- Dapper Use For Net
Dapper.Net by example januari 6, 2012 When the team behind StackOverflow released the mini-ORM Dappe ...
- 利用 Lua 实现 App 动态化方案
因为动态化的东西我第一次看实现方案的源码,而且目前还是大三的学生,缺少很多实践经验说错的地方还请原谅,也希望能指出,被告知.想了很久还是决定写出来,求大神勿喷. 并且我的一个朋友bestswifter ...
- Java基础知识强化之集合框架笔记16:List集合的特有功能概述和测试
1. List集合的特有功能概述: (1)添加功能: void add(int index, Object element):在指定位置添加元素 (2)获取功能: Object get(int ind ...
- 本地tomcat访问mysql数据库
虽然以前经常听人说起过tomcat,但是今天头一次使用tomcat. 1.Tomcat的安装过程: 首先应该从Apache官方网站上下载是用于Windows的.zip压缩包. 下面是相应的下载链接: ...
- Android布局管理器(贞布局)
贞布局有FrameLayout所代表,它直接继承了ViewGroup组建 贞布局为每个加入其中的组件创建一个空白区域(一帧),所以每个子组件占用一帧,这些贞都会根据gravity属性执行自动对齐 贞布 ...
- Javascript的AMD规范
Javascript发展到今天,已经从一个小丑语言变成了不可替代的前端利器,已经脱离了低端的玩笑脚步,而转变为有规可依的强大语言. 本文主要讲述下如今被大力推广的AMD规范,为什么要AMD,什么场景是 ...
- Chess---->简单命令框象棋(人VS人)
简单粗暴,直接先上代码: ChessBoard.h: 1 #ifndef CHESBOARD_H 2 #include<iostream> 3 #include<string& ...
- input+div 下拉选择框
前台html页面 <html> <head> <meta name="viewport" content="width=device-wid ...