搜档网
当前位置:搜档网 › STM32串口中断接收方式详细比较

STM32串口中断接收方式详细比较

STM32串口中断接收方式详细比较
STM32串口中断接收方式详细比较

串口中断接收方式详细比较

串口调试,以前也调过,只是没这么深入的琢磨过,最近又在弄,感觉串口很基本,也很有学问,要是出现BUG可能导致系统奔溃。。。现在贴出来,欢迎拍砖指正!!!

本例程通过PC机的串口调试助手将数据发送至STM32,STM32通过SP3232芯片采用中断接收方式完成,然后接收数据后将所接收的数据又发送至PC机,具体下面详谈。。。

实例一:

void USART1_IRQHandler(u8 GetData)

{

u8 BackData;

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生

{

USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志.

GetData = UART1_GetByte(BackData); //也行GetData=USART1->DR;

USART1_SendByte(GetData); //发送数据

GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED闪烁,接收成功发送完成

delay(1000);

GPIO_ResetBits(GPIOE, GPIO_Pin_8 );

}

}

这是最基本的,将数据接收完成后又发送出去,接收和发送在中断函数里执行,main 函数里无其他要处理的。

优点:简单,适合很少量数据传输。

缺点:无缓存区,并且对数据的正确性没有判断,数据量稍大可能导致数据丢失。

实例二:

void USART2_IRQHandler()

{

if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生

{

USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志

Uart2_Buffer[Uart2_Rx_Num] = USART_ReceiveData(USART2);

Uart2_Rx_Num++;

}

if((Uart2_Buffer[0] == 0x5A)&&(Uart2_Buffer[Uart2_Rx_Num-1] == 0xA5)) //判断最后接收的数据是否为设定值,确定数据正确性

Uart2_Sta=1;

if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出

{

USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR

USART_ReceiveData(USART2); //读DR

}

}

if( Uart2_Sta )

{

for(Uart2_Tx_Num=0;Uart2_Tx_Num < Uart2_Rx_Num;Uart2_Tx_Num++)

USART2_SendByte(Uart2_Buffer[Uart2_Tx_Num]); //发送数据

Uart2_Rx_Num = 0; //初始化

Uart2_Tx_Num = 0;

Uart2_Sta = 0;

}

这是加了数据头和数据尾的接收方式,数据头和尾的个数可增加,此处只用于调试之用。中断函数用于接收数据以及判断数据的头尾,第二个函数在main函数里按照查询方式执行。

优点:较简单,采用缓存区接收,对提高数据的正确行有一定的改善。

缺点:要是第一次数据接收错误,回不到初始化状态,必须复位操作。

实例三:

vvoid USART2_IRQHandler()

{

if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生

{

USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志.

Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2);

Uart2_Rx++;

Uart2_Rx &= 0x3F; //判断是否计数到最大

}

if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出

{

USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR

USART_ReceiveData(USART2); //读DR

}

}

if( Uart2_Tx != Uart2_Rx )

{

USART2_SendByte(Uart2_Buffer[Uart2_Tx]); //发送数据

Uart2_Tx++;

Uart2_Tx &= 0x3F; //判断是否计数到最大

}

采用FIFO方式接收数据,由0x3F可知此处最大接收量为64个,可变,中断函数只负责

收,另一函数在main函数里执行,FIFO方式发送。

优点:发送和接收都很自由,中断占用时间少,有利于MCU处理其它。

缺点:对数据的正确性没有判断,一概全部接收。

实例四:

void USART2_IRQHandler()

{

if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生

{

USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志

Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2);

Uart2_Rx++;

Uart2_Rx &= 0xFF;

}

if(Uart2_Buffer[Uart2_Rx-1] == 0x5A) //头

Uart2_Tx = Uart2_Rx-1;

if((Uart2_Buffer[Uart2_Tx] == 0x5A)&&(Uart2_Buffer[Uart2_Rx-1] == 0xA5)) //检测到头的情况下检测到尾

{

Uart2_Len = Uart2_Rx-1- Uart2_Tx; //长度

Uart2_Sta=1; //标志位

}

if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出

{

USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR

USART_ReceiveData(USART2); //读DR

}

}

if( Uart2_Sta )

{

for(tx2=0;tx2 <= Uart2_Len;tx2++,Uart2_Tx++)

USART2_SendByte(Uart2_Buffer[Uart2_Tx]); //发送数据

Uart2_Rx = 0; //初始化

Uart2_Tx = 0;

Uart2_Sta = 0;

}

