stm32和python实现DMA+串口数据收发

STM32F103配置

1-0 串口配置

c 复制代码
void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//使能USART1时钟
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); //复位串口1
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//RX PA.10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子优先级1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
  //USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); //初始化串口1
	
//  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 ???
  USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 空闲中断,打开接收中断。
  USART_Cmd(USART1, ENABLE);                    //使能串口1 
	usart1_dma_tx_init();
	usart1_dma_rx_init();	
}

1-1 DMA发送模式配置

c 复制代码
static void usart1_dma_tx_init(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel4);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)usart1_tx_buff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 0;/*避免初始化发送数据,设置为0*/
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(DMA1_Channel4, ENABLE);
}

1-2 通过DMA传输数据到USART1的发送寄存器

c 复制代码
// 用于通过DMA传输数据到USART1的发送寄存器
uint8_t usart1_dma_tx_data(void* buffer, uint16_t data_lenth)
{
	if(data_lenth < 1)// 判断长度是否有效
	{
		return ERROR;
	}
	
	while (DMA_GetCurrDataCounter(DMA1_Channel4));// 检查DMA发送通道内是否还有数据
	if(NULL == buffer)//指针判空
	{
		return ERROR;
	}
	
	USART1_state.txc = RESET; // 表示发送未完成。
	// 使用memcpy函数将buffer中的数据复制到usart1_tx_buff中。
	// 复制的长度为data_lenth和USART1_TX_BUFF_MAX_LENTH中较小的值。这是为了防止数据溢出。
	memcpy(usart1_tx_buff, buffer,((data_lenth > USART1_TX_BUFF_MAX_LENTH) ? USART1_TX_BUFF_MAX_LENTH:data_lenth));
	
    DMA_Cmd(DMA1_Channel4, DISABLE); //DMA发送数据-要先关 ,以确保设置发送长度之前DMA传输已经停止。
    DMA_SetCurrDataCounter(DMA1_Channel4, data_lenth);// 设置DMA1_Channel4的发送长度为data_lenth。
    DMA_Cmd(DMA1_Channel4, ENABLE);// 启用DMA1_Channel4,以启动DMA传输
	
	return SUCCESS;
}

1-3 串口数据发送

将usart1_dma_tx_data()函数放在main函数中或者中断处理函数中即可,如下所示:

c 复制代码
void main()
{
    uint8_t data_array[8];
	data_array[0] =  0x12;
	data_array[1] =  0x34;
	data_array[2] = (int)Encoder & 0xFF;
	data_array[3] = ((int)Encoder >> 8) & 0xFF;
	data_array[4] = (int)Adc & 0xFF;
	data_array[5] = ((int)Adc >> 8) & 0xFF;
	data_array[6] =  0x56;
	data_array[7] =  0x78;
	usart1_dma_tx_data(data_array, 8);
}

2-1 DMA接收模式配置

c 复制代码
#define USART1_RX_BUFF_MAX_LENTH 200    //定义最大接收字节数 200
#define USART1_TX_BUFF_MAX_LENTH 200
static void usart1_dma_rx_init(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;           // 初始化外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)usart1_rx_buff;            // 缓存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                     // 外设作为数据来源
    DMA_InitStructure.DMA_BufferSize = USART1_RX_BUFF_MAX_LENTH;           // 缓存容量
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       // 外设地址不递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                // 内存递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 外设字节宽度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;        // 内存字节宽度
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;						   // 正常模式,即满了就不在接收了,而不是循环存储
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                    // 优先级很高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                           // 内存与外设通信,而非内存到内存
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
    DMA_Cmd(DMA1_Channel5, ENABLE);
}

2-2 串口结束中断

c 复制代码
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)/*空闲中断接收*/
    {
        u8 data_lenth = 0 ;
		
        DMA_Cmd(DMA1_Channel5, DISABLE);// 关闭DMA ,防止干扰
		USART_ReceiveData( USART1 );
		
        data_lenth = USART1_RX_BUFF_MAX_LENTH - DMA_GetCurrDataCounter(DMA1_Channel5);//获得接收到的字节数
        DMA_SetCurrDataCounter(DMA1_Channel5, USART1_RX_BUFF_MAX_LENTH);//  重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
        DMA_Cmd(DMA1_Channel5, ENABLE);
				USART1_state.rxc = SET;  //设置接收完成标志
		
		my_usmart_scan(usart1_rx_buff,data_lenth); //配置自己的接收处理函数//执行usmart扫描	
		
        memset(usart1_rx_buff, 0, USART1_RX_BUFF_MAX_LENTH); //清空接收缓存区		 
				USART_ClearITPendingBit(USART1, USART_IT_IDLE); // Clear IDLE interrupt flag bit
    }
		if(USART_GetITStatus(USART1,USART_IT_TC) != RESET)  //发送完成标记
		{
			DMA_Cmd(DMA1_Channel4, DISABLE);                // 关闭DMA
			DMA_SetCurrDataCounter(DMA1_Channel4,RESET);    // 清除数据长度
			USART1_state.txc = SET;                         // 设置发送完成标志
			USART_ClearITPendingBit(USART1, USART_IT_TC);   // 清除完成标记
		}	
}

