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

C8T6超绝模块--USART串口通信

C8T6超绝模块–USART串口通信

注意USART的引脚请自行查阅相应的数据手册

本模块主要实现功能
实现开发板与电脑通信,在开发板上电时通过 USART 发送一串字符串给电脑,然后开发板进入中断接收等待状态,如果电脑有发送数据过来,开发板就会产生中断,我们在中断服务函数接收数据,并马上把数据返回发送给电脑

大纲

  1. USART原理和结构体讲解
  2. 代码流程(收发数据)
  3. 代码流程(实现控制)

具体案例

USART原理和结构体讲解

在USART–串口通信一文中有详细解释,这里就不做详细解释

代码流程(收发数据)

USART.H

这是使用的宏定义

#ifndef __BSP_USART_H
#define __BSP_USART_H#include "stm32f10x.h"
#include <stdio.h>/** * 串口宏定义,不同的串口挂载的总线和IO不一样,移植时需要修改这几个宏* 1-修改总线时钟的宏,uart1挂载到apb2总线,其他uart挂载到apb1总线* 2-修改GPIO的宏*/#define	DEBUG_USART1		1
#define	DEBUG_USART2		0
#define	DEBUG_USART3		0
#define	DEBUG_USART4		0
#define	DEBUG_USART5		0#if DEBUG_USART1
// 串口1-USART1
#define  DEBUG_USARTx                   USART1
#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1
#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_9
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10#define  DEBUG_USART_IRQ                USART1_IRQn
#define  DEBUG_USART_IRQHandler         USART1_IRQHandler#elif DEBUG_USART2
// 串口2-USART2
#define  DEBUG_USARTx                   USART2
#define  DEBUG_USART_CLK                RCC_APB1Periph_USART2
#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_2
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_3#define  DEBUG_USART_IRQ                USART2_IRQn
#define  DEBUG_USART_IRQHandler         USART2_IRQHandler#elif DEBUG_USART3
// 串口3-USART3
#define  DEBUG_USARTx                   USART3
#define  DEBUG_USART_CLK                RCC_APB1Periph_USART3
#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOB)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  DEBUG_USART_TX_GPIO_PORT       GPIOB   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_10
#define  DEBUG_USART_RX_GPIO_PORT       GPIOB
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_11#define  DEBUG_USART_IRQ                USART3_IRQn
#define  DEBUG_USART_IRQHandler         USART3_IRQHandler#elif DEBUG_USART4
// 串口4-UART4
#define  DEBUG_USARTx                   UART4
#define  DEBUG_USART_CLK                RCC_APB1Periph_UART4
#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOC)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  DEBUG_USART_TX_GPIO_PORT       GPIOC   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_10
#define  DEBUG_USART_RX_GPIO_PORT       GPIOC
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_11#define  DEBUG_USART_IRQ                UART4_IRQn
#define  DEBUG_USART_IRQHandler         UART4_IRQHandler#elif DEBUG_USART5
// 串口5-UART5
#define  DEBUG_USARTx                   UART5
#define  DEBUG_USART_CLK                RCC_APB1Periph_UART5
#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd#define  DEBUG_USART_TX_GPIO_PORT       GPIOC   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_12
#define  DEBUG_USART_RX_GPIO_PORT       GPIOD
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_2#define  DEBUG_USART_IRQ                UART5_IRQn
#define  DEBUG_USART_IRQHandler         UART5_IRQHandler#endifvoid USART_Config(void);
void Usart_SendByte(USART_TypeDef* pUSARTx,uint8_t data);
void Usart_SendHalfWord(USART_TypeDef * pUSARTx,uint16_t data);
void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t *array,uint8_t num);
void Usart_SendStr(USART_TypeDef * pUSARTx,uint8_t *str);#endif

USART.C

首先设置中断的优先级

static void NVIC_Configuration(void)
{NVIC_InitTypeDef NVIC_InitSructure;// 进行嵌套向量中断控制器的选择NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 配置USART为中断源NVIC_InitSructure.NVIC_IRQChannel = DEBUG_USART_IRQ;// 抢断优先级NVIC_InitSructure.NVIC_IRQChannelPreemptionPriority = 1;// 子优先级NVIC_InitSructure.NVIC_IRQChannelSubPriority = 1;// 使能中断NVIC_InitSructure.NVIC_IRQChannelCmd = ENABLE;// 初始化配置NVICNVIC_Init(& NVIC_InitSructure);
}

其次是USART串口的初始化

void USART_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 打开串口GPIO的时钟DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK,ENABLE);// 打开串口外设的时钟DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK,ENABLE);// 初始化GPIO, 将USART Tx配置为推挽复用模式GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);// 将USART Rx的GPIO配置为浮空输入模式GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);// 配置串口的工作的参数// 配置波特率USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;// 配置字数据长USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 配置停止位USART_InitStructure.USART_StopBits = USART_StopBits_1;// 配置校验位USART_InitStructure.USART_Parity = USART_Parity_No;// 配置硬件流控制USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 配置工作模式,收发一起USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 完成串口初始化的设置USART_Init(DEBUG_USARTx,& USART_InitStructure);// 串口中断优先级配置NVIC_Configuration();// 使能串口接收中断USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE);// 使能串口(其实是打开UE)USART_Cmd(DEBUG_USARTx,ENABLE);}

