STM32 串口

2023-05-16

文章目录

  • USART 通信协议
    • RS-232与TTL电平
  • 串口通信数据包组成
  • USART功能框图讲解
    • 引脚
    • 寄存器
      • 状态寄存器(USART_SR)
      • 数据寄存器(USART_DR)
      • 控制寄存器(USART_CR)
      • 波特比率寄存器(USART_BRR)
      • 发送过程中寄存器的变化
  • 固件库编程
    • 结构体
      • 初始化结构体 USART_InitTypeDef
    • 固件库函数
  • 开始编程(一)
    • 初始化
      • GPIO
      • USART
    • 中断配置
      • 配置外设中断
      • 配置中断优先级分组
      • 配置 NVIC 寄存器
      • 整合配置代码
    • 发送数据
    • 重新定向printf
    • 用宏定义封装
  • 开始编程(二)
    • 编写中断服务函数
      • 控制LED
  • 发送和接收过程中的编码
  • sizeof

USART 通信协议

  所谓协议,就是一种交换信息的规定。想要传输信息,必须按照一定的规则才能识别。USART是串行,全双工,异步通信

RS-232与TTL电平

TTL: 0~3.3/5V 一般芯片输出的都是TTL;
RS-232:-15~15V,但-15V对应逻辑1,+15V对应逻辑0。主要用于工业设备的通信,高的电平差有较高的容错能力。

USB转串口 :电平转换芯片有CH340,PL2303,CP2102;需要安装驱动。指南者上的是CH340,通过跳帽连接USART1;

串口通信数据包组成

起始位:一个逻辑0表示
结束位:一般由一个1个逻辑1表示,也可选择其他方式。
有效数据位:数据位后面就是数据位,stm32中为9个位。
校验位:可以使用校验来提高稳定性。

  1. 偶校验:添加校验位后,校验位和有效数据位的1有偶数个。
  2. 奇校验:添加校验位后,校验位和有效数据位的1有奇数个。

USART功能框图讲解

引脚

TX:数据发送。
RX:数据接收。
SCLK:时钟,仅同步通信使用(一般使用异步)
nRTS: 请求发送
nCTS: 允许发送
这些引脚外设可以在数据手册 3 Pinouts and pin descriptions 查到,下面是VET6芯片的引脚总结。
在这里插入图片描述这里列出的是串口复用功能的默认端口,在重映射下,这些功能可以对应其他端口,这样同样可以在数据手册这一章查到。在参考手册 8.3 有更集中的总结。

注意这里只有USART1是挂在在APB2总线下的,其于串口在APB1总线下,打开时钟的时候需要注意。

寄存器

状态寄存器(USART_SR)

  其反应了发送过程中,发送状态的改变

数据寄存器(USART_DR)

  9位有效,其包含一个发送数据寄存器TDR和接收数据寄存器RDR。

控制寄存器(USART_CR)

  一共有3个控制寄存器,这三个寄存器完成对USART通信模式的控制,如使能,字长,校验等。并且其中有对发送和接收中断的配置。
  发送时,起始的配置位有 CR1UE,TE,RE 位。

波特比率寄存器(USART_BRR)

在这里插入图片描述

配置波特率,这个配置需要配置整数和小数部分。这样是因为配置波特率的公式中需要用到小数。
  stm32波特率计算公式是:
b a u d = f C K 16 ∗ U S A R T D I V baud = \frac{f_{CK}}{16*USARTDIV} baud=16USARTDIVfCK
b a u d baud baud是波特率, f C K f_{CK} fCK是时钟频率, U S A R T D I V USARTDIV USARTDIV就是要配置寄存器写入值
如:想要波特率为115200,配置时钟为72M,可以算出,USARTDIV=39.0625。
  如何配置呢?对于整数部分,直接写入39,16进制为0x17
  对于小数,寄存器中留有四个二进制位,可以表示16个数,也就是1被16等分,0001就表示 1 16 \frac{1}{16} 161,因此想要得到0.625,就应该写入0.625/ 1 16 \frac{1}{16} 161=0x01。如果为0.1875,0.1875/ 1 16 \frac{1}{16} 161=0x03
  最终,向寄存器写入0x171表示39.0625.若写入0x173则表示39.1875。(注意这里表示为16进制数)

