主题中讨论的其他器件:CC1310、
您好!
在这里、我将 MSP430G2102微控制器用作从器件、将 CC1310 TI 芯片用作主器件。
TI 芯片根据 GPIO 高电平/低电平唤醒。 我们在这里使用了 LPM4模式。
器件在收到任何按键按压(P1.1、P1.2 P1.3、P1.4、P1.5)中断时唤醒。器件将按键数据传输到主器件。
主器件在接收到按键数据时发送 NACK、主器件发送数据0xAA 到 MSP430从器件。 一旦 MSP430从器件接收到0xAA、它将禁用 GPIO (端口引脚 P1.0)、从而切断 TI CC1310主芯片的电源。
但在开关情况10的其他部分、我面临的问题是、尽管在调试模式下、MSP430器 件接收到0xAA、但引脚 P1.0有时会变得较高、并通过以下语句(P1OUT &=~BIT1)保持永久高电平而不是低电平。
在这里、请找到 i2c 从器件发送接收代码供您参考、并告知我以下查询。
1)在开关情况10中、其他部分虽然 MSP430器件获得0xAA、但 线路 (P1OUT &=~BIT1)不会使引脚永久处于低电平、但有时会一直保持高电平。 您能告诉我为什么会发生这种情况吗? 我的代码中的问题是什么。
2) 2)我是否在我所连接的代码中正确处理了低功耗模式4?
3) 3)为 我提供解决方案、以便在每次获取0xAA 时、GPIO 引脚 P1.0都被禁用、而这种禁用现在大部分时间都保持高电平。
4) 4)代码中的 I2C 例程 是否正常?
代码:
#include
char flag=0;
char Slave_Tx = 1;
char SLV_Data = 0;//传输数据的变量
char SLV_Addr = 0x90;//对于 R/W、地址为0x48<1
INT I2C_STATE = 0;//状态变量
int i=0;
void i2c_init (void)
{
USICTL0 = USIPE6 + USIPE7 + USISWRST;//端口和 USI 模式设置
USICTL1 = USII2C + USIIE + USISTTIE;//启用 I2C 模式和 USI 中断
USICKCTL = USICKPL;//设置时钟极性
USICNT |= USIIFGCC;//禁用自动清除控制
USICTL0 &=~USISWRST;//启用 USI
USICTL1 &=~USIIFG;//清除挂起标志
_enable_interrupt ();
}
int main (空)
{
WDTCTL = WDTPW + WDTHOLD;//停止看门狗
if (CALBC1_1MHz == 0xFF)// if 校准常数被擦除
{
while (1);//请勿加载,陷阱 CPU!!
}
DCOCTL = 0;//选择最低 DCOx 和 MODx 设置*/
BCSCTL1 = CALBC1_1MHz;//设置 DCO
DCOCTL = CALDCO_1MHz;
P1DIR |=(BIT7 + BIT6 + BIT0);//将 P1.0设置为输出方向
P1DIR &=~(BIT1 + BIT2 + BIT3 + BIT4 + BIT4);
P1OUT |=(BIT7 + BIT6);
P1OUT &=~BIT0;
P1IES |=(BIT1 + BIT2 + BIT3 + BIT4 + BIT4);// P1.1高/低边沿
P1IFG &=~(BIT1 + BIT2 + BIT3 + BIT4 + BIT4);// IFG 被清零
P1IE |=(BIT1 + BIT2 + BIT3 + BIT4 + BIT4);//中断被启用
I2C_init();
while (1)
{
if (flag==1)
{
P1OUT |= BIT0;
}
其他
{
P1DIR |= BIT0;
P1OUT &=~BIT0;
_bis_SR_register (LPM4_bits + GIE);
}
}
}
//********
// USI 中断服务例程
//********
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector = USI_vector
_interrupt void USI_TXRX (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (USI_vector)) USI_TXRX (void)
其他
错误编译器不受支持!
#endif
{
if (USICTL1和 USISTTIFG)//开始输入?
{
I2C_STATE = 2;//开始时进入第一个状态
}
开关(I2C_STATE)
{
情况0://Idle、不应该在这里
中断;
案例2://RX 地址
USICNT =(USICNT & 0xE0)+ 0x08;//位计数器= 8、RX 地址
USICTL1 &=~USISTTIFG;//清除启动标志
I2C_STATE = 4;//转至下一状态:检查地址
中断;
案例4://处理地址并发送(N)Ack
IF (USISRL & 0x01)//如果读取...
SLV_Addr++;//保存 R/W 位
USICTL0 |= USIOE;// SDA =输出
if (USISRL =SLV_Addr)//地址匹配?
{
USISRL = 0x00;//发送确认
I2C_STATE = 8;//转至下一状态:TX 数据
}
其他
{
USISRL = 0xFF;//发送 NACK
I2C_STATE = 6;//转到下一状态:为下一个开始做好准备
flag=0;
}
USICNT |= 0x01;//位计数器= 1、发送(N) Ack 位
中断;
案例6://准备开始条件
USICTL0 &=~USIOE;// SDA =输入
SLV_Addr = 0x90;//复位从器件地址
I2C_STATE = 0;//复位状态机
中断;
情况8://发送数据字节
IF (Slave_Tx)
{
USICTL0 |= USIOE;// SDA =输出
USISRL = SLV_Data;//发送数据字节
}
其他
{
USICTL0 &=~USIOE;// SDA =输入
}
USICNT |= 0x08;//位计数器= 8、RX 数据
I2C_STATE = 10;//转至下一状态:测试数据和(N) Ack
中断;
案例10://接收数据(N)Ack
IF (Slave_Tx)
{
USICTL0 &=~USIOE;// SDA =输入
USICNT |= 0x01;//位计数器= 1、接收(N)确认
I2C_STATE = 12;//转至下一状态:检查(N) Ack
}
其他
{
//检查数据和 TX (N)确认
USICTL0 |= USIOE;// SDA =输出
如果(USISRL = 0xAA)//如果数据有效...
{
USISRL = 0x00;//发送确认
Slave_Tx = 1;
flag=0;
}
其他
{
USISRL = 0xFF;//发送 NACK
}
USICNT |= 0x01;//位计数器= 1、发送(N) Ack 位
I2C_STATE = 6;//转到下一状态:为下一个开始做好准备
}
中断;
案例12://处理数据确认/否定应答
if (USISRL & 0x01)//如果 NACK 被接收...
{
Slave_Tx = 0;
}
//准备开始条件
USICTL0 &=~USIOE;// SDA =输入
SLV_Addr = 0x90;//复位从器件地址
I2C_STATE = 0;//复位状态机
中断;
}
USICTL1 &=~USIIFG;//清除挂起标志
}
//端口1中断服务例程
#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=Port1_vector
_interrupt void Port_1 (void)
#Elif defined (_GNU_)
void __attribute__((interrupt (Port1_vector))) Port_1 (void)
其他
错误编译器不受支持!
#endif
{
IF (P1IFG 和 BIT1)
{
SLV_Data = 1;
P1IFG &=~BIT1;// P1.1 IFG 被清零
}
IF (P1IFG 和 BIT2)
{
SLV_Data = 2;
P1IFG &=~BIT2;// P1.2 IFG 被清零
}
中频(P1IFG 和 BIT3)
{
SLV_Data = 3;
P1IFG &=~BIT3;//复位 Port1中断标志
}
IF (P1IFG 和 BIT4)
{
SLV_Data = 4;//保存开关4的状态
P1IFG &=~BIT4;// P1.4 IFG 被清零
}
中频(P1IFG 和 BIT5)
{
SLV_Data = 5;//保存开关5的状态
P1IFG &=~BIT4;// P1.5 IFG 被清零
}
flag=1;
_BIC_SR_REGISTER_ON_EXIT (LPM4_BITS);
}
正在等待回复。
谢谢