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 */ 单步调试;
检查是否有相应的中断函数; 记得改变TRX中断的状态,需要在UCSWRST状态下吧?如果没有在UCSWRST状态下,修改TRX IE是不成功的。但是这应该不会引起你程序乱跑。如果乱跑,那就是你的逻辑有问题。另外乱跑太模糊,啥叫乱跑?是不断的RESET么?如果使能了某个中断,但是没有该中断的handler,中断发生时,同样会reset。
#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;
}
} 首先,十分感谢各位的回答。
中断的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++;
}
}
}
} 断点调试仿真,进入不了while(1)循环,个人觉得程序跑飞了,也就是说CPU处于不可意料状态。在TI官方例程里面,也没有看到起串口初始化时两个同时使能 #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;
}
}
这是全部程序代码 我估计,你的程序一直在中断函数里跑,因为TX中断一直在产生,一直在响应。(你可以观察中断标志位一目了然,是一直置位的,用软件清0应该也无实际意义)
TX中断一直开是不正确的用法,应该在发送数据时才开中断,数据发送完毕后响应中断,并在中断中禁止发送中断。 程序写错了,你写在case 4。{:lol:}{:lol:}{:lol:} 000h No interrupt pending
002h Data received UCRXIFG Highest
004h Transmit buffer empty UCTXIFG Lowest 写在case 4
没错 十分感谢大家,特别是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;
}
}
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++;
}
}
}
} 还是有几个疑点
1:为什么没有使能中断时TXIFG一直是1?PDF里面说,如果TX缓冲区为空时TXIFG=1,有数据是自动清0,置1是不是硬件置1?
2:如果使能中断了,响应中断时TXIFG为0,要手动置1,PDF里面说,如果TX缓冲区为空时TXIFG=1,但是不知道是不是硬件自动置1?
页:
[1]