请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号:MSP432P401R 我正在尝试使用两对i2c引脚(EUSCI_B0和EUSCI_B1)与具有相同从属地址的两个不同设备通信。 我使用驱动程序库使EUSCI_B0正常工作,但在针脚6.4 和6.5 上使用EUSCI_B1时遇到问题。 尝试从寄存器读取时,我在i2c行上看不到任何启动条件,并且程序在轮询中断标志时卡住。
尝试写入寄存器时,MSP432会寻址从属设备,但当从属设备发送ACK时时,时钟信号会卡住。 这可以在下面的统计数据捕获中看到。 前2个通道是EUSCIB0线路,后两个通道是EUSCIB1线路。
代码卡在此处。
下面是我的代码
/* DriverLib定义*/ #include "driverlib.h" #include <stdint.h> #include <string.h> #include <stdio.h>/* I2C从属地址*/ #define slaver_address 0x64 #define NUM_OF_REC_Bytes 2 //static uint8_t read; static uint8_t RX; static uint8_t TXByteCtr; // static float horAngle,verAngle, 强度; 静态uint16_t X1,X2,Y1,Y2; /*变量*/ 静态uint8_t TXData[3]={0x12, 0x5f, 0x0c}; 静态uint8_t RXData[NUM_OF_REC_Bytes]; 静态易失性UINT32_t xferIndex; 静态易失性bool stopSent; /* I2C主配置参数*/ const eUSCI_I2C_{配置= i2cConfig EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK时钟源 300万, // SMCLK = 3MHz EUSCI_B_I2C_SET_DATA_RATE_100KBPS, //所需的I2C时钟为100kHz 0, //无字节计数器阈值 EUSCI_B_I2C_NO_AUTO_STOP //无自动停止 }; #define timer_period 0xB71B /* Timer_A Uptime配置参数*/ const Timer_a_UptodeConfig ={ Timer_A_CLOCKSOURCE_SMCLK, // SMCLK时钟源 Timer_a_CLOCKSOURCE_diverer_64, // SMCLK/1 = 3MHz Timer_Period, // 5000 tick period Timer_a_TAIE_INTERRUST_DISABLE, //禁用计时器中断 Timer_a_CCIE_CCR0_interrupT_enable,//启用CCR0中断 Timer_a_DO清除 //清除值 };// UART配置 连接eUSI_UART_Config uartConfig ={ EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK时钟源 //1.92万 39, 1, 0, EUSCI_A_UART_NO_PARity, //不奇偶校验 EUSCI_A_UART_LSB First, // LSB优先 EUSCI_A_UART_ON_STOP_BIT, //一个停止位 EUSCI_A_UART_MODE, // UART模式 EUSCI_A_UART_oversampling_BAUDRATE_generation // Oversampling }; bool Setup_Register (unsigned char,unsigned char,unsigned char); bool Setup_Register1 (unsigned char, unsigned char,unsigned char); uint16_t read_Data_register (unsigned char); uint16_t read_Data_Register1 (unsigned char); void khzclock_Calibration(); void Setup_Config(); void Setup_Config1(); void UART_Transmit (uint16_t); void ADC_Calibration (unsigned char,unsigned char); const UINT32_t default_config[]={ 0x000c000f, 0x0010101010, 0x1.1004万c, 0x0.0125万f0c, 0x0013ada5, 0x14.008万, 0x15万, 0x16.06万, 0x17万, 0x18.2693万, 0x19.0004万, 0x001a4280, 0x001b0060, 0x001c2094,// SDA/SCL制动片回转速率限制器已启用 // INT输出:已启用 // INT输入:已禁用 0x001d0000, 0x001e0001, 0x001f0000, 0x20.032万, 0x21.0513万, 0x22.032万, 0x23.0113万, 0x24万, 0x25.2414万, 0x26.2414万, 0x27.0022万, 0x28万, 0x29.03万, 0x002a1770, 0x002b157c, 0x002c4268, 0x002d2710, 0x002e0000, 0x002f0000, 0x30万, 0x31万, 0x32.004万, 0x33万, 0x0034E400, 0x38.808万, 0x39.808万, 0x003a2000, 0x003b2000, 0x003c2000, 0x003d2000, 0x003e0000, 0x4.0806万d, 0x0.0411万f2f, 0x42.4万, 0x43万, 0x44.0005万, //0x46.002万,//采样模式的小数率:4 0x46.003万, 0x0.48万df,// INT_STATUS寄存器:示例中断 0x49万, 0x45.0008万,//操作模式:示例模式 }; int main(void){ /*禁用监视程序*/ MAP_WDT_A_HoldTimer(); /*将DCO设置为12MHz */ cs_setDCOCenteredFrequency (CS_DCO_Frequency_12); /*将DCO设置为24MHz (升级Vcore) Flashctl_setWaitState(flash_BANK0, 2); Flashctl_setWaitState(flash_Bank1,2); MAP_PCM_setCoreVoltageLevel (PCM_VCORE1); cs_setDCOCenteredFrequency (CS_DCO_Frequency_24); */ /*为I2C选择端口1 -将引脚6,7设置为输入主模块功能, *(UCB0SIMO/UCB0SDA,UCB0SOMI/UCB.S.)。 */ MAP_GPIO设置外围模块功能输入引脚(GPIO_PORT_P1, GPIO _PIN6 + GPIO _PIN7,GPIO主要模块功能); //2nd I2C引脚 MAP_GPIO设置外围模块功能输入引脚(GPIO_PORT_P6), GPIO _PIN4 + GPIO _PIN5,GPIO主要模块功能); /*在UART模式下选择WFP 1.2 和WFP 1.3 */ MAP_GPIO设置外围模块功能输入引脚(GPIO_PORT_P1, GPIO _PIN1 | GPIO _PIN2 | GPIO _PIN3,GPIO主要模块功能); stopSent =假; memset (RXData,0x00,NUM_OF_REC_Bytes); /*在100kHz的频率下将I2C主设备初始化到SMCLK,没有自动停止*/ MAP_I2C_INITMaster (EUSCI_B0_BASE,&i2cConfig); MAP_I2C_INITMaster (EUSCI_B1_BASE,&i2cConfig); /*指定从属地址*/ MAP_I2C_setSlaveAddress (EUSCI_B0_BASE,SLAVE_ADDRESS); MAP_I2C_setSlaveAddress (EUSCI_B1_BASE,SLAVE_ADDRESS); /*将主中继器设置为传输模式*/ MAP_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_MODE); MAP_I2C_setMode (EUSCI_B1_BASE,EUSCI_B_I2C_Transmit_MODE); /*启用I2C模块以启动操作*/ MAP_I2C_enableModule (EUSCI_B0_BASE); MAP_I2C_enableModule (EUSCI_B1_BASE); /*配置UART模块*/ MAP_UART_INITModule (EUSCI_A0_BASE,&uartConfig); /*启用UART模块*/ MAP_UART_enableModule (EUSCI_A0_BASE); /*启用并清除中断标志*/ MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE, EUSCI_B_I2C_Transmit_INTERRUPT0 + EUSCI_B_I2C_receive _INTERRUPT0); MAP_I2C_clearInterruptFlag (EUSI_B1_BASE, EUSCI_B_I2C_Transmit_INTERRUPT1 + EUSCI_B_I2C_receive _INTERRUPT1); //启用主接收中断 MAP_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_INTERRUPT0); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableInterrupt (INT_EUSCIB0); MAP_I2C_enableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Transmit_INTERRUPT1); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableInterrupt (INT_EUSCIB1); //map_Interrupt_enableSleepOnIsrExit(); //MAP_Timer_a_configureUpMode(Timer_A1_base,&upConfig); //MAP_Interrupt_enableInterrupt (INT_TA1_0); MAP_Interrupt_enableMaster(); //将中断引脚设置为输入 MAP_GPIO设置输入引脚(GPIO_PORT_P6,GPIO _PIN7); printf ("正在读取芯片ID和版本值\n"); while (READ_Data_Register (0x08)!= 0x03fc); printf ("设置寄存器\n"); Setup_Register (0x0F,0x00,0x01); //重置设备 Setup_Config(); // 004配置 Setup_Config1(); printf ("已加载默认配置\n"); Setup_Register (0x49,0x08,0x20); 同时(1) { 如果(P6IN和BIT7){ Setup_Register (0x49,0x08,0x20); x1 =读取数据注册(0x00); X2 =读取数据注册(0x01); Y1 = READ_Data_Register (0x02); y2 =读取数据注册(0x03); MAP_UART_ESDLData(EUSI_A0_base, 0x00); UART_Transmit (X1); UART_Transmit (X2); UART_Transmit (Y1); UART_Transmit(Y2); } }}/*************************************************************************************** * eUSCIB0 ISR。 此 ISR内发生重复的启动和发送/接收操作*。 ***************** / void EUSCIB0_IRQHandler (void) { UINT_FAST16_t状态; 状态= MAP_I2C_getEnabledInterruptStatus (EUSCI_B0_BASE); MAP_I2C_clearInterruptFlag (EUSCI_B0_BASE,STATUS); /*如果我们达到传输中断,则表示我们位于的索引1 *传输缓冲区。 在我们到达之前反复启动时 *最后一个字节我们需要将模式更改为接收模式,设置开始 *条件发送位,然后将最后一个字节加载到TXBUF中。 */ IF (状态和EUSCI_B_I2C_Transmit_INTERRUPT0) { /*IF (Rx == 0){*/ 如果(TXByteCtr){ //发送下一个数据并递减字节计数器 MAP_I2C_masterSendMultiByteNext(EUSI_B0_BASE,TXData[3 - TXByteCtr ]); TXByteCtr --; } 否则{ 如果(Rx ==0){ MAP_I2C_masterSendMultiByteStop (EUSCI_B0_BASE); stopSent =真; MAP_Interrupt_DisableSleepOnIsrExit(); } 否则{ MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Transmit_INTERRUPT0); MAP_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Receive_mode); xferIndex = 0; MAP_I2C_masterReceiveStart (EUSCI_B0_BASE); MAP_I2C_enableInterrupt (EUSI_B0_BBASE,EUSCI_B_I2C_receive _INTERRUPT0); } } } /*将字节接收到接收缓冲区。 如果我们已收到所有字节, *发送停止条件*/ IF (状态和EUSCI_B_I2C_Receive_INTERRUPT0) { IF (xferIndex == NUM_OF_REC_Bytes -2) { MAP_I2C_masterReceiveMultiByteStop (EUSCI_B0_BASE); RXData[xferIndex+]= MAP_I2C_masterReceiveMultiByteNext(EUSI_B0_base); } 否则,如果(xferIndex == NUM_OF_REC_Bytes -1) { RXData[xferIndex+]= MAP_I2C_masterReceiveMultiByteNext(EUSSCI_B0_base); MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Receive_INTERRUPT0); MAP_I2C_setMode (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_MODE); xferIndex = 0; stopSent =真; MAP_Interrupt_DisableSleepOnIsrExit(); } 否则 { RXData[xferIndex+]= MAP_I2C_masterReceiveMultiByteNext(EUSI_B0_base); } } } 作废EUSCIB1_IRQHandler(void){ UINT_FAST16_t状态; 状态= MAP_I2C_getEnabableInterruptStatus (EUSCI_B1_BASE); MAP_I2C_clearInterruptFlag (EUSCI_B1_BASE,状态); /*如果我们达到传输中断,则表示我们位于的索引1 *传输缓冲区。 在我们到达之前反复启动时 *最后一个字节我们需要将模式更改为接收模式,设置开始 *条件发送位,然后将最后一个字节加载到TXBUF中。 */ IF (状态和EUSCI_B_I2C_Transmit_INTERRUPT1) { /*IF (Rx == 0){*/ 如果(TXByteCtr){ //发送下一个数据并递减字节计数器 MAP_I2C_masterSendMultiByteNext(EUSI_B1_base, TXData[3 - TXByteCtr ]; TXByteCtr --; } 否则{ 如果(Rx ==0){ MAP_I2C_masterSendMultiByteStop(EUSI_B1_base); stopSent =真; MAP_Interrupt_DisableSleepOnIsrExit(); } 否则{ MAP_I2C_DisableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Transmit_INTERRUPT1); MAP_I2C_setMode (EUSCI_B1_BASE,EUSCI_B_I2C_Receive_mode); xferIndex = 0; MAP_I2C_masterReceiveStart (EUSCI_B1_BASE); MAP_I2C_enableInterrupti(EUSI_B1_base, EUSCI_B_I2C_Receive_INTERRUPT1); } } } /*将字节接收到接收缓冲区。 如果我们已收到所有字节, *发送停止条件*/ IF (状态和EUSCI_B_I2C_Receive_INTERRUPT1) { IF (xferIndex == NUM_OF_REC_Bytes -2) { MAP_I2C_masterReceiveMultiByteStop (EUSCI_B1_BASE); RXData[xferIndex+]= MAP_I2C_masterReceiveMultiByteNext(EUSI_B1_base); } 否则,如果(xferIndex == NUM_OF_REC_Bytes -1) { RXData[xferIndex+]= MAP_I2C_masterReceiveMultiByteNext(EUSSCI_B1_base); MAP_I2C_DisableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Receive_INTERRUPT1); MAP_I2C_setMode (EUSCI_B1_BASE,EUSCI_B_I2C_Transmit_MODE); xferIndex = 0; stopSent =真; MAP_Interrupt_DisableSleepOnIsrExit(); } 否则 { RXData[xferIndex+]= MAP_I2C_masterReceiveMultiByteNext(EUSI_B1_base); } } }// 将配置值加载到第一个从属设备的寄存器 void Setup_Config(){ uINT8_t i; 对于(i = 0;i < 54;I++){ unsigned char address =(unsigned char)(default_config[i]>> 16); unsigned char MSB =(unsigned char)(default_config[i]>> 8); unsigned char lsb =(unsigned char)(default_config[i]); //printf ("地址:%X\tData:%X%X\n",地址,MSB,lsb); //uint8_t verify = Setup_Register (地址,MSB,lsb); //同时(验证!= 1) //verify = Setup_Register (地址,MSB,lsb); while (Setup_Register(address, MSB, lsb)!=1);} }// 将配置值加载到第二个从属设备的寄存器 void Setup_Config1(){ uINT8_t i; 对于(i = 0;i < 54;I++){ unsigned char address =(unsigned char)(default_config[i]>> 16); unsigned char MSB =(unsigned char)(default_config[i]>> 8); unsigned char lsb =(unsigned char)(default_config[i]); //printf ("地址:%X\tData:%X%X\n",地址,MSB,lsb); //uint8_t verify = Setup_Register (地址,MSB,lsb); //同时(验证!= 1) //verify = Setup_Register (地址,MSB,lsb); while (Setup_Register1(address, MSB, lsb)!=1);} } void UART_transmit (uint16_t数据){ unsigned char *ptr =(unsigned char *)数据(&D); MAP_UART_HESRData(EUSI_A0_base,*PTR+); MAP_UART_HESRData(EUSI_A0_base,*PTR); //MAP_UART_SESARData (EUSCI_A0_BASE,*PTR++); //MAP_UART_TRANSDLData(EUSSCI_A0_base,*PTR); }// 写入第一个从机寄存器 的函数bool Setup_Register (无符号字符地址,无符号字符高字节,无符号字符低字节){ while (MAP_I2C_MASTOISStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending停止); Rx = 0; TXByteCtr = 2; TXData[0]=地址; TXData[1]=高字节; TXData[2]=低字节; MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Receive_INTERRUPT0); MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE,TXData[0]); MAP_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_INTERRUPT0); //MAP_Interrupt_enableInterrupt (INT_EUSCIB0); while (!stopSent) { MAP_PCM_GotoLPM0InterruptSafe (); } stopSent =假; 如果(地址== 0x49) 返回1; UINT16_t data =读取数据注册(地址); //printf ("注册:%x\tValue:%x\n",地址,数据) return (data ==(highByte <<8)+lowByte); }// 写入第二个从机寄存器 bool Setup_Register1(unsigned char address,unsigned char highByte,unsigned char lowByte){的函数 while (MAP_I2C_MASTOISStopSent (EUSCI_B1_BASE)== EUSCI_B_I2C_Sending停止); Rx = 0; TXByteCtr = 2; TXData[0]=地址; TXData[1]=高字节; TXData[2]=低字节; MAP_I2C_DisableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Receive_INTERRUPT1); MAP_I2C_masterSendMultiByteStart (EUSCI_B1_BASE,TXData[0]); MAP_I2C_enableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Transmit_INTERRUPT1); //MAP_Interrupt_enableInterrupt (INT_EUSCIB0); while (!stopSent) { MAP_PCM_GotoLPM0InterruptSafe (); } stopSent =假; 如果(地址== 0x49) 返回1; UINT16_t data =读取数据注册器1 (地址); //printf ("注册:%x\tValue:%x\n",地址,数据) 返回(data ==(highByte <<8)+lowByte) ;}// 用于读取第一个从属设备的寄存器 uint16_t read_Data_Register (unsigned char地址){ while (MAP_I2C_MASTOISStopSent (EUSCI_B0_BASE)== EUSCI_B_I2C_Sending停止); Rx = 1; TXByteCtr = 0; MAP_I2C_DisableInterrupt (EUSCI_B0_BASE,EUSCI_B_I2C_Receive_INTERRUPT0); MAP_I2C_masterSendMultiByteStart (EUSCI_B0_BASE,地址); MAP_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_INTERRUPT0); //MAP_Interrupt_enableInterrupt (INT_EUSCIB0); while (!stopSent) { MAP_PCM_GotoLPM0InterruptSafe (); } stopSent =假; 返回(RXData[0]<<8)+RXData[1];}// 函数,用于读取第二个从属设备的寄存器 uint16_t read_Data_Register1 (无符号字符地址){ while (MAP_I2C_MASTOISStopSent (EUSCI_B1_BASE)== EUSCI_B_I2C_Sending停止); Rx = 1; TXByteCtr = 0; MAP_I2C_DisableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Receive_INTERRUPT1); MAP_I2C_masterSendMultiByteStart (EUSCI_B1_BASE,地址); MAP_I2C_enableInterrupt (EUSCI_B1_BASE,EUSCI_B_I2C_Transmit_INTERRUPT1); //MAP_Interrupt_enableInterrupt (INT_EUSCIB0); while (!stopSent) { MAP_PCM_GotoLPM0InterruptSafe (); } stopSent =假; Return (RXData[0]<<8)+RXData[1]; }
