单片机 MSP430 模拟IIC编程(1)
来源:互联网 发布:淘宝保证金计划5000元 编辑:程序博客网 时间:2024/05/18 23:54
20151121
以下附上的是模拟IIC通信模块程序,是我在TI官网提供的投影仪评估板例程中拿出来的,本人还没有验证,暂且认为他可以工作,估计下个星期就会去验证他,到时候再修改。
其实贴出这个程序的主要目的是,我刚开始不理解他对于SCL、SDA的高低电平的操作方法,下一篇文章我将解释。
i2c_master.h
#ifndef __i2c_master#define __i2c_master#ifdef __cplusplusextern "C" {#endif// defines#define I2C_NO_ACK 0// functionsvoid I2C_Master_Start(void);void I2C_Master_Stop(void);uint08 I2C_MasterTransmitByte(uint08 data);uint08 I2C_MasterReceiveByte(void);uint08 I2C_PolledMasterWrite(uint08 device_addr, uint08* write_data, uint08 num_bytes);uint08 I2C_PolledMasterRead(uint08 device_addr, uint08* read_data, uint08 num_bytes);//uint08 I2C_Write_DPP(uint08 subaddr, uint32 data);//uint08 I2C_Read_DPP(uint08 subaddr, uint32* data);void I2C_Master_Init (void);void I2C_SetSDA_High (void);void I2C_SetSDA_Low (void);BOOL I2C_GetSDA_Input (void);void I2C_SetSCL_High (void);void I2C_SetSCL_Low (void);BOOL I2C_GetSCL_Input (void);#ifdef __cplusplus /* matches __cplusplus construct above */}#endif#endif // #ifndef __i2c_master
i2c_master.c
#include "common.h"#include "i2c_master.h"#include "msp430x22x4.h"//org ==> //#include "msp430f2132.h"#include "ddp343xEVM_pins.h"#define SDA_HI I2C_SetSDA_High()#define SDA_LO I2C_SetSDA_Low()#define SDA_IN I2C_GetSDA_Input()#define SCL_HI I2C_SetSCL_High()#define SCL_LO I2C_SetSCL_Low()#define SCL_IN I2C_GetSCL_Input()// local functions//uint08 i2c_master_check_nak_timeout(uint08 timeout, uint08 check_nak);//void i2c_master_cleanup(void);////////////////////////////////////////////////////////////////////////void I2C_Master_Start(void) // Set up start condition for I2C/** * Generates the start condition for I2C read/write * */{volatile uint08 i; SDA_HI; __no_operation(); SCL_HI; for (i=0; i<5; i++) { __no_operation(); SDA_LO; __no_operation(); __no_operation(); SCL_LO; //after end of start condition both SDA and SCL will be low }}////////////////////////////////////////////////////////////////////////void I2C_Master_Stop(void) // Set up stop condition for I2C/** * Generates the stop condition for I2C read/write * */{ volatile uint08 i; SDA_LO; __no_operation(); SCL_HI; for (i=0; i<8; i++) { __no_operation(); } SDA_HI; i=0; //ensure bus is in default condition ( freed by slave) while(!SDA_IN) // i is just a variable to control the while loop run time. { SCL_HI; __no_operation(); __no_operation(); SCL_LO; __no_operation(); __no_operation(); i++; if( i > 25) { break; } } SCL_HI; //After generating stop condition SCL and SDA are both high. Default condition for I2C bus. }////////////////////////////////////////////////////////////////////////uint08 I2C_PolledMasterWrite(uint08 device_addr, uint08* write_data, uint08 num_bytes)/** * Writes data to the specified device address * * @param device_addr - I - 7 Bit device Address * @param write_data - I - Pointer to data buffer to be written to slave * @param num_bytes - I - Number of bytes to be written * @return PASS - Completed successfully * I2C_NO_ACK - Slave NAck'ed * */{ uint08 ByteCount; uint08 *data_ptr; uint08 status=PASS; // initialize pointer to the data and start the transfer data_ptr = write_data; // Generate START condition // // Data line loow when clock is high // I2C_Master_Start(); // Before writing address ensure the bit 0 is set to zero // Bit 0 =0 means master is writing , Bit 0 =1 means master wants to read // BIT0 = 0x1 if (I2C_MasterTransmitByte(device_addr & ~0x1) == I2C_NO_ACK) { // If not Acknowledged by slave// status = I2C_NO_ACK; } else // Tranmit all the data bytes as slave has acknowledged// { for (ByteCount=0; ByteCount<num_bytes; ByteCount++) { if (I2C_MasterTransmitByte(*data_ptr)== I2C_NO_ACK) { // If not Acknowledged by slave// status = I2C_NO_ACK; break; } else data_ptr++; } } // Generate STOP Condition // Data line high, when clock is high I2C_Master_Stop(); return status;}////////////////////////////////////////////////////////////////////////uint08 I2C_PolledMasterRead(uint08 device_addr, uint08* read_data, uint08 num_bytes)/** * Reads data from the specified device address * * @param device_addr - I - 7 Bit device Address * @param read_data - I - Pointer to buffer to hold received data from slave * @param num_bytes - I - Number of bytes to be read * @return PASS - Completed successfully * I2C_NO_ACK - Slave NAck'ed * */{ uint08* data_ptr; uint08 status=PASS; uint08 ByteCount; data_ptr = read_data; // Generate START condition // // Data line low when clock is high // I2C_Master_Start(); // Transmit the slave address // // Before writing address ensure the bit 0 is set to 1 // Bit 0 =0 means master is writing , Bit 0 =1 means master is reading // BIT0 = 0x1 if(I2C_MasterTransmitByte(device_addr | 0x1) == I2C_NO_ACK) { // If not Acknowledged // status = I2C_NO_ACK; } else { // Receive all the data bytes // for(ByteCount = 0; ByteCount < num_bytes; ByteCount++) { *data_ptr = I2C_MasterReceiveByte(); data_ptr++; } } // Generate STOP Condition // Data line high, when clock is high I2C_Master_Stop(); return status;}////////////////////////////////////////////////////////////////////////uint08 I2C_MasterTransmitByte(uint08 data)/** * This routine transmits one byte of data over the given clock and data lines and * receives the ack from slave. * * @param data - I - The 8 bit data to be transmitted * @return I2C_NO_ACK - Not Acknowledgeed * PASS - Acknowledged * */{ uint08 Ack=1; uint08 i; uint08 Byte = data; // Send Byte It is assumed that the start condition would have made SCL and SDA low. // SDA should change only when SCA is low. SCL_LO; for(i = 0; i < 8 ; i++) { if( Byte & 0x80) SDA_HI; else SDA_LO; __no_operation(); __no_operation(); SCL_HI; Byte <<= 1; __no_operation(); //need to optimize the delay. __no_operation(); __no_operation(); __no_operation(); SCL_LO; //leave SDA at the end if(i == 7) { SDA_HI; } __no_operation(); __no_operation(); } //Receive Ack __no_operation(); __no_operation(); SCL_HI; __no_operation(); __no_operation(); // delay added bcoz without this delay ack was received wrong. __no_operation(); // need to optimize the delay. // If data line is pulled low by slave- it is acknowledged if (SDA_IN) Ack = 0; //ack not received else Ack = 1; //ack received SCL_LO; __no_operation(); __no_operation(); SDA_LO; //After transmitting one byte of data SCL and SDA are both low. return Ack;}////////////////////////////////////////////////////////////////////////uint08 I2C_MasterReceiveByte()/** * This routine receives one byte of data over the given clock and data lines and * sends the ack to slave. * * @return one byte of data received from slave. * */{ uint08 Data=0; uint08 i; //Make SDA as input SDA_HI; __no_operation(); __no_operation(); for(i = 0; i < 8 ; i ++) { SCL_HI; __no_operation(); __no_operation(); Data <<= 1; if (SDA_IN) Data |=1; else Data |=0; SCL_LO; __no_operation(); __no_operation(); } //After the eight bits are transferred by slave, slave will pull SDA high ( default condition for I2C bus) // Generate ack for slave. SDA_LO; __no_operation(); __no_operation(); SCL_HI; __no_operation(); __no_operation(); SCL_LO; //After receiving one byte of data SCL and SDA are both low. return Data;}//////////////////////////////////////////////////void I2C_Master_Init(void)/** * Initializes I2C. Makes SCL and SDA high. */{ //bit banging P3SEL &= ~(SCL | SDA); // Set GPIO function P3OUT &= ~(SDA | SCL); I2C_SetSCL_Low(); //although not required but want to make sure SCL is low when SDA goes high I2C_SetSDA_High(); __no_operation(); I2C_SetSCL_High(); __no_operation();}///////////////////////////////////////////////////* I2C SDA and SCL Lines */void I2C_SetSDA_High (void){ P3DIR &= ~SDA;}//////////////////////////////////////////////////void I2C_SetSDA_Low (void){ P3DIR |= SDA;}//////////////////////////////////////////////////BOOL I2C_GetSDA_Input (void){ return (P3IN & SDA ? 1 : 0);}//////////////////////////////////////////////////void I2C_SetSCL_High (void){ P3DIR &= ~SCL;}//////////////////////////////////////////////////void I2C_SetSCL_Low (void){ P3DIR |= SCL;}//////////////////////////////////////////////////BOOL I2C_GetSCL_Input (void){ return (P3IN & SCL ? 1 : 0);}
0 0
- 单片机 MSP430 模拟IIC编程(1)
- 单片机 MSP430 模拟IIC编程(2)
- 单片机 MSP430 IIC控制器编程(1)
- 单片机 MSP430 IIC控制器编程(2)
- 51单片机 软件模拟IIC
- 自制BSL编程MSP430单片机
- 51单片机IIC总线编程
- 单片机模拟IIC时序读写24C02
- MSP430单片机
- MSP430单片机
- MSP430 IIC通信
- 单片机--iic
- 单片机iic
- 基于51单片机实现模拟IIC总线时序
- 单片机模拟 IIC 总线与 EEPROM(AT24C02)通信
- 基于51单片机实现模拟IIC总线时序
- STM32F103单片机软件模拟IIC并读取TMP112数字温度传感器
- 模拟IIC
- JAVA将一个字符串反向颠倒
- 大数加法模板
- LeetCode -- Linked List Cycle II
- JAVA去掉一个字符串的前后空格
- php eval使用
- 单片机 MSP430 模拟IIC编程(1)
- Android Intent 用法全面总结
- DBUtil的使用
- matlab 图像处理
- 响应式布局
- 内存对齐
- LeetCode -- LRU Cache
- 在Eclipse中搭建ArcGIS API for JavaScript 3.9 开发环境
- c++ 对象模型(二)