875102538 发表于 2013-1-24 17:39:14

MSP430F5529发送中断使能

我用F5529芯片,串口初始化时不能同时使能接收与发送中断,使能时,编译器不报错,编译通过,但是程序乱跑

void Uart_initial(void)
{
          UCA1CTL1 |= UCSWRST;                      // 复位状态机
          UCA1CTL1 |= UCSSEL_2;                     // BRCLK时钟为SMCLK时钟,1MHz
          UCA1BR0 = 9;                              // 1MHz 115200 (see User's Guide)
          UCA1BR1 = 0;                              // 1MHz 115200
          UCA1MCTL |= UCBRS_1 + UCBRF_0;            // 调制 UCBRSx=1, UCBRFx=0
          UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
        UCA1IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
}

同时头文件设置没错
#define UCTXIE               (0x0002)       /* USCI Transmit Interrupt Enable */
#define UCRXIE               (0x0001)       /* USCI Receive Interrupt Enable */

lcofjp 发表于 2013-1-24 17:48:45

单步调试;
检查是否有相应的中断函数;

jetlib 发表于 2013-1-24 17:55:20

记得改变TRX中断的状态,需要在UCSWRST状态下吧?如果没有在UCSWRST状态下,修改TRX IE是不成功的。但是这应该不会引起你程序乱跑。如果乱跑,那就是你的逻辑有问题。另外乱跑太模糊,啥叫乱跑?是不断的RESET么?如果使能了某个中断,但是没有该中断的handler,中断发生时,同样会reset。

875102538 发表于 2013-1-24 18:47:15

#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break;                               // Vector 0 - no interrupt
case 2:if(UCA1RXBUF=='{')                   // 接收数据帧,包头为“{”,包尾为“}”
         {
                receive_count=0;
                Uart_receive=UCA1RXBUF;
                receive_count++;
         }
         else if((UCA1RXBUF=='}')&&(receive_count<20))
         {
             Uart_receive=UCA1RXBUF;
             receive_finish=1;
         }
         else
         {
             Uart_receive=UCA1RXBUF;
             receive_count++;
         }
         break;
case 4: break;                               // Vector 4 - TXIFG
default: break;
}
}

875102538 发表于 2013-1-24 18:51:07

首先,十分感谢各位的回答。
中断的handler,已经有,当不使能TXIE时,中断正常接收,当时使能TXIE时,即 UCA1IE |= UCRXIE+UCTXIE; 时
void main(void)
{
unsigned char m;
char *FLASH_ject;
WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
Port_Mapping();                           //UART端口映射到P4
P4DIR |= 0xFF;                            // P4.0 - P4.7 output
P4SEL |= 0xFF;                            // P4.0 - P4.6 Port Map functions
Uart_initial();                           //初始化与启动串口
__enable_interrupt();                     //使能全局中断
while(1)
{
          if( receive_finish==1)
          {
                  receive_finish=0;               //操作完成
                  write_SegC();                     //写进FLASH
                  FLASH_ject=(char *) 0x1880;
                  for(m=0;m<20;m++)               //通过串口把FLASH里面的数据发出去,检验FLASH里面数据是否正确
                  {
                          while (!(UCA1IFG&UCTXIFG));
                          UCA1TXBUF=*FLASH_ject++;
                  }

          }

}
}

875102538 发表于 2013-1-24 18:52:56

断点调试仿真,进入不了while(1)循环,个人觉得程序跑飞了,也就是说CPU处于不可意料状态。在TI官方例程里面,也没有看到起串口初始化时两个同时使能

875102538 发表于 2013-1-24 18:53:32

#include <msp430f5529.h>
#definePORT_MAP_EINT                     //映射完成,开中断
const unsigned char PortSequence = {
                                                PM_NONE,
                                                PM_NONE ,
                                                PM_UCA1TXD,
                                                PM_UCA1RXD,
                                                PM_NONE ,
                                                PM_NONE

                                                   };
unsigned char Uart_receive;
unsigned char receive_finish=0;
unsigned char receive_count=0;
void Port_Mapping(void);
void Uart_initial(void);


void write_SegC();
void copy_C2D(void);