发送过程中寄存器的变化

  1. 发送数据
    从CPU或DMA读取数据到TDR,放到发送移位寄存器,一位一位从TX发送出去。
    SR寄存器的 TXE 会置1,表示数据已经移动到移位寄存器。
    发送完成 TC 置1。
  2. 接收数据
    数据从 RX传来,接收移位寄存器接收,传给RDR,传给CPU。
    SR寄存器的 RXNE 置1,表示接收到数据可以读取。

固件库编程

结构体

其实真正的寻找应该从函数开始,到结构体。但那样太乱,这先介绍结构体。

初始化结构体 USART_InitTypeDef

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;

固件库函数

这里列出一些重要的函数。

  • USART_Init:初始化串口,其传入了对应串口和初始化结构体,因此配置了结构体中的内容。对应了CR,BRR寄存器的置位。
  • USART_Cmd:使能对应串口,对应CR寄存器中的置位操作。
  • USART_ITConfig:中断使能,对应CR寄存器中的置位操作。
  • USART_SendData,USART_ReceiveData:发送,接收;对应于DR寄存器的操作。
  • USART_GetITStatus:获取标志位,对应SR寄存器的操作。

开始编程(一)

两个编程任务,第一实现串口发送;第二,实现接收返回,和串口控制led灯。第一部分完成串口的发送。

初始化

  使用USART接收电脑发送的数据,并且返回这个数据。使用中断完成

GPIO

  因为USART是复用功能,从GPIO原理框图可以看出,必须初始化GPIO。PA9为发送,初始化为推挽输出;PA10为输入,初始化为浮空输入;打开时钟;

static void USART_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
}

USART

初始化USART,配置波特率115200,字长8,停止位1,无校验位,无硬件流。
这里注意
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
这个骚操作,直接把输入和输出模式一起配置了。
注意,最后要使能 USART

static void USART_Init_Config(void)
{
	USART_InitTypeDef USART_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	USART_InitStruct.USART_BaudRate   = 115200;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;
	USART_InitStruct.USART_StopBits   = USART_StopBits_1;
	USART_InitStruct.USART_Parity     = USART_Parity_No;
	USART_InitStruct.USART_Mode       = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	
	USART_Init(USART1,&USART_InitStruct);
	USART_Cmd(USART1,ENABLE);
}

中断配置

中端的配置为了第二个实验的接收

配置外设中断

USART的中断配置十分简单,一个函数就可以解决。

	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

对串口1配置,接收中断。

配置中断优先级分组

配置分组为1

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

配置 NVIC 寄存器

这里要注意 NVIC_IRQChannel 这个结构体成员变量可赋值的查找。详细请见STM32 EXTI外部中断小结 配置 NVIC 寄存器 部分。

static void USART_NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置优先级分组
	
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	
	NVIC_Init(&NVIC_InitStruct);
}

  下面应该写中断配置函数,在中断配置函数中读取输入数据,然后发送回电脑。这部分内容放在实验二,现在先把上面的代码整合一下。

整合配置代码

  这样所有的初始化工作完成,编写一个函数集成上面的函数。

void USART_Config(void)
{
	USART_GPIO_Config();    //配置GPIO端口
	USART_Init_Config();    //配置USART模式
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  //使能中断,接收中断
	USART_NVIC_Config();    //配置中断管理
}

配置到这里,程序已经可以使得芯片接收数据,并且跳转到中断中了。

发送数据

  为了完成在中断中读取数据和发送数据我们必须编写函数。
  在USART库中有函数 USART_SendData,这个函数实际上已经可以发送一些数据了,这里对其进行包装。使用函数检测是否发送完成。其实这里不用检测。直接使用USART_SendData也可完成这项工作。

