STM32库函数串口stm32 奇偶校验验正确么

STM32串口实验
> STM32串口实验
STM32串口实验
STM32串口简介串口作为MCU的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。现在基本上所有的MCU都会带有串口,STM32自然也不例外。STM32的串口资源相当丰富的,功能也相当强劲。ALIENTEK战舰STM32开发板所使用的STM32F103ZET6最多可提供5路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDA SIRENDEC规范、具有DMA等。5.3节对串口有过简单的介绍,大家看这个实验的时候记得翻过去看看。接下来我们将主要从库函数操作层面结合寄存器的描述,告诉你如何设置串口,以达到我们最基本的通信功能。本章,我们将实现利用串口1不停的打印信息到电脑上,同时接收从串口发过来的数据,把发送过来的数据直接送回给电脑。战舰STM32开发板板载了1个USB串口和1个RS232串口,我们本章介绍的是通过USB串口和电脑通信。在4.4.1章节端口复用功能已经讲解过,对于复用功能的IO,我们首先要使能GPIO时钟,然后使能复用功能时钟,同时要把GPIO模式设置为复用功能对应的模式(这个可以查看手册《STM32中文参考手册V10》P110的表格&8.1.11外设的GPIO配置&)。这些准备工作做完之后,剩下的当然是串口参数的初始化设置,包括波特率,停止位等等参数。在设置完成只能接下来就是使能串口,这很容易理解。同时,如果我们开启了串口的中断,当然要初始化NVIC设置中断优先级别,最后编写中断服务函数。串口设置的一般步骤可以总结为如下几个步骤: 1) 串口时钟使能,GPIO时钟使能 2) 串口复位3) GPIO端口模式设置 4) 串口参数初始化5) 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤) 6) 使能串口7) 编写中断处理函数下面,我们就简单介绍下这几个与串口基本配置直接相关的几个固件库函数。这些函数和定义主要分布在stm32f10x_usart.h和stm32f10x_usart.c文件中。1.串口时钟使能。串口是挂载在APB2下面的外设,所以使能函数为: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);2.串口复位。当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。复位的是在函数USART_DeInit()中完成:void USART_DeInit(USART_TypeDef* USARTx); 比如我们要复位串口1,方法为: USART_DeInit(USART1); //复位串口13.串口参数初始化。串口初始化是通过USART_Init()函数实现的,void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct); 这个函数的的第一个入口参数是指定初始化的串口标号,这里选择USART1。第二个入口参数是一个USART_InitTypeDef类型的结构体指针,这个结构体指针的成员变量用来设置串口的一些参数。一般的实现格式为:USART_InitStructure.USART_BaudRate = //一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_N //无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USART_Init(USART1, &USART_InitStructure); //初始化串口从上面的初始化格式可以看出初始化需要设置的参数为:波特率,字长,停止位,奇偶校验位,硬件数据流控制,模式(收,发)。我们可以根据需要设置这些参数。4.数据发送与接收。STM32的发送与接收是通过数据寄存器USART_DR来实现的,这是一个双寄存器,包含了TDR和RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到收据的时候,也是存在该寄存器内。 STM32库函数操作USART_DR寄存器发送数据的函数是:void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); 通过该函数向串口寄存器USART_DR写入一个数据。STM32库函数操作USART_DR寄存器读取串口接收到的数据的函数是:uint16_t USART_ReceiveData(USART_TypeDef* USARTx); 通过该函数可以读取串口接受到的数据。5.串口状态。串口的状态可以通过状态寄存器USART_SR读取。图9.1.1 USART_SR寄存器各位描述这里我们关注一下两个位,第5、6位RXNE和TC。 RXNE(读数据寄存器非空),当该位被置1的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取USART_DR,通过读USART_DR可以将该位清零,也可以向该位写0,直接清除。TC(发送完成),当该位被置位的时候,表示USART_DR内的数据已经被发送完成了。如果设置了这个位的中断,则会产生中断。该位也有两种清零方式:1)读USART_SR,写USART_DR。2)直接向该位写0。状态寄存器的其他位我们这里就不做过多讲解,大家需要可以查看中文参考手册。 在我们固件库函数里面,读取串口状态的函数是:FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); 这个函数的第二个入口参数非常关键,它是标示我们要查看串口的哪种状态,比如上面讲解的RXNE(读数据寄存器非空)以及TC(发送完成)。例如我们要判断读寄存器是否非空(RXNE),操作库函数的方法是:USART_GetFlagStatus(USART1, USART_FLAG_RXNE); 我们要判断发送是否完成(TC),操作库函数的方法是:USART_GetFlagStatus(USART1, USART_FLAG_TC);这些标识号在MDK里面是通过宏定义定义的:#define USART_IT_PE ((uint16_t)0x0028) #define USART_IT_TXE ((uint16_t)0x0727) #define USART_IT_TC ((uint16_t)0x0626) #define USART_IT_RXNE ((uint16_t)0x0525) #define USART_IT_IDLE ((uint16_t)0x0424) #define USART_IT_LBD ((uint16_t)0x0846) #define USART_IT_CTS ((uint16_t)0x096A) #define USART_IT_ERR ((uint16_t)0x0060) #define USART_IT_ORE ((uint16_t)0x0360) #define USART_IT_NE ((uint16_t)0x0260) #define USART_IT_FE ((uint16_t)0x0160)6, 串口使能。串口使能是通过函数USART_Cmd()来实现的,这个很容易理解,使用方法 是: USART_Cmd(USART1, ENABLE); //使能串口 7,开启串口响应中断。有些时候当我们还需要开启串口中断,那么我们还需要使能串口中断,使能串口中断的函数是:void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)这个函数的第二个入口参数是标示使能串口的类型,也就是使能哪种中断,因为串口的中断类型有很多种。比如在接收到数据的时候(RXNE读数据寄存器非空),我们要产生中断,那么我们开启中断的方法是:USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断 我们在发送数据结束的时候(TC,发送完成)要产生中断,那么方法是:USART_ITConfig(USART1,USART_IT_TC,ENABLE); 8,获取相应中断状态。当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。经常我们在中断处理函数中,要判断该中断是哪种中断,使用的函数是: ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT) 比如我们使能了串口发送完成中断,那么当中断发生了, 我们便可以在中断处理函数中调用这个函数来判断到底是否是串口发送完成中断,方法是:USART_GetITStatus(USART1, USART_IT_TC) 返回值是SET,说明是串口发送完成中断发生。
分享给小伙伴们:
我来说两句……
最新技术贴
微信公众号二
微信公众号一查看: 501|回复: 0
一个关于UART通信奇偶校验出错位的读取话题
某客户使用STM32F4系列芯片做产品开发,用到USART外设,将其配置在智能卡模式。USART配置为智能卡模式后,并开启了奇偶校验。
当MCU通过UART从卡端读取数据时,如果读到的数据发生奇偶校验错误,根据相关通信协议,USART硬件会自动在刚收到数据的结尾处强行拉低数据线一个时间段告知智能卡控制器,表示USART接收到的数据奇偶校验有错,期待数据重发。
1.jpg (26.7 KB, 下载次数: 2)
11:58 上传
他发现,当UART从智能卡接收数据遇到奇偶校验出错时,的确可以从硬件线路上观测到数据的重发。可他的软件接收代码里却没法分辨数据正误,也就是说不管是否发生校验错误,一律当作正确的数据接收了进来。他觉得甚为奇怪。
重点怀疑代码问题,查看其相关代码,他的数据接收流程大致是这样的:
先检测到USART_SR寄存器中的RXNE为1;然后从USAR_DR寄存器读取数据;再接着检测USART_SR寄存器中的校验出错位PE位是否为1,如果是1则丢弃刚才收到的数据。咋看上去,貌似没啥问题。
如果查看STM32相关芯片的参考手册就会发现,通过对USART_SR的读和接着对USART_DR的读操作序列会导致对RXNE和PE位的清零。
2.png (31.02 KB, 下载次数: 1)
11:58 上传
既然这样,按照该客户的做法,先读SR,然后读DR。这个连续操作之后已经就将RXNE和PE清零了,若再来读PE,永远读不到它为1的时候,即发现不了校验出错的情况,自然导致数据全部被当做正确的收纳了。
所以,他的接收代码需要稍微调整下,先检查到RXNE为1后,接着检查PE是否为1,根据PE是否为1 来决定从DR中读得数据的取舍并完成对PE和RXNE的清零。
STM32的寄存器中,尤其是那些状态寄存器的部分状态标志的置位和清零并不一定是简单地、对应地直接置1写0。比方有些寄存器位的清零是对相关寄存器位写1;有些寄存器位的清零则个软件操作序列。比方STM32F4/STM32F1系列中USART的PE位、ORE位就是通过软件操作序列实现清零。STM32产品线众多,即使相同外设的寄存器不同系列间的操作可能略有差异。比如这里谈到的USART的PE位、ORE位,在STM32F0系列里是可以通过软件对相关寄存器位写1达到对其清零的目的,此时无需软件操作序列。
当然,如果你使用ST官方的参考库函数的话,有些细节可能感受不到。开发过程中在具体使用到某些并不熟悉的寄存器位时,适当地核对下手册往往是个不错的举动。有时一个无意的想当然的举动可能会浪费很多时间和精力。
简单问题,分享出来,互为提醒。其实,开发过程中很多折腾人的地方往往就是些小细节。
Powered by后使用快捷导航没有帐号?
查看: 7308|回复: 21
STM32F103的USART1接收数据不一致,请香版主和各位兄弟帮忙
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
我使用英倍特的MCBSTM32开发板,用其USART1进行收发一串数据。
我现在的问题:
串口配置:波特率1200,1个起始位,8位数字,1个EVEN校验,一个停止位
STM32配置:波特率1200,1个起始位,9位数字,1个EVEN校验,一个停止位
串口发送数据:FE 68 33 49 18 00 00 00 68 01 02 43 c7 71 16
MCU接收数据:66 59 b2 38 9a 33 a2 39 8a 38 82 30 82 30 82
串口发送的数据与MCU接收的数据两者不一致!!!
我想知道这是为什么?
如果STM32 USART1配置为8位字长,无奇偶校验;
& &&&上位机串口软件配置同上:
STM32接收到的数据和串口软件发送数据是相同的,没有变化!
我怀疑是不是由于STM32的校验位设置影响了所接收到的数据!STM32在USART1这里是不是有问题!
看了STM3210X的DATASHEET与reference文档。知道校验控制功能如下:发送时生成一个奇偶校验位,接收时进行奇偶校验,按理来说不会有这种问题的!
请各位兄弟帮忙找出问题的关键,在些先谢谢各位的访问与回复!
USART1配置如下:
&&USART_InitStructure.USART_BaudRate& && && && &= 1200;
&&USART_InitStructure.USART_WordLength& && & =&&USART_WordLength_9b;
&&USART_InitStructure.USART_StopBits& && && && &= USART_StopBits_1;
&&USART_InitStructure.USART_Parity& && && && &&&= USART_Parity_E
&&USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_N
&&USART_InitStructure.USART_Mode& && && && && & = USART_Mode_Rx | USART_Mode_Tx;
&&USART_InitStructure.USART_Clock& && && && && &= USART_Clock_D
&&USART_InitStructure.USART_CPOL& && && && && & = USART_CPOL_L
&&USART_InitStructure.USART_CPHA& && && && && & = USART_CPHA_2E
&&USART_InitStructure.USART_LastBit& && && && & = USART_LastBit_D
USART1 中断函数如下:
&&if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
& & RxBuffer[RxCounter++] = (USART_ReceiveData(USART1) & 0x0FF);
& & USART_ClearITPendingBit(USART1, USART_IT_RXNE);
& && &if( RxCounter == 15 )
& &&&RxCounter = 0;
& &&&TRANS_FLAG = TRUE; //自定义标志位,当为真时,在主函数中会进入串口发送函数
&&&&&&&&&&
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
这个是我原先调试串口发送时的问题:
1、如果将数据位设置为8位,即USART_WordLength_8b,则设置为无校验和偶校验的时候,上位机PC可以正确接收到发送的数据,设置为奇校验的时候则接收到的数据是错误的。
2、将数据位设置为9位,即USART_WordLength_9b,则不论设置为奇校验或是偶校验和无校验,上位机就能正确的接收到发送的数据。
串口接收的部分没有调试。
你可以将上位机的串口发送软件设置为8位数据位、偶校验、一位停止位,然后在单片机上设置为8或9位数据位、偶校验、一位停止位试试,看看哪种情况能接收到正确数据
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
谢谢二楼的建议。可我现在上位机的串口发送软件已经设置为8位数据位、偶校验、1位停止位。
在STM32F103上因为串口USART1上发送的数据必须是9位数据位、偶校验、1位停止位的配置,
STM32发送数据时的确是对的;STM32也能接收到数据,只是数据不一致,但两者一定有某种关系。
现在我想怎样对USARTx-&DR 这个数据进行处理使之转化为正确的数据呢?
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一个起始位(0),8位数据,一个偶校验位,一个停止位
这个时候你数据位要配置成9bit的,因为stm32数据长度是包括校验位的
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
感谢四楼的回复。我现在的首先问题是怎样对接收到的数据进行处理,使之正确!!
你说的我知道。我的USART1配置和你所说的是一样的。如下,不会有错。
USART_InitStructure.USART_BaudRate& && && && &= 1200;
&&USART_InitStructure.USART_WordLength& && && & = USART_WordLength_9b;
&&USART_InitStructure.USART_StopBits& && && && &= USART_StopBits_1;
&&USART_InitStructure.USART_Parity& && && && &&&= USART_Parity_E
&&USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_N
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
接收的时候,stm32会自动处理的,会把奇偶校验位去掉的
我用过,也是接收,没问题
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
谢谢六楼的两次回复。
按照我上面的配置,接收数据时确实会出现不一致的情况:
用上位机串口程序配置:波特率1200,1个起始位,8位数字,1个EVEN校验,一个停止位
& &&&向STM32发送数据:FE 68 33 49 18 00 00 00 68 01 02 43 c7 71 16
STM32F103的配置为:波特率1200,1个起始位,9位数字,1个EVEN校验,一个停止位
在STM32中接收到的数据为:66 59 b2 38 9a 33 a2 39 8a 38 82 30 82 30 82
我承认你做的接收是成功的,但是你保证咱们俩的配置是一模一样的吗?
如果STM32配置为8位字长,接收到的数据是正确的。现在我的问题是9位字长的!
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
难道是STM32的一个bug?
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
呵呵,你说的有道理。
1200这个速度很慢,我用过最低的也是9600
最好用工具抓一下波形分析一下是发的问题还是收的问题。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
同意楼上的
看配置应该是没有错的,无图无真相
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
九楼,十楼的朋友:
& &想上传图片,可惜不会传,回复设置中图片显示是无效的。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
点“高级回复”,然后选择“添加附件”,把图片文件添加进来,
我就是这样上传图片的,别的方法不会,呵呵
另外,波特率越慢,应该传输数据越可靠吧
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&我也出现 这个问题&&好像波特率低了 就不行了&&st的人呢
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&不一致,可能就是你的波特率设置不对
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
看了楼主的帖子,有一个问题我要申明一下:
& &楼主使用的软件库是很老的一个版本,希望楼主更新一下软件库再测试一下。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
& & & & & & & & & & & & & & & &&&我用的2.0&&也是不行的&&我不知道 用哪个版本 会好呢?
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&请升级到至少2.0.3版本以上。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&不是这个问题
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
ST_ARM 同志:
& && &&&真的不是固件版本的问题,我已经用了STM32F10x_StdPeriph_Lib_V3.1.2的固件库。
可是问题依旧。唉,继续找解决问题的方案了。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
问题解决了。
昨天晚上设置错了,确实是固件库的问题。
谢谢ST_ARM 同志!
EEWORLD 官方微信
Powered by
逛了这许久,何不进去瞧瞧?1037人阅读
STM32学习(9)
&串口设置的一般步骤可以总结为如下几个:
1) 串口时钟使能, GPIO时钟使能&
2) 串口复位
3)GPIO 端口模式设置
4) 串口参数初始化&
5) 开启中断并且初始化 NVIC(如果需要开启中断才这个步骤) (如果需要开启中断才这个步骤)
6) 使能串口 使能串口
7) 编写中断处理函数&
下面,我们就简单介绍这几个与串口基本配置直接相关的固件库函数。这些函数和 定义主要分布在 stm32f10x_usart.h ,stm32f10x_usart.c 文件中。&
1.串口时钟使能。串口是挂载在APB2上的,所以使能函数为:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1)
2.串口复位。当外设出现异常的时候可以通过复位置 ,实现该外设的复位,然后重新配置这个外设让其重新工作的目。一般在系统刚开始配置时候,都会先执行复位该这个外 设达到让其重新工作的目。复位是在函数 USART_DeInit()完成:
void USART_DeInit(USART_TypeDef* USARTx)
3串口参数初始化
void USART_Init()函数:&
&&&&&voidUSART_Init(USART_TypeDef*USARTx,USART_InitTypeDef*USART_InitStruct);
&&&&&&&&& 根据指定参数初始化相应串口(波特率,字长,停止位,奇偶校验,硬件流控制等)
&&&&&&&&&& 主要是用来初始化寄存器BRR以及CR1,CR2,CR3控制寄存器
使用范例:
&&&&&&&& USART_InitTypeDefUSART_InitS &
&&&&&&&& USART_InitStructure.USART_BaudRate= 9600;//波特率设置;
&&&&&&& USART_InitStructure.USART_WordLength= USART_WordLength_8b;//字长为8位数据格式
&&&&&&& USART_InitStructure.USART_StopBits= USART_StopBits_1;//一个停止位
&&&&&&& USART_InitStructure.USART_Parity= USART_Parity_No;//无奇偶校验位
&&&&&&& USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_N //无硬件数据流控制
&&&&&& USART_InitStructure.USART_Mode= USART_Mode_Rx| USART_Mode_Tx;& //收发模式
&&&&& USART_Init(USART1,&USART_InitStructure);//初始化串口
4.void USART_Cmd()函数:&
&&&&&&voidUSART_Cmd(USART_TypeDef*USARTx,FunctionalStateNewState);
&&&&&&&&&&& 使能相应的串口,用来设置寄存器CR1的串口使能位
&使用范例:
&&&&&&&&&& USART_Cmd(USART1,ENABLE);&&&&&&&&&&&&&&&&&&& //使能串口1
5.void USART_ITConfig()函数:&
原型:&&&&&voidUSART_ITConfig(USART_TypeDef*USARTx,
uint16_t&&& USART_IT, FunctionalStateNewState);
&作用:开启串口相应中断,设置串口控制寄存器
& 使用范例:
&&&&&&&&&&& USART_ITConfig(USART1,USART_IT_RXNE, ENABLE); //开启读数据寄存器非空中断
6.USART_SendData()函数:&
&&&&&& voidUSART_SendData(USART_TypeDef* USARTx, uint16_t Data);
&&&&&&&&&&& 发送数据到串口。
&使用范例:
&&&&&&&&& USART_SendData(USART1,0x12); & & & & & & & & & &
7.uint16_tUSART_ReceiveData()函数:&
原型: uint16_t USART_ReceiveData(USART_TypeDef*USARTx)
获取串口最新接受的值。
&使用范例:
& & &USART_ReceiveData(USART1);
8.四个状态标志相关的函数:
FlagStatusUSART_GetFlagStatus(USART_TypeDef*USARTx,uint16_t USART_FLAG);
void USART_ClearFlag(USART_TypeDef*USARTx,uint16_t USART_FLAG);
ITStatusUSART_GetITStatus(USART_TypeDef*USARTx,uint16_t USART_IT);
void USART_ClearITPendingBit(USART_TypeDef*USARTx,uint16_t USART_IT);
以下是一个完整的初始化串口函数和一个中断服务函数:
//初始化IO 串口1&
//bound:波特率
void uart_init(u32 bound){
& & //GPIO端口设置
& & GPIO_InitTypeDef GPIO_InitS
&USART_InitTypeDef USART_InitS
&NVIC_InitTypeDef NVIC_InitS
&RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
//使能USART1,GPIOA时钟
& &USART_DeInit(USART1); &//复位串口1
//USART1_TX & PA.9
& & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
& & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//复用推挽输出
& & GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
& & //USART1_RX &PA.10
& & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
& & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
& & GPIO_Init(GPIOA, &GPIO_InitStructure); &//初始化PA10
& &//Usart1 NVIC 配置
& & NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
&NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
//子优先级3
&NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ通道使能
&NVIC_Init(&NVIC_InitStructure);
//根据指定的参数初始化VIC寄存器
& &//USART 初始化设置
USART_InitStructure.USART_BaudRate =//一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_N//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
//收发模式
& & USART_Init(USART1, &USART_InitStructure); //初始化串口
& & USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
& & USART_Cmd(USART1, ENABLE); & & & & & & & & & &//使能串口&
void USART1_IRQHandler(void) & & & & & & & &
//串口1中断服务程序
#ifdef OS_TICKS_PER_SEC //如果时钟节拍数定义了,说明要使用ucosII了.
OSIntEnter(); & &
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) &//接收中断(接收到的数据必须是0x0d 0x0a结尾)
Res =USART_ReceiveData(USART1);//(USART1-&DR);
//读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
if(USART_RX_STA&0x4000)//接收到了0x0d
if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000;
//接收完成了&
else //还没收到0X0D
if(Res==0x0d)USART_RX_STA|=0x4000;
USART_RX_BUF[USART_RX_STA&0X3FFF]=R
USART_RX_STA++;
if(USART_RX_STA&(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
#ifdef OS_TICKS_PER_SEC
//如果时钟节拍数定义了,说明要使用ucosII了.
OSIntExit(); &
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:30499次
排名:千里之外
原创:19篇
转载:17篇
(4)(2)(2)(6)(10)(2)(3)(8)}

我要回帖

更多关于 串口奇偶校验 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信