2-3 对串口接收的数据进行处理

c 复制代码
void my_usmart_scan(uint8_t * data_array,uint8_t data_lenth)
{
	if(SET == USART1_state.rxc)//串口接收完成标志位
	{					   
			if(data_array[0] == 0x2D && data_array[1] == 0x01 && data_array[5] == 0x56 && data_array[6] == 0x78) // 判断帧头1和2是否正确、帧尾1和2是否正确 
			{
				float value = 0;
				int16_t sign = 1;
				if(data_array[2] == 0x45) // 符号位判断
				{
					sign = -1;
				}
				value = (data_array[4] << 8) + data_array[3];	
				action = sign * value;  // 接收的数据
		}																			
		USART1_state.rxc = RESET;//状态寄存器清空	    
	}	
}	 
	 

python上位机程序

python 复制代码
# 从串口接收的数据为:编码器(整型)、角位移传感器(浮点型)
def read_serial_one_data_encoder_adc(ser):
    global receive_result
    BUF_SIZE = 8
    buf = bytearray([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    c1 = ib = flag = 0

    while True:
        R = ser.read(1)
        # print("data", R)
        if R == b'':
            print("Read Fail")
            ser.close()
            break
        c = int.from_bytes(R, byteorder='big')
        # print("data", c)
        if flag > 0:
            if ib < BUF_SIZE:
                buf[ib] = c
                ib += 1
            if ib == 8:
                if buf[6] == 0x56 and buf[7] == 0x78:
                    Encoder = (buf[3] << 8) + buf[2]
                    Adc= (buf[5] << 8) + buf[4]
                    receive_result = [Encoder, Adc]
                    break
                else:
                    print("CRC Fail")
                flag = 0
        if flag == 0:
            if c1 == 0x12 and c == 0x34:
                flag = 1
                ib = 2
        c1 = c
    return receive_result

def run_play():
    result = [0, 0]
    action = bytearray([0x12, 0x34, 0x00, 0x00, 0x00, 0x56, 0x78])
    ser = serial.Serial(  # 下面这些参数根据情况修改
        port='COM8',  # 串口
        baudrate=921600,  # 波特率
        timeout=None,
        parity=serial.PARITY_ODD, #
        stopbits=serial.STOPBITS_ONE,
        bytesize=8
    )
    if ser.isOpen():  # 判断串口是否打开
        print("open success")
    for i in range(1000000):
        result2 = read_serial_one_data_encoder_adc(ser)                    # /************从串口接收数据函数**************/
        print("result2=",result)
        ser.write(action) # 使用DMA需要多个字节一起发送                       /************往串口发送数据函数**************/

if __name__ == '__main__':
    run_play()

3 完整程序

c 复制代码
#include "sys.h"
#include "usart.h"
#include <string.h>
#include <math.h>
#include <stdio.h>
uint16_t Res;
float action;
uint16_t check_flag;

#define USART1_RX_BUFF_MAX_LENTH 200    //定义最大接收字节数 200
#define USART1_TX_BUFF_MAX_LENTH 200

uint8_t ReceiveBuff[RECEIVEBUFF_SIZE];
static uint8_t usart1_tx_buff[USART1_TX_BUFF_MAX_LENTH];
uint8_t usart1_rx_buff[USART1_RX_BUFF_MAX_LENTH];

typedef struct
{
	uint8_t rxc;
	uint8_t txc;
}uart_state_t;

uart_state_t USART1_state;

// 	 
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos 使用	  
#endif  

//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
重定义fputc函数 
//int fputc(int ch, FILE *f)
//{      
//	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
//    USART1->DR = (u8) ch;      
//	return ch;
//}
#endif 
#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
  
void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	//使能USART1时钟
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); //复位串口1
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TX PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//RX PA.10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子优先级1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
  //USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); //初始化串口1
	
//  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 ???
  USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); // 空闲中断,打开接收中断。
  USART_Cmd(USART1, ENABLE);                    //使能串口1 
	usart1_dma_tx_init();
	usart1_dma_rx_init();	
}


static void usart1_dma_tx_init(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel4);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)usart1_tx_buff;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 0;/*避免初始化发送数据,设置为0*/
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(DMA1_Channel4, ENABLE);
}
// 用于通过DMA传输数据到USART1的发送寄存器
uint8_t usart1_dma_tx_data(void* buffer, uint16_t data_lenth)
{
	if(data_lenth < 1)// 判断长度是否有效
	{
		return ERROR;
	}
	
	while (DMA_GetCurrDataCounter(DMA1_Channel4));// 检查DMA发送通道内是否还有数据
	if(NULL == buffer)//指针判空
	{
		return ERROR;
	}
	
	USART1_state.txc = RESET; // 表示发送未完成。
	// 使用memcpy函数将buffer中的数据复制到usart1_tx_buff中。
	// 复制的长度为data_lenth和USART1_TX_BUFF_MAX_LENTH中较小的值。这是为了防止数据溢出。
	memcpy(usart1_tx_buff, buffer,((data_lenth > USART1_TX_BUFF_MAX_LENTH) ? USART1_TX_BUFF_MAX_LENTH:data_lenth));
	
    DMA_Cmd(DMA1_Channel4, DISABLE); //DMA发送数据-要先关 ,以确保设置发送长度之前DMA传输已经停止。
    DMA_SetCurrDataCounter(DMA1_Channel4, data_lenth);// 设置DMA1_Channel4的发送长度为data_lenth。
    DMA_Cmd(DMA1_Channel4, ENABLE);// 启用DMA1_Channel4,以启动DMA传输
	
	return SUCCESS;
}