void USART_SentByte(USART_TypeDef* pUSARTx, uint8_t data)
{
	USART_SendData(pUSARTx, data);
	while( USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);
}

  函数需要传入USART外设的指针和要发送的数据。
  另外注意。虽然USART_SendData 的第二个参数可以传入16位数据,但实际上只有低8位有效,也就是说,使用一次USART_SendData 只能发送一个字节的数据。
  注意:单片机发出的信号其实是一串二进制码,串口调试助手默认是以ASCII码的方式显示。在keil中,发送的数据也以ASCII码的形式编码。

  这是一张ASCII码对应表,具体可见ASCII码对照表
  如:USART_SentByte(USART1, 0x41),这里单片机把 0x41 编码为2进制 0100 0001 ,通过串口发送出去,串口调试助手默认把这串二进制码用ASCII解释,显示A
  如: USART_SentByte(USART1,'A') ,这里keil把 A 按ASCII码编码为0100 0001,通过串口发送出去,串口调试助手认把这串二进制码用ASCII解释,显示A。但如果选中16进制显示,则会显示FF41
  因为只能发送一个字节,我们在编写一个可以发送两个字节。

void USART_Sent2Byte(USART_TypeDef* pUSARTx, uint16_t data)
{
	uint8_t temp_h,temp_l;
	temp_h = (data >> 8) & 0x00ff;
	temp_l = data&0x00ff;
	
	USART_SendData(pUSARTx, temp_h);
	while( USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);
	
	USART_SendData(pUSARTx, temp_h);
	while( USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);
}

重新定向printf

其实实际使用中用的最多的是使用重新定向后的printf。记得要在头文件中引用C库 #include <stdio.h>

//重新定向C库函数,以便于使用printf
int fputc(int ch, FILE *f)
{
		USART_SendData(USART1, (uint8_t) ch);
		while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);		
		return (ch);
}

//重新定向C库函数,以便于使用scanf
int fgetc(FILE *f)
{
		while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
		return (int)USART_ReceiveData(USART1);
}

更具体的这些函数做到了什么,我也没学,没法解释。但实验的结果可以看出,在printf() 的括号中填入任何长度的字符,都可打印出来。

用宏定义封装

为了使得代码有较好的移植性,我们使用宏定义对代码进行封装。

  1. GPIO部分
    GPIO肯定是要对引脚和GPIOx进行封装。对时钟函数中的参数封装。这里使用和野火教程中一样的封装。
// GPIO
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#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
  1. USART部分
    要封装USARTx,因不同的USART会对应不同的总线,因此不仅要对时钟函数的参数封装,还要封装时钟函数;另外为了以后便于调节波特率,把波特率也用宏定义封装。
//USART
#define  DEBUG_USARTx                   USART1
#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1
#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200

3.中断部分
初始化NVIC中,channel的选择和中断服务函数的编写用到了USARTx

#define  DEBUG_USART_IRQ                USART1_IRQn
#define  DEBUG_USART_IRQHandler         USART1_IRQHandler

这样,整个程序就有了对于USARTx之间的移植性,只要修改宏定义中的参数,就可以开启不同的USART。

开始编程(二)

第二部分完成数据的接收返回和控制LED。

编写中断服务函数

上面已经完成中断配置的前三个步骤了,这里完成最后一个上面已经完成中断配置的前三个步骤了,这里完成最后一个。
中断服务函数最好写在stm32f10x_it.c中,其名称必须为startup_stm32f10x_hd.s 中定义的名称。

void DEBUG_USART_IRQHandler(void)
{
	uint8_t Sentback;
	//进入中断后再次检测是否真的置位
	if( USART_GetFlagStatus(DEBUG_USARTx,USART_IT_RXNE) != RESET)
	{
		Sentback = USART_ReceiveData(DEBUG_USARTx);
		USART_SendData(DEBUG_USARTx,Sentback);//使用这个函数把得到的数据返回
		//也可用printf("%d",Sentback);代替
	}
}

控制LED

