c语言编译c141,单片机C语言错误C141:syntax error near 'void'请大家帮忙看下程序,谢谢...

这篇博客主要展示了如何使用C语言进行单片机编程,包括时间初始化、延迟函数、显示函数以及AD转换。在AD转换过程中,通过P3口的信号控制,读取P0口的数据并进行温度计算,将结果显示在显示器上。遇到的错误C141: syntax error near 'void'可能是语法错误,需检查void关键字的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include

#include "intrins.h"      //调用_nop_();延时函数用

unsigned char code dispbitcode[]=

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

unsigned char dispbuf[4];

unsigned char getdata;

unsigned int temp;

sbit ST=P3^0;

sbit OE=P3^1;

sbit EOC=P3^2;

sbit CLK=P3^3;

sbit ALE=P3^7;

sbit P34=P3^4;

sbit P35=P3^5;

sbit P36=P3^6;

sbit P20=P2^0;

sbit P21=P2^1;

sbit P22=P2^2;

sbit P23=P2^3;

sbit P17=P1^7;

sbit P26=P2^6;

sbit P27=P2^7;

void TimeInitial();

void Delay(unsigned int i);

void TimeInitial()

{ TMOD=0x01;

TH0=(65536-200)/256;

TL0=(65536-200)%256;

EA=1;

ET0=1;

TR0=1;

}

void Delay(unsigned int i)

{

unsigned int j;

for(;i>0;i--)

{

for(j=0;j<100;j++)

{;}

}

}

void Display()

{

P1=dispbitcode[dispbuf[3]];

P20=0;

P21=1;

P22=1;

P23=1;

Delay(10);//避免闪烁

P1=0x00;  //关闭一下,否则显示不全

P1=dispbitcode[dispbuf[2]];

P17=1;

P20=1;

P21=0;

P22=1;

P23=1;

Delay(10);

P1=0x00;

P1=dispbitcode[dispbuf[1]];

P20=1;

P21=1;

P22=0;

P23=1;

Delay(10);

P1=0x00;

P1=dispbitcode[dispbuf[0]];

P20=1;

P21=1;

P22=1;

P23=0;

Delay(10);

P1=0x00;

}

void adzhuanh()

{P34=0;        //地址通道

P35=0;

P36=0;

ALE=1;

_nop_();

_nop_();

ALE=0;

ST=1;

_nop_();

_nop_();

ST=0;

_nop_();

_nop_();

_nop_();

_nop_();

while(EOC==0);

OE=1;

getdata=P0;

OE=0;/*

temp=getdata*1.0/255*500;*/temp=getdata*200.0/255.0*12.0;

if (temp>1800)

{_nop_();

_nop_();

_nop_();

_nop_();

P26=1;

P27=0;

dispbuf[0]=temp/2%10;

dispbuf[1]=temp/20%10;

dispbuf[2]=temp/200%10;

dispbuf[3]=temp/2000;

}

void main()

{

TimeInitial();

while(1)

{adzhuanh();

Display(); }

else

{_nop_();

_nop_();

_nop_();

_nop_();

P27=1;

P26=0;

dispbuf[0]=temp/2%10;

dispbuf[1]=temp/20%10;

dispbuf[2]=temp/200%10;

dispbuf[3]=temp/2000;

Display();}

}

}

void t0(void) interrupt 1 using 0

{

TH0=(65536-200)/256;

TL0=(65536-200)%256;

CLK=~CLK;

}

