#include<msp430g2553.h>
void delay()
{
unsigned int a=5000;
while(a–)
_NOP();
}
int b=0;
void main(void)
{
//unsigned char b=0;
WDTCTL=WDTPW+WDTHOLD;
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1|=UCSWRST;
UCB0CTL0 = UCMST+UCMODE_3+UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 |= UCSSEL_2; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0X48; // Set slave address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0CTL1|=UCTR;
UCB0CTL1|=UCTXSTT;
delay();
UCB0TXBUF=0x01;
while(!(UCB0TXIFG&IFG2));
delay();
UCB0TXBUF=0X85;
while(!(UCB0TXIFG&IFG2));
delay();
UCB0TXBUF=0X83;
UCB0CTL1|=UCTXSTP;
while(UCB0CTL1&UCTXSTP);
UCB0CTL1|=UCTR;
UCB0CTL1|=UCTXSTT;
delay();
UCB0TXBUF=0X00;
delay();
UCB0CTL1|=UCTXSTP;
IFG2&=~UCB0TXIFG;
while(UCB0CTL1 &UCTXSTP);
UCB0CTL1&=~UCTR;
UCB0CTL1|=UCTXSTT;
delay();
while(!(UCB0RXIFG&IFG2));
b=UCB0RXBUF;
delay();
//UCB0CTL1|=UCTXSTT;
// UCB0CTL1|=UCTXSTP;
// while(UCB0STAT & UCBUSY);
while(!(UCB0RXIFG&IFG2));
b=b<<8+UCB0RXBUF;
delay();
UCB0CTL1|=UCTXSTP;
delay();
while(1);
}
Hardy Hu:
建议单步调试,第一步是看MCU有没有与ADS1115正确通讯上,第二部看寄存器是否写对,最后才看输出结果
shan wang1:
回复 Hardy Hu:
嗨,不知道你的问题解决了没有,我先在页是这个问题,很纠结!
haidong zhao:
你的I2c的从地址弄错了吧,addr pin 地址是7位,还有一位最低位. “0”是表示主机想写数据到从机,“1”表示主机想读从机的数据。要把最低位加上才是从机I2C的从地址吧。
Hardy Hu:
回复 haidong zhao:
1.把从机地址放进UCB0I2CSA,将UCB0CTLW0中的UCRT设置为需要的方式(receiver或者transmitter),USCI_B模块会由硬件完成移位等操作。
2.UCB0CTLW0 |=UCTXSTT, 后地址与方向信息就会发送,需要等待UCTXIFG时给TX BUFFER第一个数据,然后接受从机ACK,如果没有从机或者地址错误,则会触发NACK中断
XiaoLei Qin:
我用的时候会卡死在这句上 while(!(UCB0RXIFG&IFG2));
Hardy Hu:
回复 XiaoLei Qin:
一定要判断ACK位,估计你的IIC总线出现了NACK,则 while(!(UCB0RXIFG&IFG2)); 永远不成立,故会卡在这里
Hardy Hu:
回复 XiaoLei Qin:
两个办法:
1.用示波器抓波形,如果发送地址后的第9bit为高则是NACK;
2.NACKIFG被置1
HaiTao Li:
回复 XiaoLei Qin:
在I2C设定的时候,不要UCB0BR1 = 0这句,不知道为什么,我也是卡在这儿了,但是把他注视掉就好了。
Leon Yan:
你好:
下面是一个查询方式的例程,供参考。
void main(void){ unsigned char m; unsigned char n;
n = 2;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
__delay_cycles(10000);
if (CALBC1_16MHZ==0xFF)while(1); // do not load, trap CPU!! DCOCTL = 0; // Select lowest DCOx and MODx settings BCSCTL1 = CALBC1_16MHZ; // Set DCO DCOCTL = CALDCO_16MHZ;
#ifdef BEBUG_ON debug_uart_init(); debug_print("Master init…\r\n");#endif
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0I2CSA = 0x51; UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset#ifdef I2C400 UCB0BR0 = 40;#else UCB0BR0 = 160;#endif UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0STAT &= ~UCSTTIFG; // clear STT; IFG2 &= ~UCB0TXIFG; // clear TX int flag;
while(n–) { m_cmd_index_cur = m_cmd_cur = s_cmd_index_cur = 0;
for(m=0;m<96;m++) { t_m_i2c(M_CMD_index[m_cmd_index_cur], &M_CMD[m_cmd_cur], S_CMD_index[s_cmd_index_cur]); m_cmd_cur = m_cmd_cur + M_CMD_index[m_cmd_index_cur]; m_cmd_index_cur++; s_cmd_index_cur++;
__delay_cycles(1600); // used for waveform observation;
#ifdef BEBUG_ON debug_print("M: "); debug_print_hex(m); debug_print("\r\n");#endif }
__delay_cycles(160000); // used for waveform observation;
}
#ifdef BEBUG_ON debug_print("end\r\n");#endif
while (1);}
void t_m_i2c(unsigned int w_size, unsigned char *w_data, unsigned int r_size){ int m; unsigned char data_temp;
UCB0STAT &= ~UCSTTIFG; // clear STT; IFG2 &= ~UCB0TXIFG; // clear TX int flag; IFG2 &= ~UCB0RXIFG; // clear RX int flag;
if(w_size) { UCB0CTL1 |= UCTR | UCTXSTT; // send start; while(!(IFG2 & UCB0TXIFG)); // check start ok;
for(m=0;m<w_size;m++) { UCB0TXBUF = *w_data; w_data ++; while(!(IFG2 & UCB0TXIFG)); // check TX ok; } } else { _nop(); }
if(r_size > 0) { while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 &= ~UCTR; UCB0CTL1 |= UCTXSTT; while(!(UCB0CTL1 & UCTXSTT)); // check start ok;
for(m=0;m<r_size;m++) { while(!(IFG2 & UCB0RXIFG)); // check RX ok; data_temp = UCB0RXBUF; data_temp = data_temp; if(m == (r_size – 2)) UCB0CTL1 |= UCTXSTP; // send stop; } } else { UCB0CTL1 |= UCTR | UCTXSTP; // send stop; while (UCB0CTL1 & UCTXSTP); }}
HaiTao Li:
回复 Leon Yan:
想问一下Leon Yan,你这个程序是测试通过的么?
另外下面那一段是个什么意思,我在G2553的手册里没有找到关于UCB0BR0和UCB0BR1的详细说明
#ifdef I2C400 UCB0BR0 = 40; #else UCB0BR0 = 160; #endif
实际上,我在做G2553和ADS1115的IIC通讯的时候遇上了一些麻烦。能否就“始终设定”和“波特率寄存器”之间的关系做个说明