This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
第一个问题:我在使用G2单片机的硬件I2C时,使用如下指令开启收发中断,程序正常运行,
UCB0CTL1 &= ~UCSWRST;
IE2 |= UCB0TXIE+UCB0RXIE; // Enable TX RX interrupt
但是使用:
IE2 |= UCB0TXIE+UCB0RXIE; // Enable RX interrupt
UCB0CTL1 &= ~UCSWRST;
配置后,中断无效,原因何在?
第二个问题: 软件WDTCTL = WDTPW + WDTHOLD;将看门狗关掉,并用grace生成的代码初始化SMCLK为1MHz后,当我同时打开这两个中断,进行对外设芯片读取任务操作。发现单片机一直处于软件复位状态!! 这是什么原因引发的软件复位呢?排出了看门狗和时钟配置的影响,还有什么其他原因呢? 亟待专家指点。
The USCI is reset by a PUC or by setting the UCSWRST bit. After a PUC, the UCSWRST bit is
automatically set, keeping the USCI in a reset condition. When set, the UCSWRST bit resets the
UCAxRXIE, UCAxTXIE, UCAxRXIFG, UCRXERR, UCBRK, UCPE, UCOE, UCFE, UCSTOE and
UCBTOE bits and sets the UCAxTXIFG bit. Clearing UCSWRST releases the USCI for operation.
NOTE: Initializing or Re-Configuring the USCI Module
The recommended USCI initialization/re-configuration process is:
1. Set UCSWRST (BIS.B #UCSWRST,&UCAxCTL1)
2. Initialize all USCI registers with UCSWRST = 1 (including UCAxCTL1)
3. Configure ports.
4. Clear UCSWRST via software (BIC.B #UCSWRST,&UCAxCTL1)
5. Enable interrupts (optional) via UCAxRXIE and/or UCAxTXIE
至于复位问题,你可以先关闭一个中断,看是否是由于i2c中断引起的
可以参考以下代码
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB0I2COA = 0x48; // Own Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0I2CIE |= UCSTTIE; // Enable STT interrupt
IE2 |= UCB0TXIE; // Enable TX interrupt
TXData = 0xff; // Used to hold TX data
while (1)
{
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
}
}
// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
UCB0TXBUF = TXData; // TX data
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
// USCI_B0 State ISR
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
UCB0STAT &= ~UCSTTIFG; // Clear start condition int flag
TXData++; // Increment data
}
中断我关掉了一个,现在只剩下I2C收发中断源。 可是,当我往I2C芯片中写入数据时,没问题。而读取时,就会导致程序进入不断软件复位状态:
收发程序代码如下:
//-------I2C 发送中断----------
void I2C_Tx()
{
unsigned char i=0;
_DINT();
switch(TCA6416A_TxState)
{
case SLAVE_ADDR_STATE:
UCB0TXBUF = TCA6416A_Command;
TCA6416A_TxState=COMMAND_STATE;
break;
case COMMAND_STATE:
UCB0TXBUF = TCA6416A_OutptBuffer&0x00ff ;
TCA6416A_TxState= DATA0_STATE;
break;
case DATA0_STATE:
UCB0TXBUF = (TCA6416A_OutptBuffer&0xff00) >> 8;
TCA6416A_TxState=DATA1_STATE;
break;
case DATA1_STATE:
TCA6416A_TxState = STOP_STATE;
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
break;
default: break;
}
switch(TCA6416A_RxState)
{
case SLAVE_ADDR_STATE:
UCB0TXBUF = TCA6416A_Command;
TCA6416A_RxState=COMMAND_STATE;
break;
case COMMAND_STATE:
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
TCA6416A_RxState=SLAVE_REP_ADDR_STATE;
for(i=0;i<100;i++); // 适当的延时
UCB0CTL1 &=~UCTR;
UCB0CTL1 |= UCTXSTT; //触发起始位。
break;
default:break;
}
_EINT();
}
void I2C_IODect() ;
//-------I2C 接收中断----------
void I2C_Rx()
{
unsigned int temp=0;
_DINT();
switch(TCA6416A_RxState)
{
case SLAVE_REP_ADDR_STATE:
TCA6416A_InputBuffer=((unsigned int)UCB0RXBUF)&0x00ff;
TCA6416A_RxState=DATA0_STATE;
break;
case DATA0_STATE:
UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
temp = UCB0RXBUF;
TCA6416A_InputBuffer=(temp<<8 )& 0xff00;
TCA6416A_RxState=STOP_STATE;
P1OUT ^= BIT0;
//IFG2 &= ~UCB0RXIFG; // Clear USCI_B0 TX int flag
//I2C_IODect(); //检测通过,则会调用事件处理函数
break;
// case DATA1_STATE:
// //IFG2 &= ~UCB0RXIFG; // Clear USCI_B0 TX int flag
// break;
default: break;
}
_EINT();
}上面两个函数,就是我在收发中断里面执行的函数。 由于我是在用I2C控制TCA6416A扩展IO口操作, 现在想读取扩展IO口上的按键状态。
程序现在让我简化的只剩触发I2C发送以下两句代码
UCB0CTL1 |= UCTR ; //主机发送模式
UCB0CTL1 |= UCTXSTT; //触发起始位
和上面的收发函数了,可是只往芯片中发送可以, 读取芯片就会导致不断复位。 这是什么情况? 我单片机换过了,没问题, 外设板用其他程序测试过,也没问题。肯请专家点一点!