单片机 MSP430 IIC控制器编程(2)

来源:互联网 发布:淘梦淘宝大学教程网 编辑:程序博客网 时间:2024/05/18 22:50

直接附上最近调试成功的IIC控制器程序,只贴出IIC模块,因为程序最主要的东西就是IIC通信了,其次是那些参数的设置。

这个程序暂时还比较简单,因为项目还才做到一半。


iic.h

#include "utils.h"#ifndef __IIC_H__#define __IIC_H__void iic_master_init(uint8 slave_address);int8 iic_write_register_data(uint8 slave_address, uint8 reg_address, uint8 *data, uint8 data_len);int8 iic_read_register_one_byte(uint8 slave_address, uint8 reg_address, uint8 *data);#endif /* end of iic.h */


iic.h

#include "iic.h"#include "uart.h"#define MASTER_USE_NO_INTERRUPTvoid iic_master_init(uint8 slave_address){    //Assign I2C pins to USCI_B0    P3.1 IIC_SDA   P3.2 IIC_SCL    P3SEL |= 0x06;                //选择USCI模式    UCB0CTL1 |= UCSWRST;                            //置位UCSWRST, 使得USCI处于复位状态    UCB0CTL0 |= UCMST + UCMODE_3 + UCSYNC;          //主控, I2C, 同步模式    UCB0CTL1 |= UCSSEL_2 + UCSWRST;                 // Use SMCLK    UCB0BR0 = 240;                                  // fSCL = SMCLK/240 = 100kHz    UCB0BR1 = 0;    UCB0I2CSA = (slave_address >> 1);                      // Slave Address    UCB0CTL1 &= ~UCSWRST;                           // Clear SW reset, resume operation}static void iic_slave_init(uint8 self_address){    //Assign I2C pins to USCI_B0    P3.1 IIC_SDA   P3.2 IIC_SCL    P3SEL |= 0x06;                //选择USCI模式    UCB0CTL1 |= UCSWRST;                            //置位UCSWRST, 使得USCI处于复位状态    UCB0CTL0 &= ~UCMST;                             //受控    UCB0CTL0 |= UCMODE_3 + UCSYNC;                  //I2C, 同步模式    UCB0I2COA = self_address;                       // self address    UCB0CTL1 &= ~UCSWRST;                           // Clear SW reset, resume operation}static uint8 iic_is_busy(void){    uint8 busy = UCB0STAT & UCBBUSY;                //0, idle; 1, busy    return !!busy;}#ifdef MASTER_USE_NO_INTERRUPTstatic void iic_master_set_writemode(void){    UCB0CTL1 |= UCTR;                               //发送器    IFG2 &= ~UCB0TXIFG;                             //清除发送中断标志    IE2 &= ~UCB0RXIE;                               // Disable RX interrupt    IE2 &= ~UCB0TXIE;                               // Disable TX interrupt}static void iic_master_set_readmode(void){    UCB0CTL1 &= ~UCTR;                              //接收器    IFG2 &= ~UCB0RXIFG;                             //清除接收中断标志    IE2 &= ~UCB0TXIE;                               // Disable TX interrupt    IE2 &= ~UCB0RXIE;                               // Disable RX interrupt}//===========================================static int8 iic_master_send_multibyte_start_timeout(uint32 time_out){    volatile uint32 timeout = 0;    //发送起始信号    UCB0CTL1 |= UCTXSTT;    timeout = time_out;    //起始信号产生后,TXIFG会被置位,此时从器件已经对地址作出应答(可以再判断UCTXSTT是否被清零)    while(!(IFG2 & UCB0TXIFG) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        return __TIMEOUT;                                       //超时    }    IFG2 &= ~UCB0TXIFG;                                         //清除发送中断标志    return __OK;}static int8 iic_master_send_multibyte_next_timeout(uint8 tx_data, uint32 time_out){    volatile uint32 timeout = 0;    //先发送一个字节数据    UCB0TXBUF = tx_data;    timeout = time_out;    //等待该字节发送完毕    while(!(IFG2 & UCB0TXIFG) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        return __TIMEOUT;                                       //超时    }    IFG2 &= ~UCB0TXIFG;                                         //清除发送中断标志    return __OK;}static int8 iic_master_send_multibyte_finish_timeout(uint8 tx_data, uint32 time_out){    iic_master_send_multibyte_next_timeout(tx_data, time_out);    //发送停止信号    UCB0CTL1 |= UCTXSTP;    return __OK;}static void iic_master_send_multibyte_stop(void){    //发送停止信号    UCB0CTL1 |= UCTXSTP;}//==================================================static int8 iic_master_recv_multibyte_start_timeout(uint32 time_out){    volatile uint32 timeout = 0;    //Send start condition, and master device will send slave_address to slave device    UCB0CTL1 |= UCTXSTT;    timeout = time_out;    //从器件已经对地址作出应答,UCTXSTT就被清零    while((UCB0CTL1 & UCTXSTT) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        return __TIMEOUT;                                     //超时    }    return __OK;}static int8 iic_master_recv_multibyte_next_timeout(uint8 *rx_data, uint32 time_out){    volatile uint32 timeout = 0;    timeout = time_out;    // Wait for RX buffer    while((!(IFG2 & UCB0RXIFG)) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        return __TIMEOUT;    }    IFG2 &= ~UCB0RXIFG;    //Capture data from receive buffer after setting stop bit due to    //MSP430 I2C critical timing.    *rx_data = UCB0RXBUF;    return __OK;}static int8 iic_master_recv_multibyte_finish_timeout(uint8 *rx_data, uint32 time_out){    volatile uint32 timeout = 0;    //发送停止信号    UCB0CTL1 |= UCTXSTP;    timeout = time_out;    //等待停止信号发送成功: 主机在接收完最后一个字节后,就发起停止信号,从机停止向主机发送数据    while((UCB0CTL1 & UCTXSTP) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        return __TIMEOUT;    }    timeout = time_out;    // Wait for RX buffer    while((!(IFG2 & UCB0RXIFG)) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        return __TIMEOUT;    }    IFG2 &= ~UCB0RXIFG;    //Capture data from receive buffer after setting stop bit due to    //MSP430 I2C critical timing.    *rx_data = 0x00;    *rx_data = UCB0RXBUF;    return __OK;}static void iic_master_recv_multibyte_stop(void){    //发送停止信号    UCB0CTL1 |= UCTXSTP;}#endif  /* end of MASTER_USE_NO_INTERRUPT *///===================================================int8 iic_write_register_data(uint8 slave_address, uint8 reg_address, uint8 *data, uint8 data_len){    uint8 i = 0;    int8 ret = __OK;    Printf("0000\n");    iic_master_init(slave_address);    //检测IIC总线是否繁忙    while( iic_is_busy() == 1)    {        ;    }    //设置发送模式    iic_master_set_writemode();    //开始一次数据传输:先发送寄存器地址    ret = iic_master_send_multibyte_start_timeout(100);    if(ret == __TIMEOUT)    {        iic_master_send_multibyte_stop();        Printf("1111\n");        return ret;    }    ret= iic_master_send_multibyte_next_timeout(reg_address, 1000);    if(ret == __TIMEOUT)    {        iic_master_send_multibyte_stop();        Printf("2222\n");        return ret;    }    for(i = 0; i < data_len; i++)    {        ret= iic_master_send_multibyte_next_timeout(*(data + i), 1000);        if(ret == __TIMEOUT)        {            iic_master_send_multibyte_stop();            Printf("3333\n");            return ret;        }    }    iic_master_send_multibyte_stop();    Printf("4444\n");    return __OK;}#if 1int8 iic_read_register_one_byte(uint8 slave_address, uint8 reg_address, uint8 *data){    int8 ret = __OK;    Printf("0000\n");    iic_master_init(slave_address);    Printf("6666\n");    //检测IIC总线是否繁忙    while( iic_is_busy() == 1)    {        ;    }    Printf("7777\n");    //设置发送模式: 写    iic_master_set_writemode();    //发送起始信号和器件地址    ret = iic_master_send_multibyte_start_timeout(100);    if(ret == __TIMEOUT)    {        iic_master_send_multibyte_stop();        Printf("1111\n");        return ret;    }    //发送寄存器地址    ret = iic_master_send_multibyte_next_timeout(reg_address, 1000);    if(ret == __TIMEOUT)    {        iic_master_send_multibyte_stop();        Printf("2222\n");        return ret;    }    //设置接收模式    iic_master_set_readmode();    //发送起始信号和器件地址    ret = iic_master_recv_multibyte_start_timeout(600000);    if(ret == __TIMEOUT)    {        iic_master_recv_multibyte_stop();        Printf("3333\n");        return ret;    }    //接收从机发来的一个字节    ret = iic_master_recv_multibyte_finish_timeout(data, 10000);    if(ret == __TIMEOUT)    {        iic_master_recv_multibyte_stop();        Printf("5555\n");        return ret;    }    Printf("4444\n");    return __OK;}#elseint8 iic_read_register_one_byte(uint8 slave_address, uint8 reg_address, uint8 *data){    int8 ret = __OK;    Printf("0000\n");    iic_master_init(slave_address);    Printf("6666\n");    //检测IIC总线是否繁忙    while( iic_is_busy() == 1)    {        ;    }    Printf("1212120\n");    //设置发送模式: 写    iic_master_set_writemode();    //开始一次数据传输:先发送寄存器地址    volatile uint32 timeout = 0;    //Send start condition.    UCB0CTL1 |= UCTXSTT;    timeout = 100;    //Poll for transmit interrupt flag.    while(!(IFG2 & UCB0TXIFG) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        Printf("7777 timeout\n");        return __TIMEOUT;                                     //超时    }    IFG2 &= ~UCB0TXIFG;                             //清除发送中断标志    //Send single byte data.    UCB0TXBUF = reg_address;    Printf("34444\n");    timeout = 100;    //Poll for transmit interrupt flag.    while(!(IFG2 & UCB0TXIFG) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        Printf("78956 timeout\n");        return __TIMEOUT;                                     //超时    }    IFG2 &= ~UCB0TXIFG;                             //清除发送中断标志    //设置接收模式    iic_master_set_readmode();    //发送起始信号: 读    UCB0CTL1 |= UCTXSTT;    timeout = 5000;    //Poll for transmit interrupt flag.    while((UCB0CTL1 & UCTXSTT) && (--timeout))    {        //PutChar('x');    }    if(timeout == 0)    {        Printf("3131 timeout\n");        return __TIMEOUT;                                     //超时    }    //Send stop condition.    UCB0CTL1 |= UCTXSTP;    timeout = 5000;    //Wait for Stop to finish    while((UCB0CTL1 & UCTXSTP) && (--timeout))    {        //PutChar('x');    }    //Check if transfer timed out    if(timeout == 0)    {        Printf("9990 timeout\n");        return __TIMEOUT;    }    Printf("2244\n");    timeout = 5000;    // Wait for RX buffer    while((!(IFG2 & UCB0RXIFG)) && (--timeout))    {        //PutChar('x');    }    //Check if transfer timed out    if(timeout == 0)    {        Printf("1234 timeout\n");        return __TIMEOUT;    }    IFG2 &= ~UCB0RXIFG;    //Capture data from receive buffer after setting stop bit due to    //MSP430 I2C critical timing.    *data = UCB0RXBUF;    Printf("4444\n");    return __OK;}#endif//======================================================#ifdef USE_INTERRUPTvoid iic_set_writeMode(void){    UCB0CTL1 |= UCTR;                               //发送器    IFG2 &= UCB0TXIFG;                              //清楚发送中断标志    IE2 &= ~UCB0RXIE;                               // Disable RX interrupt    IE2 |= UCB0TXIE;                                // Enable TX interrupt}void iic_ReadMode(void){    UCB0CTL1 &= ~UCTR;                              //接收器    IFG2 &= UCB0RXIFG;                              //清楚接收中断标志    IE2 &= ~UCB0TXIE;                               // disable TX interrupt    IE2 |=  UCB0RXIE;                               // enable RX interrupt}#endif



0 0