您的位置 首页 方案

STM32 USART串口的学习与领会

1.串口的基本概念看了很多STM32的USART的编码,但我觉得虽然都说出了中点但,写的都不是很好!作为一个刚刚学stm的菜鸟,看了很多资料,写…

1.串口的基本概念

看了许多STM32USART的编码,但我觉得尽管都说出了中点但,写的都不是很好!作为一个刚刚学stm的菜鸟,看了许多材料,写出了我以为比较满意的串口通讯的常识

当然学习了许多前人的汗水和stm官方的库函数模板,这也是自己榜首次在csdn少上写博客!

在STM32的参阅手册中,串口被描绘成通用同步异步收发器(USART),它供给了一种灵敏的办法与运用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART运用分数波特率发生器供给宽规模的波特率挑选。它支撑同步单向通讯和半双工单线通讯,也支撑LIN(部分互联网),智能卡协议和IrDA(红外数据安排)SIR ENDEC标准,以及调制解调器(CTS/RTS)操作。它还答应多处理器通讯。还能够运用DMA办法,完结高速数据通讯。

USART经过3个引脚与其他设备衔接在一起,任何USART双向通讯至少需求2个引脚:承受数据输入(RX)和发送数据输出(TX)。

RX: 承受数据串行输入。经过过采样技能来差异数据和噪音,然后康复数据。

TX: 发送数据输出。当发送器被制止时,输出引脚康复到它的I/O端口装备。当发送器被激活,而且不发送数据时,TX引脚处处于高电平。在单线和智能卡形式里,此I/O口被一起用于数据的发送和接纳。

2.串口的怎么作业的

一般有两种办法:查询和中止。

(1)查询:串口程序不断地循环查询,看看当时有没有数据要它传送。假如有,就协助传送(能够从PC到STM32板子,也能够从STM32板子到PC)。

(2)中止:平常串口只需翻开中止即可。假如发现有一个中止来,则意味着要它协助传输数据——它就立刻进行数据的传送。相同,能够从PC到STM3板子,也能够从STM32板子到PC。

3.串口的硬件衔接

我用的斗争STM32 V3开发板具有二路RS-232 接口,CPU 的PA9-US1-TX(P68)、PA10-US1-RX(P69)、PA9-US2-TX(P25)、PA10-US2-RX(P26)经过MAX3232 完结两路RS-232 接口,别离衔接在XS5 和XS17 接口上。 USART1在体系存储区发动形式下,将经过该口经过PC对板上的CPU进行ISP,该口也可作为一般串口功用运用,JP3,JP4 的短路冒拔去,将断开第二路的RS232通讯,仅作为TTL 通讯通道。

4.编程实例

咱们要对串口进行操作,首要要将STM32的串口和CPU进行衔接。在Windows操作体系中,有一个自带的体系软件叫“超级终端”。VISTA以上的操作体系去掉了这个软件,不过能够从XP的体系中,“hypertrm.dll”和“hypertrm.exe”到“windows/system32”文件夹下,然后双击运转hypertrm.exe,就能够看见超级终端的运转界面了。

运转超级终端今后,会弹出“衔接描绘”,输入称号和挑选图标,这个当地随意写个什么称号都能够。然后弹出“衔接到”设置,在“衔接时运用”挑选你自己PC和STM32衔接的COMx,假如不知道是哪个COM口的话,能够在PC的设备管理器中找到。在挑选好COM口之后,会弹出一个“特点”对话框,在“位/秒”挑选和你STM32中设置的波特率共同就好,数据位也是依照STM32的设置来挑选,奇偶校验挑选无,中止位挑选1,数据流操控挑选无。留意,以上的选项都必须和STM32中的串口设置相匹配,要不然可能会呈现一些不知道过错。

装备好超级终端之后,咱们便能够开端对STM32进行编程了。编程一般依照如下过程进行:

(1) RCC装备;

(2) GPIO装备;

(3) USART装备;

(4) NVIC装备;

(5) 发送/接纳数据。

在RCC装备中,咱们除了惯例的时钟设置以外,要记住翻开USART相对应的IO口时钟,USART时钟,还有管脚功用复用时钟。

在GPIO装备中,将发送端的管脚装备为复用推挽输出,将接纳端的管脚装备为浮空输入。

在USART的装备中,经过USART_InitTypeDef结构体对USART进行初始化操作,依照自己所需的功用装备好就能够了。留意,在超级终端的设置中,需求和这个晒干的装备相对应。咱们我是选用中止接纳数据的办法,所以记住在USART的装备中要翻开串口的中止,一起最终还要翻开串口。

在NVIC的装备中,主要是USART1_IRQChannel的装备,和曾经的笔记中推荐的中止装备相似,不会装备的能够参阅曾经的笔记。

悉数装备好之后就能够开端发送/接纳数据了。发送数据用USART_SendData()函数,接纳数据用USART_ReceiveData()函数。详细的函数功用能够参阅固件库的参阅文件。依据USART的装备,在发送和接纳时,都是选用的8bits一帧来进行的,因而,在发送的时分,先拓荒一个缓存区,将需求发送的数据送入缓存区,然后再将缓存区中的数据发送出去,在接纳的时分,相同也是先接纳到缓存区中,然后再进行相应的操作。

