一个菜鸟的改错(真的很菜,纯记录一下,大佬就别看了,会影响心情)

本人菜鸟,在编译main.c文件时发现报了四个错

先贴出原始程序和报错

main.c(12): error:  #65: expected a ";"

main.c(38): warning: At end of source:  #12-D: parsing restarts here after previous syntax error

main.c(38): error: At end of source:  #130: expected a "{"

main.c(38): error: At end of source:  #67: expected a "}"

main.c: 1 warning, 4 errors

#include "stm32f10x.h"                  // Device header

#include "delay.h"//使用延时函数

#include "timer.h"

void LED0_Init()



int main(void)
{
	
//	OLED_Init();
	
	LED0_Init();

	Timer_Init();
	
	while(1)
	{
//	   GPIO_ResetBits(GPIOA,GPIO_Pin_0);//亮
	};
}

void LED0_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
//	GPIO_SetBits(GPIOA,GPIO_Pin_0);
	
}

在参考了别的文章中大佬的建议后查了别的文件,都没有漏并且很正常,我就想可能是不是就是main文件自己的问题,然后,在我改掉开头的声明后(只加了一个;)报错就只有一个了

void LED0_Init();

贴出此时的报错(warning因为个人原因有俩,不过另一个是没空行,很好解决)

main.c(28): error:  #268: declaration may not appear after executable statement in block

      GPIO_InitTypeDef GPIO_InitStructure;

main.c(7): warning:  #1295-D: Deprecated declaration LED0_Init - give arg types

这件事告诉我,可能并不是其他文件的原因,可能原因就在本文件内,当然,本人C语言学艺不精,后知后觉,想起来可能是函数声明的问题,所列的warning在括号内补充void后消失了

贴出改好的main.c,此main文件并未使用C99mode,这和我看到大佬的示例有一定差别,但,不使用C99mode也避免了在原文下出现的换用C99mode报错的可能

#include "stm32f10x.h"                  // Device header

#include "delay.h"//使用延时函数

#include "timer.h"

void LED0_Init(void);

int main(void)
{
	
//	OLED_Init();
	
	LED0_Init();

	Timer_Init();
	
	while(1)
	{
//	   GPIO_ResetBits(GPIOA,GPIO_Pin_0);//亮
	};
}

void LED0_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
//	GPIO_SetBits(GPIOA,GPIO_Pin_0);
	
}

总结:可以不使用C99mode,但要在开头声明函数(记得加;),可以把函数放在末尾

