|
最近在调试MSP430F5437单片机读写24LC系列EEPROM的过程中遇到了一些问题卡住了,一时不知如何解决,还请各位大侠多多帮助,不胜感激!!!先在这里谢过了。
情况是这样的:我看到网上大多都是用软件模拟的方式去模拟IIC协议,实现数据的传输,感觉过程比较繁琐。而MSP430F5xx系列单片机内部自带IIC模块,于是我写了一个程序去实现。单步调试时,发现程序总是停在while((UCB1IFG & UCTXIFG)==0);这个语句。这个语句在程序中用来判断UCB1TXBUF的数据是否被取走,取走则UCTXIFG置1,程序才能继续执行,继续发送数据。但实际上,好像UCB1TXBUF的数据没有被取走,UCTXIFG总是为0。
下面是我的程序:
/*-------------------------------------------------------------------------------------------*/
#include "msp430x54x.h"
typedef unsigned char u8;
u8 data[8];
u8 buffer[8];
void delay(unsigned short i)
{
while(i--);
}
void Init_IIC(void)
{
UCB1CTL1 |= UCSWRST; // Enable SW reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB1CTL1 |= UCSSEL_2 ; // Use SMCLK
UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = 0x50; // Slave Address is 50h
P3SEL |= 0x80; // P3.7 as SDA
P5SEL |= 0x10; // P5.4 as SCL
// P3SEL |= 0x06;
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE+UCRXIE; // Enable TX RX interrupt
}
void DataPageTrans(u8 StartAddr,u8 *ptr)
{
while(UCB1CTL1 & UCTXSTP); // 确保停止位已发出,总线空闲
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
UCB1TXBUF=0xa0; //device addr
while((UCB1IFG & UCTXIFG)==0);
UCB1TXBUF=StartAddr; //sub-device addr
while((UCB1IFG & UCTXIFG)==0);
for(u8 i=0;i<8;i++)
{
UCB1TXBUF=*(ptr+i);
while((UCB1IFG & UCTXIFG)==0);
}
UCB1CTL1 |= UCTXSTP; // I2C stop condition
while((UCB1CTL1 & UCTXSTP)==1); // 等待停止信号是否已发送完成
}
void DataTrans(u8 StartAddr,u8 data)
{
while(UCB1CTL1 & UCTXSTP); // 确保停止位已发出,总线空闲
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
// UCB1TXBUF=0xa0; //device addr
// while((UCB1IFG & UCTXIFG)==0);
UCB1TXBUF=StartAddr; //sub-device addr
while((UCB1IFG & UCTXIFG)==0);
UCB1TXBUF=data;
while((UCB1IFG & UCTXIFG)==0);
UCB1CTL1 |= UCTXSTP; // I2C stop condition
while((UCB1CTL1 & UCTXSTP)==1); // 等待停止信号是否已发送完成
}
void DataStrRec(u8 StartAddr,u8 *ptr)
{
/*dummy write 哑写入*/
while (UCB1CTL1 & UCTXSTP); // 确保停止位已发出,总线空闲
UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
// UCB1TXBUF=0xa0; //device addr
// while((UCB1IFG & UCTXIFG)==0);
UCB1TXBUF=StartAddr; //sub-device addr
while((UCB1IFG & UCTXIFG)==0);
/*----------*/
UCB1CTL1 &= ~UCTR;
UCB1CTL1 |= UCTXSTT;
while((UCB1CTL1 & UCTXSTT)==1); // 确保发出
// UCB1TXBUF=0xa1; //device addr
// while((UCB1IFG & UCTXIFG)==0);
for(u8 i=0;i<8;i++)
{
*(ptr+i)=UCB1RXBUF;
while((UCB1IFG&UCRXIFG)==0);
}
UCB1CTL1 |= UCTXSTP; // I2C stop condition
}
unsigned char DataRec (u8 StartAddr)
{
while (UCB1CTL1 & UCTXSTP); // 确保停止位已发出,总线空闲
UCB1CTL1 |= UCTXSTT + UCTR; // 启动开始信号+写模式
UCB1TXBUF = StartAddr; // 写入地址
while((UCB1IFG & UCTXIFG)==0);
UCB1CTL1 &= ~UCTR; // 改为读模式
UCB1CTL1 |= UCTXSTT; // 重新启动开始信号
while((UCB1CTL1 & UCTXSTT)==1); // 确保发出
delay(1000); // 增加一个适当延时
while((UCB1IFG&UCRXIFG)==0); // 等待接受一个数据
u8 tmp = UCB1RXBUF; // 读入一个数据
UCB1CTL1 |= UCTXSTP+ UCTXNACK; // 启动停止信号,发应答信号
return tmp;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
data[0]=1;
for(u8 i=0;i<7;i++)
{
data[i+1]=data+1;
}
/***********************init*****************/
Init_IIC();
_EINT();
/***********************trans*****************/
// DataPageTrans(0,data);
DataTrans(0x05,0xaa);
/*********************rec*******************/
// DataStrRec(0,buffer);
buffer[0]=DataRec(0x05);
while(1);
}
/*---------------------------------------------------------------------------------------*/
问题到底在哪里呢?还望大家给出出主意。
(原文件名:硬件电路图.PNG) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|