第8周实验----基于中断DMA方式的串口通信

第8周实验----基于中断/DMA方式的串口通信

一.配置CUBEMX。

选择STM32F103C8T6点击START PROJECT.

在这里插入图片描述

点击RCC 将HSE设置为CRYSTAL/CERAMIC RESONATOR

在这里插入图片描述

点击SYS 将DEBUG 设置为SERIAL WIRE

在这里插入图片描述

点击进入USART1,将MODE 设置为ASYNCHRONOUS

在这里插入图片描述

进入NVIC 将USART1 GLOBAL INTERRUT 选上

在这里插入图片描述

点击进入PROJECT MANAGER 输入PROJECT NAME(不能是中文)

在这里插入图片描述

勾选GENERATE PERIPHERAI

在这里插入图片描述

然后点击GENERATE CODE生成MDK文件。

二,代码烧录

打开烧录出的文件夹

在这里插入图片描述

进入MDK-ARM.打开文件工程

在这里插入图片描述
在这里插入图片描述

将下段代码复制粘贴入main.c文件内。

`#include “main.h”
#include “usart.h”
#include “gpio.h”
#include <string.h>

void SystemClock_Config(void);

char c;
char message[]=“hello Windows\n”;
char tips[]=“CommandError\n”;
char tips1[]=“Start…\n”;
char tips2[]=“Stop…\n”;
int flag=0;
const char START[] = “START”;
const char STOP[] = “STOP”;
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();

HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);

while (1)
{
if(flag==1){

		HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF); 


HAL_Delay(1000);
}
}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
static uint8_t idx = 0; // 添加静态变量用于索引
char receivedChar = c;

if (receivedChar == START[idx]) {  
    idx++;  
    if (idx == strlen(START)) {  
        flag = 1; // 接收到START,设置flag为1  
        idx = 0; // 重置索引  
    }  
} else if (receivedChar == STOP[idx]) {  
    idx++;  
    if (idx == strlen(STOP)) {  
        flag = 0; // 接收到STOP,设置flag为0  
        idx = 0; // 重置索引  
    }  
} else if (idx > 0) {  
    // 如果接收字符不符合START或STOP的条件,且索引不为0,则重置索引  
    idx = 0;  
}  
  
if (flag == 1) {  
    HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message), 0xFFFF);  
} else {  
    HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2), 0xFFFF);  
}  
  
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1); // 继续接收下一个字符  

}

void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE`

然后点击保存编译,生成HEX文件,烧录进入单片机。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三.DMA通信:

创建新工程:

在这里插入图片描述

选择USTAR1

在这里插入图片描述

使能串口

在这里插入图片描述
在这里插入图片描述

创建工程

在这里插入图片描述

然后,将下列代码从粘贴到main.c中。
在这里插入图片描述

`#include “main.h”
#include “dma.h”
#include “usart.h”
#include “gpio.h”
void SystemClock_Config(void);

int stringcompare(char str1[6],char str2[6])
{
uint8_t i=0;

	for(i = 0 ; i < 6 ; i++)
	{
	if (str1[i] != str2[i]) 
		
		return 0;//如果输入数据与原有数据不符,返回0
}

return 1;//如果位数全部相同,则返回1

}

char start[6] = “start”;//初始字符串
uint8_t flag=3;//标志位

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
//配置函数
uint8_t hello[20]=“Hello,Windows!\r\n”;
uint8_t stop[50]=“Stop!please enter ‘start’ to continue!\r\n”;
HAL_UART_Receive_DMA(&huart1,(uint8_t*)start,5);

while (1)
{
	
	 if(flag==1)//标志位为1,发送hellowindows
	{					
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
	   
	    HAL_UART_Transmit_DMA(&huart1,hello,20);
	    HAL_Delay(1000);
	}
	else if(flag==0)//标志位为0,停止发送0.
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
		 HAL_UART_Transmit_DMA(&huart1,stop,50);
		flag=3;
	}

}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

if(stringcompare(start,"stop!"))//输入为stop时,标志位置0
{
	flag=0;
	
}


else if(stringcompare(start,"start"))//输入为 start时,标志位置1
{
	flag=1;
}

//重新设置中断
HAL_UART_Receive_DMA(&huart1,(uint8_t*)start,5);

}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }

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

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

  • @brief This function is executed in case of error occurrence.
  • @retval None
    /
    void Error_Handler(void)
    {
    /
    USER CODE BEGIN Error_Handler_Debug /
    /
    User can add his own implementation to report the HAL error return state /
    __disable_irq();
    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 /
    USE_FULL_ASSERT */`

  • 烧录进去

    在这里插入图片描述

  • 结果:

