程序之前一直在系统默认的1mhz频率下跑的,现在更改为11.0592Mhz之后,出现通讯异常。我把IIC的频率设置与原来的一样,170Khz左右,读操作包括两个部分,先写后读,程序大概如下,其中void UCSInit(void)之前没用,加上就有问题,不知道什么原因。下面为程序。
void UCSInit(void)
{
P7SEL |= (BIT0 + BIT1); //set P7.0 and P7.1 to XT1
SetVCore(PMMCOREV_2); // Set VCore = 1.75V
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFOCLK
UCSCTL4 |= SELA__REFOCLK; // Set ACLK = REFOCLK
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_6; // Select DCO range 44.2368MHz operation
UCSCTL2 = FLLD_1 | 674; // Set DCO Multiplier for 22.1184MHz
__bic_SR_register(SCG0); // Enable the FLL control loop
__delay_cycles(375000);
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive
#if 1
// strength
//设置系统时钟为11.0592MHz
UCSCTL4 |=SELM_4; //MCLK选择DCO时钟分频
UCSCTL4 |=SELS_4; //SMCLK选择DCO时钟分频
UCSCTL5 |=DIVS_1; //进行如下操作SMCLK=SMCLK/2
UCSCTL5 |=DIVM_1; //进行如下操作MCLK=SMCLK/2
//UCSCTL5 |=DIVA__16; //进行如下操作ACLK=ACLK/32=32768HZ
#endif
}
void I2C_init(void)
{
//i2c--0
P3SEL |= BIT1 + BIT2; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
//UCB0BR0 = CPU_SMAINCLK / 400000; // fSCL = SMCLK/12 = ~100kHz
UCB0BR0 = 62; // fSCL = SMCLK/12 = ~100kHz(内部1mhz)
UCB0BR1 = 0; //系统内部晶振 为06
UCB0I2CSA = 0x21; // Slave Address is 021h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
P2DIR |=BIT6;
P2SEL |=BIT6; // MCU ACLK(32.768Khz)时钟输出,QN8036 XCLK输入
P2SEL &= ~BIT2; //片选输出引脚
P2DIR |= BIT2;
P2OUT |= BIT2; //p2.2高电平有效
P2SEL &= ~BIT1; //p2.1MCU I/O中断输入
P2DIR &= ~BIT1; //QN8036中断输出(INT),MCU I/O 中断输入
stepValue = qnd_StepTbl[qnd_CH_STEP];
}
unsigned char QND_ReadReg(unsigned char Address) //iic读操作
{
unsigned char adr_lo;
UCB0I2CSA = (0x21);
while (UCB0STAT & UCBUSY); // wait until I2C module has
// finished all operations
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[0] = adr_lo; // be sent in the I2CBuffer.
PTxData = (unsigned char *)I2CBufferArray; // TX array start address
TXByteCtr = 1; // set I2CBufferArray Pointer
I2CWriteInit();
UCB0CTL1 |= UCTXSTT; // start condition generation
// => I2C communication is started
__bis_SR_register(GIE); // Enter LPM0 w/ interrupts
I2CReadInit();
UCB0I2CSA = (0x21); // Slave Address is 048h
UCB0CTL1 |= UCTXSTT; // I2C start condition
while (UCB0CTL1 & UCTXSTT); // Ensure start condition got sent
UCB0CTL1 |= UCTXNACK; //baimahe
UCB0CTL1 |= UCTXSTP; // I2C stop condition
__bis_SR_register(GIE); // Enter LPM0 w/ interrupts
while(UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
return I2CBuffer;
}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break; // Vector 0: No interrupts
case 2: break; // Vector 2: ALIFG
case 4: break; // Vector 4: NACKIFG
case 6: break; // Vector 6: STTIFG
case 8: break; // Vector 8: STPIFG
case 10: // Vector 10: RXIFG
I2CBuffer = UCB0RXBUF; // Get RX data
break;
case 12: // Vector 12: TXIFG
if (TXByteCtr--) // Check TX byte counter
{
UCB0TXBUF = *PTxData++; // Load TX buffer
}
else
{
UCB0CTL1 |= UCTXSTP; // I2C stop condition
UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
}
break;
default: break;
}
}
这张为异常的图片
这张为正常的