数据采用数据包的形式接收,接收后存放于缓存区,通过判断数据头和数据尾(可变)来判断数据的“包”及有效性,中断函数用于接收数据和判断头尾以及数据包长度,另一函数在main函数里执行,负责发送该段数据。

优点:适合打包传输,稳定性和可靠性很有保证,可随意发送,自动挑选有效数据。

缺点:缓存区数据长度要根据“包裹”长度设定,要是多次接收后无头无尾,到有头有尾的那一段数据恰好跨越缓存区最前和最后位置时,可能导致本次数据丢失,不过这种情况几乎没有可能。

串口中断服务函数集

串口中断服务函数集 https://www.sodocs.net/doc/8e3325017.html, 2003-4-22 电子工程师网站 //本函数集来自“51单片机世界”,作者斑竹丁丁(聂小猛)。 //主页地址https://www.sodocs.net/doc/8e3325017.html, //串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理 //出入均设有缓冲区,大小可任意设置。 //可供使用的函数名: //char getbyte(void);从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。 //getline(char idata *line, unsigned char n); 获取一行数据回车结束,必须定义最大输入字符数 //putbyte(char c);放入一个字节到发送缓冲区 //putbytes(unsigned char *outplace,j);放一串数据到发送缓冲区,自定义长度//putstring(unsigned char code *puts);发送一个定义在程序存储区的字符串到串口 //puthex(unsigned char c);发送一个字节的hex码,分成两个字节发。 //putchar(uchar c,uchar j);输出一个无符号字符数的十进制表示,必须标示小数点的位置,自动删除前面无用的零 //putint(uint ui,uchar j);输出一个无符号整型数的十进制表示,必须标示小数点的位置,自动删除前面无用的零 //delay(unsigned char d); 延时n x 100ns //putinbuf(uchar c);人工输入一个字符到输入缓冲区 //CR;发送一个回车换行 //********************************************************************** *** #include #define uchar unsigned char #define uint unsigned int #define OLEN 32 /* size of serial transmission buffer */ idata unsigned char outbuf[OLEN]; /* storage for transmission buffer */ unsigned char idata *outlast=outbuf; //最后由中断传输出去的字节位置unsigned char idata *putlast=outbuf; //最后放入发送缓冲区的字节位置 #define ILEN 12 /* size of serial receiving buffer */ idata unsigned char inbuf[ILEN]; unsigned char idata *inlast=inbuf; //最后由中断进入接收缓冲区的字节位置unsigned char idata *getlast=inbuf; //最后取走的字节位置 bit outbufsign0; //最后一个数据覵BUF发完标志发完=0 bit outbufsign; //输出缓冲区非空标志有=1 bit inbufsign; //接收缓冲区非空标志有=1 bit inbufful; //输入缓冲区满标志满=1

关于STM32串口空闲中断IDEL的问题

关于STM32串口空闲中断IDEL的问题 1.空闲中断是接受数据后出现一个byte 的高电平(空闲)状态,就会触发空闲 中断.并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个 byte,如果一直是低电平是不会触发空闲中断的(会触发break 中断)。 2.关于第二点有要铺垫的三个情况,datasheet 中”当一空闲帧被检测到时,其处 理步骤和接收到普通数据帧一样,但如果IDLEIE 位被设置将产生一个中断”“空 闲符号被视为完全由'1'组成的一个完整的数据帧,后面跟着包含了数 据的下一帧的开始位'1'的位数也包括了停止位的位数”空闲符号的 配图后面跟这一个低电平.有人理解为只有收到下一个数据的起始位才会触发中 断,这样理解是不对的,应该是数据后有空闲了一帧就会触发. 3.清中断的方式感觉奇怪,使用函数USART_ClearITPendingBit( USART1, USART_IT_IDLE )清除不了中断的.我用的是3.5 的库,查看函数说明,里面的 @param 参数并没有IDLE,后面的@note 中,这样说:”PE(Parity error),FE(Framing error),NE(Noise error),ORE(OverRun error) and IDLE(Idle line detected) pending bits are cleared by software sequence: a read operation to USART_SR register (USART_GetITStatus()) followed by a read operation to USART_DR register (USART_ReceiveData()).”我是通过语句”USART1->DR;”来清除IDLE 中断的. 现在有很多数据处理都要用到不定长数据,而单片机串口的RXNE 中断一次 只能接收一个字节的数据,没有缓冲区,无法接收一帧多个数据,现提供两种 利用串口IDLE 空闲中断的方式接收一帧数据,方法如下: 方法1:实现思路:采用STM32F103 的串口1,并配置成空闲中断IDLE 模 式且使能DMA 接收,并同时设置接收缓冲区和初始化DMA。那么初始化完成 之后,当外部给单片机发送数据的时候,假设这帧数据长度是200 个字节,那

