Other Parts Discussed in Thread: MSP430FR2310
主题中讨论的其他器件:MSPWARE、
工具/软件:Code Composer Studio
您好!
我认为这是一项非常简单的任务,现在已经把一个项目推迟了两个星期,虽然我认为我已经查明了问题,但我希望得到专家的建议。
MSP430在系统启动时用于单个任务。 它会延迟30秒、然后在400kHz 频率下以0x33向 I2C 从设备发送0x1F。 就是这样。
我已经阅读了时钟系统和用户手册的 i2c 部分、不认为我缺少任何东西、并查看了代码示例[此处]。
我尽量靠近示例。 我的方法如下:
首先、我跟随其中一个示例 msp430fr231x_CS_01.c "将 MCLK 配置为8MHz、源自 DCO。" 将 DCO 设置为2.4kHz (尽管我不确定它不是2kHz)
然后、我使用 CSCTL5将 MCLK 设置为2.4MHz、并将 SMCLK 设置为400kHz。 接下来、我配置 I2C 引脚、然后为了测试目的、每3秒发送0x1F 至0x33。
我复制并粘贴了示例中的中断处理和修整函数、并修改了一些参数。
我已经验证了 SCL 信号是否与示波器一起存在、但除了从器件制造商提供的测试工具之外、我还使用了总相位的"aardvark "i2c 测试器件、两者都无法实际识别正在发送的信息。 以下代码是否与任务匹配? 上面的描述中是否有任何内容暗示了另一个错误?
提前感谢、
#include void Software_Trim (); //获取最佳 DCOFTRIM 值 的软件调整 unsigned char TXData =0x1F; unsigned char TXByteCtr; #define MCLK_FREQ_MHz 2.4 // MCLK = 2.4MHz int main (void) { WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器 _bis_SR_register (SCG0); //禁用 FLL CSCTL3 |= SELREF_REFOCLK; //将 REFO 设置为 FLL 基准源 CSCTL1 = DCOFTRIMEN_1 | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_3;// DCOFTRIM = 3、DCO 范围= 2.4MHz CSCTL2 = FLLD_0 + 243; // DCODIV = 2.4MHz _DELAY_CYCLES (3); _BIC_SR_register (SCG0); //启用 FLL Software_Trim (); //软件调整以获得最佳 DCOFTRIM 值 CSCTL4 = SELMS_DCOCLKDIV | SELA_REFOCLK;//将默认 REFO (~32768Hz)设置为 ACLK 源、ACLK = 32768Hz //默认 DCODIV 为 MCLK 和 SMCLK 源 CSCTL5 |= DIVM_0 | DIVS_3; // MCLK = XT1CLK = 2.4MHZ、 // SMCLK = MCLK/2 = 0.4MHz = 400kHz //配置 I2C 引脚 P1SEL0 |= BIT2 | BIT3; //I2C 引脚 //禁用 GPIO 上电默认高阻抗模式 //激活先前配置的端口设置 PM5CTL0 &=~LOCKLPM5; //将 USCI_B0配置为 I2C 模式 UCB0CTLW0 |= UCSWRST; //将 eUSCI_B 置于复位状态 UCB0CTLW0 |= UCMODE_3 | UCMST; // I2C 主控模式、SMCLK UCB0BRW = 0x8; //波特率= SMCLK /8 UCB0CTLW0 &=~ UCSWRST; //清除复位寄存器 UCB0IE |= UCTXIE0 | UCNACKIE; //发送和 NACK 中断使能 while (1){ //延迟3秒 _DELAY_CYCLES (300000);//30000000 //所有4根天线的部署算法1 UCB0I2CSA = 0x33; //将从地址配置为0x33 TXByteCtr = 2; //加载 TX 字节计数器 while (UCB0CTLW0和 UCTXSTP); //确保发送了停止条件 UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX、启动条件 _bis_SR_register (LPM0_bits | GIE); //输入带中断的 LPM0 } //返回0; } #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_ICC__) #pragma vector = USCI_B0_vector __interrupt void USCIB0_ISR (void) #Elif defined (__GNU__) #void __attribute__(interrupt (USCI_B0_ISR )#vector (void USCIB0_ISR!)#USCIB0 Compiler! #endif { switch (__even_in_range (UCB0IV、USCI_I2C_UCBIT9IFG)) } USCI_NONE 案例:中断; //向量0:无中断 USCI_I2C_UCALIFG 案例:中断; //向量2:ALIFG 案例 USCI_I2C_UCNACKIFG:中断; //向量4:NACKIFG 案例 USCI_I2C_UCSTTIFG:中断; //向量6:STTIFG USCI_I2C_UCSTPIFG 案例: //向量8:STPIFG TXData = 0; UCB0IFG &=~UCSTPIFG; //清除停止条件 int 标志 中断; USCI_I2C_UCRXIFG3案例:中断; //向量10:RXIFG3 USCI_I2C_UCTXIFG3案例:中断; //向量14:TXIFG3 USCI_I2C_UCRXIFG2案例:中断; //向量16:RXIFG2 USCI_I2C_UCTXIFG2案例:中断; //向量18:TXIFG2 USCI_I2C_UCRXIFG1案例:中断; //向量20:RXIFG1 USCI_I2C_UCTXIFG1案例:中断; //向量22:TXIFG1 案例 USCI_I2C_UCRXIFG0:中断; //向量24:RXIFG0 USCI_I2C_UCTXIFG0案例: UCB0TXBUF = TXData++; 中断; //向量26:TXIFG0 案例 USCI_I2C_UCBCNTIFG:break; //向量28:BCNTIFG USCI_I2C_UCCLTOIFG 案例:中断; //向量30:时钟低电平超时 USCI_I2C_UCBIT9IFG 案例:中断; //向量32:第9位 默认值:break; } void Software_Trim () { unsigned int oldDcotTap = 0xFFFF; unsigned int newDcoTap = 0xFFFF; unsigned int newDcoDelta = 0xFFFF; unsigned int bestDcoDelta = 0xFFFF; unsigned int csCtl0Copy = 0; unsigned int csCtl1Copy = 0; 无符号 int csCtl0Read = 0; 无符号 int csCtl1Read = 0; unsigned int dcoFreqTrim = 3; unsigned char endLoop = 0; 操作 { CSCTL0 = 0x100; // DCO 抽头= 256 操作 { CSCTL7 &=~DCOFFG; //清除 DCO 故障标志 } while (CSCTL7 & DCOFFG); //测试 DCO 故障标志 __DELAY_CYCLLES ((unsigned int) 3000 * MCLK_FREQ_MHz);//等待 FLL 锁定状态(FLLUNLOCK)保持稳定 //建议等待24个经过分频的 FLL 参考时钟周期 while (((CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1))和&((CSCTL7 & DCOFFG)= 0)); CSCCtl0Read = CSCTL0; //读取 CSCTL0 CSCCtl1Read = CSCTL1; //读取 CSCTL1 oldDcoTap = newDcoTap; //记录上次的 DCOTAP 值 NewDcoTap = csCtl0Read & 0x01ff; //获取此次的 DCOTAP 值 dcoFreqTrim =(csCtl1Read & 0x0070)>>4;//获取 DCOFTRIM 值 if (newDcoTap < 256) // DCOTAP < 256 { newDcoDelta = 256 - newDcoTap; // DCPTAP 和256之间的增量值 if ((oldDcotap!= 0xFFFF)&&(oldDcotap >= 256)// DCOTAP 交叉256 endLoop = 1; //停止 while 循环 其他 { dcoFreqTrim --; CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim<4); } } 其他 // DCOTAP >= 256 { newDcoDelta = newDcoTap - 256; // DCPTAP 和256之间的增量值 if (oldDcoTap < 256) // DCOTAP 交叉256 endLoop = 1; //停止 while 循环 其他 { dcoFreqTrim++; CSCTL1 =(csCtl1Read &(~DCOFTRIM))|(dcoFreqTrim<4); } } if (newDcoDelta < bestDcoDelta) //记录最接近256的 DCOTAP { csCtl0Copy = csCtl0Read; csCtl1Copy = csCtl1Read; bestDcoDelta = newDcoDelta; } }while (endLoop =0); //轮询直至 endLoop = 1 CSCTL0 = csCtl0Copy; //重新加载锁定的 DCOTAP CSCTL1 = csCtl1Copy; //重新加载锁定的 DCOFTRIM while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));//轮询直到 FLL 被锁定 }