MSP430串口通信时接受、发送中断是怎么产生的

MSP430串口通信时接受、发送中断是怎么产生的,第1张

怎么产生的?如果就字面意思来说的话~就是由芯片内的中断逻辑产生的~串口模块发送寄存器为空或接受寄存器为满时,会向430中断控制器发信号~

这是TI的官方代码样例

//

//  MSP-FET430x140 Demo - USART0, Ultra-Low Pwr UART 9600 String, 32kHz ACLK

//

//  Description: This program demonstrates a full-duplex 9600-baud UART using

//  USART0 and a 32kHz crystal  The program will wait in LPM3, and will

//  respond to a received 'u' character using 8N1 protocol The response will

//  be the string 'Hello World

//  ACLK = LFXT1 = UCLK0, MCLK = SMCLK = default DCO ~ 800KHz

//  Baud rate divider with 32768hz XTAL @9600 = 32768Hz/9600 = 341 (000Dh 4Ah )

//  // An external watch crystal is required on XIN XOUT for ACLK //

//

//               MSP430F149

//            -----------------

//        /|\|              XIN|-

//         | |                 | 32kHz

//         --|RST          XOUT|-

//           |                 |

//           |             P34|----------->

//           |                 | 9600 - 8N1

//           |             P35|<-----------

//

//  M Buccini

//  Texas Instruments Inc

//  Feb 2005

//  Built with CCE Version: 320 and IAR Embedded Workbench Version: 321A

//

#include  <msp430x14xh>

static char string1[] = { "Hello World\r\n" };

char i;

void main(void)

{

WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog

P3SEL = 0x30;                             // P33,4 = USART0 TXD/RXD

ME1 |= UTXE0 + URXE0;                     // Enabled USART0 TXD/RXD

UCTL0 |= CHAR;                            // 8-bit character, SWRST=1

UTCTL0 |= SSEL0;                          // UCLK = ACLK

UBR00 = 0x03;                             // 9600 from 1Mhz

UBR10 = 0x00;                             //

UMCTL0 = 0x4A;                            // Modulation

UCTL0 &= ~SWRST;                          // Initialize USART state machine

IE1 |= URXIE0 + UTXIE0;                   // Enable USART0 RX/TX interrupt

IFG1 &= ~UTXIFG0;                         // Clear inital flag on POR

_BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupt

}

// UART0 TX ISR

#pragma vector=USART0TX_VECTOR

__interrupt void usart0_tx (void)

{

if (i < sizeof string1-1)

TXBUF0 = string1[i++];

}

// UART0 RX ISR

#pragma vector=USART0RX_VECTOR

__interrupt void usart0_rx (void)

{

if (RXBUF0 == 'u')                        // 'u' received

{

i = 0;

TXBUF0 = string1[i++];

}

}

摘录一段我写的程序供参考:

;------------------相关寄存器定义------------------------

AUXR EQU 8EH ;辅助寄存器

AUXR1 EQU 0A2H ;辅助寄存器1

CLK_DIV EQU 97H ;时钟分频器

S2CON EQU 9AH ;串口2控制寄存器

S2BUF EQU 9BH ;串口2数据缓冲区

BRT EQU 9CH ;波特率寄存器

IE2 EQU 0AFH ;中断控制寄存器2

;-----------------串行初始化程序-------------------------

UART_INIT:

ORL PCON,#80H ;使能波特率倍速位SMOD

MOV SCON,#50H ;8位数据,可变波特率

MOV S2CON,#50H ;8位数据,可变波特率

MOV BRT,#0FAH ;57600bps@110592MHz

ORL AUXR,#14H ;独立波特率发生器时钟为Fosc,即1T

ORL IE2,#01H ;允许串口2中断

ANL AUXR,#03FH ;定时器12时钟为Fosc,即12T

ANL AUXR,#0FEH ;串口1选择定时器1为波特率发生器

MOV TMOD,#21H ;设定定时器1为8位自动重装方式,0为16位定时器

MOV TL1,#0FFH ;57600bps@110592MHz

MOV TH1,#0FFH ;设定定时器重装值

MOV SERGET,#0 ;接收RS232 Pointer is 0

MOV SERPUT,#0 ;取值RS232 Pointer is 0

MOV RXGET,#0 ;接收RS485 Pointer is 0

MOV RXPUT,#0 ;取值RS485 Pointer is 0

CLR P44 ;485处于接收状态

ORL IPH,#10H ;

SETB PS ;串口1中断优先级11为最高

CLR ET1 ;禁止定时器1中断

SETB TR1 ;启动定时器1

CLR BUSY

RET

;-----------------串行通讯2中断服务程序-------------------------

SER2INT:

PUSH ACC

PUSH PSW

MOV A,S2CON

JNB ACC0,SER2INT1 ;S2RI

ANL S2CON,#NOT S2RI

MOV A,S2BUF

MOV B,A

MOV R0,#RXRAM

MOV A,RXPUT

ANL A,#0FH

ORL A,R0

MOV R0,A

MOV A,B

MOV @R0,A

LCALL SENDRXDAT

INC RXPUT

SJMP SERINT2

SER2INT1:

MOV A,S2CON

JNB ACC1,SERINT2 ;S2TI

