MSP430F2013的I2C与C8051F410的SMBus通信问题
请问有没有人用过MSP430F2013的USI---I2C与 C8051F410的SMBus 进行通信?有没有什么注意事项?我尝试用它们的例程,C8051F410为主机,MSP430F2013为从机,不知为何,从机没有响应?? 请问两个单片机的系统时钟要求一致吗? 请问有没有谁用过MSP430F2013的I2C模块,有没有什么要注意的方面?为什么和C8051F410连接没有响应呢? 同样问题,帮顶。我的问题是,MSP430F2013的USI---I2C做为从,只能识到地址,下一步接数据就有问题了, 楼上请问你是怎么看出来识别出地址的? 可以用仿真看,程序状态啊! 回复【5楼】sunrun
-----------------------------------------------------------------------
哦,是的,我也用示波器看了一下,当时只是显示开始和发送地址的波形 昨天晚上终于找到原因了,说出来很惭愧,不过还是得说,以此自警。
采用的例程会在从机没有响应的时候重新开始通信。调试过程中偶然间看到了数据发送的波形,事实上我并没有对程序进行修改,但之前一直没有通信,只是显示开始和地址波形。这样发送的数据波形时有时无,有些不解。找原因。偶然想到可能是单片机焊接的不还,引脚接触不良。于是又焊了一下,测试,的确是这个原因!忙了好几天,最后发现是这个原因!以此自警!!谨记谨记! 回复【3楼】sunrun
同样问题,帮顶。
我的问题是,msp430f2013的usi---i2c做为从,只能识到地址,下一步接数据就有问题了,
-----------------------------------------------------------------------
地址接收了说明可以正常通信,你的程序是自己写的还是TI的例程?是不是从机ACK发送错了(发送的是NACK?)?地址设置的对吗?你可以先用TI的例程试一下,另外也可以用示波器观察一下,这样比较直观 //******************************************************************************
//MSP430F20xx Demo - I2C Slave Receiver / Slave Transmitter, multiple bytes
//
//Description: I2C Master communicates with I2C Slave using
//the USI. Master data should increment from 0x55 with each transmitted byte.
//ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz
//
//***THIS IS THE SLAVE CODE***
//
// Slave Master
// (msp430x20x3_usi_12.c)
// MSP430F20x2/3 MSP430F20x2/3
// ----------------- -----------------
// /|\| XIN|- /|\| XIN|-
// | | | | | |
// --|RST XOUT|- --|RST XOUT|-
// | | | |
// LED <-|P1.0 | | |
// | | | P1.0|-> LED
// | SDA/P1.7|------->|P1.6/SDA |
// | SCL/P1.6|<-------|P1.7/SCL |
//
//Note: internal pull-ups are used in this example for SDA & SCL
//
//R. B. Elliott / H. Grewal
//Texas Instruments Inc.
//February 2008
//Built with IAR Embedded Workbench Version: 3.42A
//******************************************************************************
#include<msp430x20x3.h>
#define Number_of_Bytes5 // **** How many bytes?? ****
void Setup_USI_Slave(void);
char MST_Data = 0; // Variable for received data
char SLV_Data = 0x55;
char SLV_Addr = 0x90; // Address is 0x48<<1 for R/W
int I2C_State, Bytecount, transmit = 0; // State variables
void Data_RX(void);
void TX_Data(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;
Setup_USI_Slave();
LPM0; // CPU off, await USI interrupt
_NOP();
}
//******************************************************************************
// USI interrupt service routine
// Rx bytes from master: State 2->4->6->8
// Tx bytes to Master: State 2->4->10->12->14
//******************************************************************************
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
if (USICTL1 & USISTTIFG) // Start entry?
{
P1OUT |= 0x01; // LED on: sequence start
I2C_State = 2; // Enter 1st state on start
}
switch(__even_in_range(I2C_State,14))
{
case 0: // Idle, should not get here
break;
case 2: // RX Address
USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, RX address
USICTL1 &= ~USISTTIFG; // Clear start flag
I2C_State = 4; // Go to next state: check address
break;
case 4: // Process Address and send (N)Ack
if (USISRL & 0x01){ // If master read...
SLV_Addr = 0x91; // Save R/W bit
transmit = 1;}
else{transmit = 0;
SLV_Addr = 0x90;}
USICTL0 |= USIOE; // SDA = output
if (USISRL == SLV_Addr) // Address match?
{
USISRL = 0x00; // Send Ack
P1OUT &= ~0x01; // LED off
if (transmit == 0){
I2C_State = 6;} // Go to next state: RX data
if (transmit == 1){
I2C_State = 10;} // Else go to next state: TX data
}
else
{
USISRL = 0xFF; // Send NAck
P1OUT |= 0x01; // LED on: error
I2C_State = 8; // next state: prep for next Start
}
USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
break;
case 6: // Receive data byte
Data_RX();
break;
case 8:// Check Data & TX (N)Ack
USICTL0 |= USIOE; // SDA = output
if (Bytecount <= (Number_of_Bytes-2))
// If not last byte
{
USISRL = 0x00; // Send Ack
I2C_State = 6; // Rcv another byte
Bytecount++;
USICNT |= 0x01; // Bit counter = 1, send (N)Ack bit
}
else // Last Byte
{
USISRL = 0xFF; // Send NAck
USICTL0 &= ~USIOE; // SDA = input
SLV_Addr = 0x90; // Reset slave address
I2C_State = 0; // Reset state machine
Bytecount =0; // Reset counter for next TX/RX
}
break;
case 10: // Send Data byte
TX_Data();
break;
case 12:// Receive Data (N)Ack
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack
I2C_State = 14; // Go to next state: check (N)Ack
break;
case 14:// Process Data Ack/NAck
if (USISRL & 0x01) // If Nack received...
{
USICTL0 &= ~USIOE; // SDA = input
SLV_Addr = 0x90; // Reset slave address
I2C_State = 0; // Reset state machine
Bytecount = 0;
// LPM0_EXIT; // Exit active for next transfer
}
else // Ack received
{
P1OUT &= ~0x01; // LED off
TX_Data(); // TX next byte
}
break;
}
USICTL1 &= ~USIIFG; // Clear pending flags
}
void Data_RX(void){
USICTL0 &= ~USIOE; // SDA = input
USICNT |=0x08; // Bit counter = 8, RX data
I2C_State = 8; // next state: Test data and (N)Ack
}
void TX_Data(void){
USICTL0 |= USIOE; // SDA = output
USISRL = SLV_Data++;
USICNT |=0x08; // Bit counter = 8, TX data
I2C_State = 12; // Go to next state: receive (N)Ack
}
void Setup_USI_Slave(void){
P1OUT = 0xC0; // P1.6 & P1.7 Pullups
P1REN |= 0xC0; // P1.6 & P1.7 Pullups
P1DIR = 0xFF; // Unused pins as outputs
P2OUT = 0;
P2DIR = 0xFF;
USICTL0 = USIPE6+USIPE7+USISWRST; // Port & USI mode setup
USICTL1 = USII2C+USIIE+USISTTIE; // Enable I2C mode & USI interrupts
USICKCTL = USICKPL; // Setup clock polarity
USICNT |= USIIFGCC; // Disable automatic clear control
USICTL0 &= ~USISWRST; // Enable USI
USICTL1 &= ~USIIFG; // Clear pending flag
transmit = 0;
_EINT();
} 我的程序是自已改的.改动不多.调了几天还是找不到问题.手上没有示波器,真是寸步难行啊.... 请问楼主.这下地址主机你发的是什么."char SLV_Addr = 0x90; // Address is 0x48<<1 for R/W "
是发0x90还是发的 0x48,
地址为什么要左移一位呢. 回复【11楼】sunrun
请问楼主.这下地址主机你发的是什么."char slv_addr = 0x90; // address is 0x48<<1 for r/w "
是发0x90还是发的 0x48,
地址为什么要左移一位呢.
-----------------------------------------------------------------------
我用C8051F410做主机,地址和从机的地址一样,都是0x90,最后一位是读写控制位,不用移位。注释的意思是0x90=0x48<<1,这样最后一位就是读写控制位了。实际是0x90代表从机地址为0x90,主机进行写操作;0x91表示从机地址为0x90,主机进行读操作,所以发送的是0x90(主机写)或0x91(主机读)。
能不能借台示波器,通过波形可以分析程序的运行情况,尤其是第一次使用I2C,没有经验,用处的确很大... 我也是这样写的.示波器没有熟人借不到.以前到写过IIC.但是没有用430的USI写过.真是晕......
不知道 是我的从机没有发应答还是其它原因/
-----------------------------------------------------------------------
回复【楼主位】PowerSource
请问有没有人用过msp430f2013的usi---i2c与 c8051f410的smbus 进行通信?有没有什么注意事项?我尝试用它们的例程,c8051f410为主机,msp430f2013为从机,不知为何,从机没有响应??
-----------------------------------------------------------------------
楼主用SMBUS是用在哪方面啊.能不将代码发给我参考一下,方便的话请发到:sunrun@sunrun.tk
谢谢 SMBus是双向串行总线,和I2C兼容,我用的就是Silicon laboratories的例程,下面是主机收发多字节的代码,程序加上注释太长了,压缩一下传上去,你可以看看。里面包括主从,单字节,多字节收发的例程。 下面是C8051F410的SMBus的例程:
C8051F410的SMBus例程ourdev_652449K42AFJ.rar(文件大小:30K) (原文件名:SMBus.rar) 非常感谢楼主.其实我也做过IIC通讯的例子.以前用AVR mega88/16都挺好的.只是,转到MSP430F2013上就有这个问题.我在MSP430f2132上也调通过(USCI模块),为什么在2013(USI模块)调不通,麻烦楼主能不能将调好的2013程序发给我参考一下.谢谢! 问题已解决了,昨晚将单片机时钟调到16MHz,就可以通讯了.晕啊430单片机的指令周期是几个时钏啊,以前用AVR的只要2M就跑得很好了.现在430在8MHz下死活不行.必须在12M才可以(主机IIC时钟才60-90KHz).是不是我哪里设置还有问题啊!!!!!!!!!!以此自警!!谨记谨记! 回复【17楼】sunrun
呵呵,解决了就好!我之前向人请教,他告诉我需要注意系统时钟设置,但是当时改了时钟也不行
(单片机引脚都没焊好,肯定不行,就把这个原因忽略了)原来系统时钟也很关键.一块学习!
我设置的I2C时钟就是10KHz,有空我再试试其他系统时钟或I2C时钟是不是有影响.我也不是很懂,第一次使用I2C.
刚才在网上查了一下,在430中,
一个时钟周期= MCLK晶振的倒数.如果MCLK是8M,则一个时钟周期为1/8us;
一个机器周期 =一个时钟周期,即430每个动作都能完成一个基本操作;
一个指令周期 = 1~6个机器周期,具体根据具体指令而定。
详细可参考:http://hi.baidu.com/cdutwbj1/blog/item/740d28d198ca4739970a169c.html
AVR单片机,采用哈佛结构(数据和程序分开存储)和精简指令集,一个机器周期等于一个时钟周期。
也就是执行一条单周期指令只需要一个时钟脉冲。
参考网址:http://www.91avr.com/htm/question/34.html
http://080520130.blog.163.com/blog/static/116095844201111211252432/ 是啊.弄得我好几天都不痛快.以后还得多多学习
谢谢楼主 互相学习,共同进步! 我有个问题:smbus通信,采用多主模式,一边是C8051F340,系统时钟是24M, I2C时钟速率是1M,另一边是C8051F360,系统时钟是98M,I2C时钟速率为1M,C8051F340作为主机时,C8051F360可以接收数据,但是360作为主机时,340不能接收数据,而360的I2C时钟速率设为500K才能通信,为什么这样的? 你的时钟频率有点高了。现在好像增强型是可以达到1M的速率,但是不是很稳定,最好是设在400K以下会好点。 回复【3楼】sunrun
-----------------------------------------------------------------------
我的连地址都识别不出来。好像从机根本就没反应似的,你那有没有430的I2C初始化程序,有的话传一个给我。我的邮箱是57462554qq@.com 学习了,谢谢卤煮~~~
页:
[1]