void main(void)
{
unsigned char m;
char *FLASH_ject;
WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
Port_Mapping();                           //UART端口映射到P4
P4DIR |= 0xFF;                            // P4.0 - P4.7 output
P4SEL |= 0xFF;                            // P4.0 - P4.6 Port Map functions
Uart_initial();                           //初始化与启动串口
__enable_interrupt();                     //使能全局中断
while(1)
{
          if( receive_finish==1)
          {
                  receive_finish=0;               //操作完成
                  write_SegC();                     //写进FLASH
                  FLASH_ject=(char *) 0x1880;
                  for(m=0;m<20;m++)               //通过串口把FLASH里面的数据发出去,检验FLASH里面数据是否正确
                  {
                          while (!(UCA1IFG&UCTXIFG));
                          UCA1TXBUF=*FLASH_ject++;
                  }

          }

}
}
//*********************************************************************************
//****函数名称:void Uart_initial()
//****函数功能:初始UART,设置BRCLK时钟为1MHz,波特率为115200,数据位8,停止1,无校验
//****返回值   :无
//**********************************************************************************
void Uart_initial(void)
{
          UCA1CTL1 |= UCSWRST;                      // 复位状态机
          UCA1CTL1 |= UCSSEL_2;                     // BRCLK时钟为SMCLK时钟,1MHz
          UCA1BR0 = 9;                              // 1MHz 115200 (see User's Guide)
          UCA1BR1 = 0;                              // 1MHz 115200
          UCA1MCTL |= UCBRS_1 + UCBRF_0;            // 调制 UCBRSx=1, UCBRFx=0
          UCA1CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
          UCA1IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
}
//*********************************************************************************
//****函数名称:Port_Mapping(void)
//****函数功能:PUC上电时,映射一次,P4.3/P4,.2为Uart口,映射完成开中断
//****返回值   :无
//**********************************************************************************
void Port_Mapping(void)
{
unsigned char i;
volatile unsigned char *ptr;
__disable_interrupt();                  // Disable Interrupts before altering Port Mapping registers
PMAPPWD = 0x02D52;                        // Enable Write-access to modify port mapping registers

#ifdef PORT_MAP_RECFG
PMAPCTL = PMAPRECFG;                      // Allow reconfiguration during runtime
#endif

ptr = &P4MAP0;
for(i=0;i<6;i++)
{
    *ptr = PortSequence;
    ptr++;
}

PMAPPWD = 0;                              // Disable Write-Access to modify port mapping registers
#ifdef PORT_MAP_EINT
__enable_interrupt();                     // Re-enable all interrupts
#endif
}

//***********************************************************************************
//****函数名称:void write_SegC(char value)
//****函数功能:先擦除C扇区128字节,在把Value写入128字节
//****返回值   : 无
//************************************************************************************
void write_SegC()
{
unsigned char i;
char * Flash_ptr;                         // Initialize Flash pointer
Flash_ptr = (char *) 0x1880;

__disable_interrupt();                  // 对FLASH操作禁止中断,防止出错

FCTL3 = FWKEY;                            // Clear Lock bit
FCTL1 = FWKEY+ERASE;                      // Set Erase bit
*Flash_ptr = 0;                           // Dummy write to erase Flash seg
FCTL1 = FWKEY+WRT;                        // Set WRT bit for write operation

for (i = 0; i < 20; i++)
{
    *Flash_ptr++ = Uart_receive;         // Write value to flash
}
FCTL1 = FWKEY;                            // Clear WRT bit
FCTL3 = FWKEY+LOCK;                     // Set LOCK bit
__enable_interrupt();
}

//***********************************************************************************
//****函数名称:void copy_C2D(void)
//****函数功能:先擦除D扇区128字节,再把C扇区的值复制到D扇区
//****返回值   : 无
//************************************************************************************
void copy_C2D(void)
{
unsigned int i;
char *Flash_ptrC;
char *Flash_ptrD;

Flash_ptrC = (char *) 0x1880;             // Initialize Flash segment C ptr
Flash_ptrD = (char *) 0x1800;             // Initialize Flash segment D ptr

__disable_interrupt();                  // 5xx Workaround: Disable global
                                          // interrupt while erasing. Re-Enable
                                          // GIE if needed
FCTL3 = FWKEY;                            // Clear Lock bit
FCTL1 = FWKEY+ERASE;                      // Set Erase bit
*Flash_ptrD = 0;                        // Dummy write to erase Flash seg D
FCTL1 = FWKEY+WRT;                        // Set WRT bit for write operation

for (i = 0; i < 128; i++)
{
    *Flash_ptrD++ = *Flash_ptrC++;          // copy value segment C to seg D
}

FCTL1 = FWKEY;                            // Clear WRT bit
FCTL3 = FWKEY+LOCK;                     // Set LOCK bit
__enable_interrupt();
}
//***********************************************************************************
//****函数名称: USCI_A1_ISR(void)
//****函数功能: Uart接收与发送中断
//****返回值   : 无
//************************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break;                               // Vector 0 - no interrupt
case 2:if(UCA1RXBUF=='{')                   // 接收数据帧,包头为“{”,包尾为“}”
         {
                receive_count=0;
                Uart_receive=UCA1RXBUF;
                receive_count++;
         }
         else if((UCA1RXBUF=='}')&&(receive_count<20))
         {
             Uart_receive=UCA1RXBUF;
             receive_finish=1;
         }
         else
         {
             Uart_receive=UCA1RXBUF;
             receive_count++;
         }
         break;