直接修改中断服务函数,使用 getchar() 获得输入;使用 switch构成判断。

void DEBUG_USART_IRQHandler(void)
{
	uint8_t LED_Common;
	LED_Common = getchar();
	
	switch(LED_Common)
	{
		case '1':LED_R(ON);printf("LED_R ON!\n");Infor_LED[0]=1;break;
		case '2':LED_G(ON);printf("LED_R ON!\n");Infor_LED[1]=1;break;
		case '3':LED_B(ON);printf("LED_R ON!\n");Infor_LED[2]=1;break;
		
		case '4':LED_R(OFF);printf("LED_R OFF!\n");Infor_LED[0]=0;break;
		case '5':LED_G(OFF);printf("LED_R OFF!\n");Infor_LED[1]=0;break;
		case '6':LED_B(OFF);printf("LED_R OFF!\n");Infor_LED[2]=0;break;
	}

发送和接收过程中的编码

  上面提到,如果使用USART_SentByte(USART1, A),函数会把发送的数据以ASIIC码编码,通过串口发送,A 的 ASIIC码 为0100 0001。串口调试助手默认以 ASIIC码 解码 显示 A。若选择 以16进制显示 则显示 41

  同样对于电脑端发送的数据,串口调试助手也以 ASIIC码 编码发送。如发送 A,会编码 0100 0001 发送。若选择以16进制发送,则会发送 1010

sizeof

  有了串口程序,stm32和电脑就可以通信了,这样我们就可以展开一些实验,如这里介绍的sizeof。
  sizeof可以返回对应值的长度,在不同的机器上返回值不同。在stm32上写下如下代码。

#include "stm32f10x.h"
#include "bsp_usart.h"
#include <stdio.h>

int text(int a[])
{
	uint8_t i =sizeof(a);
	return i;
}

int main(void)
{	
	int a[5] = {1,2,3,4,5};
	uint8_t b    = sizeof(int);
	USART_Config();
  
  	printf("b=%d\n",b);
	printf("sizeof a = %d\n",sizeof(a));
  	printf("fun:sizeof a = %d",text(a));
  	while(1)
	{	
		
	}	
}

返回值为:

b=4
sizeof a = 20
fun:sizeof a = 4

  这里我们调用 sizeof 查看 int 的数据宽度为4(b对应的值)。在main中调用 sizeof 查看数组 a 的宽度为20,查看函数 text 宽度为4.
  这和普通PC返回的值不一样。在64位电脑上,使用VScode运行上面这段代码,获得的结果如下:

b=4
sizeof a = 20
fun:sizeof a = 8

  先解释 b=4;这一点stm32和电脑返回值一致,因为int类型占用的就是4个数据位。
  sizeof a,查看main函数中a数组的宽度。返回20,表示4×5=20(数据宽度×数据个数)。
  fun:sizeof a,查看函数返回的a的数据宽度。这里PC返回8,stm32返回4。和上面直接在main函数中查看不同。这是因为,向函数传输数组时,传输的不是数组本身,而是数组的首地址(指针)。在32位机中,指针长度为4,64位机中,指针长度为8.
  这也提示我们,在函数中,我们无法使用sizeof得到传入数组的大小。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 串口 的相关文章

  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • 134-基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真+源程序...

    资料编号 134 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 ds1302时钟 DHT11温湿度 电机 蜂鸣器 制作一个基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真 2 通过DH
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • 137-基于stm32单片机智能保温杯控制装置Proteus仿真+源程序

    资料编号 137 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DS18B20传感器 电机 制作一个基于stm32单片机智能保温杯控制装置Proteus仿真 2 通过DS18b20传感器检测当前保温杯水的温度 并且
  • 136-基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真+源程序

    资料编号 136 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 蜂鸣器 制作一个基于stm32单片机家庭温湿度防漏水系统设计Proteus仿真 2 通过DHT11传感器检测当前温湿度 并且显示到L
  • rt-thread studio中新建5.02版本报错

    先吐槽一下 rt thread studio出现BUG真多 好多时间都是在找BUG 但里面用好多控件还是挺好用的 真是又爱又恨 所以一般使用功能不多的话还是用keil多一点 创建5 02版本工程之后直接进行编译 直接会报下面这个错误 资源
  • Push_back() 导致程序在进入 main() 之前停止

    我正在为我的 STM32F3 Discovery 板使用 C 进行开发 并使用 std deque 作为队列 在尝试调试我的代码 直接在带有 ST link 的设备上或在模拟器中 后 代码最终在 main 中输入我的代码之前在断点处停止 然
  • STM32F103概要

    The STM32F103x4 STM32F103x6 STM32F103xC STM32F103xD and STM32F103xE are a drop in replacement for STM32F103x8 B medium d
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • STM32的HAL中实现单按、长按和双按功能

    我正在尝试实现单击 双击和长按功能来执行不同的功能 到目前为止 我已经理解了单击和长按的逻辑 但我不知道如何检测双击 至于代码 我使用计数器实现了单击和长按 但代码仅停留在第一个 if 条件上 bool single press false
  • 无法使用 OpenOCD 找到脚本文件

    我正在尝试按照本教程将 OpenOCD 与我的 ST 发现板一起使用 https japaric github io discovery README html https japaric github io discovery READM
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • GCC 变量映射和 MISRA-C

    我主要知道两种使用 GCC 声明内存映射寄存器的方法 有许多变体 使用双字段 每个外设的数据结构等 要么使用初始化为正确地址的指针 例如volatile uint32 t pMyRegister uint32 t 0xDEADBEEFUL
  • 读取STM32 MCU SPI数据寄存器的值

    有很多类似的问题 但似乎没有一个问题完全相同 我正在将 STML4 MCU 连接到 6 轴传感器 LSM6DS3 我已经成功地在 I2C 中实现了所有内容 但想要 SPI 的额外速度 和 DMA 如果我能让这些第一步工作起来的话 因此 第一

随机推荐

  • 介绍@dynamic的用法

    介绍 64 dynamic的用法 Objective C 2 0提供了属性 64 property xff0c 可以让编译器自动生成setter和getter方法 如果不想编译器自作主张生成这些setter和getter方法 xff0c 则
  • OkHttpUtils的使用

    OkHttpUtils是一个非常好的网络协议框架 xff0c 它是在OkHttp的基础上进行了二次封装 要使用这个类首先下载jar包 xff0c 如下 xff1a http download csdn net download xxdw19
  • 十进制整数转为十六进制整数(C++实现)

    一 代码功能 xff1a 输入一个十进制整数 xff0c 将其转化为十六进制整数并输出 二 源码 include lt iostream gt include lt cstring gt include lt cmath gt using
  • 我的四轴专用PID参数整定方法及原理---超长文慎入(转)

    给四轴调了好久的PID xff0c 总算是调好了 xff0c 现分享PID参数整定的心得给大家 xff0c 还请大家喷的时候手下留情 首先说明一下 xff0c 这篇文章的主旨并不是直接教你怎么调 xff0c 而是告诉你这么调有什么道理 xf
  • 简单的TCP客户端发包工具

    一 TCP介绍 先放这里有时间在写 xff0c 最近在写DuiLib相关的使用内容 xff0c 这部分大家凑活着看 二 程序截图 下载链接 链接 xff1a https pan baidu com s 1MzNUzwd7WwBat6vNMc
  • C++常用头文件汇总

    之前说过的头文件这就来了 1 首先是本人最喜欢也是最最方便的万能头文件 xff0c 顾名思义 xff0c 不管是天上飘的还是地下埋的 xff0c 只要不是不对的头文件它都包含 xff0c 除了本篇第14个头文件 xff1a include
  • 基于I2C/SPI的温湿度采集与OLED显示

    基于I2C SPI的温湿度采集与OLED显示 一 AHT20温湿度采集1 I2C2 温湿度采集代码效果 二 OLED显示1 显示学号姓名2 诗句显示 三 总结四 参考 一 AHT20温湿度采集 1 I2C 解释什么是 软件I2C 和 硬件I
  • 游戏客户端编程

    游戏客户端编程 1 代码实现服务器连接发送按钮 2 显示消息3 发送信息4 播放背景音乐5 变换游戏背景图片6 参考 1 代码实现 服务器连接 span class token keyword private span span class
  • 卷积神经网络实现表情识别

    卷积神经网络实现表情识别 CNN人脸表情识别图片预处理原本效果处理后效果 图片数据集效果 CNN人脸识别创建模型归一化与数据增强创建网络 摄像头人脸识别图片识别 参考 CNN人脸表情识别 图片预处理 span class token key
  • IIC协议及其工程【FPGA】

    IIC协议及其工程 FPGA 一 IIC协议1 IIC简介2 IIC中相关的术语1 应答信号 xff08 ACK xff09 2 无应答信号 xff08 NOACK xff09 3 虚写3 IIC的时序 二 EEPROM1 时钟频率2 起始
  • char *与char []的区别

    其实 xff0c 只要记住一点就能很好区分char 和char xff1a char 定义的是一个指向字符串的指针 xff08 注意 xff1a C语言中没有对应字符串的内置类型或者类类型 xff09 xff0c 而char 就是C语言中的
  • SPI协议读取FLASH【FPGA】

    SPI协议读取FLASH FPGA 一 SPI协议1 SPI简介2 SPI物理层3 SPI协议层CPOL CPHA 及通讯模式 4 SPI 基本通讯过程5 通讯的起始和停止信号6 数据有效性 二 Flash1 状态寄存器1 WIP xff0
  • 基于FPGA的图像边缘检测

    基于FPGA的图像边缘检测 一 图像处理算法1 灰度转换2 高斯滤波3 二值化4 Sobel 二 项目框架1 摄像头配置模块2 图像处理模块3 数据缓存模块4 其它模块 三 部分代码1 数据采集模块2 读写控制模块 四 参考五 源码 简介
  • 基本认证_摘要认证_HTTPS

    1 HTTP基本认证 HTTP提供了一个原生的质询 响应 xff08 challenge response xff09 框架 Web应用程序收到一条HTTP请求报文时 xff0c 服务器没有按照请求执行动作 xff0c 而是以一个 认证质询
  • 什么是奇校验(Odd Parity),什么是偶校验(Even Parity)?

  • 2021-03-08

    今天在网上安装PR xff0c 网上下载的安装器把电脑默认装了一大堆垃圾工具 xff0c 依次删除后突然发现谷歌浏览器主页被篡改了 xff0c 随后用360等工具修复 xff0c 均提示无异常 通过浏览器设置和重置主页后仍然无效 xff0c
  • 2021-03-08

    大疆无人机自己动手更换电芯的注意事项 xff0c 当电池多电芯出现均大压差且调整数据无效后 xff0c 或发现某块或多块电芯鼓包 xff0c 说明电芯已经老化 xff0c 寿命用尽 xff0c 就需要更换电芯了 xff0c 厂家为保护消费者
  • can't run '/etc/init.d/rcS': No such file or directory 最终解决方法

    drivers rtc hctosys c unable to open rtc device rtc0 end request I O error dev mtdblock2 sector 256 isofs fill super bre
  • Ubuntu下的CuteCom串口详细调试教程

    I MX6ULL嵌入式开发学习 串口调试 一 Ubuntu下的串口调试助手安装 嵌入式开发学习过程中学习到串口调试这一章 xff0c 以前在Win10操作时都有相对应的串口调试界面 xff0c 安装个串口驱动在电脑设备端口里面看到COM3时
  • STM32 串口

    文章目录 USART 通信协议RS 232与TTL电平 串口通信数据包组成USART功能框图讲解引脚寄存器状态寄存器 USART SR 数据寄存器 USART DR 控制寄存器 USART CR 波特比率寄存器 USART BRR 发送过程