在这里插入图片描述

https://blog.csdn.net/vic_to_ry/article/details/110451036
https://blog.csdn.net/Constellation_zZ/article/details/134165845?spm=1001.2014.3001.5502

四:

了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别

串口协议是用于数据通信的一种通信协议,它定义了数据的传输格式和数据交换的规则。串口通信常用于连接计算机与外部设备,例如串口打印机、调制解调器、传感器等。其中,RS-232 是一种常见的串口协议标准。

RS-232(Recommended Standard 232)是由美国电子工程师学会(Electronic Industries Association)制定的一套串行通信接口标准。它规定了数据的传输格式、电气特性以及接线方式等。

至于RS232电平和TTL电平,它们指的是串口通信中使用的电信号电平。RS232电平是一种标准的串口电平,通常使用±12V表示逻辑1和逻辑0。而TTL(Transistor-Transistor Logic)电平是另一种常见的电信号电平,通常使用0V表示逻辑0,以及3.3V或5V表示逻辑1。

区别主要有几点:

  1. 电压范围:RS232电平使用高低电平的正负电压表示逻辑1和逻辑0,而TTL电平使用固定的电压值表示逻辑1和逻辑0。
  2. 电气特性:RS232电平具有较高的电压和电流能力,可以实现较长距离的信号传输(通常可达15米以上),而TTL电平适用于较短距离的通信(通常在数米范围内)。
  3. 适用设备:由于电压范围和电气特性的不同,RS232电平主要用于连接计算机与外部设备,如调制解调器、打印机等,而TTL电平通常用于单片机与外部设备的通信。

需要注意的是,由于电压范围和电气特性的差异,直接连接RS232和TTL设备可能会导致电平不匹配和损坏设备。因此,如果需要连接RS232和TTL设备,可能需要使用电平转换器或专门的串口转换模块来进行信号转换。

了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理

USB/TTL转232"模块(例如基于CH340芯片的模块)被广泛用于将USB接口的设备与RS-232串口设备进行连接。下面是其工作原理的一般过程:

  1. USB接口:该模块的一侧是USB接口,用于连接到计算机或其他USB主机设备。USB接口提供了数据传输和电源供应。
  2. CH340芯片:CH340是一款USB转串口芯片,模块上集成了该芯片。CH340芯片负责将USB中的数据转换为串行数据,以便与RS-232设备进行通信。
  3. TTL电平转换:在CH340芯片的输出端,存在TTL电平。TTL电平一般为0V表示逻辑0,以及3.3V或5V表示逻辑1。这种电平适用于与单片机或其他TTL电平设备进行通信。
  4. RS-232电平转换:通过RS-232电平转换电路,将TTL电平转换为RS-232电平。这是为了与RS-232设备进行兼容,RS-232电平一般是正负12V分别表示逻辑1和逻辑0。
  5. RS-232串口:模块的另一侧提供了RS-232串口,您可以通过它连接到其他RS-232设备,如调制解调器、打印机等。

SB主机设备。USB接口提供了数据传输和电源供应。
2. CH340芯片:CH340是一款USB转串口芯片,模块上集成了该芯片。CH340芯片负责将USB中的数据转换为串行数据,以便与RS-232设备进行通信。
3. TTL电平转换:在CH340芯片的输出端,存在TTL电平。TTL电平一般为0V表示逻辑0,以及3.3V或5V表示逻辑1。这种电平适用于与单片机或其他TTL电平设备进行通信。
4. RS-232电平转换:通过RS-232电平转换电路,将TTL电平转换为RS-232电平。这是为了与RS-232设备进行兼容,RS-232电平一般是正负12V分别表示逻辑1和逻辑0。
5. RS-232串口:模块的另一侧提供了RS-232串口,您可以通过它连接到其他RS-232设备,如调制解调器、打印机等。

总结来说,"USB/TTL转232"模块利用CH340芯片实现USB到串口的转换,并通过TTL到RS-232电平的转换,将USB接口转换为RS-232串口接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值