留意在对数据进行发送和接纳的时分,要检查USART的状况,只需比及数据发送或接纳结束之后才干进行下一帧数据的发送或接纳。选用USART_GetFlagStatus()函数。

一起还要留意的是,在发送数据的最开端,需求铲除一下USART的标志位,不然,第1位数据会丢掉。由于在硬件复位之后,USART的状况位TC是置位的。当包括有数据的一帧发送完结之后,由硬件将该方位位。只需当USART的状况位TC是置位的时分,就能够进行数据的发送。然后TC位的置零则是经过软件序列来铲除的,详细的过程是“先读USART_SR,然后写入USART_DR”,只需这样才干够铲除标志位TC,但是在发送榜首帧数据的时分,并没有进行读USART_SR的操作,而是直接进行写操作,因而TC标志位并没有清空,那么,当发送榜首帧数据,然后用USART_GetFlagStatus()检测状况时回来的是现已发送结束(由于TC位是置1的),所以程序会立刻发送下一帧数据,那么这样,榜首帧数据就被第二帧数据给覆盖了,所以看不到榜首帧数据的发送。

依照上面的办法编程后,咱们便能够在超级终端上检查串口通讯的详细状况了。我的这个例程,在硬件复位今后,能够立刻在超级终端上看见“Welcome>

RCC_cfg();

GPIO_cfg();

NVIC_cfg();

USART_cfg();

//铲除标志位,不然第1位数据会丢掉

USART_ClearFlag(USART1,USART_FLAG_TC);

//发送数据

//PB5的作用是显现正在发送数据

//当有数据在发送的时分,PB5会亮

for(>

{

USART_SendData(USART1,TxBuf1[i]);

GPIO_SetBits(GPIOB,GPIO_Pin_5);

//等候数据发送结束

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

GPIO_ResetBits(GPIOB,GPIO_Pin_5);

}

while(1);

}

//RCC时钟装备

void RCC_cfg()

{

//界说过错状况变量

ErrorStatus HSEStartUpStatus;

//将RCC寄存器从头设置为默认值

RCC_DeInit();

//翻开外部高速时钟晶振

RCC_HSEConfig(RCC_HSE_ON);

//等候外部高速时钟晶振作业

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

//设置AHB时钟(HCLK)为体系时钟

RCC_HCLKConfig(RCC_SYSCLK_Div1);

//设置高速AHB时钟(APB2)为HCLK时钟

RCC_PCLK2Config(RCC_HCLK_Div1);

//设置低速AHB时钟(APB1)为HCLK的2分频

RCC_PCLK1Config(RCC_HCLK_Div2);

//设置FLASH代码延时

FLASH_SetLatency(FLASH_Latency_2);

//使能预取指缓存

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

//设置PLL时钟,为HSE的9倍频8MHz * 9 = 72MHz

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

//使能PLL

RCC_PLLCmd(ENABLE);

//等候PLL准备就绪

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

//设置PLL为体系时钟源

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//判别PLL是否是体系时钟

while(RCC_GetSYSCLKSource() != 0x08);

}

//翻开GPIO时钟,复用功用,串口1的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA>

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA , &GPIO_InitStructure);

//PA10作为US1的RX端,担任接纳数据

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

//LED显现串口正在发送/接纳数据

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOB, &GPIO_InitStructure);

}

//串口初始化

void USART_cfg()

{

USART_InitTypeDef USART_InitStructure;

//将结构体设置为缺省状况

USART_StructInit(&USART_InitStructure);

//波特率设置为115200

USART_InitStructure.USART_BaudRate = 115200;

//一帧数据的宽度设置为8bits

USART_InitStructure.USART_WordLength =USART_WordLength_8b;

//在帧结束传输1个中止位

USART_InitStructure.USART_StopBits = USART_StopBits_1;

//奇偶失能形式,无奇偶校验

USART_InitStructure.USART_Parity = USART_Parity_No;

//发送/接纳使能

USART_InitStructure.USART_Mode = USART_Mode_Rx>

//设置串口1

USART_Init(USART1,&USART_InitStructure);

//翻开串口1的中止呼应函数

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

//翻开串口1

USART_Cmd(USART1, ENABLE);

}

//装备中止

void NVIC_cfg()

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//挑选中止分组2

NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQChannel; //挑选串口1中止

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占式中止优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //呼应式中止优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//使能中止

NVIC_Init(&NVIC_InitStructure);

}

然后在stm32f10x_it.c文件中找到相应的中止处理函数,并填入一下内容。留意在stm32f10x_it.c中,要声明一下外部变量RX_status

extern FlagStatus RX_status;

void USART1_IRQHandler(void)

{

GPIO_SetBits(GPIOB, GPIO_Pin_5);

//结语是否接纳到数据

RX_status = USART_GetFlagStatus(USART1,USART_FLAG_RXNE);

//接纳到数据

if(RX_status == SET)

{

//将数据回送至超级终端

USART_SendData(USART1, USART_ReceiveData(USART1));

//等候数据发送结束

while(USART_GetFlagStatus(USART1, USART_FLAG_TC) ==RESET);

GPIO_ResetBits(GPIOB, GPIO_Pin_5);

}

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/265119.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部