static void usart1_dma_rx_init(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;           // 初始化外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)usart1_rx_buff;            // 缓存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                     // 外设作为数据来源
    DMA_InitStructure.DMA_BufferSize = USART1_RX_BUFF_MAX_LENTH;           // 缓存容量
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       // 外设地址不递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                // 内存递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 外设字节宽度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;        // 内存字节宽度
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;						   // 正常模式,即满了就不在接收了,而不是循环存储
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                    // 优先级很高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                           // 内存与外设通信,而非内存到内存
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
    DMA_Cmd(DMA1_Channel5, ENABLE);
}

void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)/*空闲中断接收*/
    {
        u8 data_lenth = 0 ;
		
        DMA_Cmd(DMA1_Channel5, DISABLE);// 关闭DMA ,防止干扰
				USART_ReceiveData( USART1 );
		
        data_lenth = USART1_RX_BUFF_MAX_LENTH - DMA_GetCurrDataCounter(DMA1_Channel5);//获得接收到的字节数
        DMA_SetCurrDataCounter(DMA1_Channel5, USART1_RX_BUFF_MAX_LENTH);//  重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
        DMA_Cmd(DMA1_Channel5, ENABLE);
				USART1_state.rxc = SET;  //设置接收完成标志
		
				my_usmart_scan(usart1_rx_buff,data_lenth); //配置自己的接收处理函数//执行usmart扫描	
		
        memset(usart1_rx_buff, 0, USART1_RX_BUFF_MAX_LENTH); //清空接收缓存区		 
				USART_ClearITPendingBit(USART1, USART_IT_IDLE); // Clear IDLE interrupt flag bit
    }
		if(USART_GetITStatus(USART1,USART_IT_TC) != RESET)  //发送完成标记
		{
			DMA_Cmd(DMA1_Channel4, DISABLE);                // 关闭DMA
			DMA_SetCurrDataCounter(DMA1_Channel4,RESET);    // 清除数据长度
			USART1_state.txc = SET;                         // 设置发送完成标志
			USART_ClearITPendingBit(USART1, USART_IT_TC);   // 清除完成标记
		}	
}
	 
///********************************************************
//Function:   void my_usmart_scan(uint8_t * data_array,uint8_t data_lenth)
//Description:处理接收数据
//Input:
//Output:
//Others:
//*********************************************************/
void my_usmart_scan(uint8_t * data_array,uint8_t data_lenth)
{
	if(SET == USART1_state.rxc)//串口接收完成标志位
	{					   
			if(data_array[0] == 0x2D && data_array[1] == 0x01 && data_array[5] == 0x56 && data_array[6] == 0x78) // 判断帧头是否正确、判断奇偶校验位是否正确 || USART_RX_BUF[1] == check_flag
			{
				float value = 0;
				int16_t sign = 1;
					if(data_array[2] == 0x45)
					{
						sign = -1;
					}
					value = (data_array[4] << 8) + data_array[3];	
					action = sign * value;
		}																			
		USART1_state.rxc = RESET;//状态寄存器清空	    
	}	
}	 
	 
相关推荐
广州灵眸科技有限公司7 小时前
瑞芯微(EASY EAI)RV1126B CAN使用
linux·网络·单片机·嵌入式硬件
SmartRadio7 小时前
CH584M vs nRF52840 vs 主流BLE SoC全面对比
单片机·嵌入式硬件·mcu·物联网·开源·硬件工程
在屏幕前出油7 小时前
二、Python面向对象编程基础——理解self
开发语言·python
阿方索8 小时前
python文件与数据格式化
开发语言·python
信创天地10 小时前
信创国产化数据库的厂商有哪些?分别用在哪个领域?
数据库·python·网络安全·系统架构·系统安全·运维开发
不哦罗密经10 小时前
python相关
服务器·前端·python
happybasic10 小时前
python字典中字段重复性的分析~~
开发语言·python
山海青风10 小时前
人工智能基础与应用 - 数据处理、建模与预测流程 6 模型训练
人工智能·python·机器学习
l木本I10 小时前
Reinforcement Learning for VLA(强化学习+VLA)
c++·人工智能·python·机器学习·机器人
颖风船10 小时前
锂电池SOC估计的一种算法(改进无迹卡尔曼滤波)
python·算法·信号处理