搜索
bottom↓
回复: 14

MSP430F5529发送中断使能

[复制链接]

出0入0汤圆

发表于 2013-1-24 17:39:14 | 显示全部楼层 |阅读模式
我用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 */

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-1-24 17:48:45 | 显示全部楼层
单步调试;
检查是否有相应的中断函数;

出0入0汤圆

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

出0入0汤圆

 楼主| 发表于 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[receive_count]=UCA1RXBUF;
                receive_count++;
         }
         else if((UCA1RXBUF=='}')&&(receive_count<20))
         {
                 Uart_receive[receive_count]=UCA1RXBUF;
                 receive_finish=1;
         }
         else
         {
                 Uart_receive[receive_count]=UCA1RXBUF;
                 receive_count++;
         }
         break;
  case 4: break;                               // Vector 4 - TXIFG
  default: break;
  }
}

出0入0汤圆

 楼主| 发表于 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++;
                  }

          }

  }
}

出0入0汤圆

 楼主| 发表于 2013-1-24 18:52:56 | 显示全部楼层
断点调试仿真,进入不了while(1)循环,个人觉得程序跑飞了,也就是说CPU处于不可意料状态。在TI官方例程里面,也没有看到起串口初始化时两个同时使能

出0入0汤圆

 楼主| 发表于 2013-1-24 18:53:32 | 显示全部楼层
#include <msp430f5529.h>
#define  PORT_MAP_EINT                     //映射完成,开中断
const unsigned char PortSequence[6] = {
                                                  PM_NONE,
                                                  PM_NONE ,
                                                  PM_UCA1TXD,
                                                  PM_UCA1RXD,
                                                  PM_NONE ,
                                                  PM_NONE

                                                     };
unsigned char Uart_receive[20];
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[i];
    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[i];         // 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[receive_count]=UCA1RXBUF;
                receive_count++;
         }
         else if((UCA1RXBUF=='}')&&(receive_count<20))
         {
                 Uart_receive[receive_count]=UCA1RXBUF;
                 receive_finish=1;
         }
         else
         {
                 Uart_receive[receive_count]=UCA1RXBUF;
                 receive_count++;
         }
         break;
  case 4: break;                               // Vector 4 - TXIFG
  default: break;
  }
}

出0入0汤圆

 楼主| 发表于 2013-1-24 18:54:07 | 显示全部楼层
这是全部程序代码

出0入0汤圆

发表于 2013-1-24 19:02:37 | 显示全部楼层
我估计,你的程序一直在中断函数里跑,因为TX中断一直在产生,一直在响应。(你可以观察中断标志位一目了然,是一直置位的,用软件清0应该也无实际意义)
TX中断一直开是不正确的用法,应该在发送数据时才开中断,数据发送完毕后响应中断,并在中断中禁止发送中断。

出0入0汤圆

发表于 2013-1-24 19:36:34 | 显示全部楼层
程序写错了,你写在case 4。

出0入0汤圆

 楼主| 发表于 2013-1-25 08:38:04 | 显示全部楼层
000h No interrupt pending
002h Data received UCRXIFG Highest
004h Transmit buffer empty UCTXIFG Lowest

出0入0汤圆

 楼主| 发表于 2013-1-25 08:38:31 | 显示全部楼层
写在case 4
没错

出0入0汤圆

 楼主| 发表于 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[receive_count]=UCA1RXBUF;
                receive_count++;
         }
         else if((UCA1RXBUF=='}')&&(receive_count<20))
         {
                 Uart_receive[receive_count]=UCA1RXBUF;
                 receive_finish=1;
         }
         else
         {
                 Uart_receive[receive_count]=UCA1RXBUF;
                 receive_count++;
         }
         break;
  case 4:
              UCA1IE&= ~UCTXIE;
              UCA1IFG|=UCTXIFG;
          break;                               // Vector 4 - TXIFG
  default: break;
  }
}

出0入0汤圆

 楼主| 发表于 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++;
                  }

          }

  }
}

出0入0汤圆

 楼主| 发表于 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?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-28 07:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表