TMS320F28335外部中断总结

TMS320F28335外部中断总结 作者:Free 文章来源:Free 点击数:93 更新时间:2010-8-26 在这里我们要十分清楚DSP的中断系统。C28XX一共有16个中断源,其中有2个不可屏蔽的中断RESET和NMI、定时器1和定时器2分别使用中断13 和14。这样还有12个中断都直接连接到外设中断扩展模块PIE上。说的简单一点就是PIE 通过12根线与28335核的12个中断线相连。而PIE的另外 一侧有12*8根线分别连接到外设,如AD、SPI、EXINT等等。这样PIE共管理12*8=96个外部中断。这12组大中断由28335核的中断寄存器IER来控 制,即IER确定每个中断到底属于哪一组大中断(如IER |= M_INT12;说明我们要用第12组的中断,但是第12组里面的什么中断CPU并不知道需 要再由PIEIER确定)。接下来再由PIE模块中的寄存器PIEIER中的低8确定该中断是这一组的第几个中断,这些配置都要告诉CPU(我们不难想 象到PIEIER共有12总即从PIEIER1-PIEIER12)。另外,PIE模块还有中断标志寄存器PIEIFR,同样它的低8位是来自外部中断的8个标志位,同 样CPU的IFR寄存器是中断组的标志寄存器。由此看来,CPU的所有中断寄存器控制12组的中断,PIE的所有中断寄存器控制每组内8个的中断。 除此之外,我们用到哪一个外部中断,相应的还有外部中断的寄存器,需要注意的就是外部中断的标志要自己通过软件来清零。而PIE和CPU的 中断标志寄存器由硬件来清零。 EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.XINT2 = &ISRExint; //告诉中断入口地址 EDIS; // This is needed to disable write to EALLOW protected registers PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block使能PIE PieCtrlRegs.PIEIER1.bit.INTx5= 1; //使能第一组中的中断5 IER |= M_INT1; // Enable CPU 第一组中断

利用中断实现UART串口

中断方式下进行串口通讯的正确方法 一般普遍的把串口通讯分为查询方式和中断方式。查询方式比较容易理解,各种书籍上都介绍的比较清楚。但中断方式,没有几本书讲得好的,甚至有些例程根本无法实际应用。 问题有: 1,半中断法。只使用接收中断,不使用发送中断,发送时还是依靠查询中断标志的办法;如下: ES = 0;//若是接收使用中断方式,某些单片机需要关中断。但C51不一定需要。这里只是示例。 SBUF = needsendchar; While (!TI); TI = 0; ES = 1; 这里的问题是:发送数据时需要等待数据发完才能继续其他工作,程序效率降低;发送时需要关中断,影响数据接收。 2,接收中断的处理方法错误。如下: 中断程序: void ser() interrupt 4 { RI = 0; temp = SBUF; //读走数据,放入缓存(全局的)变量 rx_flag = 1; //设置接收标志 } 主程序: void main(){ …;//初始化 While (1) { If (rx_flag ==1){//查询接收标志 rx_flag = 0; //清楚接收标志 x = temp; //从暂存变量读取数据 …;//接收处理 } …; //其它操作 } } 这里的问题是:如果串口接收数据的间隔时间小于“接收处理”和“其它操作”所用的时间时,接收数据会丢失一部分。 正确使用中断方式处理串口收发应达到以下目的: 1,完全使用中断控制接收和发送,以达到最快的收发速度。 2,接收和发送互不影响,达到全双工通讯效果。 3,应用程序不发生等待,以达到最高运行效率。

正确的中断发送方法如下: 1,建立一个足够大小的环形发送缓冲区,建立一个信号量(用于指示发送的数据量),建立一个发送标志位(用于指示发送状态)。 2,应用程序将数据写入环形发送缓冲区,查询发送接收标志,若不在发送状态,手动触发中断。 3,产生发送中断时,查询信号量,以判别发送缓冲区内是否有数据;若有,置发送标志位,从缓冲区读取数据发送,累减信号量;若无,清除发送标志位。 C51的例程如下: //变量定义 #define BUF_SIZE 0x10//环形收发缓冲区长度 //发送参数 char tx_circbuf[BUF_SIZE];//环形发送缓冲区 uint8 tx_sem;//信号量 bool tx_run;//发送标志位 uint8 tx_circin;//进环形缓冲区的位置指示 uint8 tx_circout;//出环形缓冲区的位置指示 //发送初始化程序 void tx_init(void){ //硬件初始化略 //发送参数初始化 tx_sem = 0; tx_run = False; tx_circin = 0; tx_circout = 0; } //中断程序 void tx_int(void) interrupt 4 { if (TI){ TI = 0; if (tx_sem){ SBUF = tx_circbuf [tx_circout]; // 发送缓冲区中的字符 if (++tx_circout >= BUF_SIZE) tx_circout = 0; tx_sem--;//累减信号量 tx_run = True;//置发送标志位 } else tx_run = False;//清除发送标志位 } } //发送处理程序,由应用程序调用 //输入:发送数据指针,发送数据长度