注意初始化串口时,分别初始化串口的TX(推挽复用)RX(浮空输入)两个引脚后,再配置串口的结构体的参数。再调用前面的设置中断的优先级。使能串口接收中断
上面完成的是串口初始化的代码,下面是具体实现数据发送的功能函数

// 发送一个字节
void Usart_SendByte(USART_TypeDef* pUSARTx,uint8_t data)
{USART_SendData(pUSARTx,data);while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);}// 发射两个字节
void Usart_SendHalfWord(USART_TypeDef * pUSARTx,uint16_t data)
{uint8_t temp_h,temp_l;temp_h = (data & 0xff00) >> 8;temp_l = data & 0xff;USART_SendData(pUSARTx,temp_h);while( USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET );USART_SendData(pUSARTx,temp_l);while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE));}// 发送8位数据的数组
void Usart_SendArray(USART_TypeDef * pUSARTx,uint8_t *array,uint8_t num)
{uint8_t i;for(i = 0; i < num;i++){ Usart_SendByte(pUSARTx,*array++);}while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC) == RESET);
}// 发送字符串
void Usart_SendStr(USART_TypeDef * pUSARTx,uint8_t *str)
{uint8_t i = 0;do{Usart_SendByte(pUSARTx,*(str + i));i++;}while(*(str + i) != '\0');while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC) == RESET);}// 重定向c库函数printf到串口,重定向后可使用printf函数int fputc(int ch,FILE *f)
{// 发送一个字节到串口USART_SendData(DEBUG_USARTx,(uint8_t)ch);// 等待发送完成while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_TXE) == RESET);return (ch);
}// 重定向c库函数scanf到串口,重写向后可使用的scanf,getchar函数
int fgetc(FILE *f)
{// 等待串口输入数据while (USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(DEBUG_USARTx);
}

USART中断服务函数

// 串口中断函数
void DEBUG_USART_IRQHandler(void)
{uint8_t	ucTemp;if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE) != RESET){ucTemp = USART_ReceiveData(DEBUG_USARTx);USART_SendData(DEBUG_USARTx,ucTemp);}}

这是串口完成接收时,接收到数据后,存储在ucTemp然后再发送回来他接收到的数据

main

# include "stm32f10x.h"#include "bsp_led.h"
#include "bsp_usart.h"void Delay( uint32_t count)
{for(;count != 0;count--);
}int main(void)
{USART_Config();	printf("串口printf函数测试\n");
putchar('p');	while(1){}}

其实这里主要还是就是完成串口的初始化

代码流程(实现控制)

主要的串口初始化和接收函数和上面一样
我们这里主要通过接收到的数据控制小灯
小灯初始化请见:C8T6超绝模块–点亮小灯
而与上面的差别,主要体现在主函数里面

main

# include "stm32f10x.h"#include "bsp_led.h"
#include "bsp_usart.h"int main(void)
{USART_Config();uint8_t ch;LED_GPIO_Config();while(1){printf("这是串口控制LED的程序\n");ch = getchar();printf("ch=%c\n",ch);switch(ch){case '1':LED_G(ON);break;case '2':LED_G(OFF);break;default:LED_G(OFF);}}}

这里主要通过getchar()来把USART返回的值存储到ch中,然后再通过ch的值进行判断,来进行点亮或者熄灭小灯

但是这里要注意点一点是:
我们使用这个getchar()要实现返回接收到的串口数据值,需要实现他的重定向
在上面的代码主要体现在这一块

// 重定向c库函数scanf到串口,重写向后可使用的scanf,getchar函数
int fgetc(FILE *f)
{// 等待串口输入数据while (USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_RXNE) == RESET);return (int)USART_ReceiveData(DEBUG_USARTx);
}

判断是否接受完成,如果接收完成,就返回接收到的值


http://www.mrgr.cn/news/23226.html

相关文章:

  • docker conda
  • 分组注解和自定义注解及分页查询
  • 4.人事管理系统(springbootvue项目)
  • AUTOSAR_EXP_ARAComAPI的5章笔记(4)
  • 【重学 MySQL】二十二、limit 实现分页
  • 手把手带你拿捏指针(1)
  • Pytorch添加自定义算子之(13)-CMake与Ninja编译Pytorch自定义算子
  • TinyWebSever源码逐行注释(五)_ http_conn.cpp
  • Curator+Zookeeper实现分布式锁的示例
  • 哈 希 表
  • 记录深度学习量化操作
  • 朴素贝叶斯法(Naive Bayes)—有监督学习方法、概率模型、生成模型、非线性模型、参数化模型、批量学习、贝叶斯学习
  • [linux]GCC G++官方源码国内下载地址汇总
  • 详细步骤!分享6款AI论文写作助手自动生成器实例操作!
  • 【自考zt】【软件工程】【21.04】(部分)
  • 驾校预约学习系统的设计与实现
  • Rocky Linux9下安装Docker和卸载Docker
  • CTK框架(六):服务工厂
  • 重卡换电解决方案换电连接器
  • Flink