大家好,我想知道 CCS SDK 中的一件事,他们已经为 UART UCA0端口提供了一个代码,所以我想更改为另一个引脚,这样我就只需要更改这个引脚了。 我所做的是使用 P1SEL 将寄存器名称从 AO 更改为 A1、并将引脚更改为 P1SEL、这就是我所做的更改已经足够了、或者我需要更改任何内容了。。。
谢谢,此致
Veerendra B
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.
大家好,我想知道 CCS SDK 中的一件事,他们已经为 UART UCA0端口提供了一个代码,所以我想更改为另一个引脚,这样我就只需要更改这个引脚了。 我所做的是使用 P1SEL 将寄存器名称从 AO 更改为 A1、并将引脚更改为 P1SEL、这就是我所做的更改已经足够了、或者我需要更改任何内容了。。。
谢谢,此致
Veerendra B
感谢您的响应、实际上我已将形式 UCA0更改为 UCA1、并且硬件也正确连接、引脚也从 P3.0、P3.1更改为 P4.1、P4、2
实际代码:
P3SEL |= BIT0 + BIT1;// P3.0、1选项选择
UCB0CTL1 |= UCSWRST;//启用 SW 复位
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式
UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持软件复位
UCB0BR0 = 160;// fSCL = SMCLK/160 =~100kHz
UCB0BR1 = 0;
UCB0I2CSA = SLAVE_ADDR;//从地址为048h
UCB0CTL1 &=~UCSWRST;//清除 SW 复位,恢复运行
UCB0IE |= UCNACKIE;
修改的代码:
P4SEL |= BIT1 + BIT2;// P4.1、2选项选择
UCB1CTL1 |= UCSWRST;//启用 SW 复位
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式
UCB1CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持软件复位
UCB1BR0 = 160;// fSCL = SMCLK/160 =~100kHz
UCB1BR1 = 0;
UCB1I2CSA = SLAVE_ADDR;//从地址为048h
UCB1CTL1 &=~UCSWRST;//清除 SW 复位,恢复运行
UCB1IE |= UCNACKIE;
是的,我已经通过调试不是从中断 ISR 发出的代码进行了检查,下面只是我之前使用过的代码,现在我想从 UCB0更改为 UCB1,所以请帮助我在哪里以及我需要在代码中进行更改... // // MSP430F552x 演示- USCI_B0、I2C 主设备多字节 TX/RX // 说明:I2C 主设备与 I2C 从设备通信发送和接收 // 3个不同长度的不同消息。 I2C 主设备将在 等待使用 I2C 中断发送/接收消息时进入 LPM0模式//。 // ACLK = nA、MCLK = SMCLK = DCO 16MHz。 // ///|\/|/ MSP430F5529 4.7K | //--- |4.7K ///|\| P3.1|-+-|- I2C 时钟(UCB.S.) //||||// -|RST P3.0|--- +/- I2C 数据(UCB0SDA) //| //||// |//| //|// |//| //|//|//| // // Nima Eskandari // Texas Instruments Inc. // 2017年4月 //使用 CCS V7.0构建 /********* #include #include #include // //示例命令(Example Commands Commands // #define SLAVE_ADDR 0x10 // CMD_TYPE_X_SLAVE 是主设备发送到从设备的示例命令。 *从属方将发送示例 SlaveTypeX 缓冲区进行响应。 * * CMD_TYPE_X_MASTER 是主器件发送到从器件的示例命令。 *从器件将初始化自身以接收 MasterTypeX 示例缓冲区。 **/ #define CMD_TYPE_0_SLAVE 0 #define CMD_TYPE_1_SLAVE 1 #define CMD_TYPE_2_SLAVE 2 #define CMD_TYPE_0_MASTER 3 #define CMD_TYPE_1_MASTER 4 #define CMD_TYPE_2_MASTER 5 #define TYPE_0_LENGTH 1 #define CMD_MASTER 2 在 MAX_LENGTH_LENGTH 1 #define RAME_TYPE_6中已初始化*#define max_TYPE_6_LENGTH #define 2 它们将由主器件*发送到从器件。 * SlaveTypeX 是在从器件中初始化的示例缓冲 区,它们将由从器件*发送到主器件。 */ uint8_t MasterType2 [type_2_length]={'F'、'4'、'1'、'9'、'2'、 'b'}; uint8_t MasterType1 [type_1_length]={8、9}; uint8_t MasterType0 [type_0_length]={11}; uint8_t SlaveType2 [type_2_length]={0}; uint8_t SlaveType1 [type_1_length]={ ****/} //通用 I2C 状态机 // typedef enum I2C_ModeEnum{ ide_mode、 nack_mode、 TX_REG_ADDRESS_MODE、 RX_REG_ADDRESS_MODE、 TX_DATA_MODE、 RX_DATA_MODE、 SWITCH_TO_RX_MODE、 SWITHC_TO_TX_MODE、 TIMEOUT_MODE }I2C_Mode; //*用于跟踪软件状态机的状态*/ I2C_Mode MasterMode = IDLE_MODE; //要使用的寄存器地址/命令*/ uint8_t TransmitRegAddr = 0; // *接收 RX缓冲 区: 剩余待接收的字节数 * ReceiveIndex:ReceiveBuffer * TransmitBuffer:用于在 ISR 中传输数据的缓冲 区* TXByteCtr:剩余要传输的字节数 * TransmitIndex: 要在 TransmitBuffer *中传输的下一个字节的索引*/ uint8_t ReceiveBuffer[MAX_Buffer_SIZE]={0}; uint8_t RXByteCtr = 0; uint8_t ReceiveIndex = 0; uint8_t TransmitBuffer[MAX_Buffer_SIZE]={0}; uint8_TXBytCtr = 0 ;uint8_t 索引= 0 /* I2C 写入和读取函数*/ //对于具有 DEV_addr 的从器件,写入在*reg_data * * DEV_addr:从器件地址中指定的数据。 *示例:SLAVE_ADDR * REG_addr:要发送到从器件的寄存器或命令。 *示例:cmd_type_0_master ***reg_data:要写入的缓冲 区*示例:MasterType0 *计数:* reg_data 的长度 *示例:type_0_length *// /I2C_Mode I2C_Master_WriteReg (uint8_t dev_addr、uint8_addr、uint8_addr、uint8_addr、uint_addr、uint8_addr、uint8_addr、uint8_addr 、uint_reg_addr、uint8_addr、uint8、uint_date_read* *接收到的数据在 ReceiveBuffer 中可用* DEV_addr:从器件地址。 *示例:SLAVE_ADDR * REG_addr:要发送到从器件的寄存器或命令。 *示例:cmd_type_0_slave *计数:要读取的数据长度 *示例:type_0_length **/ I2C_Mode I2C_Master_ReadReg (uint8_t *缓冲区、uint8_t DEV_addr、uint8_t REG_addr、uint8_t count); //void Array (uint8_t *复制8、uintt 源* uint8_t count); uint8_t * strcpy (uint8_t * destination、const uint8_t * source); I2C_Mode I2C_Master_ReadReg (uint8_t * buffer、uint8_t DEV_addr、uint8_addr、uint8_t * Receivedr、uint8_t * Transdr);TX_Mode_Transdr = 0;TXDr = 0;TX_Bytedr = Transdr = 0;TX_Dr = Transdr = 0;TX_Dr = Transdr = r_Dr;TXDr = r_Dr TransmitIndex = 0; //初始化从器件地址和中断*/ UCB0I2CSA = DEV_addr; UCB0IFG &=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断 UCB0IE &=~UCRXIE;//禁用 RX 中断 UCTXIE |= UCTXIE;/ UCB0IE + UCTL 中断条件| UCB0IE;/ UCTL0I2C_START //输入 LPM0,带中断 strcpy (buffer、ReceiveBuffer); 返回 MasterMode; } void CopyArray (uint8_t *源、uint8_t * dest、uint8_t count); I2C_Mode I2C_Master_WriteReg (uint8_t DEV_addr、uint8_t REG_addr、 uint8_t * reg_data、uint8_t count) { //初始化状态机*/ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = REG_addr; //将寄存器数据复制到 TransmitBuffer CopyArray (REG_DATA、TransmitBuffer、COUNT); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; //初始化从器件地址和中断*/ UCB0I2CSA = DEV_addr; UCB0IFG &=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断 UCB0IE &=~UCRXIE;//禁用 RX 中断 UCB0IE | UCTXIE | UCTXTL = UCTXIE;//启用 UCB0IE; // I2C TX,起始条件 __bis_sr_register (LPM0_bits + GIE);//输入 LPM0,带中断 返回 MasterMode; } void CopyArray (uint8_t *源,uint8_t * 计数,uint8_t 计数){uint8_t 索引= 0;for (ude= 0+[copyIndex }+[copyIndex + 索引] //设备初始化 // void initClockTo16MHz () { UCSCTL3 |= SELREF_2;//设置 DCO FLL 基准= REFO UCSCTL4 |= SELA_2;//设置 ACLK = REFO _ bis_SR_register (SCG0);//禁用 FLL 控制环路 UCSCTL0 = 0x0000;//设置 ACL1 =可能的最低位 DCODL1;//设置 UCMOx = DCODL1 //选择 DCO 范围16MHz 运行 UCSCTL2 = FLLD_0 + 487;//将 DCO 乘法器设置为16MHz //(N + 1)* FLLRef = Fdco //(487 + 1)* 32768 = 16MHz //设置 FLL Div = fDCOCLK __BIC_SR_register (SCG0); //启用 FLL 控制环路 // DCO 范围位已 更改时最坏情况下的稳定时间//为 n x 32 x 32 x f_MCLK /f_FLL_reference。 有关优化、请参阅5xx // UG 中的 UCS 一章。 // 32 x 32 x 16 MHz / 32、768 Hz = 500000 = MCLK 周期、以便 DCO 稳定 __DELAY_CYCLS (50000);// 循环、直到 XT1、XT2和 DCO 故障标志被清除 DO { UCSCTL7 &&=~ ~(XT2OFFG + XT1LFOFFG + DCOFFG);XSFT1、XIFG 和 XSFG = FAULT 标志;//清除 //清除故障标志 } while (SFRIFG1&OFIFG);//测试振荡器故障标志 } uint16_t setVCoreUp (uint8_t level){ uint32_t PMMRIE_BACKUP、SVSMHCTL_BACKUP、SVSMLCTL_BACKUP; //增加 Vcore 的代码流已被修改为在 FLASH37周围工作。 //请参阅勘误表以了解特定器件是否受到影响 //请勿更改此函数 //打开 PMM 寄存器以进行写访问 PMMCTL0_H = 0xA5; //禁用专用中断 //备份所有寄存器 PMMRIE_BACKUP = PMMRIE; PMMRIE &=~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHDIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE ); SVSMHCTL_BACKUP = SVSMHCTL ;SVSMLCTL_BACKUP = SVSMLPM0 /清零标志 ; //将 SVM 高侧设置为新的电平,并检查 VCORE 是否可能增大 SVSMHCTL = SVMHE | SVSHE |(SVSMHRRL0 *电平); //等待 SVM 高侧稳定 while ((PMMIFG & SVSMHDLYIFG)=0) { ; // 清除标志 PMMIFG & SVSMHDLYIFG =~; //如果 (((PMMIFG & SVMHIFG)=SVMHIFG) { //->Vcc 对于 Vcore 增加而言过低 //恢复之前的设置 PMMIFG &=~SVSMHDLYIFG; SVSMHCTL = SVSMHCTL_BACKUP; //等待 SVSMLYVM = 0 (同时 SVSMHDLYIFG)稳定,直到 SVSMHIFG = 0 (SVSMLYVM = 0)时,检查 VCORE 是否有可能增加 //清除所有标志 PMMIFG &&~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG ); //恢复 PMM 中断使能寄存器 PMMRIE = PMMRIE_BACKUP; //用于写入访问 的 PMMCMC0寄存 器= 0x00_RETURN ;//未设置逻辑0 = 0x00_RETURN =错误 //同时将 SVS 高侧设置为新电平 //Vcc 足够高以便 Vcore 增加 SVSMHCTL |=(SVSHRVL0 *电平); //等待 SVM 高侧稳定 while ((PMMIFG & SVSMHDLYIFG)=0) { ; } //清除标志 PMMIRE &=~SVSMCLY0 ;*将 PMSMCLYIFG 设置为新电平; //将 SVM、SVS 低电平侧设置为新的电平 SVSMLCTL = SVMLE |(SVSMLRRL0 *电平)| SVSLE |(SVSLRVL0 *电平); //等待 SVM、SVS 低电平侧稳定 ,同时((((PMMIFG & SVSMLDLYIFG)=0) { ; // 清除 SVSMLPMIFG 标志;//清除 PMMIFG ~; //SVS、SVM 内核和高侧现在被设置为保护新的内核电平 //恢复低侧设置 //清除所有其他位_except _电平设置 SVSMLCTL &&(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2 ); //清除备份寄存器中的电平设置,保留所有其他位 SVSMLCTL_BACKUP 和= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2); //恢复低侧 SVS 监视器设置 SVSMLCTL |= SVSMLCTL_BACKUP; //恢复高侧设置 //清除除电平设置 之外的所有其他位 SVSMHCTL &=(SSVSHRVL0+SVSHRVL1 +SVSMHRRL0+SVSMHRRL1 +SVSMHRRL2 ); //清除备份寄存器中的电平设置,保留所有其他位 SVSMHCTL_BACKUP &= ~(SSVSMHRRL0+SVSMHRRL2;SVSMHRSMHRRTL0+SVSMHRRL2 ) ;SVSMHRSMHRSMHRRTL0 + 备份 SVSMHRSMHRRTL0 + SVSMHRSMHRRTL //等待直到高侧、低侧稳定 while (((PMMIFG & SVSMLDLYIFG)=0)&& ((PMMIFG & SVSMHDLYIFG)=0) { ; } //清除所有标志 PMMIFG &=~(SVMHVLRIFG | SVMHIFG | 备份 SVSMHDLYIFG | SIMPRIFG | PMMRSIMPLIFG =中断/恢复 PMMRLIFG | PMSMLIFG | PMMRLIFG |中断 PMSMLIFG | PMMRLIFG = PMMRLIFG 寄存器 //锁定 PMM 寄存器以进行写访问 PMMCTL0_H = 0x00; 返回 true; } bool increaseVCoreToLevel2 () { uint8_t level = 2; uint8_t actlevel; bool status = true; //为 Max 设置掩码。 Level level &= PMMCOREV_3; //get actual VCORE actlevel = PMMCTL0 & PMMCOREV_3; //逐步增加或减少 while ((level!= actlevel)&&(status = true)) { if (level > inactlevel) { status = setVCoreSel (++actLevel); }返回 状态 (0);0 + BitveleI2C (0);0) // P3.0、1选项选择 UCB0CTL1 |= UCSWRST;//启用 SW 复位 UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式 UCB0CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持 SW 复位 = UCB0160 ~UCB0CTL1 = UCB0CLK ;// UCB0BR0 = UCS0160 UCB0CLK = UCB0CLK = UCB0CLK;// UCB0CL0 = UCB0CLK = UCB0CLK = UCB0160 //从机地址为048h UCB0CTL1 &=~UCSWRST;//清除软件复位,恢复操作 UCB0IE |= UCNACKIE; } //******** // I2C 中断 // #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_) #pragma vector=USCI_B0_vector __interrupt void USCI_B0_ISR (void) #Elif defined (__GNU__) void __attribute__(interrupt (USCI_B0_vector)#USCI_ISR vector (void )#USCI_编译器0 (void)错误! #endif { //必须从 UCB0RXBUF uint8_t RX_val 读取= 0; switch (_even_in_range (UCB0IV、0xC) { case USCI_NONE:break;//向量0 -无中断 案例 USCI_I2C_UCALIFG:break;//中断向量:USCI_I2C_CCIFG :UCCIFG:中断向 量:UCCUSCI_I2C_CCIFG:中断向量:UCCIFG:中断向量中断向量 UCCIFG:中断向量 UCCIFG:中断中断向量 UCCIFG:中断中断中断中断 I2C 模式:UCSTPIFG 案例 USCI_I2C_UCRXIFG: RX_val = UCB0RXBUF; IF (RXByteCtr) { for (I = 0;I < 600;I++); ReceiveBuffer[ReceiveIndex+]]= RX_val; RXByteCtr -; } if (RXByteCtr = 1) { UCB0CTL1 |= UCTXSTP; } 否则(RXByteCtr = 0) { UCB0IE &=~UCRXIE; MasterMode = IDLE_MODE; __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0 } break; = UCBRXCC_DR_EXCCUST_REG/ UCCRISTER = UCC_TRUCC_TRUCC_TRIP_TRIP_TRIP_TRIPE;(UCC_TRUCC_TRUCC_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TRIP_TR //需要立即开始接收 else MasterMode = TX_DATA_MODE;//继续传输数据并使其处于发送缓冲 区中断状态; case switch_TO_RX_MODE: UCB0IE |= UCRXIE;//启用 RX 中断 UCB0IE &=~UCTXIE;//禁用 TX 中断 UCB0CTL1 &=~UCTR;//切换 至 Masterdata 模式;// //状态是接收数据 UCB0CTL1 |= UCTXSTT;//如果 (RXByteCtr = 1)则发送重复起始 { //必须发送停止,因为这是 N-1字节 while (((UCB0CTL1 & UCTXSTT)); UCB0CTCtr |= UCTXSTP;//发送停止,因为这是 N-1字节 while (UCB0CTL1 & UCTXSTT);UCB0CTL = 0);如果是数据中断条件(TXBUT_START = 0); I < 1000;I++); UCB0TXBUF = TransmitBuffer[TransmitIndex+]; TXByteCtr -; } else { //通过传输 UCB0CTL1完成|= UCTXSTP;//发送停止条件 MasterMode = IDLE_MODE; UCB0IE &=~UCTXIE;//禁用 TX 中断 __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0 } break; 默认: __NO_OPERATION; //中断向量 ://中断中断中断中断://中断中断向量:中断中断向量中断中断:中断中断:中断中断中断中断
e2e.ti.com/.../0842.i2c.cyeah我已经通过调试不是从中断 ISR 发出的代码进行了检查,下面只是我之前使用过的代码 ,现在我想从 UCB0更改为 UCB1,所以请帮助我在哪里以及我需要在代码中进行更改...
/*修改后的代码表 B0至 B1 *//********* // MSP430F552x 演示- USCI_B1、I2C 主设备多字节 TX/RX // 说明:I2C 主设备与 I2C 从设备通信发送和接收 // 3条不同长度的不同消息。 I2C 主设备将在 等待使用 I2C 中断发送/接收消息时进入 LPM0模式//。 // ACLK = nA、MCLK = SMCLK = DCO 16MHz。 // ///|\/|/ MSP430F5529 4.7K | //--- |4.7K ///|\| P3.1|-+-|- I2C 时钟(UCB.S.) //||||// -|RST P3.0|--- +/- I2C 数据(UCB1SDA) //| //||// |//| //|// |//| //|//|//|// // Nima Eskandari // Texas Instruments Inc. // 2017年4月 //使用 CCS V7.0构建 /********* #include #include #include // //示例命令(Example Commands Commands // #define SLAVE_ADDR 0x10 // CMD_TYPE_X_SLAVE 是主设备发送到从设备的示例命令。 *从属方将发送示例 SlaveTypeX 缓冲区进行响应。 * * CMD_TYPE_X_MASTER 是主器件发送到从器件的示例命令。 *从器件将初始化自身以接收 MasterTypeX 示例缓冲区。 **/ #define CMD_TYPE_0_SLAVE 0 #define CMD_TYPE_1_SLAVE 1 #define CMD_TYPE_2_SLAVE 2 #define CMD_TYPE_0_MASTER 3 #define CMD_TYPE_1_MASTER 4 #define CMD_TYPE_2_MASTER 5 #define TYPE_0_LENGTH 1 #define CMD_MASTER 2 在 MAX_LENGTH_LENGTH 1 #define RAME_TYPE_6中已初始化*#define max_TYPE_6_LENGTH #define 2 它们将由主器件*发送到从器件。 * SlaveTypeX 是在从器件中初始化的示例缓冲 区,它们将由从器件*发送到主器件。 */ uint8_t MasterType2 [type_2_length]={'F'、'4'、'1'、'9'、'2'、 'b'}; uint8_t MasterType1 [type_1_length]={8、9}; uint8_t MasterType0 [type_0_length]={11}; uint8_t SlaveType2 [type_2_length]={0}; uint8_t SlaveType1 [type_1_length]={ ****/} //通用 I2C 状态机 // typedef enum I2C_ModeEnum{ ide_mode、 nack_mode、 TX_REG_ADDRESS_MODE、 RX_REG_ADDRESS_MODE、 TX_DATA_MODE、 RX_DATA_MODE、 SWITCH_TO_RX_MODE、 SWITHC_TO_TX_MODE、 TIMEOUT_MODE }I2C_Mode; //*用于跟踪软件状态机的状态*/ I2C_Mode MasterMode = IDLE_MODE; //要使用的寄存器地址/命令*/ uint8_t TransmitRegAddr = 0; // *接收 RX缓冲 区: 剩余待接收的字节数 * ReceiveIndex:ReceiveBuffer * TransmitBuffer:用于在 ISR 中传输数据的缓冲 区* TXByteCtr:剩余要传输的字节数 * TransmitIndex: 要在 TransmitBuffer *中传输的下一个字节的索引*/ uint8_t ReceiveBuffer[MAX_Buffer_SIZE]={0}; uint8_t RXByteCtr = 0; uint8_t ReceiveIndex = 0; uint8_t TransmitBuffer[MAX_Buffer_SIZE]={0}; uint8_TXBytCtr = 0 ;uint8_t 索引= 0 /* I2C 写入和读取函数*/ //对于具有 DEV_addr 的从器件,写入在*reg_data * * DEV_addr:从器件地址中指定的数据。 *示例:SLAVE_ADDR * REG_addr:要发送到从器件的寄存器或命令。 *示例:cmd_type_0_master ***reg_data:要写入的缓冲 区*示例:MasterType0 *计数:* reg_data 的长度 *示例:type_0_length *// /I2C_Mode I2C_Master_WriteReg (uint8_t dev_addr、uint8_addr、uint8_addr、uint8_addr、uint_addr、uint8_addr、uint8_addr、uint8_addr 、uint_reg_addr、uint8_addr、uint8、uint_date_read* *接收到的数据在 ReceiveBuffer 中可用* DEV_addr:从器件地址。 *示例:SLAVE_ADDR * REG_addr:要发送到从器件的寄存器或命令。 *示例:cmd_type_0_slave *计数:要读取的数据长度 *示例:type_0_length **/ I2C_Mode I2C_Master_ReadReg (uint8_t *缓冲区、uint8_t DEV_addr、uint8_t REG_addr、uint8_t count); //void Array (uint8_t *复制8、uintt 源* uint8_t count); uint8_t * strcpy (uint8_t * destination、const uint8_t * source); I2C_Mode I2C_Master_ReadReg (uint8_t * buffer、uint8_t DEV_addr、uint8_addr、uint8_t * Receivedr、uint8_t * Transdr);TX_Mode_Transdr = 0;TXDr = 0;TX_Bytedr = Transdr = 0;TX_Dr = Transdr = 0;TX_Dr = Transdr = r_Dr;TXDr = r_Dr TransmitIndex = 0; //初始化从器件地址和中断*/ UCB1I2CSA = DEV_addr; UCB1IFG &=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断 UCB1IE &=~UCRXIE;//禁用 RX 中断 UCTXIE |= UCTXIE;//启用 UCTL1 | UCT10CTL 中断 // I2C TX、起始条件0001 0000 + 0000 0010 __bis_SR_register (LPM0_bits + GIE);//输入 LPM0、带中断 strcpy (buffer、ReceiveBuffer); 返回 MasterMode; } void CopyArray (uint8_t *源、uint8_t *目标、uint8_t);uint8_addr uint8_r eReg (uint8_t) uint8_t * reg_data、uint8_t count) { //初始化状态机*/ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = REG_addr; //将寄存器数据复制到 TransmitBuffer CopyArray (REG_DATA、TransmitBuffer、COUNT); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; //初始化从器件地址和中断*/ UCB1I2CSA = DEV_addr; UCB1IFG &=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断 UCB1IE &=~UCRXIE;//禁用 RX 中断 UCB1IE | UCTXIE ;//启用 UCTXCTL | UCTXIE; // I2C TX,起始条件 __bis_sr_register (LPM0_bits + GIE);//输入 LPM0,带中断 返回 MasterMode; } void CopyArray (uint8_t *源,uint8_t * 计数,uint8_t 计数){uint8_t 索引= 0;for (ude= 0+[copyIndex }+[copyIndex + 索引] //设备初始化 // void initClockTo16MHz () { UCSCTL3 |= SELREF_2;//设置 DCO FLL 基准= REFO UCSCTL4 |= SELA_2;//设置 ACLK = REFO _ bis_SR_register (SCG0);//禁用 FLL 控制环路 UCSCTL0 = 0x0000;//设置 ACL1 =可能的最低位 DCODL1;//设置 UCMOx = DCODL1 //选择 DCO 范围16MHz 运行 UCSCTL2 = FLLD_0 + 487;//将 DCO 乘法器设置为16MHz //(N + 1)* FLLRef = Fdco //(487 + 1)* 32768 = 16MHz //设置 FLL Div = fDCOCLK __BIC_SR_register (SCG0); //启用 FLL 控制环路 // DCO 范围位已 更改时最坏情况下的稳定时间//为 n x 32 x 32 x f_MCLK /f_FLL_reference。 有关优化、请参阅5xx // UG 中的 UCS 一章。 // 32 x 32 x 16 MHz / 32、768 Hz = 500000 = MCLK 周期、以便 DCO 稳定 __DELAY_CYCLS (50000);// 循环、直到 XT1、XT2和 DCO 故障标志被清除 DO { UCSCTL7 &&=~ ~(XT2OFFG + XT1LFOFFG + DCOFFG);XSFT1、XIFG 和 XSFG = FAULT 标志;//清除 //清除故障标志 } while (SFRIFG1&OFIFG);//测试振荡器故障标志 } uint16_t setVCoreUp (uint8_t level){ uint32_t PMMRIE_BACKUP、SVSMHCTL_BACKUP、SVSMLCTL_BACKUP; //增加 Vcore 的代码流已被修改为在 FLASH37周围工作。 //请参阅勘误表以了解特定器件是否受到影响 //请勿更改此函数 //打开 PMM 寄存器以进行写访问 PMMCTL0_H = 0xA5; //禁用专用中断 //备份所有寄存器 PMMRIE_BACKUP = PMMRIE; PMMRIE &=~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHDIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE ); SVSMHCTL_BACKUP = SVSMHCTL ;SVSMLCTL_BACKUP = SVSMLPM0 /清零标志 ; //将 SVM 高侧设置为新的电平,并检查 VCORE 是否可能增大 SVSMHCTL = SVMHE | SVSHE |(SVSMHRRL0 *电平); //等待 SVM 高侧稳定 while ((PMMIFG & SVSMHDLYIFG)=0) { ; // 清除标志 PMMIFG & SVSMHDLYIFG =~; //如果 (((PMMIFG & SVMHIFG)=SVMHIFG) { //->Vcc 对于 Vcore 增加而言过低 //恢复之前的设置 PMMIFG &=~SVSMHDLYIFG; SVSMHCTL = SVSMHCTL_BACKUP; //等待 SVSMLYVM = 0 (同时 SVSMHDLYIFG)稳定,直到 SVSMHIFG = 0 (SVSMLYVM = 0)时,检查 VCORE 是否有可能增加 //清除所有标志 PMMIFG &&~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG ); //恢复 PMM 中断使能寄存器 PMMRIE = PMMRIE_BACKUP; //用于写入访问 的 PMMCMC0寄存 器= 0x00_RETURN ;//未设置逻辑0 = 0x00_RETURN =错误 //同时将 SVS 高侧设置为新电平 //Vcc 足够高以便 Vcore 增加 SVSMHCTL |=(SVSHRVL0 *电平); //等待 SVM 高侧稳定 while ((PMMIFG & SVSMHDLYIFG)=0) { ; } //清除标志 PMMIRE &=~SVSMCLY0 ;*将 PMSMCLYIFG 设置为新电平; //将 SVM、SVS 低电平侧设置为新的电平 SVSMLCTL = SVMLE |(SVSMLRRL0 *电平)| SVSLE |(SVSLRVL0 *电平); //等待 SVM、SVS 低电平侧稳定 ,同时((((PMMIFG & SVSMLDLYIFG)=0) { ; // 清除 SVSMLPMIFG 标志;//清除 PMMIFG ~; //SVS、SVM 内核和高侧现在被设置为保护新的内核电平 //恢复低侧设置 //清除所有其他位_except _电平设置 SVSMLCTL &&(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2 ); //清除备份寄存器中的电平设置,保留所有其他位 SVSMLCTL_BACKUP 和= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2); //恢复低侧 SVS 监视器设置 SVSMLCTL |= SVSMLCTL_BACKUP; //恢复高侧设置 //清除除电平设置 之外的所有其他位 SVSMHCTL &=(SSVSHRVL0+SVSHRVL1 +SVSMHRRL0+SVSMHRRL1 +SVSMHRRL2 ); //清除备份寄存器中的电平设置,保留所有其他位 SVSMHCTL_BACKUP &= ~(SSVSMHRRL0+SVSMHRRL2;SVSMHRSMHRRTL0+SVSMHRRL2 ) ;SVSMHRSMHRSMHRRTL0 + 备份 SVSMHRSMHRRTL0 + SVSMHRSMHRRTL //等待直到高侧、低侧稳定 while (((PMMIFG & SVSMLDLYIFG)=0)&& ((PMMIFG & SVSMHDLYIFG)=0) { ; } //清除所有标志 PMMIFG &=~(SVMHVLRIFG | SVMHIFG | 备份 SVSMHDLYIFG | SIMPRIFG | PMMRSIMPLIFG =中断/恢复 PMMRLIFG | PMSMLIFG | PMMRLIFG |中断 PMSMLIFG | PMMRLIFG = PMMRLIFG 寄存器 //锁定 PMM 寄存器以进行写访问 PMMCTL0_H = 0x00; 返回 true; } bool increaseVCoreToLevel2 () { uint8_t level = 2; uint8_t actlevel; bool status = true; //为 Max 设置掩码。 Level level &= PMMCOREV_3; //get actual VCORE actlevel = PMMCTL0 & PMMCOREV_3; //逐步增加或减少 while ((level!= actlevel)&&(status = true)) { if (level > iniminactlevel) { status = setVCoreSel (++actLevel); }2 (vit1);{vit1 + BteI2C (ve2);}2 (vit2) // P4.1、2选项选择 UCB1CTL1 |= UCSWRST;//启用 SW 复位 UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式 UCB1CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持 SW 复位 = UCB1CT0 = UCB1BR0 ~UCS1K0;// UCB1CLK = UCB1CSR0 = UCB1K0 = UCB1K0 = UCB1CLK;// UCB1CLK = UCB1CSR0 //从器件地址为048h UCB1CTL1 &=~UCSWRST;//清除软件复位,恢复操作 UCB1IE |= UCNACKIE; } // // I2C 中断 // #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_) #pragma vector = USCI_B1_vector __interrupt void USCI_B1_ISR (void) #Elif defined (__GNU__) void __attribute__((interrupt (USCI_B1_vector))) USCI_B1_Compiler #void (不 支持 USCI_B1_ISR!错误#b1_b1! #endif { //必须从 UCB1RXBUF uint8_t Rx_val 读取= 0; switch (_even_in_range (UCB1IV、12)// 12或0XC { case USCI_none:break;//向量0 -无中断 案例 USCI_I2C_UCALIFG:break;/ UCSTIFG :USCI_USCI_CCIFG 中断向量:UCCIFG:UCCIFG:中断向量 USCI_USCI_中断/中断向量 UCCIFG:中断:中断向量 UCCIFG:中断:中断向量 UCCIFG:UCCIFG:中断/中断向量 UCCIFG:中断向量 UCCIFG:中断:中断 //中断矢量:I2C 模式:UCSTPIFG 情况 USCI_I2C_UCRXIFG: RX_val = UCB1RXBUF; IF (RXByteCtr) { for (I = 0;I < 600;I++); ReceiveBuffer[ReceiveIndex+]]= Rx_val; RXByteCtr - } if (RXByteCtr = 1) { UCB1CTL1 |= UCTXSTP; } 否则(RXByteCtr = 0) { UCB1IE &=~UCRXIE; MasterMode = IDLE_MODE; __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0 } break;UCB1TXCC_USCI = UCTXG = UCCTRIFG;UCCUST_REG/ UCCTRIFG = UCCTRIFG = UCCTRUST_REG/ UCCTRIFG:UCCTRUST_REG/ UCCTRIFG = UCCTRIFG (UCCTRIFG:UCCTRIFG:UCCTRIFG:U ~(RXByteCtr){MasterMode = switch_TO_RX_mode;//需要立即开始接收}否则{MasterMode = TX_DATA_MODE;//使用发送缓冲区中的数据继续传输}break;case switch_TO_RX_mode:UCB1IE |= UCRXIE;//启用 RX 中断 UCB1IE 和= UCB1IE &= UCTL1 ~μ s;/禁用 UCB1IE;/ UCTL1中断 //切换到接收 器 MasterMode = RX_DATA_MODE;//状态是接收数据 UCB1CTL1 |= UCTXSTT;//如果 (RXByteCtr = 1) { //必须发送 STOP、因为这是 N-1字节 while (((UCB1CTL1 & UCTXSTT))); UCB1CTL1 = 发送数据;//中断条件:// if (TXByteCtr) { for (i = 0;i < 1000;i++); UCB1TXBUF = TransmitBuffer[TransmitIndex+]; TXByteCtr -; } else { //通过传输 UCB1CTL1完成|= UCTXSTP;//发送停止条件 MasterMode = IDLE_MODE; UCB1IE &=~UCTXIE;//禁用 TX 中断 __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0 } break; 默认: __NO_OPERATION; //中断向量 ://中断中断中断中断中断://中断中断中断中断中断中断中断:}
/*修改后的代码 表 B0至 B1 */
// // MSP430F552x 演示- USCI_B1、I2C 主设备多字节 TX/RX // 说明:I2C 主设备与 I2C 从设备通信发送和接收 // 3条不同长度的不同消息。 I2C 主设备将在 等待使用 I2C 中断发送/接收消息时进入 LPM0模式//。 // ACLK = nA、MCLK = SMCLK = DCO 16MHz。 // ///|\/|/ MSP430F5529 4.7K | //--- |4.7K ///|\| P3.1|-+-|- I2C 时钟(UCB.S.) //||||// -|RST P3.0|--- +/- I2C 数据(UCB1SDA) //| //||// |//| //|// |//| //|//|//|// // Nima Eskandari // Texas Instruments Inc. // 2017年4月 //使用 CCS V7.0构建 /********* #include #include #include // //示例命令(Example Commands Commands // #define SLAVE_ADDR 0x10 // CMD_TYPE_X_SLAVE 是主设备发送到从设备的示例命令。 *从属方将发送示例 SlaveTypeX 缓冲区进行响应。 * * CMD_TYPE_X_MASTER 是主器件发送到从器件的示例命令。 *从器件将初始化自身以接收 MasterTypeX 示例缓冲区。 **/ #define CMD_TYPE_0_SLAVE 0 #define CMD_TYPE_1_SLAVE 1 #define CMD_TYPE_2_SLAVE 2 #define CMD_TYPE_0_MASTER 3 #define CMD_TYPE_1_MASTER 4 #define CMD_TYPE_2_MASTER 5 #define TYPE_0_LENGTH 1 #define CMD_MASTER 2 在 MAX_LENGTH_LENGTH 1 #define RAME_TYPE_6中已初始化*#define max_TYPE_6_LENGTH #define 2 它们将由主器件*发送到从器件。 * SlaveTypeX 是在从器件中初始化的示例缓冲 区,它们将由从器件*发送到主器件。 */ uint8_t MasterType2 [type_2_length]={'F'、'4'、'1'、'9'、'2'、 'b'}; uint8_t MasterType1 [type_1_length]={8、9}; uint8_t MasterType0 [type_0_length]={11}; uint8_t SlaveType2 [type_2_length]={0}; uint8_t SlaveType1 [type_1_length]={ ****/} //通用 I2C 状态机 // typedef enum I2C_ModeEnum{ ide_mode、 nack_mode、 TX_REG_ADDRESS_MODE、 RX_REG_ADDRESS_MODE、 TX_DATA_MODE、 RX_DATA_MODE、 SWITCH_TO_RX_MODE、 SWITHC_TO_TX_MODE、 TIMEOUT_MODE }I2C_Mode; //*用于跟踪软件状态机的状态*/ I2C_Mode MasterMode = IDLE_MODE; //要使用的寄存器地址/命令*/ uint8_t TransmitRegAddr = 0; // *接收 RX缓冲 区: 剩余待接收的字节数 * ReceiveIndex:ReceiveBuffer * TransmitBuffer:用于在 ISR 中传输数据的缓冲 区* TXByteCtr:剩余要传输的字节数 * TransmitIndex: 要在 TransmitBuffer *中传输的下一个字节的索引*/ uint8_t ReceiveBuffer[MAX_Buffer_SIZE]={0}; uint8_t RXByteCtr = 0; uint8_t ReceiveIndex = 0; uint8_t TransmitBuffer[MAX_Buffer_SIZE]={0}; uint8_TXBytCtr = 0 ;uint8_t 索引= 0 /* I2C 写入和读取函数*/ //对于具有 DEV_addr 的从器件,写入在*reg_data * * DEV_addr:从器件地址中指定的数据。 *示例:SLAVE_ADDR * REG_addr:要发送到从器件的寄存器或命令。 *示例:cmd_type_0_master ***reg_data:要写入的缓冲 区*示例:MasterType0 *计数:* reg_data 的长度 *示例:type_0_length *// /I2C_Mode I2C_Master_WriteReg (uint8_t dev_addr、uint8_addr、uint8_addr、uint8_addr、uint_addr、uint8_addr、uint8_addr、uint8_addr 、uint_reg_addr、uint8_addr、uint8、uint_date_read* *接收到的数据在 ReceiveBuffer 中可用* DEV_addr:从器件地址。 *示例:SLAVE_ADDR * REG_addr:要发送到从器件的寄存器或命令。 *示例:cmd_type_0_slave *计数:要读取的数据长度 *示例:type_0_length **/ I2C_Mode I2C_Master_ReadReg (uint8_t *缓冲区、uint8_t DEV_addr、uint8_t REG_addr、uint8_t count); //void Array (uint8_t *复制8、uintt 源* uint8_t count); uint8_t * strcpy (uint8_t * destination、const uint8_t * source); I2C_Mode I2C_Master_ReadReg (uint8_t * buffer、uint8_t DEV_addr、uint8_addr、uint8_t * Receivedr、uint8_t * Transdr);TX_Mode_Transdr = 0;TXDr = 0;TX_Bytedr = Transdr = 0;TX_Dr = Transdr = 0;TX_Dr = Transdr = r_Dr;TXDr = r_Dr TransmitIndex = 0; //初始化从器件地址和中断*/ UCB1I2CSA = DEV_addr; UCB1IFG &=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断 UCB1IE &=~UCRXIE;//禁用 RX 中断 UCTXIE |= UCTXIE;//启用 UCTL1 | UCT10CTL 中断 // I2C TX、起始条件0001 0000 + 0000 0010 __bis_SR_register (LPM0_bits + GIE);//输入 LPM0、带中断 strcpy (buffer、ReceiveBuffer); 返回 MasterMode; } void CopyArray (uint8_t *源、uint8_t *目标、uint8_t);uint8_addr uint8_r eReg (uint8_t) uint8_t * reg_data、uint8_t count) { //初始化状态机*/ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = REG_addr; //将寄存器数据复制到 TransmitBuffer CopyArray (REG_DATA、TransmitBuffer、COUNT); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; //初始化从器件地址和中断*/ UCB1I2CSA = DEV_addr; UCB1IFG &=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断 UCB1IE &=~UCRXIE;//禁用 RX 中断 UCB1IE | UCTXIE ;//启用 UCTXCTL | UCTXIE; // I2C TX,起始条件 __bis_sr_register (LPM0_bits + GIE);//输入 LPM0,带中断 返回 MasterMode; } void CopyArray (uint8_t *源,uint8_t * 计数,uint8_t 计数){uint8_t 索引= 0;for (ude= 0+[copyIndex }+[copyIndex + 索引] //设备初始化 // void initClockTo16MHz () { UCSCTL3 |= SELREF_2;//设置 DCO FLL 基准= REFO UCSCTL4 |= SELA_2;//设置 ACLK = REFO _ bis_SR_register (SCG0);//禁用 FLL 控制环路 UCSCTL0 = 0x0000;//设置 ACL1 =可能的最低位 DCODL1;//设置 UCMOx = DCODL1 //选择 DCO 范围16MHz 运行 UCSCTL2 = FLLD_0 + 487;//将 DCO 乘法器设置为16MHz //(N + 1)* FLLRef = Fdco //(487 + 1)* 32768 = 16MHz //设置 FLL Div = fDCOCLK __BIC_SR_register (SCG0); //启用 FLL 控制环路 // DCO 范围位已 更改时最坏情况下的稳定时间//为 n x 32 x 32 x f_MCLK /f_FLL_reference。 有关优化、请参阅5xx // UG 中的 UCS 一章。 // 32 x 32 x 16 MHz / 32、768 Hz = 500000 = MCLK 周期、以便 DCO 稳定 __DELAY_CYCLS (50000);// 循环、直到 XT1、XT2和 DCO 故障标志被清除 DO { UCSCTL7 &&=~ ~(XT2OFFG + XT1LFOFFG + DCOFFG);XSFT1、XIFG 和 XSFG = FAULT 标志;//清除 //清除故障标志 } while (SFRIFG1&OFIFG);//测试振荡器故障标志 } uint16_t setVCoreUp (uint8_t level){ uint32_t PMMRIE_BACKUP、SVSMHCTL_BACKUP、SVSMLCTL_BACKUP; //增加 Vcore 的代码流已被修改为在 FLASH37周围工作。 //请参阅勘误表以了解特定器件是否受到影响 //请勿更改此函数 //打开 PMM 寄存器以进行写访问 PMMCTL0_H = 0xA5; //禁用专用中断 //备份所有寄存器 PMMRIE_BACKUP = PMMRIE; PMMRIE &=~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE | SVMHDIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE ); SVSMHCTL_BACKUP = SVSMHCTL ;SVSMLCTL_BACKUP = SVSMLPM0 /清零标志 ; //将 SVM 高侧设置为新的电平,并检查 VCORE 是否可能增大 SVSMHCTL = SVMHE | SVSHE |(SVSMHRRL0 *电平); //等待 SVM 高侧稳定 while ((PMMIFG & SVSMHDLYIFG)=0) { ; // 清除标志 PMMIFG & SVSMHDLYIFG =~; //如果 (((PMMIFG & SVMHIFG)=SVMHIFG) { //->Vcc 对于 Vcore 增加而言过低 //恢复之前的设置 PMMIFG &=~SVSMHDLYIFG; SVSMHCTL = SVSMHCTL_BACKUP; //等待 SVSMLYVM = 0 (同时 SVSMHDLYIFG)稳定,直到 SVSMHIFG = 0 (SVSMLYVM = 0)时,检查 VCORE 是否有可能增加 //清除所有标志 PMMIFG &&~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG ); //恢复 PMM 中断使能寄存器 PMMRIE = PMMRIE_BACKUP; //用于写入访问 的 PMMCMC0寄存 器= 0x00_RETURN ;//未设置逻辑0 = 0x00_RETURN =错误 //同时将 SVS 高侧设置为新电平 //Vcc 足够高以便 Vcore 增加 SVSMHCTL |=(SVSHRVL0 *电平); //等待 SVM 高侧稳定 while ((PMMIFG & SVSMHDLYIFG)=0) { ; } //清除标志 PMMIRE &=~SVSMCLY0 ;*将 PMSMCLYIFG 设置为新电平; //将 SVM、SVS 低电平侧设置为新的电平 SVSMLCTL = SVMLE |(SVSMLRRL0 *电平)| SVSLE |(SVSLRVL0 *电平); //等待 SVM、SVS 低电平侧稳定 ,同时((((PMMIFG & SVSMLDLYIFG)=0) { ; // 清除 SVSMLPMIFG 标志;//清除 PMMIFG ~; //SVS、SVM 内核和高侧现在被设置为保护新的内核电平 //恢复低侧设置 //清除所有其他位_except _电平设置 SVSMLCTL &&(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2 ); //清除备份寄存器中的电平设置,保留所有其他位 SVSMLCTL_BACKUP 和= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2); //恢复低侧 SVS 监视器设置 SVSMLCTL |= SVSMLCTL_BACKUP; //恢复高侧设置 //清除除电平设置 之外的所有其他位 SVSMHCTL &=(SSVSHRVL0+SVSHRVL1 +SVSMHRRL0+SVSMHRRL1 +SVSMHRRL2 ); //清除备份寄存器中的电平设置,保留所有其他位 SVSMHCTL_BACKUP &= ~(SSVSMHRRL0+SVSMHRRL2;SVSMHRSMHRRTL0+SVSMHRRL2 ) ;SVSMHRSMHRSMHRRTL0 + 备份 SVSMHRSMHRRTL0 + SVSMHRSMHRRTL //等待直到高侧、低侧稳定 while (((PMMIFG & SVSMLDLYIFG)=0)&& ((PMMIFG & SVSMHDLYIFG)=0) { ; } //清除所有标志 PMMIFG &=~(SVMHVLRIFG | SVMHIFG | 备份 SVSMHDLYIFG | SIMPRIFG | PMMRSIMPLIFG =中断/恢复 PMMRLIFG | PMSMLIFG | PMMRLIFG |中断 PMSMLIFG | PMMRLIFG = PMMRLIFG 寄存器 //锁定 PMM 寄存器以进行写访问 PMMCTL0_H = 0x00; 返回 true; } bool increaseVCoreToLevel2 () { uint8_t level = 2; uint8_t actlevel; bool status = true; //为 Max 设置掩码。 Level level &= PMMCOREV_3; //get actual VCORE actlevel = PMMCTL0 & PMMCOREV_3; //逐步增加或减少 while ((level!= actlevel)&&(status = true)) { if (level > iniminactlevel) { status = setVCoreSel (++actLevel); }2 (vit1);{vit1 + BteI2C (ve2);}2 (vit2) // P4.1、2选项选择 UCB1CTL1 |= UCSWRST;//启用 SW 复位 UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;// I2C 主器件、同步模式 UCB1CTL1 = UCSSEL_2 + UCSWRST;//使用 SMCLK、保持 SW 复位 = UCB1CT0 = UCB1BR0 ~UCS1K0;// UCB1CLK = UCB1CSR0 = UCB1K0 = UCB1K0 = UCB1CLK;// UCB1CLK = UCB1CSR0 //从器件地址为048h UCB1CTL1 &=~UCSWRST;//清除软件复位,恢复操作 UCB1IE |= UCNACKIE; } // // I2C 中断 // #if defined (__TI_Compiler_version__)|| defined (__IAR_systems_icc_) #pragma vector = USCI_B1_vector __interrupt void USCI_B1_ISR (void) #Elif defined (__GNU__) void __attribute__((interrupt (USCI_B1_vector))) USCI_B1_Compiler #void (不 支持 USCI_B1_ISR!错误#b1_b1! #endif { //必须从 UCB1RXBUF uint8_t Rx_val 读取= 0; switch (_even_in_range (UCB1IV、12)// 12或0XC { case USCI_none:break;//向量0 -无中断 案例 USCI_I2C_UCALIFG:break;/ UCSTIFG :USCI_USCI_CCIFG 中断向量:UCCIFG:UCCIFG:中断向量 USCI_USCI_中断/中断向量 UCCIFG:中断:中断向量 UCCIFG:中断:中断向量 UCCIFG:UCCIFG:中断/中断向量 UCCIFG:中断向量 UCCIFG:中断:中断 //中断矢量:I2C 模式:UCSTPIFG 情况 USCI_I2C_UCRXIFG: RX_val = UCB1RXBUF; IF (RXByteCtr) { for (I = 0;I < 600;I++); ReceiveBuffer[ReceiveIndex+]]= Rx_val; RXByteCtr - } if (RXByteCtr = 1) { UCB1CTL1 |= UCTXSTP; } 否则(RXByteCtr = 0) { UCB1IE &=~UCRXIE; MasterMode = IDLE_MODE; __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0 } break;UCB1TXCC_USCI = UCTXG = UCCTRIFG;UCCUST_REG/ UCCTRIFG = UCCTRIFG = UCCTRUST_REG/ UCCTRIFG:UCCTRUST_REG/ UCCTRIFG = UCCTRIFG (UCCTRIFG:UCCTRIFG:UCCTRIFG:U ~(RXByteCtr){MasterMode = switch_TO_RX_mode;//需要立即开始接收}否则{MasterMode = TX_DATA_MODE;//使用发送缓冲区中的数据继续传输}break;case switch_TO_RX_mode:UCB1IE |= UCRXIE;//启用 RX 中断 UCB1IE 和= UCB1IE &= UCTL1 ~μ s;/禁用 UCB1IE;/ UCTL1中断 //切换到接收 器 MasterMode = RX_DATA_MODE;//状态是接收数据 UCB1CTL1 |= UCTXSTT;//如果 (RXByteCtr = 1) { //必须发送 STOP、因为这是 N-1字节 while (((UCB1CTL1 & UCTXSTT))); UCB1CTL1 = 发送数据;//中断条件:// if (TXByteCtr) { for (i = 0;i < 1000;i++); UCB1TXBUF = TransmitBuffer[TransmitIndex+]; TXByteCtr -; } else { //通过传输 UCB1CTL1完成|= UCTXSTP;//发送停止条件 MasterMode = IDLE_MODE; UCB1IE &=~UCTXIE;//禁用 TX 中断 __BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0 } break; 默认: __NO_OPERATION; //中断向量 ://中断中断中断中断中断://中断中断中断中断中断中断中断:}
大家好、TI 团队今天早上好... 在这里,我在 ISR 函数中遇到了问题,实际上它应该检查直到数据的最后一个字节为止的情况(开关情况指的是运行模式,如 TX/Rx 模式或 TX_DATA_MODE /SWITCH_TO_RX_MODE),但只检查一次,它就从开关出来了.... 我已经提到---- *1*像这样的代码,您可以在下面检查...
_interrupt void USCI_B0_ISR (void) #elif defined (__GNU__) void __attribute__((interrupt (USCI_B0_vector))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { //必须从 UCB0RXBUF uint8_t Rx_val 读取= 0; switch (_even_in_range (UCB0IV、12))//12或0XC { 案例 USCI_NONE:break; //向量0 -无中断 案例 USCI_I2C_UCALIFG:break; //中断矢量:I2C 模式:UCALIFG 案例 USCI_I2C_UCNACKIFG:break; //中断矢量:I2C 模式:UCNACKIFG 案例 USCI_I2C_UCSTTIFG:break; //中断矢量:I2C 模式:UCSTTIFG 案例 USCI_I2C_UCSTPIFG:break; //中断矢量:I2C 模式:UCSTPIFG USCI_I2C_UCRXIFG 案例: RX_val = UCB0RXBUF; IF (RXByteCtr) { 对于(i = 0;i < 600;i++); ReceiveBuffer[ReceiveIndex++]= Rx_val; RXByteCtr --; } IF (RXByteCtr = 1) { UCB0CTL1 |= UCTXSTP; } 否则、如果(RXByteCtr = 0) { UCB0IE &=~UCRXIE; MasterMode = IDLE_MODE; _BIC_SR_REGISTER_ON_EXIT (CPUOFF); //退出 LPM0 } 中断; //中断矢量:I2C 模式:UCRXIFG USCI_I2C_UCTXIFG 案例: 开关(主模式) { 案例 TX_REG_ADDRESS_MODE: UCB0TXBUF = TransmitRegAddr; RXByteCtr = 0; IF (RXByteCtr) { MasterMode = SWITCH_TO_RX_MODE;//需要立即开始接收 } 其他 { MasterMode = TX_DATA_MODE; //继续使用发送缓冲 器中的数据进行传输} 中断; 案例切换至 RX_MODE: UCB0IE |= UCRXIE; //启用 RX 中断 UCB0IE &=~UCTXIE; //禁用 TX 中断 UCB0CTL1 &=~UCTR; //切换到接收器 MasterMode = RX_DATA_MODE; //状态是接收数据 UCB0CTL1 |= UCTXSTT; //发送重复起始 IF (RXByteCtr = 1) { //必须发送停止,因为这是 N-1字节 while ((UCB0CTL1 & UCTXSTT)); UCB0CTL1 |= UCTXSTP; //发送停止条件 } 中断; 案例 TX_DATA_MODE: IF (TXByteCtr) { 对于(i = 0;i < 1000;i++); UCB0TXBUF =传输缓冲器[TransmitIndex++]; TXByteCtr --; } 其他 { //传输完成 UCB0CTL1 |= UCTXSTP; //发送停止条件 MasterMode = IDLE_MODE; UCB0IE &=~UCTXIE; //禁用 TX 中断 _BIC_SR_REGISTER_ON_EXIT (CPUOFF); //退出 LPM0 } 中断; 默认值: __no_operation(); 中断; } 中断; //中断矢量:I2C 模式:UCTXIFG 默认值:中断; }-->----------------- * 1 *//here 仅在首次执行时直接出现 }
好的、假设在上面显示的代码中、与 B0相关的所有内容都被 B1替换、那么您的问题如下:
1)仅检查一个字节(直到最后一个字节才检查所有字节)和
2) 2)开关跳至默认情况。
您是否单步执行应用程序、是否验证了所需的标志是否已实际设置?
您期望的标志是否会被重置? 如果可能发生这种情况、请查看用户指南的第38.3.7节。
关于1):能否解释您希望固件执行的操作? 将根据中断标志检查开关情况。 您可能希望查看上述代码中的以下代码片段:
RX_val = UCB0RXBUF; IF (RXByteCtr) { 对于(i = 0;i < 600;i++); ReceiveBuffer[ReceiveIndex++]= Rx_val; RXByteCtr --; }
请检查您是否确实需要延迟循环、或者是否要填充 ReceiveBuffer? 您可能需要在梯形情况下删除分号、
您能否确认您的应用程序在默认情况下不会跳转到任何情况? 是这样的。 我知道这对您来说很累、但我真的希望详细描述您看到的问题、最好是描述您在单步执行应用时看到的行为。
非常感谢、
Britta