case 4: break;                               // Vector 4 - TXIFG
default: break;
}
}

875102538 发表于 2013-1-24 18:54:07

这是全部程序代码

lcofjp 发表于 2013-1-24 19:02:37

我估计,你的程序一直在中断函数里跑,因为TX中断一直在产生,一直在响应。(你可以观察中断标志位一目了然,是一直置位的,用软件清0应该也无实际意义)
TX中断一直开是不正确的用法,应该在发送数据时才开中断,数据发送完毕后响应中断,并在中断中禁止发送中断。

ggyyll8683 发表于 2013-1-24 19:36:34

程序写错了,你写在case 4。{:lol:}{:lol:}{:lol:}

875102538 发表于 2013-1-25 08:38:04

000h No interrupt pending
002h Data received UCRXIFG Highest
004h Transmit buffer empty UCTXIFG Lowest

875102538 发表于 2013-1-25 08:38:31

写在case 4
没错

875102538 发表于 2013-1-25 08:51:59

十分感谢大家,特别是lcofjp
的确,程序不能一直把TX中断打开,否则一直是响应TX中断,需要在中断里把它关掉,同时需要发数据时才打开。
同时,必须把UCTXIFG置1。因为当数据放进TX缓冲区时,UCTXIFG自动清零,表示缓冲区里面有数据。要等到
UCTXIFG=1时,才可以再次把数据放进缓冲区,所以需要在中断中置1.
//***********************************************************************************
//****函数名称: USCI_A1_ISR(void)
//****函数功能: Uart接收与发送中断
//****返回值   : 无
//************************************************************************************
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
switch(__even_in_range(UCA1IV,4))
{
case 0:break;                               // Vector 0 - no interrupt
case 2:if(UCA1RXBUF=='{')                   // 接收数据帧,包头为“{”,包尾为“}”
         {
                receive_count=0;
                Uart_receive=UCA1RXBUF;
                receive_count++;
         }
         else if((UCA1RXBUF=='}')&&(receive_count<20))
         {
             Uart_receive=UCA1RXBUF;
             receive_finish=1;
         }
         else
         {
             Uart_receive=UCA1RXBUF;
             receive_count++;
         }
         break;
case 4:
              UCA1IE&= ~UCTXIE;
              UCA1IFG|=UCTXIFG;
          break;                               // Vector 4 - TXIFG
default: break;
}
}

875102538 发表于 2013-1-25 08:52:48

void main(void)
{
unsigned char m;
char *FLASH_ject;
WDTCTL = WDTPW+WDTHOLD;                   // Stop WDT
Port_Mapping();                           //UART端口映射到P4
P4DIR |= 0xFF;                            // P4.0 - P4.7 output
P4SEL |= 0xFF;                            // P4.0 - P4.6 Port Map functions
Uart_initial();                           //初始化与启动串口
__enable_interrupt();                     //使能全局中断
while(1)
{
          if( receive_finish==1)
          {
                  receive_finish=0;               //操作完成
                  write_SegC();                     //写进FLASH
                  FLASH_ject=(char *) 0x1880;
                  for(m=0;m<20;m++)               //通过串口把FLASH里面的数据发出去,检验FLASH里面数据是否正确
                  {
                          while (!(UCA1IFG&UCTXIFG));
                          UCA1IE|= UCTXIE;
                          UCA1TXBUF=*FLASH_ject++;
                  }

          }

}
}

875102538 发表于 2013-1-25 09:11:57

还是有几个疑点

1:为什么没有使能中断时TXIFG一直是1?PDF里面说,如果TX缓冲区为空时TXIFG=1,有数据是自动清0,置1是不是硬件置1?

2:如果使能中断了,响应中断时TXIFG为0,要手动置1,PDF里面说,如果TX缓冲区为空时TXIFG=1,但是不知道是不是硬件自动置1?
页: [1]
查看完整版本: MSP430F5529发送中断使能