先将cubemx配置好端口
千万不要马虎,特别是对自己不熟悉的板子 一定要检查tx rx接口是否和板子外接的串口对应上了
在使用H723VGT6时
开启串口 并开启中断后
cube上默认的是PB14 PB15 端口
而与板子相连的是PA9 PA19 口
***********************************************************************************************接下来就是编写函数了
main.c
uint8_t Res,buf,flag=0;
HAL_UART_Receive_IT(&huart1, &Res, 1); 用于开启中断
//重写回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
buf=Res;
HAL_UART_Transmit(&huart1,(uint8_t*)&buf,1, 1000);
if(buf == '1')
{
flag = 1;
}
else if(buf == '2')
{
flag = 2;
}
// 等待下一次接收中断
HAL_UART_Receive_IT(&huart1, &Res, 1);
}
}
问题:HAL_UART_Transmit(&huart1,&Res,1, 1000);
传参错误
指针变成了野指针
程序死机
把一级指针当作二级指针使用
需要在回调里面用buf就行转存
Res会被冲掉
接下来在由上位机传过来的参数是{300|500}
需要给中间两个数字取出来
传到另外的函数中
还有需要注意 这两个数字的大小是在 -1000~1000
uint8_t 是0~255
int8_t 是 -128 到 127
uint16_t
是 C/C++ 中的无符号 16 位整数类型,范围是从 0 到 65535(
2
16
−
1
2^{16} - 1
216−1)。这意味着它可以表示的整数范围是从 0 到 65535,包括这两个端点值。
int16_t
是 C/C++ 中的有符号 16 位整数类型,范围是从 -32768 到 32767。
control.h
#ifndef __CINTROL_H
#define __CINTROL_H
#include "main.h"
#include "usart.h"
#include "stdlib.h"
#endif
control.c
#include "control.h"
uint8_t buf[256];
uint8_t idx=0,start=0,end=0;
extern uint8_t Res;
extern int16_t speed,angula;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
if(Res=='{')
start=1;
else if(Res=='}')
{
start=0;
end=1;
}
if(start==1)
{
buf[idx++]=Res;
}
if(end==1)
{
char *p;
p=(char *)&buf[0];
p=p+1;
angula = atoi((char*)p);
p=strchr((char*)buf,'|');
speed=atoi(p+1);
idx=0;
end=0;
printf("angula:%d\n",angula);
printf("speed:%d\n",speed);
memset(buf,0,256);
}
// 等待下一次接收中断
HAL_UART_Receive_IT(&huart1, &Res, 1);
}
}
当串口未接收到数据时候 需要将flag置为0 但是串口在未接收到消息时候不进入 串口中断回调函数 不能直接在串口回调函数里面判断
#include "control.h"
char str[10];
uint8_t buf[256];
uint8_t idx=0,start=0,end=0;
extern int a;
extern uint32_t last_receive_time,no_data_timeout;
extern uint8_t Res,flag;
extern int16_t speed,angula;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
if(Res=='{')
{
start=1;
a=3;
}
else if(Res=='}')
{
start=0;
end=1;
}
if(start==1)
{
buf[idx++]=Res;
}
if(end==1)
{
char *p;
p=(char *)&buf[0];
p=p+1;
flag = atoi((char*)p);
p=strchr((char*)buf,'|');
speed=atoi(p+1);
idx=0;
end=0;
// printf("flag:%d\n",flag);
// printf("speed:%d\n",speed);
memset(buf,0,256);
last_receive_time = HAL_GetTick(); // 更新最后接收时间
}
// 等待下一次接收中断
HAL_UART_Receive_IT(&huart1, &Res, 1);
}
}
main.c
uint32_t last_receive_time = 0;
uint32_t no_data_timeout = 2000; // 设置没有接收到数据的超时时间,单位为毫秒
while (1)
{
if ((HAL_GetTick() - last_receive_time) > no_data_timeout)
{
flag = 0; // 如果超时没有接收到数据,将 flag 置为 0
}
数据处理这块给我干蒙了
还有个方法
给定时器定为100ms 然后 100ms 到了 检测标志量是否为1 标志量置为0
但是只要串口中断在接收 标志量就会被置为1 就可以避免 标志量一直为1 然后只要标志量为0 就停
将发送给串口3的数据存储在数组中
#define MAX_RX_BUFFER_SIZE 100 // 定义最大接收缓冲区大小,根据实际需要调整
uint8_t rxBuffer[MAX_RX_BUFFER_SIZE]; // 定义接收数据的数组
uint32_t rxBufferIdx = 0; // 定义接收数据的索引
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart3) // 假设是串口3的接收中断
{
rxBuffer[rxBufferIdx++] = huart->Instance->DR; // 将接收到的数据存入数组,并更新索引
if (rxBufferIdx >= MAX_RX_BUFFER_SIZE)
{
rxBufferIdx = 0; // 如果超过了数组大小,可以选择重置索引或者其他处理方式
}
HAL_UART_Transmit(&huart3, &rxBuffer[rxBufferIdx - 1], 1, 1000); // 发送刚接收到的单个字节
HAL_UART_Receive_IT(&huart3, &rxBuffer[rxBufferIdx], 1); // 重新启动接收
}
}
问题分析和解决方案:
发送数据问题:
在 HAL_UART_Transmit(&huart3, (uint8_t*)&rxBuffer, 1, 1000); 这行代码中,你发送了 rxBuffer 数组的内容,而不是实际接收到的数据。
rxBuffer 是一个数组,你发送的是数组的地址,而不是单个接收到的字节。这会导致上位机接收到的数据可能不是你预期的内容。
解决方案:
如果你想要发送刚接收到的单个字节,应该发送 rxBuffer[rxBufferIdx - 1],因为 rxBufferIdx 在存储完数据后已经自增了。
修改为 HAL_UART_Transmit(&huart3, &rxBuffer[rxBufferIdx - 1], 1, 1000); 这样可以发送刚接收到的单个字节。
我发送数据的格式改为{X20,Y-30}
#include "uart_control.h"
uint8_t buf[256];
uint8_t idx=0,start=0,end=0;
extern uint8_t Res;
extern int16_t x_speed,y_speed;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart3)
{
if(Res=='{')
start=1;
else if(Res=='}')
{
start=0;
end=1;
}
if(start==1)
{
buf[idx++]=Res;
}
else if (end == 1)
{
buf[idx] = '\0'; // Null-terminate the string
char *p = strstr((char*)buf, "X");
if (p != NULL)
{
p += 1; // Skip 'X'
char *endptr;
x_speed = (int16_t)strtol(p, &endptr, 10);
p = strstr((char*)buf, "Y");
if (p != NULL)
{
p += 1; // Skip 'Y'
y_speed = (int16_t)strtol(p, &endptr, 10);
}
}
idx = 0;
end = 0;
memset(buf, 0, sizeof(buf));
}
// 等待下一次接收中断
HAL_UART_Receive_IT(&huart3, &Res, 1);
}
}
#ifndef UART__CONTROL_H
#define UART__CONTROL_H
#include "main.h"
#include "usart.h"
#include "stdlib.h"
#include "string.h"
#endif