怎么产生的?如果就字面意思来说的话~就是由芯片内的中断逻辑产生的~串口模块发送寄存器为空或接受寄存器为满时,会向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单片机串口程序,发送数据利用中断方式好,还是查询方式好,为什么等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)