正点原子STM32F103学习笔记(八) 您所在的位置:网站首页 补办饭卡申请书怎么写给财务员 正点原子STM32F103学习笔记(八)

正点原子STM32F103学习笔记(八)

2023-07-30 12:59| 来源: 网络整理| 查看: 265

串口通信基本原理 处理器与外部设备通信的两种方式 并行通信 传输原理:数据各个位同时传输。优点:速度快缺点:占用引脚资源多 串行通信

传输原理:数据按位顺序传输。

优点:占用引脚资源少

缺点:速度相对较慢

按照数据传送方向,分为:

单工: 数据传输只支持数据在一个方向上传输半双工: 允许数据在两个方向上传输,但是,在某一时刻,只允许数 据在一个方向上传输,它实际上是一种切换方向的单工通信;全双工: 允许数据同时在两个方向上传输,因此,全双工通信是两个 单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。 在这里插入图片描述

串行通信的通信方式

同步通信:带时钟同步信号传输。 -SPI,IIC通信接口异步通信:不带时钟同步信号。 -UART(通用异步收发器),全双工,单总线,要约定速度(波特率)

常见的串行通信接口: 在这里插入图片描述

STM32的串口通信接口

UART: 通用异步收发器 USART: 通用同步异步收发器 大容量STM32F10x系列芯片,包含3个USART和2个UART

UART异步通信方式引脚连接方法: RXD:数据输入引脚。数据接受。TXD:数据发送引脚。数据发送。 在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

UART异步通信方式特点: 全双工异步通信。分数波特率发生器系统,提供精确的波特率。 -发送和接受共用的可编程波特率,最高可达4.5Mbits/s可编程的数据字长度(8位或者9位);可配置的停止位(支持1或者2位停止位);可配置的使用DMA多缓冲器通信。单独的发送器和接收器使能位。检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志多个带标志的中断源。触发中断。其他:校验控制,四个错误检测标志。 在这里插入图片描述 STM32串口异步通信需要定义的参数: 起始位数据位(8位或者9位)奇偶校验位(第9位)停止位(1,15,2位)波特率设置 在这里插入图片描述

在这里插入图片描述

发射器控制(发射器时钟)和接收器控制(接收器时钟)受到同一个单元控制。

串口寄存器配置 常用的串口相关寄存器

USART_SR状态寄存器 USART_DR数据寄存器(只用到了位0-8) USART_BRR波特率寄存器 USART_CR1控制寄存器(使能)

波特率计算方法

在这里插入图片描述

在这里插入图片描述

串口操作相关库函数(省略入口参数): void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能 void USART_Cmd();//使能串口 void USART_ITConfig();//使能相关中断 //DR寄存器 void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据 //SR寄存器 FlagStatus USART_GetFlagStatus();//获取状态标志位 void USART_ClearFlag();//清除状态标志位 ITStatus USART_GetITStatus();//获取中断状态标志位 void USART_ClearITPendingBit();//清除中断状态标志位

USART_Init();

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) typedef struct { uint32_t USART_BaudRate; //波特率 uint16_t USART_WordLength; //字长 uint16_t USART_StopBits; //停止位 uint16_t USART_Parity; //奇偶校验位 uint16_t USART_Mode; //发送接收使能 uint16_t USART_HardwareFlowControl; //硬件流控制 } USART_InitTypeDef; 串口配置的一般步骤 串口时钟使能,GPIO时钟使能: RCC_APB2PeriphClockCmd(); 串口复位:这一步不是必须的 USART_DeInit(); GPIO端口模式设置:要查表“STM32中文参考手册”8.1.11,模式设置为GPIO_Mode_AF_PP(复用为串口一设置为复用推挽) GPIO_Init(); 串口参数初始化: USART_Init(); 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤) NVIC_Init();//优先级设置 USART_ITConfig();//确定开启哪个中断 使能串口: USART_Cmd(); 编写中断处理函数: USARTx_IRQHandler(); 串口数据收发: void USART_SendData();//发送数据到串口,DR uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据 串口传输状态获取: FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG); void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT); 程序实践

main.c

void My_USART_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //使能时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE); RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 ,ENABLE); //GPIOA9模式设置为GPIO_Mode_AF_PP GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //GPIOA10模式设置为GPIO_Mode_AF_PP GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //串口初始化 USART_InitStructure.USART_BaudRate=115200; USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件流 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//接收发送都使能 USART_InitStructure.USART_Parity=USART_Parity_No;//不用奇偶校验,通信双方要么都有要么都没有 USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位,传输停止的标志 USART_InitStructure.USART_WordLength=USART_WordLength_8b;//没有奇偶校验取八 USART_Init(USART1,&USART_InitStructure); //使能串口 USART_Cmd(USART1,ENABLE); //使能哪个串口中断 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//确定开启哪个中断,并开启接收中断(即接收到数据执行中断服务函数) //设置响应中断优先级 NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//入口参数,在stm32f10x.h头文件447行 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//是否开启中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//设置抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级 NVIC_Init(&NVIC_InitStructure); } void USART1_IRQHandler(void) //接收到数据执行这个中断 { u8 res; if(USART_GetITStatus(USART1,USART_IT_RXNE))//判断是否接收到数据 { res=USART_ReceiveData(USART1);//接受到的值赋给变量 USART_SendData(USART1,res);//发送接收到的数据 } } int main(void) { //中断设置 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //分组选择为2,两位响应两位抢占 My_USART_Init(); while(1);//使用中断接收,使用死循环 } 串口实验讲解 #define USART_REC_LEN 200 //定义最大接收字节数 200 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 u16 USART_RX_STA; //接收状态标记

在这里插入图片描述

程序要求,发送的字符是以回车换行结束(0x0D,0x0A) eg:ABCDEFGHI…….(0x0D),(0x0A) bit15标记为1时候提取USART_RX_BUF中bit13~0个有效数据

串口终端服务函数: void USART1_IRQHandler(void) //串口1中断服务程序 { u8 Res; #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntEnter(); #endif if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART1); //读取接收到的数据 if((USART_RX_STA&0x8000)==0)//最高位如果是0,接收未完成,继续下面的接收 { if(USART_RX_STA&0x4000)//接收到了0x0d 即bit14是否为1 { if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 ,最高位设为1 } else //还没收到0X0D { if(Res==0x0d)USART_RX_STA|=0x4000; else { USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;//只可以用bit13~0 USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS. OSIntExit(); #endif }

main();

int main(void) { u16 t; u16 len; u16 times=0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 KEY_Init(); //初始化与按键连接的硬件接口 while(1) { if(USART_RX_STA&0x8000) //接收完成返回1 { len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 printf("\r\n您发送的消息为:\r\n\r\n"); for(t=0;t


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有