最新stm32学习之串口usart复习进程

STM32学习之串口USART STM32 的串口是相当丰富的。最多可提供5路串口,有分数波特率发生器、支持单线光通信和半双工单线通讯、支持LIN、智能卡协议和IrDA SIR ENDEC 规范(仅串口3 支持)、具有DMA 等。串口最基本的设置,就是波特率的设置。STM32 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应IO口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了。 1、串口时钟使能。串口作为STM32 的一个外设,其时钟由外设始终使能寄存器控制,这里我们使用的串口1是在APB2ENR 寄存器的第14 位。除了串口1 的时钟使能在APB2ENR寄存器,其他串口的时钟使能位都在APB1ENR。 1、串口的作用:用在STM32板子和PC机通信的。我们调试的时候,无法知道是否正确,就可以用STM32的cpu,给串口输出一些信息给PC,我们通过屏幕(实际上是终端串口软件),可以看到这些信息,从而知道当前程序的错误可能出现的位置。当然,也可以在PC的键盘敲打命令,让串口帮传递给STM32板子,来执行这些命令。 2、串口的工作模式一般有两种方式:查询和中断 (1)查询:串口程序不断地循环查询,看看当前有没有数据要它传,如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32 板子到PC)。 (2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着要它帮助传输数据——它就马上进行数据的传送。同样,可以从PC到STM32板子,也可以从STM32板子到PC 。 步骤一从硬件开始学习。大家先打开芯达STM32开发板附带的原理图。找到串口部分。笔者把它截图如下。我们发现,串口模块的电路是这样的:STM32的CPU引脚,通过两个PA端口的引脚PA10和PA9(此两个引脚复用USART),连接到一个SP3232芯片,或者MAX232芯片。然后再连接到DB9串口座上。由于232芯片可以允许走两路信号,因此,我们扩展了一个串口COM2,请注意,如无特别说明,我们都将使用COM1。

STM32串口中断接收方式详细比较

本例程通过PC机的串口调试助手将数据发送至STM32,接收数据后将所接收的数据又发送至PC机,具体下面详谈。。。 实例一: void USART1_IRQHandler(u8 GetData) { u8 BackData; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志. GetData = UART1_GetByte(BackData); //也行GetData=USART1->DR; USART1_SendByte(GetData); //发送数据 GPIO_SetBits(GPIOE, GPIO_Pin_8 ); //LED闪烁,接收成功发送完成 delay(1000); GPIO_ResetBits(GPIOE, GPIO_Pin_8 ); } } 这是最基本的,将数据接收完成后又发送出去,接收和发送在中断函数里执行,main函数里无其他要处理的。 优点:简单,适合很少量数据传输。 缺点:无缓存区,并且对数据的正确性没有判断,数据量稍大可能导致数据丢失。 实例二: void USART2_IRQHandler() { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) //中断产生 { USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志 Uart2_Buffer[Uart2_Rx_Num] = USART_ReceiveData(USART2); Uart2_Rx_Num++; } if((Uart2_Buffer[0] == 0x5A)&&(Uart2_Buffer[Uart2_Rx_Num-1] == 0xA5)) //判断最后接收的数据是否为设定值,确定数据正确性 Uart2_Sta=1; if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) //溢出 { USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR USART_ReceiveData(USART2); //读DR } } if( Uart2_Sta ) { for(Uart2_Tx_Num=0;Uart2_Tx_Num < Uart2_Rx_Num;Uart2_Tx_Num++)

串口中断程序

//串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理 //出入均设有缓冲区,大小可任意设置。 //可供使用的函数名: //char getbyte(void);从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。 //getline(char idata *line, unsigned char n); 获取一行数据回车结束,必须定义最 大输入字符数 //putbyte(char c);放入一个字节到发送缓冲区 //putbytes(unsigned char *outplace,j);放一串数据到发送缓冲区,自定义长度 //putstring(unsigned char code *puts);发送一个定义在程序存储区的字符串到串口 //puthex(unsigned char c);发送一个字节的hex码,分成两个字节发。 //putchar(uchar c,uchar j);输出一个无符号字符数的十进制表示,必须标示小数点的位置,自动删除前面无用的零 //putint(uint ui,uchar j);输出一个无符号整型数的十进制表示,必须标示小数点的位置,自动删除前面无用的零 //delay(unsigned char d); 延时n x 100ns //putinbuf(uchar c);人工输入一个字符到输入缓冲区 //cr;发送一个回车换行 //************************************************************************* #include #define uchar unsigned char #define uint unsigned int #define olen 32 /* size of serial transmission buffer */ idata unsigned char outbuf[olen]; /* storage for transmission buffer */ unsigned char idata *outlast=outbuf; //最后由中断传输出去的字节位 置 unsigned char idata *putlast=outbuf; //最后放入发送缓冲区的字节位 置 #define ilen 12 /* size of serial receiving buffer */ idata unsigned char inbuf[ilen]; unsigned char idata *inlast=inbuf; //最后由中断进入接收缓冲区的字节位置unsigned char idata *getlast=inbuf; //最后取走的字节位置 bit outbufsign0; //最后一个数据覵buf发完标志发完=0 bit outbufsign; //输出缓冲区非空标志有=1 bit inbufsign; //接收缓冲区非空标志有=1 bit inbufful; //输入缓冲区满标志满=1 #define cr putstring("\r\n") //cr=回车换行 //***************************** //延时n x 100ns void delay(unsigned char d) //在源程序开头定义是否用w77e58或22。1184m晶振

STM32 无中断串口代码

STM32 无中断串口代码2010-05-14 16:09 串口,是我们日常使用最多的一部分,刚开始做电子工程师的,基本都是从这个开始的,下面的代码是我使用STM32库编写的串口输出和读取的代码。 1、串口初始化函数:void USART_Ini(USART_TypeDef* USARTx,u16 buad) 2、串口中断开启和关闭:USART_IT(USART_TypeDef* USARTx,FunctionalState NewState) 3、串口接收:u16 Getch(USART_TypeDef* USARTx) 4、串口单个字符输出:void Putch(USART_TypeDef* USARTx,u16 ch) 5、串口输出字符串:void PutStr(USART_TypeDef* USARTx,u16 *SendBuf,u16 Length) #include "stm32f10x_lib.h" u16 RecDateBuffer[100]; u16 RecLen; u8 SendDateBuffer[100]; /************************************************************* ****************** * Function Name : Uart_Ini * Description : 串口初始化 * Input : * Output : None * Return : ************************************************************** *****************/ void USART_Ini(USART_TypeDef* USARTx,u16 buad) { USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockIni; GPIO_InitTypeDef GPIO_InitStructure; /* Configure USART1 Tx (PA.09) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Configure USART1 Rx (PA.10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

基于单片机的GPS串口中断接收程序

#include #include "1602.h" sbit GPS_SPD=P1^1; //GPS模块速率设置 sbit KEY1=P1^0; //显示内容分屏切换 char code TIME_AREA= 8; //时区 //GPS数据存储数组 unsigned char JD[10]; //经度 unsigned char JD_a; //经度方向 unsigned char WD[9]; //纬度 unsigned char WD_a; //纬度方向 unsigned char date[6]; //日期 unsigned char time[6]; //时间 unsigned char speed[5]={'0','0','0','0','0'}; //速度 unsigned char high[6]; //高度 unsigned char angle[5]; //方位角 unsigned char use_sat[2]; //使用的卫星数 unsigned char total_sat[2]; //天空中总卫星数 unsigned char lock; //定位状态 //串口中断需要的变量 unsigned char seg_count; //逗号计数器 unsigned char dot_count; //小数点计数器 unsigned char byte_count; //位数计数器 unsigned char cmd_number; //命令类型 unsigned char mode; //0:结束模式,1:命令模式,2:数据模式unsigned char buf_full; //1:整句接收完成,相应数据有效。0:缓存数据无效。unsigned char cmd[5]; //命令类型存储数组 //显示需要的变量 unsigned int dsp_count; //刷新次数计数器 unsigned char time_count; bit page; void sys_init(void); bit chk_key(void); main() { unsigned char i; char Bhour; sys_init();

stm32 串口中断总结

本文以USART1为例,叙述串口中断的编程过程。 1、先来讲述一下在应用串口中断时涉及到的一些库文件。 首先对于STM32外设库文件的应用编程,misc.c和stm32f10x_rcc.c是肯定要添加到。 接下来就是我们要用到的相关外设了。毫无疑问,串口文件stm32f10x_usart.c是必须的。串口通信是对通用GPIO端口引脚的功能复用,所以还需要stm32f10x_gpio.c文件。另外,因为有中断的产生,所以中断文件stm32f10x_it.c也是必要的,当然这个文件一般和main.c 放在一个文件夹下(一般习惯为User文件夹),因为我们的中断响应函数是要在里面自己编写的。 当然还有其他的基本必须文件如系统配置文件等在这地方就不说了,这个是创建一个工程应该知道的。 2、初始化 对于串口通信的初始化,不仅仅只是对串口的初始化(这个地方是比较烦人的,不像别的芯片那样简洁明了)。 ●?首先时钟使能配置。STM32内部的时钟有很多,感兴趣的自己看看参考手册。此处 以USART1为例说明。有USART1时钟、GPIOA时钟、GPIO复用(AFIO)时钟。由于 此处USART1和GPIOA、AFIO均在APB2上,所以可以一次配置完成。如下: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB 2Periph_USART1 ,ENABLE); ●?其次中断配置。主要有优先级组设定、USART1中断使能、该中断的优先级,中断初 始化。程序如下: void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//选择分组方式0 /* 使能 USART1中断 */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } ●?然后GPIO复用功能配置。一般情况下我们使用原始的外设和GPIO端口引脚的映射 关系,如果要改变其映射的话,请另外查看参考手册上关于GPIO重映射部分。对 于GPIO的复用,其引脚的输入与输出模式都有要求,在参考手册上有详细说明。 void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* 配置 USART1 Rx 作为浮空输入 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(USARTy_GPIO, &GPIO_InitStructure); /* 配置 USART1 Tx 作为推挽输出 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

串口程序流程图.doc

串口程序流程图 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。我给大家整理了关于,希望你们喜欢! 串口接口划分标准 同步串行接口(英文:SynchronousSerialInterface,SSI)是一种常用的工业用通信接口。。 异步串行是指UART(Universal Asynchronous Receiver/Transmitter),通用异步接收/发送。UART是一个并行输入成为串行输出的芯片,通常集成在主板上。UART包含TTL电平的串口和RS232电平的串口。 TTL电平是3.3V的,而RS232是负逻辑电平,它定义+5~+12V为低电平,而-12~-5V 为高电平,MDS2710、MDS SD4、EL805等是RS232接口,EL806有TTL接口。 串行接口按电气标准及协议来分包括RS-232-C、RS-422、RS485等。RS-232-C、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。 RS-232 也称标准串口,最常用的一种串行通讯接口。它是在1970年由美国电子工业协会(EIA)联合贝尔系统、调制解调器厂家及计算机终端生产厂家

共同制定的用于串行通讯的标准。它的全名是"[1] 数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准"。传统的 RS-232-C接口标准有22根线,采用标准25芯D型插头座(DB25),后来使用简化为9芯D型插座(DB9),现在应用中25芯插头座已很少采用。 RS-232采取不平衡传输方式,即所谓单端通讯。由于其发送电平与接收电平的差仅为2V至3V左右,所以其共模抑制能力差,再加上双绞线上的分布电容,其传送距离最大为约15米,最高速率为20kb/s。RS-232是为点对点(即只用一对收、发设备)通讯而设计的,其驱动器负载为3~7k。所以RS-232适合本地设备之间的通信。[2] RS-422 标准全称是"平衡电压数字接口电路的电气特性",它定义了接口电路的特性。典型的RS-422是四线接口。实际上还有一根信号地线,共5根线。其DB9连接器引脚定义。由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通信,所以RS-422支持点对多的双向通信。接收器输入阻抗为4k,故发端最大负载能力是10×4k+100(终接电阻)。RS-422四线接口由于采用单独的发送和接收通道,因此不必控制数据方向,各装置之间任何必须的信号交换均可以按软件方式(XON/XOFF握手)或硬件方式(一对单独的双绞线)实现。 RS-422的最大传输距离为1219米,最大传输速率为10Mb/s。其平衡双绞线的长度与传输速率成反比,在100kb/s速率以下,才可能达到最大传

STM32个人总结

基础入门编 1.搭建开发环境 详情看光盘资料,主要是软件安装和设置。 2.新建工程 可以直接用模板,了解每个文件的含义,会使用chm帮助。 3.STM32库 库的含义。 4.GPIO流水灯 认识RCC,GPIO的各种模式,寄存器的种类和作用。 5.POLLING按键 主要介绍了各种模式,实验通过不断读取GPIO的状态以达到判断按键的目的。 6.EXTI按键 使用了GPIO的EXTI中断来判断按键,记住EXTI要开AFIO(重映射也要开),另外SYSTICK不归NVIC管。注意NVIC_IRQChannelSubPriority(),最多可以判断16种优先级,即16种中断,同一个中断入口的引脚引发的中断也算是同一种中断,同种种中断不能相互嵌套。(响应优先级是在抢占优先级相同时,同时发生才有用,其中一个发生后无用)。 7.SYSTICK 关键是SYSTICK的初始化函数,了解那几个寄存器的作用和特殊的宏定义(就是选择自己想选择的位),根据配置可以延时不同的时间,详情看代码。 8.串口通信 开启相应RCC,做好Iint,配置好中断(可选,主要用于接收),然后弄好fputc(),可以直接用printf()直接输出。 9.DMA 不经CPU处理直接相互传输,开启相应的DMA,配置好from..to..,字节大小等,用cmd 命令后可以开启传输。 10.ADC(DMA) 主要就是初始化好ADC,什么通道模式之类的,详情看代码,由于使用了DMA模式,要配置好DMA,有ADC_DMACmd()开始传输。 11..FSMC显示英文 用FSMC直接写入液晶的控制芯片的显存,注意使用的是16位的颜色,线的接法要注意(RGB为5:6:5)。 由于用的是模拟的方法,输入数据时用的都是宏,该地址线用来作为C/D,16位是往前移了一位的,因此要乘以2. 值得注意的是开窗的显示手法,在显示字符前先“开”一个窗,当一行数据写完时,自动换到下一行继续写。 在写数据的函数那里可以更换字的背景色,也可以修改该函数的.h的BACKGROUND 的宏定义。 FSMC的初始化暂时不清楚,应该是关于NOR FLASH的。控制代码是配好的,具体的设置看参考文档(有关定位坐标和扫描方式都与此有关)。 (NOR-FLASH 有4个bank,NE[3:0],区分不同的bank,实验用NE1;DataAddress_Mux 数据域地址线复用;8位地址线25:0->24:0 16位地址线25:1->24:0,宏定义是16位的地址线,对应的机内地址*2左移1位) 12.IIC-EEPROM

单片机C51串口中断接收和发送范例

//这是一个单片机C51串口接收(中断)和发送例程,可以用来测试51单片机的中断接收 //和查询发送,另外我觉得发送没有必要用中断,因为程序的开销是一样 #include #include #define INBUF_LEN 4//数据长度 unsigned char inbuf1[INBUF_LEN]; unsigned char checksum,count3; bit read_flag=0; void init_serialcomm(void) { SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload PCON |= 0x80; //SMOD=1; TH1 = 0xF4; //Baud:4800 fosc="11".0592MHz IE |= 0x90; //Enable Serial Interrupt TR1 = 1; // timer 1 run // TI="1"; } //向串口发送一个字符 void send_char_com(unsigned char ch) { SBUF="ch"; while(TI==0); TI=0; } //向串口发送一个字符串,strlen为该字符串长度 void send_string_com(unsigned char *str,unsigned int strlen) { unsigned int k=0; do { send_char_com(*(str + k)); k++; } while(k < strlen); }

STM32 Uart串口中断响应、发送接收详细程序

程序实现功能:可以直接接收USART1的数据,并通过串口调试输出显示 #include"stm32f10x_lib.h" void NVIC_Configuration(void); void RCC_Configuration(void); void GPIO_Configuration(void); ErrorStatus HSEStartUpStatus; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; int main() { #ifdef DEBUG debug #endif RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); /*串口传输速率的大小必须与RCC所设定的时钟相对应起来*/ USART_https://www.sodocs.net/doc/8e3325017.html,ART_BaudRate = 9600; //设置USART的传输速率/*设定数据的接收发送模式*/ USART_https://www.sodocs.net/doc/8e3325017.html,ART_WordLength = USART_WordLength_8b;//在一帧中传输或接受8位数据位 USART_https://www.sodocs.net/doc/8e3325017.html,ART_StopBits = USART_StopBits_1; //定义在帧的结尾传输一个停止位 USART_https://www.sodocs.net/doc/8e3325017.html,ART_Parity = USART_Parity_No; //奇偶失能 USART_https://www.sodocs.net/doc/8e3325017.html,ART_HardwareFlowControl = USART_HardwareFlowControl_None; //指定硬件流控制模式RTS和CTS使能 USART_https://www.sodocs.net/doc/8e3325017.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //指定使能或失能发送和接受模式Tx发送使能和Rx接收使能 USART_Clock https://www.sodocs.net/doc/8e3325017.html,ART_Clock = USART_Clock_Disable; //提升USART时钟时使能还是失能,钟低电平活动 USART_https://www.sodocs.net/doc/8e3325017.html,ART_CPOL = USART_CPOL_Low; //指定SLCK引脚上时钟的极性 USART_https://www.sodocs.net/doc/8e3325017.html,ART_CPHA = USART_CPHA_2Edge; //时钟第二个边缘进行数据捕获 USART_https://www.sodocs.net/doc/8e3325017.html,ART_LastBit = USART_LastBit_Disable; //在SCLK引脚上输出最后发送的那个数据字的脉冲不从SCLK输出 USART_ClockInit(USART1, &USART_ClockInitStructure); USART_Init(USART1, &USART_InitStructure); /*输入输出的中断使能*/ // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

AVR单片机atmega16串口中断接收和发送程序

AVR单片机atmega16串口中断接收和发送程序 // Target : M16 // Crystal: 8.0000Mhz //AVR单片机atmega16串口中断接收和发送程序。接收到字符后再发送出去#include #include unsigned char com_in_buf[1]; void port_init(void) { PORTA = 0xFF; DDRA = 0xFF; PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; DDRC = 0x00; PORTD = 0x00; DDRD = 0x00; } //UART0 initialize // desired baud rate: 9600 // actual: baud rate:9615 (0.2%) // char size: 8 bit // parity: Disabled void uart0_init(void) { UCSRB = 0x00; //disable while setting baud rate UCSRA = 0x00; UCSRC = BIT(URSEL) | 0x06; UBRRL = 0x33; //set baud rate lo UBRRH = 0x00; //set baud rate hi UCSRB = 0x98; } void send_data(unsigned char back) { while( !( UCSRA & (1< UDR=back; } #pragma interrupt_handler uart0_rx_isr:12 void uart0_rx_isr(void) {

串口中断发送与接收

串口中断接收与发送 以前一直写串口程序都是发送一个字符,然后等待TI=1时再发另一个字符,觉得这样很浪费时间,因为在波特率为9600时,每发一个字符差不多要1ms的时间;接收则接收一个字符即存入数组,直到有结束标志出现,后来发现这种做法很局限,因为在与一些串口设备通讯时,返回的数据很难以最后一个字符为结束标志符。 于是现在重新变换了一下串口发送(接收)的思路: 发送:中断只管发送,程序把要发送的数组写入缓存然后触发发送信号,剩下的则由中断处理,当识别到结束标志时,发送完毕,及置位发送完毕标志。 接收:中断只管接收并存入缓存,程序每循环一次则检测一次缓存是否有数据变化,若有则读缓存,若无则跳过。在读完最后一个缓存字符之后若n(设n=100)次循环检测缓存再无变化,则认为一组数据发送完毕。 程序流程图如下所示:

于是写了如下程序。 /************************************************ 串口中断接收(发送)数据 单片机接收完一组数据后将其再从串口发回 串口测试直接可运行 ************************************************/ #include #include #include #define uchar unsigned char #define uint unsigned int sbit Rxd=P1^0; //接收脚(模拟串口) sbit Txd=P1^1; //发送脚 #define RST 0x01 #define NEW 0x02 //新短信标志 #define CMGR 0x03 //读短信标志 #define BEGIN 0x04 //仪表数据开始读 #define STOP 0x05 //仪表数据结束读 #define NEXT 0x06 //准备读短信内容 #define NEXTBEGIN 0x07 //开始读短信 #define START 0x08 //开始读发送短信的手机号码 #define TRUE 0x09 //准备读号码,也作为新短信读取后的标志#define FALSE 0x0a //没有新短信 uchar xdata table_send[140]; //发送缓存 uchar SendLength=0; uchar xdata table_receive[32]; //接收缓存 uchar ReceiveLength=0; uchar xdata table_dat[100]="Hello world!\n"; //数据存储 uchar DatLength=0; //数据长度标志 uchar SendFlag=0; //发送状态标志 uchar ReadMark=0; //读取串口数据记录的位置(书签) uchar ReadFlag; //读串口标志 uint EndFlag=250; //计数250 void init_serial1(); //串口初始化为方式1:9600,n,8,1 void send_listtable(uchar *list); //串口发送一个字符串 void receive_listtable(); //串口缓存接收 void main() //主程序 {

相关主题