刚开始觉得硬件IIC很困难当我调整了后在知道,其实它就那么几句话。
很多程序,写了不一定记得住,放在这里方便记忆。
/* 程序效果: 主机msp430控制FCP8591,DA转换模拟输出方波,用LED可观看,AD转换 */
/* 把转换结果送DA转换模拟输出,用LED可观看。 */
/* 引脚连接: SDA--P3.1,SCL--P3.2 */
/* 注意事项: */
/* 1、对于从机的地址是七位,则最低位无效,控制读和写不在用最低位控制。 */
/* 2、对于从机的读写控制用寄存器UCTR来控制。 */
#include "msp430x24x.h"
#define CPU_Delay_us(t) __delay_cycles((long)t*8) //微秒延时
#define CPU_Delay_ms(t) __delay_cycles((long)t*8*1000) //毫秒延时
void Write_DA_one(unsigned char addrss,unsigned char date); //DA转换
void Read_DA_one(unsigned char control); //AD转换
unsigned char *PTxData; // 发送数据指针
unsigned char TXByteCtr; //发送数据统计
unsigned char RxData; //接收数据暂存
unsigned char TxData[5]; // 需要发送的数据
int main(void)
{
unsigned char i,j=10;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P3SEL |= 0x06; // Assign I2C pins to USCI_B0
for(i=9;i>0;i--) //仿真时,有效的解决I2C不在状态问题。
{
P3OUT |= BIT2;
CPU_Delay_us(500);
P3OUT &= ~BIT2;
CPU_Delay_us(500);
}
UCB0CTL1 |= UCSWRST; // 初始化,改变寄存器设置
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, 同步方式
UCB0CTL1 = UCSSEL_2+ UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x48; // 从机地址(0x90>>1)
UCB0CTL1 &= ~UCSWRST; // 关闭初始化, 恢复运行
while(j--)
{
Write_DA_one(0x40,0x00); //直接DA转换使得模拟输出方波
CPU_Delay_ms(40);
Write_DA_one(0x40,0xff);
CPU_Delay_ms(40);
}
while(1)
{
Read_DA_one(0x41);
CPU_Delay_ms(2);
Write_DA_one(0x40,RxData);
CPU_Delay_ms(10);
}
}
//------------------------------------------------------------------------------
// 模块功能:IIC中断
// 模块函数名:USCIAB0TX_VECTOR(这是一个中断标志有点代表性,在头文件中)
// 功能描述: 接收与发送中断控制由中断允许位控制,配合(UCTR)接收和发送。没有
// 打开中断允许控制位,buffer的数据会被传送。
//------------------------------------------------------------------------------
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if (TXByteCtr) // 检查TX字节计数器
{
UCB0TXBUF = *PTxData++; // Load TX buffer
TXByteCtr--; // TX字节计数器进行递减操作
}
else
{
UCB0CTL1 |= UCTXSTP; // I2C停止条件
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
RxData = UCB0RXBUF;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
//------------------------------------------------------------------------------
// 模块功能:发送一个DA转换数据
// 模块函数名:Write_DA_one(unsigned char addrss;unsigned char date)
// 功能描述: control是控制DA转换的(其实可以固定的写为0x40)。date是转换数据
//
//------------------------------------------------------------------------------
void Write_DA_one(unsigned char control,unsigned char date)
{
UCB0CTL1 |= UCTR; //发送模式
// UCB0CTL1 &= ~UCTR;
IE2 |= UCB0TXIE;
TxData[0]=control; //控制数据,当发送0X40,FCP8591进行DA转换
TxData[1]=date; //当设备准备好转换后,送转换数据
PTxData = (unsigned char *)TxData; // TX数组的起始地址
TXByteCtr = 2; // 加载TX字节计数器
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE);
}
//------------------------------------------------------------------------------
// 模块功能:接收一个AD转换数据
// 模块函数名:Read_AD_one(unsigned char addrss)
// 模块功能:先寻址后发送AD转换控制(通道一:0x41;通道二:0x42;),改发送
// 为接收状态,等待数据接收成功为止。
//------------------------------------------------------------------------------
void Read_DA_one(unsigned char control)
{
// UCB0CTL1 |= UCTR; //发送模式(在数据准备好的时候用配合开始条件)
IE2 |= UCB0TXIE;
TxData[0]=control;
PTxData = (unsigned char *)TxData; // TX array start address
TXByteCtr = 1; // Load TX byte counter
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE);
IE2 |= UCB0RXIE;
UCB0CTL1 &= ~UCTR; //接收模式
UCB0CTL1 |= UCTXSTT;
while (UCB0CTL1 & UCTXSTT);
__bis_SR_register(CPUOFF + GIE);
}