要对这段代码进行改错和优化,我们可以关注以下几个方面: ### 1. **异常处理** - 当前代码在 `Start()` 方法中的异常处理只捕获了串口初始化时的异常,但在 `ReadSerialPortAsync` 中也有潜在的异常(如串口关闭或Modbus通信失败)。虽然已经有一个 `try-catch` 块,但可以进一步改进以确保程序不会因为未处理的异常而崩溃。 ### 2. **资源管理** - 在 `OnApplicationQuit()` 中,应该先关闭 `serialPort` 再释放 `master`,否则可能会导致资源泄露或未定义行为。 ### 3. **异步操作的安全性** - `ReadSerialPortAsync` 是一个无限循环的任务,当应用退出时应确保它能够正确终止。可以通过设置 `CancellationToken` 来实现更安全的取消机制。 ### 4. **数据更新的同步** - 目前使用了 `MainThreadDispatcher` 来确保 UI 更新在主线程中执行,这很好。但是,为了提高性能,可以减少不必要的委托调用次数。 ### 5. **代码简化与可维护性** - 可以将一些重复的代码提取成独立的方法,比如图表初始化部分。 以下是改进建议的具体实现: ```csharp using UnityEngine; using UnityEngine.UI; using Modbus.Device; using System.IO.Ports; using System; using System.Threading; using System.Threading.Tasks; public class ModbusRTUController : MonoBehaviour { [Header("Modbus串口配置")] public string portName = "COM3"; public int baudRate = 9600; public byte slaveId = 1; [Header("数据显示")] public Text temperatureText; public Text humidityText; public Text displacementText; [Header("模型控制")] public GameObject model; private float moveSpeed = 1.0f; [Header("折线图配置")] public int maxDataPoints = 50; public float chartHeight = 200f; public LineRenderer temperatureLine; public LineRenderer humidityLine; public LineRenderer displacementLine; public RectTransform chartBackground; private SerialPort serialPort; private ModbusSerialMaster master; private Queue<float> tempData = new Queue<float>(); private Queue<float> humiData = new Queue<float>(); private Queue<float> dispData = new Queue<float>(); private CancellationTokenSource cancellationTokenSource; async void Start() { try { serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); serialPort.Open(); master = ModbusSerialMaster.CreateRtu(serialPort); InitializeCharts(); cancellationTokenSource = new CancellationTokenSource(); await Task.Run(() => ReadSerialPortAsync(cancellationTokenSource.Token)); } catch (Exception ex) { Debug.LogError("串口初始化失败: " + ex.Message); } } void InitializeCharts() { InitializeChart(temperatureLine, Color.red); InitializeChart(humidityLine, Color.blue); InitializeChart(displacementLine, Color.green); } void InitializeChart(LineRenderer line, Color color) { line.positionCount = 0; line.startWidth = 2f; line.endWidth = 2f; line.material = new Material(Shader.Find("Sprites/Default")); line.startColor = color; line.endColor = color; } async Task ReadSerialPortAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested && master != null && serialPort.IsOpen) { try { ushort[] registers = await Task.Run(() => master.ReadHoldingRegisters(slaveId, 0x00, 4), cancellationToken); MainThreadDispatcher.Instance().Enqueue(() => { UpdateUIAndControlModel(registers[0], registers[1], registers[2], registers[3]); RecordData(registers[0], registers[1], registers[2]); UpdateChart(); }); await Task.Delay(100, cancellationToken); // 根据需要调整读取间隔 } catch (OperationCanceledException) { break; // 正常取消任务 } catch (Exception ex) { Debug.LogError("Modbus通信错误: " + ex.Message); } } } void UpdateUIAndControlModel(ushort temperature, ushort humidity, ushort displacement, ushort command) { temperatureText.text = $"温度: {temperature}"; humidityText.text = $"湿度: {humidity}"; displacementText.text = $"位移: {displacement}"; if (command == 1) { model.transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime); } else if (command == 2) { model.transform.Translate(Vector3.back * moveSpeed * Time.deltaTime); } } void RecordData(float temperature, float humidity, float displacement) { EnqueueWithMax(tempData, temperature, maxDataPoints); EnqueueWithMax(humiData, humidity, maxDataPoints); EnqueueWithMax(dispData, displacement, maxDataPoints); } void EnqueueWithMax(Queue<float> queue, float value, int maxSize) { if (queue.Count >= maxSize) queue.Dequeue(); queue.Enqueue(value); } void UpdateChart() { UpdateLine(temperatureLine, tempData); UpdateLine(humidityLine, humiData); UpdateLine(displacementLine, dispData); } void UpdateLine(LineRenderer line, Queue<float> data) { if (data.Count < 2) return; Vector3[] positions = new Vector3[data.Count]; float stepX = chartBackground.rect.width / maxDataPoints; int index = 0; foreach (var value in data) { float xPos = index * stepX; float yPos = (value / 100f) * chartHeight; positions[index] = new Vector3(xPos, yPos, 0); index++; } line.positionCount = data.Count; line.SetPositions(positions); line.transform.localPosition = chartBackground.localPosition; } private void OnApplicationQuit() { cancellationTokenSource?.Cancel(); if (master != null) { master.Dispose(); } if (serialPort != null && serialPort.IsOpen) { serialPort.Close(); } } } ``` ### 主要改动点: 1. **增加了 `CancellationTokenSource`**:用于安全地取消 `ReadSerialPortAsync` 异步任务。 2. **优化了 `UpdateUIAndControlModel` 和 `RecordData` 方法**:减少了不必要的 `MainThreadDispatcher` 调用,并将队列管理逻辑提取到单独的方法中。 3. **改进了资源管理顺序**:确保在 `OnApplicationQuit` 中先取消任务再关闭串口和释放资源。 4. **增强了异常处理**:确保所有可能抛出异常的地方都得到妥善处理。 通过以上改进,代码变得更加健壮、易于维护且性能更好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值