<think>根据您提供的错误信息,错误发生在Fingerprint.h的第38行,错误类型是C141,表示在逗号附近有语法错误编译器期望看到标识符(identifier)。这种错误通常发生在函数指针声明中,尤其是在C89环境下,因为C89对函数指针的声明要求比较严格。 让我们检查Fingerprint.h的第38行(即函数指针声明行): ```c typedef void (*fp_callback_t)(u8 status, u16 id); ``` 在C89中,函数指针声明是允许的,但是需要注意: 1. 参数类型必须是已知的类型(即已经定义的类型) 2. 如果参数是自定义类型(如u8, u16),则必须确保这些类型在声明之前已经定义 由于您已经包含了`type_def.h`,并且其中定义了`u8`和`u16`,所以问题可能出在: - `type_def.h`没有被正确包含到`Fingerprint.h`中 - 编译器在处理函数指针声明时对参数类型有特殊要求 ### 解决方案: #### 1. 确保类型定义可见 在`Fingerprint.h`中,确保在函数指针声明之前包含了`type_def.h`。由于您已经通过包含`STC8G_H_GPIO.h`间接包含了`type_def.h`,但为了确保万无一失,可以在`Fingerprint.h`中显式包含`type_def.h`。 修改`Fingerprint.h`开头: ```c #ifndef _ZW101_H_ #define _ZW101_H_ /* 显式包含类型定义 */ #include "type_def.h" /* 包含其他必要头文件 */ #include "STC8G_H_GPIO.h" #include "STC8G_H_UART.h" #include "STC8G_H_Switch.h" #include "STC8G_H_NVIC.h" #include "STC8G_H_Delay.h" /* ... 其余代码 ... */ ``` #### 2. 检查类型定义冲突 检查`type_def.h`中是否有重复定义或定义错误。确保`u8`和`u16`是标准无符号类型。 #### 3. 使用完整类型名 如果问题仍然存在,尝试使用完整的底层类型代替`u8`和`u16`(仅用于测试): ```c typedef void (*fp_callback_t)(unsigned char status, unsigned int id); ``` 如果这样修改后错误消失,说明是`u8`和`u16`的可见性问题。 #### 4. 检查编译器兼容性 某些老旧的C89编译器可能不支持在函数指针声明中使用自定义类型别名。如果上述方法无效,可以尝试使用`typedef`定义新的单字节和双字节类型,并在函数指针中使用这些新类型。 在`type_def.h`中: ```c typedef unsigned char BYTE; typedef unsigned int WORD; ``` 在`Fingerprint.h`中: ```c typedef void (*fp_callback_t)(BYTE status, WORD id); ``` ### 修改后的Fingerprint.h(完整示例) ```c #ifndef _ZW101_H_ #define _ZW101_H_ /* 显式包含类型定义 */ #include "type_def.h" /* 包含其他必要头文件 */ #include "STC8G_H_GPIO.h" #include "STC8G_H_UART.h" #include "STC8G_H_Switch.h" #include "STC8G_H_NVIC.h" #include "STC8G_H_Delay.h" /* 操作模式定义 */ #define FP_MODE_IDLE 0 /* 空闲模式 */ #define FP_MODE_CHECK 1 /* 指纹验证模式 */ #define FP_MODE_ENROLL 2 /* 指纹录入模式 */ #define FP_MODE_SLEEP 3 /* 休眠模式 */ /* 协议定义 */ #define FP_SYNO_FIRST_HEAD 0xEF /* 包头第一字节 */ #define FP_SYNO_SECOND_HEAD 0x01 /* 包头第二字节 */ #define FP_SYNO_CMD_PKG 0x01 /* 命令包标识 */ #define FP_SYNO_DATA_PKG 0x02 /* 数据包 */ #define FP_SYNO_EOF_PKG 0x08 /* 结束包 */ #define GET_ARRAY_LEN(arr) (sizeof(arr)/sizeof((arr)[0])) /* 计算数组长度 */ /* 定义函数指针类型 */ typedef void (*fp_callback_t)(u8 status, u16 id); /* 函数声明 */ void ZW101_init(void); void ZW101_set_mode(u8 mode); u8 ZW101_is_busy(void); void ZW101_receive_data(void); void ZW101_sleep(void); void ZW101_wakeup(void); void ZW101_start_enroll(u16 id); void ZW101_start_check(void); void ZW101_set_callback(fp_callback_t callback); void ZW101_process_response(u8 *data, u8 len); #endif ``` ### 如果问题依旧存在 如果上述修改后仍然报错,检查: - 头文件保护宏是否冲突(例如`_ZW101_H_`是否在其他地方被定义) - 编译器是否支持在函数指针参数中使用`typedef`定义的类型 - 是否有其他编译器特定的限制(查阅编译器手册) ### 替代方案:使用void指针(不推荐) 如果所有方法都失败,可以考虑使用`void*`来传递参数,然后在回调函数中强制转换。但这会降低代码可读性和安全性。 ```c typedef void (*fp_callback_t)(void *status, void *id); /* 使用示例 */ void my_callback(void *status, void *id) { u8 s = *(u8*)status; u16 i = *(u16*)id; /* ... */ } ``` ### 最终建议 1. **简化函数指针**:如果可能,将参数简化为基本类型(如int)以避免类型问题 2. **升级编译器**:考虑使用支持C99的编译器,以获得更好的类型支持 §§相关问题§§: 1. 在C89标准下,函数指针的声明和使用有哪些限制? 2. 如何确保头文件中的类型定义在多个文件中可见且一致? 3. 在嵌入式系统中,使用函数指针回调机制有哪些优缺点? 4. 如何处理不同编译器对C标准的兼容性问题?</think>感谢您提供详细的错误信息。错误发生在 `Fingerprint.h` 的第 38 行,具体是函数指针类型定义处。让我们深入分析并解决这个问题。 ### 错误分析:`Fingerprint.h(38): error C141: syntax error near ',', expected '<id>'` 这个错误通常发生在以下情况: 1. **函数指针声明语法错误**:C89 对函数指针声明有严格的要求 2. **类型定义问题**:`u8` 和 `u16` 类型可能未被正确定义或可见 3. **编译器限制**:某些 C89 编译器对函数指针声明有特殊要求 ### 解决方案: #### 1. 修改函数指针声明(首选方案) ```c /* Fingerprint.h */ #ifndef _ZW101_H_ #define _ZW101_H_ #include "STC8G_H_GPIO.h" // 确保包含 type_def.h /* ... 其他定义 ... */ /* 修正函数指针声明 */ typedef void (*fp_callback_t)(unsigned char status, unsigned int id); /* ... 其余代码 ... */ #endif ``` **解释**: - 直接使用基本类型 `unsigned char` 和 `unsigned int` 替代 `u8` 和 `u16` - 避免依赖自定义类型的可见性问题 - C89 编译器对基本类型的支持最可靠 #### 2. 确保类型定义可见(替代方案) 如果必须使用 `u8`/`u16`,确保在函数指针声明前正确定义: ```c /* Fingerprint.h */ #ifndef _ZW101_H_ #define _ZW101_H_ /* 显式包含类型定义 */ #include "type_def.h" /* 确保类型已定义 */ #ifndef u8 typedef unsigned char u8; #endif #ifndef u16 typedef unsigned int u16; #endif /* ... 其他定义 ... */ /* 函数指针声明 */ typedef void (*fp_callback_t)(u8 status, u16 id); /* ... 其余代码 ... */ #endif ``` #### 3. 完整的修正版 `Fingerprint.h` ```c #ifndef _ZW101_H_ #define _ZW101_H_ /* 显式包含所有依赖 */ #include "type_def.h" // 直接包含类型定义 #include "STC8G_H_GPIO.h" #include "STC8G_H_UART.h" #include "STC8G_H_Switch.h" #include "STC8G_H_NVIC.h" #include "STC8G_H_Delay.h" /* 操作模式定义 */ #define FP_MODE_IDLE 0 /* 空闲模式 */ #define FP_MODE_CHECK 1 /* 指纹验证模式 */ #define FP_MODE_ENROLL 2 /* 指纹录入模式 */ #define FP_MODE_SLEEP 3 /* 休眠模式 */ /* 协议定义 */ #define FP_SYNO_FIRST_HEAD 0xEF /* 包头第一字节 */ #define FP_SYNO_SECOND_HEAD 0x01 /* 包头第二字节 */ #define FP_SYNO_CMD_PKG 0x01 /* 命令包标识 */ #define FP_SYNO_DATA_PKG 0x02 /* 数据包 */ #define FP_SYNO_EOF_PKG 0x08 /* 结束包 */ #define GET_ARRAY_LEN(arr) (sizeof(arr)/sizeof((arr)[0])) /* 计算数组长度 */ /* 定义函数指针类型 - 使用基本类型确保兼容性 */ typedef void (*fp_callback_t)(unsigned char status, unsigned int id); /* 函数声明 */ void ZW101_init(void); void ZW101_set_mode(unsigned char mode); unsigned char ZW101_is_busy(void); void ZW101_receive_data(void); void ZW101_sleep(void); void ZW101_wakeup(void); void ZW101_start_enroll(unsigned int id); void ZW101_start_check(void); void ZW101_set_callback(fp_callback_t callback); void ZW101_process_response(unsigned char *data, unsigned char len); #endif ``` ### 在 `Fingerprint.c` 中的对应修改 ```c /* Fingerprint.c */ #include "Fingerprint.h" /* ... 其他代码 ... */ /* 修改回调函数实现 */ static fp_callback_t user_callback = NULL; void ZW101_set_callback(fp_callback_t callback) { /* 设置结果回调函数 */ user_callback = callback; } /* 修改函数参数类型 */ void ZW101_process_response(unsigned char *data, unsigned char len) { /* 处理模块响应 */ unsigned char cmd; unsigned char param; unsigned int fid; /* ... 其余代码保持不变 ... */ } /* 修改其他函数声明 */ void ZW101_start_enroll(unsigned int id) { /* 开始指纹录入 */ enroll_id = id; /* ... */ } ``` ### 关键修改点解释: 1. **函数指针声明修正**: ```c // 错误声明(可能导致C141错误) typedef void (*fp_callback_t)(u8 status, u16 id); // 修正声明(使用基本类型) typedef void (*fp_callback_t)(unsigned char status, unsigned int id); ``` 2. **类型定义可见性**: - 在 `Fingerprint.h` 开头直接包含 `type_def.h` - 添加类型保护宏,确保 `u8`/`u16` 始终有定义 3. **函数声明一致性**: - 所有函数声明使用完整类型(`unsigned char` 代替 `u8`) - 保持头文件和实现文件的类型声明一致 4. **C89兼容性增强**: - 避免在函数指针中使用 typedef 定义的类型 - 使用编译器最基础支持的类型 ### 进一步诊断建议: 如果问题仍然存在,尝试: 1. **简化测试**: ```c /* test.h */ typedef void (*test_cb)(unsigned char a, unsigned int b); ``` 单独编译此文件,检查是否报错 2. **编译器选项检查**: ```makefile CFLAGS += -E -dD # 查看预处理结果 ``` 3. **隐藏字符检查**: - 使用十六进制编辑器查看第38行 - 检查是否有不可见的UTF-8 BOM或特殊字符 4. **类型大小验证**: ```c /* 在type_def.h中添加静态断言 */ typedef char u8_size_assert[sizeof(u8) == 1 ? 1 : -1]; typedef char u16_size_assert[sizeof(u16) == 2 ? 1 : -1]; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值