ANL S2CON,#NOT S2TI

CLR BUSY

SERINT2:

POP PSW

POP ACC

RETI

;-----------------串行通讯1中断服务程序-------------------------

SER1INT:

PUSH ACC

PUSH PSW

PUSH DPL

PUSH DPH

SETB RS0

CLR RS1

JBC RI,SERTIRI1 ;是接收中断,清除此标志,转接收

CLR TI ;是发送中断,清除此标志,中断返回

SJMP SEREND

SERTIRI1:

MOV A,SBUF ;接收(读入)数据

MOV B,A

SERTIRI2:

MOV R0,#SERRAM

MOV A,SERPUT

ANL A,#1FH

ORL A,R0

MOV R0,A

MOV A,B

MOV @R0,A

INC SERPUT

MOV DLY03,A

SETB SERBIT

SEREND:

POP DPH

POP DPL

POP PSW

POP ACC

RETI

AVR单片机的UART在数据发送结束时产生中断。如果数据量比较大并且需要连续发送,而单片机的时间资源又很紧张,这时最好采用中断的方式发送数据,把整个数据包扔给中断函数去处理。UART每发送完1个字节发生1次中断,中断之后就从数据缓存读取下一个字节,周而复始直至数据全部发送完毕,这样,单片机可以把有限的时间资源,支配到实时要求更高的事件处理。

如果数据量很少,单片机的时间资源也比较宽松,采用查询的方式则更方便,先把眼下的事件处理完了再处理别的事件,这样做事情更有序,也比同时处理多个事件更不容出错。

用队列缓冲,具体思路是:定义个结构体,结构体可以记录8个字节的信息,然后以此结构体定义结构体组,再定义个计数器,串口每接收完8字节,就赋值给结构体组的单元,计数器+1,主函数不停的判断计数器是否不为零,然后根据计数器处理结构体组。串口也不是你想象的连续接收完才执行主函数,而是接完一个字节就返回了。还有楼主可以去了解下通讯协议及报文设计,那个是比较严谨的数据处理方法。

stm32h750串口发送中断可能是所用电路不对。据查询相关信息显示使用485自动收发电路,(存在的问题是:成本较高,波特率可能达不到,接收状态时同样需要信号输出引脚端置为低电平,若切换时有中断进来,延长发送状态会对总线的数据造成影响。所以不可取。改用发送完成中断进行485发收状态的切换,(用DMA串口空闲中断进行收据的接收)。这样在串口传输完成后即可进行485接收状态的切换,避免程序阻塞,减少了中断的执行时间,降低了对控制程序的影响。

你可以先用串口调试助手,向单片机发送一个数据,如果有j-link,用j-link在中断函数里设置断点,进入中断后程序会停在usart中断那里,还有,通常情况下不使用发送中断,而是接收中断,对于多数据发送,可以等待发送完成标志 while(!(USART1->SR

由于你说的不详细,也不知道你晶振是多少,单片机是什么型号,波特率是多少。也才不清楚你单片机串口的数据是否是一直有用的。我就大概说一下,你可以参考:

第一:如果串口的数据是在你需要的时候才有用,这样你可以在需要的地方打开串口中断,在中断中判断接收的是不是所用串口数据的最后一个字节,如果是那么就关闭中断,如果不是那么就就会继续接收。这样会提高串口和单片机的工作效率。

第二:如果串口数据是必须接收的,那么1楼和2楼所说的就不可以了,其实正常的处理中断就可以了,只要注意中断的优先级就好。串口处理占用的时间其实不是你想的那么多,我不防给你算一下:假设波特率是9600B/S,晶振8M,至于单片机什么类型就不去假设了,毕竟太多了。

串口数据8B一个字节,那么9600的波特率1S传播的次数也就是9600B/S/8B每次=1200次每秒,这个能理解吧。那么中断的时间间隔也就是1S/1200次每秒=083ms。再看单片机的处理速度,8M晶振(不算大吧),运行每条指令的时间基本上是1S/8M=0125uS,(就算是51单片机,处理周期是晶振周期的12倍,那每条指令的时间周期也不过是1点几微秒),通过数据你看,一次中断单片机能处理上千条指令,所以不会出现你想的它只是在接收数据,其他什么也许不干的情况。你所要做的就是如果有其他中断,处理好中断的优先级,哪些中断重要,需要优先处理之类的事情即可。

你不会存在误区吧,认为一直有数据,就一直在中断中吧,它接收是一个字节一个字节的。一个字节一中断。

楼上说的定时器你还是不要考虑了,需要多少次数不定,处理定时器中断后还要在处理串口,耽误的时间会更多。而且可靠性不高,串口一直传输数据的项目我做过,正常处理就不会出问题

在程序中检测RI和TI,RI表示接收中断,TI表示发送中断,如果只要在接收中断时运行,可以如下设置:

JNB RI,EXIT

CLR RI

EXIT:

RETI

以上就是关于MSP430串口通信时接受、发送中断是怎么产生的全部的内容,包括:MSP430串口通信时接受、发送中断是怎么产生的、使用stc12c5a60s2双串口单片机时 串口2的中断服务子程序怎么写呢、avr单片机串口程序,发送数据利用中断方式好,还是查询方式好,为什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9458652.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存