当前位置: 首页 > article >正文

串口通信(STM32演示实现)

目录

一、串行通信的概念

二、寄存器

2.1控制寄存器USART_CR1

 2.2控制寄存器USART_CR2​编辑

 2.3串口寄存器USART_BRR

2.4 USART_ISR

2.5USART_TDR

2.6USART_RDR​编辑

三、实现串口数据的收发


一、串行通信的概念

u通信,最少要有两个对象,一个收,一个发
u同步通信:

     一般情况下同步通信指的是通信双方根据同步信号进行通信的方式。比如通信双方有一个共同的时钟信号,大家根据时钟信号的变化进行通信

u异步通信:是指数据传输速度匹配依赖于通信双方有自己独立的系统时钟,大家约定好通信的速度。异步通信不需要同步信号,但是并不是说通信的过程不同布 

u串行通信:指的是同一时刻只能收或发一个bit位信息。因此只用1根信号线即可。
u并行通信:指的是同一时刻可以收或发多个bit位的信息,因此需要多根信号线才行

u 单工:要么收,要么发,只能做接收设备或者发送设备。比如收音机
u 半双工:可以收,可以发,但是不能同时收发, 比如对讲机
u 全双工:可以在同一时刻既接收,又发送。 手机

n 通用同步异步收发器(USART)灵活地与外部设备进行全双工数据通信,满足外部设备对工业标准NRZ异步串行数据格式的要求。USART通过小数波特率发生器提供了多种波特率。它支持同步单向通信和半双工单线通信;还支持LIN(局域互联网络),智能卡协议与IrDA(红外数据协会)SIR ENDEC规范,以及调制解调操作(CTS/RTS)。而且,它还支持多处理器通信。
n USART支持同步模式,因此USART 需要同步始终信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此USART和一般单片机UART使用方式是一样的,都使用异步模式。

 

 STM32F051内置多达两个通用同步 / 异步收发器( USART1 USART2 ),通信速度可达 6 Mbit / s

 

              0     1      0      1      0      0      0      0     0     0             

TXD 串口输出0x05波形图、低位先发送:                                                                  

l 在串行通信中,用“波特率”来描述数据的传输速率。所谓波特率,既每秒传送的二进制位数,其单位为bps(bits per second)。它是衡量串行数据速度快慢的重要指标。

l 国际上规定一个标准的波特率系列: 110、300、600、1200、1800、2400、4800、9600、115200、14.4Kbps、19.2Kbps、……

例如:115200bps、指每秒传送115200位。通信双方必须设置同样的同学速率才能正常通信

l 注意:实际的数据没这么多,还包括起始位,结束位,校验位   

二、寄存器

2.1控制寄存器USART_CR1

 2.2控制寄存器USART_CR2

 2.3串口寄存器USART_BRR

2.4 USART_ISR

2.5USART_TDR

2.6USART_RDR

三、实现串口数据的收发

 这是F051的电路图

注意:如果无法识别串口,清装好ch340串口驱动

左侧可以直接选

void  Uart_Putchar(uint8_t ch)
{
	while(!(USART1->ISR &(1<<7)));   //等待发送寄存器空
	USART1->TDR = ch;                        //发送字符
}

void Uart_Putstring(uint8_t  *str)	
{
	while(*str != '\0')
	{
		Uart_Putchar(*str);		
		str++;
	}
}


uint8_t Uart_Getchar(void)
{
	while(!(USART1->ISR & (1<<5)));  //等待收到一个字符的数据
	
	return  USART1->RDR;                   //返回收到的字符
}


Stm32f0xx_hal_uart.c  文件中

串口的发送函数

HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

串口的接收函数

HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

 printf函数调用的是c库中的fputc函数。因此我们如果重新写了fputc函数,就可以改变printf函数的功能,可以向串口打印输出。

int fputc(int ch,FILE *f){	while((USART1->ISR&(1<<7)) == 0);	USART1->TDR=(uint8_t)ch;
	return ch;} 


/**
  ******************************************************************************
  * File Name          : main.c
  * Description        : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2017 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"
#include "usart.h"
#include "gpio.h"

/* USER CODE BEGIN Includes */
#include <string.h>
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

int fputc(int ch, FILE *f)
{
	while( !(USART1->ISR & (1<<7)));  //等待TDR为空
	
	USART1->TDR = ch;
}

/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */
	uint8_t ch[20] = {0};
	
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  //HAL_UART_Transmit(&huart1, "this is uart test\n", strlen("this is uart test\n"), 100);
 
	printf("this is printf test\n");
/* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  
	  
	//  ch = Uart_Getchar();	  
	//  Uart_Putchar(ch);
	  
	  
	  HAL_UART_Receive(&huart1, ch, 19 , 100);
	  
	  HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
	  
	  memset(ch,0,20);
	  
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void _Error_Handler(char * file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while(1) 
  {
  }
  /* USER CODE END Error_Handler_Debug */ 
}

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

/**
  * @}
  */ 

/**
  * @}
*/ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


http://www.kler.cn/a/2915.html

相关文章:

  • 【PLL】杂散生成和调制
  • 利用飞书机器人进行 - ArXiv自动化检索推荐
  • 【深度分析】DeepSeek 遭暴力破解,攻击 IP 均来自美国,造成影响有多大?有哪些好的防御措施?
  • 灰色预测模型
  • 模型I/O功能之模型包装器
  • 安卓(android)读取手机通讯录【Android移动开发基础案例教程(第2版)黑马程序员】
  • C++ 八股文(简单面试题)
  • 奇安信_防火墙部署_透明桥模式
  • ​selenium+python做web端自动化测试框架与实例详解教程​
  • 数据结构——二叉树与堆
  • 从 X 入门Pytorch——BN、LN、IN、GN 四种归一化层的代码使用和原理
  • 【docker】docker安装MySQL
  • leetcode每日一题:134. 加油站
  • 银河麒麟v10sp2安装nginx
  • [ 网络 ] 应用层协议 —— HTTP协议
  • Linux防火墙——SNAT、DNAT
  • Redis单线程还是多线程?IO多路复用原理
  • 【C++】科普:C++中的浮点数怎么在计算机中表示?
  • TCP和UDP协议的区别?
  • 【C语言蓝桥杯每日一题】——排序
  • 【Docker】CAdvisor+InfluxDB+Granfana容器监控
  • C/C++基础讲解(五十七)之图形篇(绘制蓝天图案)
  • vue3后台管理系统
  • C/C++之while(do-while)详细讲解
  • 为了之后找工作不被虐,每天刷3道《剑指offer》Day-1
  • 手写Promise源码的实现思路