活动介绍

我在另一个.h文件中#define a 0x0B,我现在需要在另一个文件.c文件中使用a,我该如何配置

时间: 2025-07-19 22:27:36 浏览: 14
<think>我们正在处理一个关于C语言宏定义使用的问题。用户想知道如何在C文件中使用在另一个头文件中通过#define定义的宏。 根据引用[1]和引用[3],我们知道宏定义是在预处理阶段进行替换的,并且头文件可以通过#include指令包含到C文件中。 因此,步骤应该是: 1. 在头文件中使用#define定义宏。 2. 在需要使用该宏的C文件中,使用#include指令包含该头文件。 3. 然后在该C文件中就可以直接使用宏名,预处理器会在编译前将宏名替换为定义的字符串。 另外,为了防止头文件被重复包含,我们通常会在头文件中使用条件编译(如引用[2]和引用[3]中提到的#ifndef...#define...#endif)。 下面我们给出一个示例: 假设我们有一个头文件叫做"my_macros.h",在该头文件中我们定义了一个宏: ```c // my_macros.h #ifndef MY_MACROS_H // 防止重复包含 #define MY_MACROS_H #define PI 3.14159 #define SQUARE(x) ((x)*(x)) #endif ``` 然后在一个C文件(例如main.c)中,我们可以这样使用: ```c // main.c #include <stdio.h> #include "my_macros.h" // 包含自定义宏的头文件 int main() { double radius = 5.0; double area = PI * SQUARE(radius); printf("圆的面积: %f\n", area); return 0; } ``` 这样,在预处理阶段,预处理器会将main.c中的PI替换为3.14159,将SQUARE(radius)替换为((radius)*(radius))。 注意:包含头文件时,使用尖括号<>通常用于系统头文件,而使用双引号""用于用户自定义的头文件(引用[3])。 另外,引用[4]提到了IAR扩展关键字__no_init,但用户的问题并不涉及特定编译器的扩展,所以我们不需要特别关注。 因此,总结如下: 1. 在头文件中定义宏(使用#define)。 2. 在C文件中通过#include包含该头文件。 3. 在C文件中直接使用宏。 但是,我们需要注意宏的作用域:从定义的位置开始,直到文件结束,或者遇到#undef(引用[3])。所以只要在头文件中定义且被包含后,在包含之后的代码中都可以使用。 同时,为了避免重复定义,头文件保护(条件编译)是必要的。 现在,根据要求生成相关问题。</think>### 如何在C文件中使用头文件中定义的宏 在C语言中,使用另一个头文件中通过`#define`定义的宏需要遵循以下步骤: 1. **在头文件中定义宏** 在`.h`文件中使用`#define`声明宏,并添加头文件保护防止重复包含: ```c // config.h #ifndef CONFIG_H // 头文件保护 #define CONFIG_H #define MAX_SIZE 100 // 定义常量宏 #define SQUARE(x) ((x)*(x)) // 定义函数式宏 #endif ``` 2. **在C文件中包含头文件** 通过`#include`指令将头文件包含到需要使用的`.c`文件中: ```c // main.c #include "config.h" // 包含自定义头文件 #include <stdio.h> // 包含系统头文件 ``` 3. **直接使用宏** 包含头文件后,宏可在当前文件中直接使用: ```c int main() { int arr[MAX_SIZE]; // 使用常量宏 int result = SQUARE(5); // 使用函数式宏 printf("结果: %d", result); return 0; } ``` #### 关键注意事项 1. **路径问题** - 系统头文件:用`#include <xxx.h>`,编译器从标准库路径查找 - 自定义头文件:用`#include "xxx.h"`,优先从当前目录查找,未找到时再到系统路径查找[^3] 2. **宏作用域** - 宏从定义位置开始生效,直到文件结束或遇到`#undef` - 通过头文件包含的宏作用域覆盖整个`.c`文件 3. **重复包含防护** 必须使用`#ifndef...#define...#endif`结构防止多次包含同一头文件导致的宏重复定义错误[^2][^3] #### 示例场景 假设需要在`math_ops.c`中使用`constants.h`中定义的圆周率: ```c // constants.h #ifndef CONSTANTS_H #define CONSTANTS_H #define PI 3.1415926 #endif // math_ops.c #include "constants.h" double circle_area(double r) { return PI * r * r; // 直接使用头文件中的宏 } ``` > **重要**:宏是**预处理器指令**,在编译前进行文本替换。使用`gcc -E main.c`可查看预处理后的代码,观察宏展开结果[^1]。 --- ### 相关问题 1. **宏定义和普通变量有何本质区别?** [提示:从编译阶段、内存分配、类型检查等角度分析] 2. **函数式宏`#define MAX(a,b) ((a)>(b)?(a):(b))`可能存在什么风险?** [提示:考虑`MAX(i++, j++)`这类调用] 3. **如何避免头文件循环包含导致的编译错误?** [提示:结合`#ifndef`防护和头文件设计原则] 4. **`#include "file.h"`和`#include <file.h>`在编译查找路径上有何不同?** [提示:编译器搜索路径顺序的差异] 5. **为什么在头文件中通常只放函数声明而不放函数实现?** [提示:链接阶段的多重定义问题] [^1]: 宏定义在预处理阶段进行文本替换,不占用内存空间 [^2]: `#ifndef...#define...#endif`是防止头文件重复包含的标准方法 [^3]: 自定义头文件优先从当前目录查找,未找到时再到系统路径查找 [^4]: 特定编译器可能扩展宏功能(如IAR的`__no_init`),需查阅编译器文档
阅读全文

相关推荐

接前面的回复,定制版PG12的sm3算法本身和pgbouncer 里添加的sm3的内容一致。pgbouncer 需根据情况做了一些调整。 定制版PG12的sm3算法为: #define GETU32(p) ((uint32)(p)[0]<<24|(uint32)(p)[1]<<16|(uint32)(p)[2]<<8|(uint32)(p)[3]) #define PUT32(p,v) ((p)[0]=(uint8)((v)>>24),(p)[1]=(uint8)((v)>>16),(p)[2]=(uint8)((v)>>8),(p)[3]=(uint8)(v)) /* 32bit data rotate left n bit */ #define ROL32(a,n) (((a)<<(n)) | (((a)&0xffffffff)>>(32-(n)))) /* base on SM3 Algorithm's function definition */ #define FF00(x,y,z) ((x) ^ (y) ^ (z)) #define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define GG00(x,y,z) ((x) ^ (y) ^ (z)) #define GG16(x,y,z) (((x)&(y)) | ((~x)&(z))) #define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) #define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) /* constant quantity */ #define T00 0x79cc4519U #define T16 0x7a879d8aU #define K0 0x79cc4519U #define K1 0xf3988a32U #define K2 0xe7311465U #define K3 0xce6228cbU #define K4 0x9cc45197U #define K5 0x3988a32fU #define K6 0x7311465eU #define K7 0xe6228cbcU #define K8 0xcc451979U #define K9 0x988a32f3U #define K10 0x311465e7U #define K11 0x6228cbceU #define K12 0xc451979cU #define K13 0x88a32f39U #define K14 0x11465e73U #define K15 0x228cbce6U #define K16 0x9d8a7a87U #define K17 0x3b14f50fU #define K18 0x7629ea1eU #define K19 0xec53d43cU #define K20 0xd8a7a879U #define K21 0xb14f50f3U #define K22 0x629ea1e7U #define K23 0xc53d43ceU #define K24 0x8a7a879dU #define K25 0x14f50f3bU #define K26 0x29ea1e76U #define K27 0x53d43cecU #define K28 0xa7a879d8U #define K29 0x4f50f3b1U #define K30 0x9ea1e762U #define K31 0x3d43cec5U #define K32 0x7a879d8aU #define K33 0xf50f3b14U #define K34 0xea1e7629U #define K35 0xd43cec53U #define K36 0xa879d8a7U #define K37 0x50f3b14fU #define K38 0xa1e7629eU #define K39 0x43cec53dU #define K40 0x879d8a7aU #define K41 0x0f3b14f5U #define K42 0x1e7629eaU #define K43 0x3cec53d4U #define K44 0x79d8a7a8U #define K45 0xf3b14f50U #define K46 0xe7629ea1U #define K47 0xcec53d43U #define K48 0x9d8a7a87U #define K49 0x3b14f50fU #define K50 0x7629ea1eU #define K51 0xec53d43cU #define K52 0xd8a7a879U #define K53 0xb14f50f3U #define K54 0x629ea1e7U #define K55 0xc53d43ceU #define K56 0x8a7a879dU #define K57 0x14f50f3bU #define K58 0x29ea1e76U #define K59 0x53d43cecU #define K60 0xa7a879d8U #define K61 0x4f50f3b1U #define K62 0x9ea1e762U #define K63 0x3d43cec5U uint32 K[64] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K60, K61, K62, K63, }; static void sm3_init(sm3_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->digest[0] = 0x7380166F; ctx->digest[1] = 0x4914B2B9; ctx->digest[2] = 0x172442D7; ctx->digest[3] = 0xDA8A0600; ctx->digest[4] = 0xA96F30BC; ctx->digest[5] = 0x163138AA; ctx->digest[6] = 0xE38DEE4D; ctx->digest[7] = 0xB0FB0E4E; } static void sm3_compress_blocks(uint32_t digest[8], const unsigned char *data, size_t blocks) { uint32 A; uint32 B; uint32 C; uint32 D; uint32 E; uint32 F; uint32 G; uint32 H; uint32 W[68]; int j = 0; uint32 SS1, SS2, TT1, TT2; while (blocks--) { A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; F = digest[5]; G = digest[6]; H = digest[7]; for (j = 0; j < 16; j++) { W[j] = GETU32(data + j*4); } for (j = 16; j < 68; j++) { W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) ^ ROL32(W[j -13], 7) ^ W[j - 6]; } for (j = 0; j < 16; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG00(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } for (j = 16; j < 64; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG16(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } digest[0] ^= A; digest[1] ^= B; digest[2] ^= C; digest[3] ^= D; digest[4] ^= E; digest[5] ^= F; digest[6] ^= G; digest[7] ^= H; data += 64; } } static void sm3_compress(uint32_t digest[8], const unsigned char block[64]) { return sm3_compress_blocks(digest, block, 1); } static void sm3_final(sm3_ctx *ctx, unsigned char *digest) { int i; ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } PUTU32(ctx->block + 56, ctx->nblocks >> 23); PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < 8; i++) { PUTU32(digest + i*4, ctx->digest[i]); } } static void sm3_update(sm3_ctx *ctx, const unsigned char *data, size_t data_len) { size_t blocks; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (data_len < left) { memcpy(ctx->block + ctx->num, data, data_len); ctx->num += data_len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress_blocks(ctx->digest, ctx->block, 1); ctx->nblocks++; data += left; data_len -= left; } } blocks = data_len / SM3_BLOCK_SIZE; sm3_compress_blocks(ctx->digest, data, blocks); ctx->nblocks += blocks; data += SM3_BLOCK_SIZE * blocks; data_len -= SM3_BLOCK_SIZE * blocks; ctx->num = data_len; if (data_len) { memcpy(ctx->block, data, data_len); } } static void bytesToHex(uint8 b[32], char *s) { static const char *hex = "0123456789abcdef"; int q, w; for (q = 0, w = 0; q < 32; q++) { s[w++] = hex[(b[q] >> 4) & 0x0F]; s[w++] = hex[b[q] & 0x0F]; } s[w] = '\0'; } bool pg_sm3_hash(const void *buff, size_t len, char *hexsum) { uint8 sum[SM3_DIGEST_LENGTH]; sm3_ctx ctx; sm3_init(&ctx); sm3_update(&ctx, buff, len); sm3_final(&ctx, sum); bytesToHex(sum, hexsum); return true; } bool pg_sm3_encrypt(const char *passwd, const char* salt, size_t salt_len, char *buf) { size_t passwd_len = strlen(passwd); char *crypt_buf = malloc(passwd_len + salt_len + 1); bool ret; if (!crypt_buf) return false; memcpy(crypt_buf, passwd, passwd_len); memcpy(crypt_buf + passwd_len, salt, salt_len); strcpy(buf, "sm3"); ret = hg_sm3_hash(crypt_buf, passwd_len + salt_len, buf + 3); free(crypt_buf); return ret; } pgbouncer/lib/usual/crypto/sm3.h: #ifndef _USUAL_CRYPTO_SM3_H_ #define _USUAL_CRYPTO_SM3_H_ #include <usual/base.h> /** Block size for SM3 */ #define SM3_BLOCK_SIZE 64 /** Result length for SM3 */ #define SM3_DIGEST_LENGTH 32 #define SM3_SALT_LENGTH 4 /** SM3 state */ typedef struct sm3_ctx { uint32_t digest[8]; // 哈希值 uint64_t nblocks; // 总分块数 unsigned char block[64]; // 当前处理块 int num; // 缓冲区填充量 } sm3_ctx; void sm3_reset(sm3_ctx *ctx); void sm3_update(sm3_ctx *ctx, const void *data, unsigned len); void sm3_final(sm3_ctx *ctx, unsigned char *digest); #endif pgbouncer/lib/usual/crypto/sm3.c: #include <usual/crypto/sm3.h> #include <usual/crypto/digest.h> #define GETU32(p) ((uint32_t)(p)[0]<<24|(uint32_t)(p)[1]<<16|(uint32_t)(p)[2]<<8|(uint32_t)(p)[3]) #define PUT32(p,v) ((p)[0]=(uint8_t)((v)>>24),(p)[1]=(uint8_t)((v)>>16),(p)[2]=(uint8_t)((v)>>8),(p)[3]=(uint8_t)(v)) /* 32bit data rotate left n bit */ #define ROL32(a,n) (((a)<<(n)) | (((a)&0xffffffff)>>(32-(n)))) /* base on SM3 Algorithm's function definition */ #define FF00(x,y,z) ((x) ^ (y) ^ (z)) #define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define GG00(x,y,z) ((x) ^ (y) ^ (z)) #define GG16(x,y,z) (((x)&(y)) | ((~x)&(z))) #define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) #define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) /* constant quantity */ #define T00 0x79cc4519U #define T16 0x7a879d8aU #define K0 0x79cc4519U #define K1 0xf3988a32U #define K2 0xe7311465U #define K3 0xce6228cbU #define K4 0x9cc45197U #define K5 0x3988a32fU #define K6 0x7311465eU #define K7 0xe6228cbcU #define K8 0xcc451979U #define K9 0x988a32f3U #define K10 0x311465e7U #define K11 0x6228cbceU #define K12 0xc451979cU #define K13 0x88a32f39U #define K14 0x11465e73U #define K15 0x228cbce6U #define K16 0x9d8a7a87U #define K17 0x3b14f50fU #define K18 0x7629ea1eU #define K19 0xec53d43cU #define K20 0xd8a7a879U #define K21 0xb14f50f3U #define K22 0x629ea1e7U #define K23 0xc53d43ceU #define K24 0x8a7a879dU #define K25 0x14f50f3bU #define K26 0x29ea1e76U #define K27 0x53d43cecU #define K28 0xa7a879d8U #define K29 0x4f50f3b1U #define K30 0x9ea1e762U #define K31 0x3d43cec5U #define K32 0x7a879d8aU #define K33 0xf50f3b14U #define K34 0xea1e7629U #define K35 0xd43cec53U #define K36 0xa879d8a7U #define K37 0x50f3b14fU #define K38 0xa1e7629eU #define K39 0x43cec53dU #define K40 0x879d8a7aU #define K41 0x0f3b14f5U #define K42 0x1e7629eaU #define K43 0x3cec53d4U #define K44 0x79d8a7a8U #define K45 0xf3b14f50U #define K46 0xe7629ea1U #define K47 0xcec53d43U #define K48 0x9d8a7a87U #define K49 0x3b14f50fU #define K50 0x7629ea1eU #define K51 0xec53d43cU #define K52 0xd8a7a879U #define K53 0xb14f50f3U #define K54 0x629ea1e7U #define K55 0xc53d43ceU #define K56 0x8a7a879dU #define K57 0x14f50f3bU #define K58 0x29ea1e76U #define K59 0x53d43cecU #define K60 0xa7a879d8U #define K61 0x4f50f3b1U #define K62 0x9ea1e762U #define K63 0x3d43cec5U uint32_t K[64] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K60, K61, K62, K63, }; static void sm3_compress_blocks(uint32_t digest[8], const unsigned char *data, size_t blocks) { uint32_t A; uint32_t B; uint32_t C; uint32_t D; uint32_t E; uint32_t F; uint32_t G; uint32_t H; uint32_t W[68]; int j = 0; uint32_t SS1, SS2, TT1, TT2; while (blocks--) { A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; F = digest[5]; G = digest[6]; H = digest[7]; for (j = 0; j < 16; j++) { W[j] = GETU32(data + j*4); } for (j = 16; j < 68; j++) { W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) ^ ROL32(W[j - 13], 7) ^ W[j - 6]; } for (j = 0; j < 16; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG00(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } for (j = 16; j < 64; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG16(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } digest[0] ^= A; digest[1] ^= B; digest[2] ^= C; digest[3] ^= D; digest[4] ^= E; digest[5] ^= F; digest[6] ^= G; digest[7] ^= H; data += 64; } } static void sm3_compress(uint32_t digest[8], const unsigned char block[64]) { return sm3_compress_blocks(digest, block, 1); } /* * Public API. */ void sm3_reset(sm3_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->digest[0] = 0x7380166F; ctx->digest[1] = 0x4914B2B9; ctx->digest[2] = 0x172442D7; ctx->digest[3] = 0xDA8A0600; ctx->digest[4] = 0xA96F30BC; ctx->digest[5] = 0x163138AA; ctx->digest[6] = 0xE38DEE4D; ctx->digest[7] = 0xB0FB0E4E; } void sm3_update(sm3_ctx *ctx, const void *data, unsigned len) { size_t blocks; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (len < left) { memcpy(ctx->block + ctx->num, data, len); ctx->num += len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress_blocks(ctx->digest, ctx->block, 1); ctx->nblocks++; data += left; len -= left; } } blocks = len / SM3_BLOCK_SIZE; sm3_compress_blocks(ctx->digest, data, blocks); ctx->nblocks += blocks; data += SM3_BLOCK_SIZE * blocks; len -= SM3_BLOCK_SIZE * blocks; ctx->num = len; if (len) { memcpy(ctx->block, data, len); } } void sm3_final(sm3_ctx *ctx, unsigned char *digest) { int i; ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } PUTU32(ctx->block + 56, ctx->nblocks >> 23); PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < 8; i++) { PUTU32(digest + i*4, ctx->digest[i]); } } /* * DigestInfo */ static const struct DigestInfo sm3 = { (DigestInitFunc *)sm3_reset, (DigestUpdateFunc *)sm3_update, (DigestFinalFunc *)sm3_final, sizeof(struct sm3_ctx), SM3_DIGEST_LENGTH, SM3_BLOCK_SIZE }; const struct DigestInfo *digest_SM3(void) { return &sm3; } 大致正确吗

这是 pgbouncer 1.12.0 的部分源码: pgbouncer/lib/usual/crypto/digest.h 里有部分内容: typedef void (DigestInitFunc)(void *ctx); typedef void (DigestUpdateFunc)(void *ctx, const void *, unsigned); typedef void (DigestFinalFunc)(void *ctx, uint8_t *); /** * Algoright info. */ struct DigestInfo { DigestInitFunc *init; DigestUpdateFunc *update; DigestFinalFunc *final; short state_len; short result_len; short block_len; }; pgbouncer/lib/usual/crypto/md5.h 里的内容: #ifndef _USUAL_CRYPTO_MD5_H_ #define _USUAL_CRYPTO_MD5_H_ #include <usual/base.h> /** Block length for MD5 */ #define MD5_BLOCK_LENGTH 64 /** Result length for MD5 */ #define MD5_DIGEST_LENGTH 16 /** MD5 state */ struct md5_ctx { uint64_t nbytes; uint32_t a, b, c, d; uint32_t buf[16]; }; /** Clean state */ void md5_reset(struct md5_ctx *ctx); /** Update state with more data */ void md5_update(struct md5_ctx *ctx, const void *data, unsigned int len); /** Get final result */ void md5_final(struct md5_ctx *ctx, uint8_t *dst); #endif pgbouncer/lib/usual/crypto/md5.c 里的内容: #include <usual/crypto/md5.h> #include <usual/crypto/digest.h> #include <usual/endian.h> #include <usual/bits.h> /* * Support functions. */ #define bufpos(ctx) ((ctx)->nbytes & (MD5_BLOCK_LENGTH - 1)) static inline void swap_words(uint32_t *w, int n) { #ifdef WORDS_BIGENDIAN for (; n > 0; w++, n--) *w = le32toh(*w); #endif } /* * MD5 core. */ #define F(X,Y,Z) ((X & Y) | ((~X) & Z)) #define G(X,Y,Z) ((X & Z) | (Y & (~Z))) #define H(X,Y,Z) (X ^ Y ^ Z) #define I(X,Y,Z) (Y ^ (X | (~Z))) #define OP(fn, a, b, c, d, k, s, T_i) \ a = b + rol32(a + fn(b, c, d) + X[k] + T_i, s) static void md5_mix(struct md5_ctx *ctx, const uint32_t *X) { uint32_t a, b, c, d; a = ctx->a; b = ctx->b; c = ctx->c; d = ctx->d; /* Round 1. */ OP(F, a, b, c, d, 0, 7, 0xd76aa478); OP(F, d, a, b, c, 1, 12, 0xe8c7b756); OP(F, c, d, a, b, 2, 17, 0x242070db); OP(F, b, c, d, a, 3, 22, 0xc1bdceee); OP(F, a, b, c, d, 4, 7, 0xf57c0faf); OP(F, d, a, b, c, 5, 12, 0x4787c62a); OP(F, c, d, a, b, 6, 17, 0xa8304613); OP(F, b, c, d, a, 7, 22, 0xfd469501); OP(F, a, b, c, d, 8, 7, 0x698098d8); OP(F, d, a, b, c, 9, 12, 0x8b44f7af); OP(F, c, d, a, b, 10, 17, 0xffff5bb1); OP(F, b, c, d, a, 11, 22, 0x895cd7be); OP(F, a, b, c, d, 12, 7, 0x6b901122); OP(F, d, a, b, c, 13, 12, 0xfd987193); OP(F, c, d, a, b, 14, 17, 0xa679438e); OP(F, b, c, d, a, 15, 22, 0x49b40821); /* Round 2. */ OP(G, a, b, c, d, 1, 5, 0xf61e2562); OP(G, d, a, b, c, 6, 9, 0xc040b340); OP(G, c, d, a, b, 11, 14, 0x265e5a51); OP(G, b, c, d, a, 0, 20, 0xe9b6c7aa); OP(G, a, b, c, d, 5, 5, 0xd62f105d); OP(G, d, a, b, c, 10, 9, 0x02441453); OP(G, c, d, a, b, 15, 14, 0xd8a1e681); OP(G, b, c, d, a, 4, 20, 0xe7d3fbc8); OP(G, a, b, c, d, 9, 5, 0x21e1cde6); OP(G, d, a, b, c, 14, 9, 0xc33707d6); OP(G, c, d, a, b, 3, 14, 0xf4d50d87); OP(G, b, c, d, a, 8, 20, 0x455a14ed); OP(G, a, b, c, d, 13, 5, 0xa9e3e905); OP(G, d, a, b, c, 2, 9, 0xfcefa3f8); OP(G, c, d, a, b, 7, 14, 0x676f02d9); OP(G, b, c, d, a, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP(H, a, b, c, d, 5, 4, 0xfffa3942); OP(H, d, a, b, c, 8, 11, 0x8771f681); OP(H, c, d, a, b, 11, 16, 0x6d9d6122); OP(H, b, c, d, a, 14, 23, 0xfde5380c); OP(H, a, b, c, d, 1, 4, 0xa4beea44); OP(H, d, a, b, c, 4, 11, 0x4bdecfa9); OP(H, c, d, a, b, 7, 16, 0xf6bb4b60); OP(H, b, c, d, a, 10, 23, 0xbebfbc70); OP(H, a, b, c, d, 13, 4, 0x289b7ec6); OP(H, d, a, b, c, 0, 11, 0xeaa127fa); OP(H, c, d, a, b, 3, 16, 0xd4ef3085); OP(H, b, c, d, a, 6, 23, 0x04881d05); OP(H, a, b, c, d, 9, 4, 0xd9d4d039); OP(H, d, a, b, c, 12, 11, 0xe6db99e5); OP(H, c, d, a, b, 15, 16, 0x1fa27cf8); OP(H, b, c, d, a, 2, 23, 0xc4ac5665); /* Round 4. */ OP(I, a, b, c, d, 0, 6, 0xf4292244); OP(I, d, a, b, c, 7, 10, 0x432aff97); OP(I, c, d, a, b, 14, 15, 0xab9423a7); OP(I, b, c, d, a, 5, 21, 0xfc93a039); OP(I, a, b, c, d, 12, 6, 0x655b59c3); OP(I, d, a, b, c, 3, 10, 0x8f0ccc92); OP(I, c, d, a, b, 10, 15, 0xffeff47d); OP(I, b, c, d, a, 1, 21, 0x85845dd1); OP(I, a, b, c, d, 8, 6, 0x6fa87e4f); OP(I, d, a, b, c, 15, 10, 0xfe2ce6e0); OP(I, c, d, a, b, 6, 15, 0xa3014314); OP(I, b, c, d, a, 13, 21, 0x4e0811a1); OP(I, a, b, c, d, 4, 6, 0xf7537e82); OP(I, d, a, b, c, 11, 10, 0xbd3af235); OP(I, c, d, a, b, 2, 15, 0x2ad7d2bb); OP(I, b, c, d, a, 9, 21, 0xeb86d391); ctx->a += a; ctx->b += b; ctx->c += c; ctx->d += d; } /* * Public API. */ void md5_reset(struct md5_ctx *ctx) { ctx->nbytes = 0; ctx->a = 0x67452301; ctx->b = 0xefcdab89; ctx->c = 0x98badcfe; ctx->d = 0x10325476; } void md5_update(struct md5_ctx *ctx, const void *data, unsigned int len) { unsigned int n; const uint8_t *ptr = data; uint8_t *buf = (uint8_t *)ctx->buf; while (len > 0) { n = MD5_BLOCK_LENGTH - bufpos(ctx); if (n > len) n = len; memcpy(buf + bufpos(ctx), ptr, n); ptr += n; len -= n; ctx->nbytes += n; if (bufpos(ctx) == 0) { swap_words(ctx->buf, 16); md5_mix(ctx, ctx->buf); } } } void md5_final(struct md5_ctx *ctx, uint8_t *dst) { static const uint8_t padding[MD5_BLOCK_LENGTH] = { 0x80 }; uint64_t final_len = ctx->nbytes * 8; int pad_len, pos = bufpos(ctx); /* add padding */ pad_len = MD5_BLOCK_LENGTH - 8 - pos; if (pad_len <= 0) pad_len += MD5_BLOCK_LENGTH; md5_update(ctx, padding, pad_len); /* add length directly */ swap_words(ctx->buf, 14); ctx->buf[14] = final_len; ctx->buf[15] = final_len >> 32; /* final result */ md5_mix(ctx, ctx->buf); le32enc(dst + 0, ctx->a); le32enc(dst + 4, ctx->b); le32enc(dst + 8, ctx->c); le32enc(dst + 12, ctx->d); } /* * DigestInfo */ static const struct DigestInfo md5 = { (DigestInitFunc *)md5_reset, (DigestUpdateFunc *)md5_update, (DigestFinalFunc *)md5_final, sizeof(struct md5_ctx), MD5_DIGEST_LENGTH, MD5_BLOCK_LENGTH }; const struct DigestInfo *digest_MD5(void) { return &md5; } 原生pgbouncer不支持sm3,需要在pgbouncer 1.12.0 源码的基础上添加sm3支持。 在 pgbouncer/lib/usual/crypto/sm3.h 里添加: #ifndef _USUAL_CRYPTO_SM3_H_ #define _USUAL_CRYPTO_SM3_H_ #include <usual/base.h> /** Block size for SM3 */ #define SM3_BLOCK_SIZE 64 /** Result length for SM3 */ #define SM3_DIGEST_LENGTH 32 /** SM3 state */ struct sm3_ctx { uint32 digest[8]; // 哈希值 uint64 nblocks; // 总分块数 unsigned char block[64]; // 当前处理块 int num; // 缓冲区填充量 }; void sm3_reset(sm3_ctx *ctx); void sm3_update(sm3_ctx *ctx, const unsigned char *data, size_t data_len); void sm3_final(sm3_ctx *ctx, unsigned char *digest); #endif 在 pgbouncer/lib/usual/crypto/sm3.c 里添加: #include <usual/crypto/sm3.h> #include <usual/crypto/digest.h> #define GETU32(p) ((uint32)(p)[0]<<24|(uint32)(p)[1]<<16|(uint32)(p)[2]<<8|(uint32)(p)[3]) #define PUT32(p,v) ((p)[0]=(uint8)((v)>>24),(p)[1]=(uint8)((v)>>16),(p)[2]=(uint8)((v)>>8),(p)[3]=(uint8)(v)) /* 32bit data rotate left n bit */ #define ROL32(a,n) (((a)<<(n)) | (((a)&0xffffffff)>>(32-(n)))) /* base on SM3 Algorithm's function definition */ #define FF00(x,y,z) ((x) ^ (y) ^ (z)) #define FF16(x,y,z) (((x)&(y)) | ((x)&(z)) | ((y)&(z))) #define GG00(x,y,z) ((x) ^ (y) ^ (z)) #define GG16(x,y,z) (((x)&(y)) | ((~x)&(z))) #define P0(x) ((x) ^ ROL32((x),9) ^ ROL32((x),17)) #define P1(x) ((x) ^ ROL32((x),15) ^ ROL32((x),23)) /* constant quantity */ #define T00 0x79cc4519U #define T16 0x7a879d8aU #define K0 0x79cc4519U #define K1 0xf3988a32U #define K2 0xe7311465U #define K3 0xce6228cbU #define K4 0x9cc45197U #define K5 0x3988a32fU #define K6 0x7311465eU #define K7 0xe6228cbcU #define K8 0xcc451979U #define K9 0x988a32f3U #define K10 0x311465e7U #define K11 0x6228cbceU #define K12 0xc451979cU #define K13 0x88a32f39U #define K14 0x11465e73U #define K15 0x228cbce6U #define K16 0x9d8a7a87U #define K17 0x3b14f50fU #define K18 0x7629ea1eU #define K19 0xec53d43cU #define K20 0xd8a7a879U #define K21 0xb14f50f3U #define K22 0x629ea1e7U #define K23 0xc53d43ceU #define K24 0x8a7a879dU #define K25 0x14f50f3bU #define K26 0x29ea1e76U #define K27 0x53d43cecU #define K28 0xa7a879d8U #define K29 0x4f50f3b1U #define K30 0x9ea1e762U #define K31 0x3d43cec5U #define K32 0x7a879d8aU #define K33 0xf50f3b14U #define K34 0xea1e7629U #define K35 0xd43cec53U #define K36 0xa879d8a7U #define K37 0x50f3b14fU #define K38 0xa1e7629eU #define K39 0x43cec53dU #define K40 0x879d8a7aU #define K41 0x0f3b14f5U #define K42 0x1e7629eaU #define K43 0x3cec53d4U #define K44 0x79d8a7a8U #define K45 0xf3b14f50U #define K46 0xe7629ea1U #define K47 0xcec53d43U #define K48 0x9d8a7a87U #define K49 0x3b14f50fU #define K50 0x7629ea1eU #define K51 0xec53d43cU #define K52 0xd8a7a879U #define K53 0xb14f50f3U #define K54 0x629ea1e7U #define K55 0xc53d43ceU #define K56 0x8a7a879dU #define K57 0x14f50f3bU #define K58 0x29ea1e76U #define K59 0x53d43cecU #define K60 0xa7a879d8U #define K61 0x4f50f3b1U #define K62 0x9ea1e762U #define K63 0x3d43cec5U uint32 K[64] = { K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K60, K61, K62, K63, }; static void sm3_compress_blocks(uint32_t digest[8], const unsigned char *data, size_t blocks) { uint32 A; uint32 B; uint32 C; uint32 D; uint32 E; uint32 F; uint32 G; uint32 H; uint32 W[68]; int j = 0; uint32 SS1, SS2, TT1, TT2; while (blocks--) { A = digest[0]; B = digest[1]; C = digest[2]; D = digest[3]; E = digest[4]; F = digest[5]; G = digest[6]; H = digest[7]; for (j = 0; j < 16; j++) { W[j] = GETU32(data + j*4); } for (j = 16; j < 68; j++) { W[j] = P1(W[j - 16] ^ W[j - 9] ^ ROL32(W[j - 3], 15)) ^ ROL32(W[j -13], 7) ^ W[j - 6]; } for (j = 0; j < 16; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF00(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG00(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } for (j = 16; j < 64; j++) { SS1 = ROL32((ROL32(A, 12) + E + K[j]), 7); SS2 = SS1 ^ ROL32(A, 12); TT1 = FF16(A, B, C) + D + SS2 + (W[j] ^ W[j + 4]); TT2 = GG16(E, F, G) + H + SS1 + W[j]; D = C; C = ROL32(B, 9); B = A; A = TT1; H = G; G = ROL32(F, 19); F = E; E = P0(TT2); } digest[0] ^= A; digest[1] ^= B; digest[2] ^= C; digest[3] ^= D; digest[4] ^= E; digest[5] ^= F; digest[6] ^= G; digest[7] ^= H; data += 64; } } static void sm3_compress(uint32_t digest[8], const unsigned char block[64]) { return sm3_compress_blocks(digest, block, 1); } /* * Public API. */ void sm3_reset(sm3_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->digest[0] = 0x7380166F; ctx->digest[1] = 0x4914B2B9; ctx->digest[2] = 0x172442D7; ctx->digest[3] = 0xDA8A0600; ctx->digest[4] = 0xA96F30BC; ctx->digest[5] = 0x163138AA; ctx->digest[6] = 0xE38DEE4D; ctx->digest[7] = 0xB0FB0E4E; } void sm3_update(sm3_ctx *ctx, const unsigned char *data, size_t data_len) { size_t blocks; if (ctx->num) { unsigned int left = SM3_BLOCK_SIZE - ctx->num; if (data_len < left) { memcpy(ctx->block + ctx->num, data, data_len); ctx->num += data_len; return; } else { memcpy(ctx->block + ctx->num, data, left); sm3_compress_blocks(ctx->digest, ctx->block, 1); ctx->nblocks++; data += left; data_len -= left; } } blocks = data_len / SM3_BLOCK_SIZE; sm3_compress_blocks(ctx->digest, data, blocks); ctx->nblocks += blocks; data += SM3_BLOCK_SIZE * blocks; data_len -= SM3_BLOCK_SIZE * blocks; ctx->num = data_len; if (data_len) { memcpy(ctx->block, data, data_len); } } void sm3_final(sm3_ctx *ctx, unsigned char *digest) { int i; ctx->block[ctx->num] = 0x80; if (ctx->num + 9 <= SM3_BLOCK_SIZE) { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 9); } else { memset(ctx->block + ctx->num + 1, 0, SM3_BLOCK_SIZE - ctx->num - 1); sm3_compress(ctx->digest, ctx->block); memset(ctx->block, 0, SM3_BLOCK_SIZE - 8); } PUTU32(ctx->block + 56, ctx->nblocks >> 23); PUTU32(ctx->block + 60, (ctx->nblocks << 9) + (ctx->num << 3)); sm3_compress(ctx->digest, ctx->block); for (i = 0; i < 8; i++) { PUTU32(digest + i*4, ctx->digest[i]); } } /* * DigestInfo */ static const struct DigestInfo sm3 = { (DigestInitFunc *)sm3_reset, (DigestUpdateFunc *)sm3_update, (DigestFinalFunc *)sm3_final, sizeof(struct sm3_ctx), SM3_DIGEST_LENGTH, SM3_BLOCK_SIZE }; const struct DigestInfo *digest_SM3(void) { return &sm3; } 注意:pgbouncer的源码中不支持sm3。sm3相关的都是我自己添加的。 结合源码中md5,讲下我添加的sm3,整体上正确吗?(不考虑其他未涉及到的文件)

//从压缩的字体数据表中加载字体数据,解压缩后发送到显示设备的功能 #include <stdio.h> #include <stdlib.h> #include <time.h> #include "types.h" #include "CommonFont.h" #if 0 #define my_printf printf #else #define my_printf #endif #define _JUNO_OSD_ #define FfontStart 0x06 //100907 aoivd overlap with arrow #define MonoFontStart 0x00 #define SpaceFont (MonoFontStart+0x01) #define Saperation_2C (MonoFontStart+0x02) #define TopLine_2C (MonoFontStart+0x03) #define TopBottom_2C (MonoFontStart+0x04) #define BottomLine_2C (MonoFontStart+0x05) #define GaugeSelect_2C (MonoFontStart+0x06) #define GaugeNormal_2C (MonoFontStart+0x07) #define Mark_2C (MonoFontStart+0x08) #define CursorFontStart (Mark_2C+0x01) #define CursorLT_2C (CursorFontStart+0x00) #define CursorTop_2C (CursorFontStart+0x01) #define CursorRT_2C (CursorFontStart+0x02) #define CursorLeft_2C (CursorFontStart+0x03) #define CursorRight_2C (CursorFontStart+0x04) #define CursorLD_2C (CursorFontStart+0x05) #define CursorDown_2C (CursorFontStart+0x06) #define CursorRD_2C (CursorFontStart+0x07) #define NumberFontStart (CursorRD_2C+0x01) #define PropFontAddr1 0x20 #define PropFontAddr2 0x80 #define _4ColorFontStart 0x180 #define SmallLogo_4C _4ColorFontStart #define SmallLogo_Size 39 #define Logo_4C 0x02 #define Logo_Size 120 #define OSD2_A4 0x101DA4 void mStar_LoadCompressedFont(BYTE u8Addr, const WORD *pu16FontPtr, WORD u16Count); void LoadCompressColorFont(const BYTE *pu8FontTbl, WORD *pu16MapPtr, BYTE u8Count); void Osd_LoadCompressColorFont( WORD addr, const BYTE *fontPtr, WORD *mapPtr, BYTE count ) { my_printf ("[%s][%d]: addr=%d; fontPtr=%p; mapPtr=%p; count=%d; \n", __func__, __LINE__, addr, fontPtr, mapPtr, count); LoadCompressColorFont( fontPtr, mapPtr, count ); } extern void Osd_LoadColorPalette256( void ); int main() { printf ("[%s][%d]: Enter\n", __func__, __LINE__

#ifndef __NRF24L01P_H__ #define __NRF24L01P_H__ #include "stm32f1xx_hal.h" /* Ó²¼þÁ¬½ÓÉèÖà */ #define NRF_MOSI_PORT GPIOA #define NRF_MOSI_PIN GPIO_PIN_7 #define NRF_MISO_PORT GPIOA #define NRF_MISO_PIN GPIO_PIN_6 #define NRF_SCK_PORT GPIOA #define NRF_SCK_PIN GPIO_PIN_5 #define NRF_CSN_PORT GPIOA #define NRF_CSN_PIN GPIO_PIN_4 #define NRF_CE_PORT GPIOA #define NRF_CE_PIN GPIO_PIN_3 #define NRF_IRQ_PORT GPIOA #define NRF_IRQ_PIN GPIO_PIN_2 /* ²ÎÊýÅäÖà */ #define TX_ADR_WIDTH 5 // ???? #define TX_PLOAD_WIDTH 32 // payload?? /* SPIÃüÁî */ #define READ_REG 0x00 #define WRITE_REG 0x20 #define RD_RX_PLOAD 0x61 #define WR_TX_PLOAD 0xA0 #define FLUSH_TX 0xE1 #define FLUSH_RX 0xE2 #define REUSE_TX_PL 0xE3 #define NOP 0xFF /* ¼Ä´æÆ÷µØÖ· */ #define CONFIG 0x00 #define EN_AA 0x01 #define EN_RXADDR 0x02 #define SETUP_AW 0x03 #define SETUP_RETR 0x04 #define RF_CH 0x05 #define RF_SETUP 0x06 #define STATUS 0x07 #define OBSERVE_TX 0x08 #define RPD 0x09 #define RX_ADDR_P0 0x0A #define RX_ADDR_P1 0x0B #define RX_ADDR_P2 0x0C #define RX_ADDR_P3 0x0D #define RX_ADDR_P4 0x0E #define RX_ADDR_P5 0x0F #define TX_ADDR 0x10 #define RX_PW_P0 0x11 #define RX_PW_P1 0x12 #define RX_PW_P2 0x13 #define RX_PW_P3 0x14 #define RX_PW_P4 0x15 #define RX_PW_P5 0x16 #define FIFO_STATUS 0x17 /* ״̬±êÖ¾ */ #define RX_DR 0x40 #define TX_DS 0x20 #define MAX_RT 0x10 /* º¯ÊýÉùÃ÷ */ void NRF24L01P_Init(SPI_HandleTypeDef *hspi); uint8_t NRF24L01P_Check(void); uint8_t NRF24L01P_Write_Reg(uint8_t reg, uint8_t value); uint8_t NRF24L01P_Write_Buf(uint8_t reg, const uint8_t *pBuf, uint8_t bytes); uint8_t NRF24L01P_Read_Reg(uint8_t reg); uint8_t NRF24L01P_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t bytes); void NRF24L01P_RX_Mode(void); void NRF24L01P_TX_Mode(void); uint8_t NRF24L01P_RxPacket(uint8_t *rxbuf); uint8_t NRF24L01P_TxPacket(uint8_t *txbuf); #endif /* __NRF24L01P_H__ */

根据此代码修改:/* ArduCAM.h - Arduino library support for CMOS Image Sensor Copyright (C)2011-2015 ArduCAM.com. All right reserved Basic functionality of this library are based on the demo-code provided by ArduCAM.com. You can find the latest version of the library at http://www.ArduCAM.com Now supported controllers: - OV7670 - MT9D111 - OV7675 - OV2640 - OV3640 - OV5642 - OV5640 - OV7660 - OV7725 - MT9M112 - MT9V111 - OV5640 - MT9M001 - MT9T112 - MT9D112 We will add support for many other sensors in next release. Supported MCU platform - Theoretically support all Arduino families - Arduino UNO R3 (Tested) - Arduino MEGA2560 R3 (Tested) - Arduino Leonardo R3 (Tested) - Arduino Nano (Tested) - Arduino DUE (Tested) - Arduino Yun (Tested) - Raspberry Pi (Tested) - ESP8266-12 (Tested) * Feather M0 (Tested with OV5642) If you make any modifications or improvements to the code, I would appreciate that you share the code with me so that I might include it in the next release. I can be contacted through http://www.ArduCAM.com This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /*------------------------------------ Revision History: 2012/09/20 V1.0.0 by Lee first release 2012/10/23 V1.0.1 by Lee Resolved some timing issue for the Read/Write Register 2012/11/29 V1.1.0 by Lee Add support for MT9D111 sensor 2012/12/13 V1.2.0 by Lee Add support for OV7675 sensor 2012/12/28 V1.3.0 by Lee Add support for OV2640,OV3640,OV5642 sensors 2013/02/26 V2.0.0 by Lee New Rev.B shield hardware, add support for FIFO control and support Mega1280/2560 boards 2013/05/28 V2.1.0 by Lee Add support all drawing functions derived from UTFT library 2013/08/24 V3.0.0 by Lee Support ArudCAM shield Rev.C hardware, features SPI interface and low power mode. Support almost all series of Arduino boards including DUE. 2014/03/09 V3.1.0 by Lee Add the more impressive example sketches. Optimise the OV5642 settings, improve image quality. Add live preview before JPEG capture. Add play back photos one by one after BMP capture. 2014/05/01 V3.1.1 by Lee Minor changes to add support Arduino IDE for linux distributions. 2014/09/30 V3.2.0 by Lee Improvement on OV5642 camera dirver. 2014/10/06 V3.3.0 by Lee Add OV7660,OV7725 camera support. 2015/02/27 V3.4.0 by Lee Add the support for Arduino Yun board, update the latest UTFT library for ArduCAM. 2015/06/09 V3.4.1 by Lee Minor changes and add some comments 2015/06/19 V3.4.2 by Lee Add support for MT9M112 camera. 2015/06/20 V3.4.3 by Lee Add support for MT9V111 camera. 2015/06/22 V3.4.4 by Lee Add support for OV5640 camera. 2015/06/22 V3.4.5 by Lee Add support for MT9M001 camera. 2015/08/05 V3.4.6 by Lee Add support for MT9T112 camera. 2015/08/08 V3.4.7 by Lee Add support for MT9D112 camera. 2015/09/20 V3.4.8 by Lee Add support for ESP8266 processor. 2016/02/03 V3.4.9 by Lee Add support for Arduino ZERO board. 2016/06/07 V3.5.0 by Lee Add support for OV5642_CAM_BIT_ROTATION_FIXED. 2016/06/14 V3.5.1 by Lee Add support for ArduCAM-Mini-5MP-Plus OV5640_CAM. 2016/09/29 V3.5.2 by Lee Optimize the OV5642 register settings 2016/10/05 V4.0.0 by Lee Add support for second generation of ArduCAM shield V2, ArduCAM-Mini-5MP-Plus(OV5642/OV5640). 2016/10/28 V4.0.1 by Lee Add support for Raspberry Pi 2017/04/27 V4.1.0 by Lee Add support for OV2640/OV5640/OV5642 functions. 2017/07/07 V4.1.0 by Lee Add support for ArduCAM_ESP32 paltform 2017/07/25 V4.1.1 by Lee Add support for MT9V034 2017/11/27 V4.1.2 by Max Add support for Feather M0 2018/10/15 V4.1.2 by Lee Add support for NRF52 2018/10/15 V4.1.2 by Lee Add support for TEENSYDUINO --------------------------------------*/ // 兼容性定义,放在 #include <ArduCAM.h> 之前或之后 #ifndef sbi #define sbi(port, bit) ((port) |= (1 << (bit))) #endif #ifndef ArduCAM_H #define ArduCAM_H #include "memorysaver.h" #if defined(RASPBERRY_PI) #else #include "Arduino.h" #include // #include "memorysaver.h" #endif #if defined(__AVR__) #define cbi(reg, bitmask) *reg &= ~bitmask #define sbi(reg, bitmask) *reg |= bitmask #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) pgm_read_byte(&cfont.font[x]) #define regtype volatile uint8_t #define regsize uint8_t #endif #if defined(__SAM3X8E__) #define cbi(reg, bitmask) *reg &= ~bitmask #define sbi(reg, bitmask) *reg |= bitmask #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #define PROGMEM #define pgm_read_byte(x) (*((char *)x)) #define pgm_read_word(x) (((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))) #define pgm_read_byte_near(x) (*((char *)x)) #define pgm_read_byte_far(x) (*((char *)x)) #define pgm_read_word_near(x) (((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x))) #define pgm_read_word_far(x) ( ((*((unsigned char *)x + 1)) << 8) + (*((unsigned char *)x)))) #define PSTR(x) x #if defined F #undef F #endif #define F(X) (X) #endif #if defined(ESP8266) #define cbi(reg, bitmask) digitalWrite(bitmask, LOW) #define sbi(reg, bitmask) digitalWrite(bitmask, HIGH) #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #endif #if defined(__SAMD51__) || defined(__SAMD21G18A__) #define Serial SERIAL_PORT_USBVIRTUAL #define cbi(reg, bitmask) *reg &= ~bitmask #define sbi(reg, bitmask) *reg |= bitmask #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #endif #if defined(ESP32) #define cbi(reg, bitmask) digitalWrite(bitmask, LOW) #define sbi(reg, bitmask) digitalWrite(bitmask, HIGH) #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #endif #if defined(__CPU_ARC__) #define cbi(reg, bitmask) *reg &= ~bitmask #define sbi(reg, bitmask) *reg |= bitmask #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) pgm_read_byte(&cfont.font[x]) #define regtype volatile uint32_t #define regsize uint32_t #endif #if defined(RASPBERRY_PI) #define regtype volatile uint32_t #define regsize uint32_t #define byte uint8_t #define cbi(reg, bitmask) digitalWrite(bitmask, LOW) #define sbi(reg, bitmask) digitalWrite(bitmask, HIGH) #define PROGMEM #define PSTR(x) x #if defined F #undef F #endif #define F(X) (X) #endif #if defined(ARDUINO_ARCH_NRF52) #define cbi(reg, bitmask) digitalWrite(bitmask, LOW) #define sbi(reg, bitmask) digitalWrite(bitmask, HIGH) #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #endif #if defined(TEENSYDUINO) #define cbi(reg, bitmask) digitalWriteFast(bitmask, LOW) #define sbi(reg, bitmask) digitalWriteFast(bitmask, HIGH) #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint8_t #define regsize uint8_t #endif #if defined(NRF52840_XXAA) #define cbi(reg, bitmask) digitalWrite(bitmask, LOW) #define sbi(reg, bitmask) digitalWrite(bitmask, HIGH) #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #define PROGMEM #if defined F #undef F #endif #define F(X) (X) #endif #if defined(ARDUINO_ARCH_STM32) #define cbi(reg, bitmask) *reg &= ~bitmask #define sbi(reg, bitmask) *reg |= bitmask #define pulse_high(reg, bitmask) \ sbi(reg, bitmask); \ cbi(reg, bitmask); #define pulse_low(reg, bitmask) \ cbi(reg, bitmask); \ sbi(reg, bitmask); #define cport(port, data) port &= data #define sport(port, data) port |= data #define swap(type, i, j) \ { \ type t = i; \ i = j; \ j = t; \ } #define fontbyte(x) cfont.font[x] #define regtype volatile uint32_t #define regsize uint32_t #endif /****************************************************/ /* Sensor related definition */ /****************************************************/ #define BMP 0 #define JPEG 1 #define RAW 2 #define OV7670 0 #define MT9D111_A 1 #define OV7675 2 #define OV5642 3 #define OV3640 4 #define OV2640 5 #define OV9655 6 #define MT9M112 7 #define OV7725 8 #define OV7660 9 #define MT9M001 10 #define OV5640 11 #define MT9D111_B 12 #define OV9650 13 #define MT9V111 14 #define MT9T112 15 #define MT9D112 16 #define MT9V034 17 #define MT9M034 18 #define OV2640_160x120 0 // 160x120 #define OV2640_176x144 1 // 176x144 #define OV2640_320x240 2 // 320x240 #define OV2640_352x288 3 // 352x288 #define OV2640_640x480 4 // 640x480 #define OV2640_800x600 5 // 800x600 #define OV2640_1024x768 6 // 1024x768 #define OV2640_1280x1024 7 // 1280x1024 #define OV2640_1600x1200 8 // 1600x1200 #define OV3640_176x144 0 // 176x144 #define OV3640_320x240 1 // 320x240 #define OV3640_352x288 2 // 352x288 #define OV3640_640x480 3 // 640x480 #define OV3640_800x600 4 // 800x600 #define OV3640_1024x768 5 // 1024x768 #define OV3640_1280x960 6 // 1280x960 #define OV3640_1600x1200 7 // 1600x1200 #define OV3640_2048x1536 8 // 2048x1536 #define OV5642_320x240 0 // 320x240 #define OV5642_640x480 1 // 640x480 #define OV5642_1024x768 2 // 1024x768 #define OV5642_1280x960 3 // 1280x960 #define OV5642_1600x1200 4 // 1600x1200 #define OV5642_2048x1536 5 // 2048x1536 #define OV5642_2592x1944 6 // 2592x1944 #define OV5642_1920x1080 7 #define OV5640_320x240 0 // 320x240 #define OV5640_352x288 1 // 352x288 #define OV5640_640x480 2 // 640x480 #define OV5640_800x480 3 // 800x480 #define OV5640_1024x768 4 // 1024x768 #define OV5640_1280x960 5 // 1280x960 #define OV5640_1600x1200 6 // 1600x1200 #define OV5640_2048x1536 7 // 2048x1536 #define OV5640_2592x1944 8 // 2592x1944 // Light Mode #define Auto 0 #define Sunny 1 #define Cloudy 2 #define Office 3 #define Home 4 #define Advanced_AWB 0 #define Simple_AWB 1 #define Manual_day 2 #define Manual_A 3 #define Manual_cwf 4 #define Manual_cloudy 5 // Color Saturation #define Saturation4 0 #define Saturation3 1 #define Saturation2 2 #define Saturation1 3 #define Saturation0 4 #define Saturation_1 5 #define Saturation_2 6 #define Saturation_3 7 #define Saturation_4 8 // Brightness #define Brightness4 0 #define Brightness3 1 #define Brightness2 2 #define Brightness1 3 #define Brightness0 4 #define Brightness_1 5 #define Brightness_2 6 #define Brightness_3 7 #define Brightness_4 8 // Contrast #define Contrast4 0 #define Contrast3 1 #define Contrast2 2 #define Contrast1 3 #define Contrast0 4 #define Contrast_1 5 #define Contrast_2 6 #define Contrast_3 7 #define Contrast_4 8 #define degree_180 0 #define degree_150 1 #define degree_120 2 #define degree_90 3 #define degree_60 4 #define degree_30 5 #define degree_0 6 #define degree30 7 #define degree60 8 #define degree90 9 #define degree120 10 #define degree150 11 // Special effects #define Antique 0 #define Bluish 1 #define Greenish 2 #define Reddish 3 #define BW 4 #define Negative 5 #define BWnegative 6 #define Normal 7 #define Sepia 8 #define Overexposure 9 #define Solarize 10 #define Blueish 11 #define Yellowish 12 #define Exposure_17_EV 0 #define Exposure_13_EV 1 #define Exposure_10_EV 2 #define Exposure_07_EV 3 #define Exposure_03_EV 4 #define Exposure_default 5 #define Exposure03_EV 6 #define Exposure07_EV 7 #define Exposure10_EV 8 #define Exposure13_EV 9 #define Exposure17_EV 10 #define Auto_Sharpness_default 0 #define Auto_Sharpness1 1 #define Auto_Sharpness2 2 #define Manual_Sharpnessoff 3 #define Manual_Sharpness1 4 #define Manual_Sharpness2 5 #define Manual_Sharpness3 6 #define Manual_Sharpness4 7 #define Manual_Sharpness5 8 #define Sharpness1 0 #define Sharpness2 1 #define Sharpness3 2 #define Sharpness4 3 #define Sharpness5 4 #define Sharpness6 5 #define Sharpness7 6 #define Sharpness8 7 #define Sharpness_auto 8 #define EV3 0 #define EV2 1 #define EV1 2 #define EV0 3 #define EV_1 4 #define EV_2 5 #define EV_3 6 #define MIRROR 0 #define FLIP 1 #define MIRROR_FLIP 2 #define high_quality 0 #define default_quality 1 #define low_quality 2 #define Color_bar 0 #define Color_square 1 #define BW_square 2 #define DLI 3 #define Night_Mode_On 0 #define Night_Mode_Off 1 #define Off 0 #define Manual_50HZ 1 #define Manual_60HZ 2 #define Auto_Detection 3 /****************************************************/ /* I2C Control Definition */ /****************************************************/ #define I2C_ADDR_8BIT 0 #define I2C_ADDR_16BIT 1 #define I2C_REG_8BIT 0 #define I2C_REG_16BIT 1 #define I2C_DAT_8BIT 0 #define I2C_DAT_16BIT 1 /* Register initialization tables for SENSORs */ /* Terminating list entry for reg */ #define SENSOR_REG_TERM_8BIT 0xFF #define SENSOR_REG_TERM_16BIT 0xFFFF /* Terminating list entry for val */ #define SENSOR_VAL_TERM_8BIT 0xFF #define SENSOR_VAL_TERM_16BIT 0xFFFF // Define maximum frame buffer size #if (defined OV2640_MINI_2MP) #define MAX_FIFO_SIZE 0x5FFFF // 384KByte #elif (defined OV5642_MINI_5MP || defined OV5642_MINI_5MP_BIT_ROTATION_FIXED || defined ARDUCAM_SHIELD_REVC) #define MAX_FIFO_SIZE 0x7FFFF // 512KByte #else #define MAX_FIFO_SIZE 0x7FFFFF // 8MByte #endif /****************************************************/ /* ArduChip registers definition */ /****************************************************/ #define RWBIT 0x80 // READ AND WRITE BIT IS BIT[7] #define ARDUCHIP_TEST1 0x00 // TEST register #if !(defined OV2640_MINI_2MP) #define ARDUCHIP_FRAMES 0x01 // FRAME control register, Bit[2:0] = Number of frames to be captured //On 5MP_Plus platforms bit[2:0] = 7 means continuous capture until frame buffer is full #endif #define ARDUCHIP_MODE 0x02 // Mode register #define MCU2LCD_MODE 0x00 #define CAM2LCD_MODE 0x01 #define LCD2MCU_MODE 0x02 #define ARDUCHIP_TIM 0x03 // Timming control #if !(defined OV2640_MINI_2MP) #define HREF_LEVEL_MASK 0x01 // 0 = High active , 1 = Low active #define VSYNC_LEVEL_MASK 0x02 // 0 = High active , 1 = Low active #define LCD_BKEN_MASK 0x04 // 0 = Enable, 1 = Disable #if (defined ARDUCAM_SHIELD_V2) #define PCLK_REVERSE_MASK 0x08 // 0 = Normal PCLK, 1 = REVERSED PCLK #else #define PCLK_DELAY_MASK 0x08 // 0 = data no delay, 1 = data delayed one PCLK #endif // #define MODE_MASK 0x10 //0 = LCD mode, 1 = FIFO mode #endif // #define FIFO_PWRDN_MASK 0x20 //0 = Normal operation, 1 = FIFO power down // #define LOW_POWER_MODE 0x40 //0 = Normal mode, 1 = Low power mode #define ARDUCHIP_FIFO 0x04 // FIFO and I2C control #define FIFO_CLEAR_MASK 0x01 #define FIFO_START_MASK 0x02 #define FIFO_RDPTR_RST_MASK 0x10 #define FIFO_WRPTR_RST_MASK 0x20 #define ARDUCHIP_GPIO 0x06 // GPIO Write Register #if !(defined(ARDUCAM_SHIELD_V2) || defined(ARDUCAM_SHIELD_REVC)) #define GPIO_RESET_MASK 0x01 // 0 = Sensor reset, 1 = Sensor normal operation #define GPIO_PWDN_MASK 0x02 // 0 = Sensor normal operation, 1 = Sensor standby #define GPIO_PWREN_MASK 0x04 // 0 = Sensor LDO disable, 1 = sensor LDO enable #endif #define BURST_FIFO_READ 0x3C // Burst FIFO read operation #define SINGLE_FIFO_READ 0x3D // Single FIFO read operation #define ARDUCHIP_REV 0x40 // ArduCHIP revision #define VER_LOW_MASK 0x3F #define VER_HIGH_MASK 0xC0 #define ARDUCHIP_TRIG 0x41 // Trigger source #define VSYNC_MASK 0x01 #define SHUTTER_MASK 0x02 #define CAP_DONE_MASK 0x08 #define FIFO_SIZE1 0x42 // Camera write FIFO size[7:0] for burst to read #define FIFO_SIZE2 0x43 // Camera write FIFO size[15:8] #define FIFO_SIZE3 0x44 // Camera write FIFO size[18:16] /****************************************************/ /****************************************************************/ /* define a structure for sensor register initialization values */ /****************************************************************/ struct sensor_reg { uint16_t reg; uint16_t val; }; /****************************************************************/ /* define a structure for sensor register initialization values */ /****************************************************************/ class ArduCAM { public: ArduCAM(void); ArduCAM(byte model, int CS); void InitCAM(void); void CS_HIGH(void); void CS_LOW(void); void flush_fifo(void); void start_capture(void); void clear_fifo_flag(void); uint8_t read_fifo(void); uint8_t read_reg(uint8_t addr); void write_reg(uint8_t addr, uint8_t data); uint32_t read_fifo_length(void); void set_fifo_burst(void); void set_bit(uint8_t addr, uint8_t bit); void clear_bit(uint8_t addr, uint8_t bit); uint8_t get_bit(uint8_t addr, uint8_t bit); void set_mode(uint8_t mode); uint8_t bus_write(int address, int value); uint8_t bus_read(int address); // Write 8 bit values to 8 bit register address int wrSensorRegs8_8(const struct sensor_reg *); // Write 16 bit values to 8 bit register address int wrSensorRegs8_16(const struct sensor_reg *); // Write 8 bit values to 16 bit register address int wrSensorRegs16_8(const struct sensor_reg *); // Write 16 bit values to 16 bit register address int wrSensorRegs16_16(const struct sensor_reg *); // Read/write 8 bit value to/from 8 bit register address byte wrSensorReg8_8(int regID, int regDat); byte rdSensorReg8_8(uint8_t regID, uint8_t *regDat); // Read/write 16 bit value to/from 8 bit register address byte wrSensorReg8_16(int regID, int regDat); byte rdSensorReg8_16(uint8_t regID, uint16_t *regDat); // Read/write 8 bit value to/from 16 bit register address byte wrSensorReg16_8(int regID, int regDat); byte rdSensorReg16_8(uint16_t regID, uint8_t *regDat); // Read/write 16 bit value to/from 16 bit register address byte wrSensorReg16_16(int regID, int regDat); byte rdSensorReg16_16(uint16_t regID, uint16_t *regDat); void OV2640_set_JPEG_size(uint8_t size); void OV3640_set_JPEG_size(uint8_t size); void OV5642_set_JPEG_size(uint8_t size); void OV5640_set_JPEG_size(uint8_t size); void OV5642_set_RAW_size(uint8_t size); void OV2640_set_Light_Mode(uint8_t Light_Mode); void OV3640_set_Light_Mode(uint8_t Light_Mode); void OV5642_set_Light_Mode(uint8_t Light_Mode); void OV5640_set_Light_Mode(uint8_t Light_Mode); void OV2640_set_Color_Saturation(uint8_t Color_Saturation); void OV3640_set_Color_Saturation(uint8_t Color_Saturation); void OV5642_set_Color_Saturation(uint8_t Color_Saturation); void OV5640_set_Color_Saturation(uint8_t Color_Saturation); void OV2640_set_Brightness(uint8_t Brightness); void OV3640_set_Brightness(uint8_t Brightness); void OV5642_set_Brightness(uint8_t Brightness); void OV5640_set_Brightness(uint8_t Brightness); void OV2640_set_Contrast(uint8_t Contrast); void OV3640_set_Contrast(uint8_t Contrast); void OV5642_set_Contrast(uint8_t Contrast); void OV5640_set_Contrast(uint8_t Contrast); void OV2640_set_Special_effects(uint8_t Special_effect); void OV3640_set_Special_effects(uint8_t Special_effect); void OV5642_set_Special_effects(uint8_t Special_effect); void OV5640_set_Special_effects(uint8_t Special_effect); void OV3640_set_Exposure_level(uint8_t level); void OV3640_set_Sharpness(uint8_t Sharpness); void OV3640_set_Mirror_Flip(uint8_t Mirror_Flip); void OV5642_set_hue(uint8_t degree); void OV5642_set_Exposure_level(uint8_t level); void OV5642_set_Sharpness(uint8_t Sharpness); void OV5642_set_Mirror_Flip(uint8_t Mirror_Flip); void OV5642_set_Compress_quality(uint8_t quality); void OV5642_Test_Pattern(uint8_t Pattern); void OV5640_set_EV(uint8_t EV); void OV5640_set_Night_Mode(uint8_t Night_mode); void OV5640_set_Banding_Filter(uint8_t Banding_Filter); void set_format(byte fmt); #if defined(RASPBERRY_PI) uint8_t transfer(uint8_t data); void transfers(uint8_t *buf, uint32_t size); #endif void transferBytes_(uint8_t *out, uint8_t *in, uint8_t size); void transferBytes(uint8_t *out, uint8_t *in, uint32_t size); inline void setDataBits(uint16_t bits); protected: regtype *P_CS; regsize B_CS; byte m_fmt; byte sensor_model; byte sensor_addr; }; #if defined OV7660_CAM #include "ov7660_regs.h" #endif #if defined OV7725_CAM #include "ov7725_regs.h" #endif #if defined OV7670_CAM #include "ov7670_regs.h" #endif #if defined OV7675_CAM #include "ov7675_regs.h" #endif #if (defined(OV5642_CAM) || defined(OV5642_MINI_5MP) || defined(OV5642_MINI_5MP_BIT_ROTATION_FIXED) || defined(OV5642_MINI_5MP_PLUS)) #include "ov5642_regs.h" #endif #if (defined(OV3640_CAM) || defined(OV3640_MINI_3MP)) #include "ov3640_regs.h" #endif #if (defined(OV2640_CAM) || defined(OV2640_MINI_2MP) || defined(OV2640_MINI_2MP_PLUS)) #include "ov2640_regs.h" #endif #if defined MT9D111A_CAM || defined MT9D111B_CAM #include "mt9d111_regs.h" #endif #if defined MT9M112_CAM #include "mt9m112_regs.h" #endif #if defined MT9V111_CAM #include "mt9v111_regs.h" #endif #if (defined(OV5640_CAM) || defined(OV5640_MINI_5MP_PLUS)) #include "ov5640_regs.h" #endif #if defined MT9M001_CAM #include "mt9m001_regs.h" #endif #if defined MT9T112_CAM #include "mt9t112_regs.h" #endif #if defined MT9D112_CAM #include "mt9d112_regs.h" #endif #if defined MT9M034_CAM #include "mt9m034_regs.h" #endif #endif

#ifndef _mpu6050_h #define _mpu6050_h #include "stdint.h" #include "ml_i2c.h" #include "math.h" #define MPU6050_ADDR 0xd0 #define SMPLRT_DIV 0x19 #define CONFIG 0x1a #define GYRO_CONFIG 0x1b #define ACCEL_CONFIG 0x1c #define ACCEL_XOUT_H 0x3b #define ACCEL_XOUT_L 0x3c #define ACCEL_YOUT_H 0x3d #define ACCEL_YOUT_L 0x3e #define ACCEL_ZOUT_H 0x3f #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x65 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6b #define PWR_MGMT_2 0x6c #define INT_ENABLE 0x38 #define WHO_AM_I 0x75 extern int16_t ax, ay, az, gx, gy, gz; extern float roll_gyro, pitch_gyro, yaw_gyro; extern float roll_acc, pitch_acc, yaw_acc; extern float roll_Kalman, pitch_Kalman, yaw_Kalman; void MPU6050_Write(uint8_t addr, uint8_t dat); uint8_t MPU6050_Read(uint8_t addr); void MPU6050_Init(void); void MPU6050_GetData(void); #endif ———————————————————————————— int16_t ax, ay, az, gx, gy, gz; float roll_gyro, pitch_gyro, yaw_gyro; float roll_acc, pitch_acc, yaw_acc; float roll_Kalman, pitch_Kalman, yaw_Kalman; void MPU6050_Write(uint8_t addr, uint8_t dat) { I2C_Start(); I2C_SendByte(MPU6050_ADDR); I2C_WaitAck(); I2C_SendByte(addr); I2C_WaitAck(); I2C_SendByte(dat); I2C_WaitAck(); I2C_Stop(); } uint8_t MPU6050_Read(uint8_t addr) { I2C_Start(); I2C_SendByte(MPU6050_ADDR); I2C_WaitAck(); I2C_SendByte(addr); I2C_WaitAck(); I2C_Stop(); I2C_Start(); I2C_SendByte(MPU6050_ADDR | 0x01); I2C_WaitAck(); uint8_t dat = I2C_ReceiveByte(); I2C_NotSendAck(); I2C_Stop(); return dat; } void MPU6050_Init() { MPU6050_Write(PWR_MGMT_1, 0x02); // ʱÖÓÔ´£ºPLL with Y axis gyroscope reference MPU6050_Write(SMPLRT_DIV, 0x4F); // ÉèÖòÉÑùƵÂÊΪ100HZ MPU6050_Write(CONFIG, 0x00); // ʧÄÜDLPF MPU6050_Write(GYRO_CONFIG, 0x18); // ÅäÖÃÍÓÂÝÒÇ Á¿³ÌΪ2000 MPU6050_Write(ACCEL_CONFIG, 0x00); // ÅäÖüÓËÙ¶È¼Æ Á¿³ÌΪ2g MPU6050_Write(INT_ENABLE, 0x01); // ʹÄÜINTÒý½Å²ÉÑùÖÐ¶Ï } void MPU6050_GetData() { uint8_t data_h, data_l; data_h = MPU6050_Read(ACCEL_XOUT_H); data_l = MPU6050_Read(ACCEL_XOUT_L); ax = data_l | (data_h << 8); data_h = MPU6050_Read(ACCEL_YOUT_H); data_l = MPU6050_Read(ACCEL_YOUT_L); ay = data_l | (data_h << 8); data_h = MPU6050_Read(ACCEL_ZOUT_H); data_l = MPU6050_Read(ACCEL_ZOUT_L); az = data_l | (data_h << 8); data_h = MPU6050_Read(GYRO_XOUT_H); data_l = MPU6050_Read(GYRO_XOUT_L); gx = data_l | (data_h << 8); data_h = MPU6050_Read(GYRO_YOUT_H); data_l = MPU6050_Read(GYRO_YOUT_L); gy = data_l | (data_h << 8); data_h = MPU6050_Read(GYRO_ZOUT_H); data_l = MPU6050_Read(GYRO_ZOUT_L); gz = data_l | (data_h << 8); } 横线上下分别是是.h和.c文件,以上程序改为德州仪器的ti mspm0G3507,变量名不改,使用的函数必须在dl库里

#include “OLED_Font.h” #include “OLED.h” /引脚配置/ #define OLED_W_SCL(x) HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, (GPIO_PinState)(x)) #define OLED_W_SDA(x) HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, (GPIO_PinState)(x)) /** @brief I2C开始 @param 无 @retval 无 / void OLED_I2C_Start(void) { OLED_W_SDA(1); OLED_W_SCL(1); OLED_W_SDA(0); OLED_W_SCL(0); } /* @brief I2C停止 @param 无 @retval 无 / void OLED_I2C_Stop(void) { OLED_W_SDA(0); OLED_W_SCL(1); OLED_W_SDA(1); } /* @brief I2C发送一个字节 @param Byte 要发送的一个字节 @retval 无 / void OLED_I2C_SendByte(uint8_t Byte) { uint8_t i; for (i = 0; i < 8; i++) { OLED_W_SDA(Byte & (0x80 >> i)); OLED_W_SCL(1); OLED_W_SCL(0); } OLED_W_SCL(1); //额外的一个时钟,不处理应答信号 OLED_W_SCL(0); } /* @brief OLED写命令 @param Command 要写入的命令 @retval 无 / void OLED_WriteCommand(uint8_t Command) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x00); //写命令 OLED_I2C_SendByte(Command); OLED_I2C_Stop(); } /* @brief OLED写数据 @param Data 要写入的数据 @retval 无 / void OLED_WriteData(uint8_t Data) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x40); //写数据 OLED_I2C_SendByte(Data); OLED_I2C_Stop(); } /* @brief OLED设置光标位置 @param Y 以左上角为原点,向下方向的坐标,范围:0~7 @param X 以左上角为原点,向右方向的坐标,范围:0~127 @retval 无 / void OLED_SetCursor(uint8_t Y, uint8_t X) { OLED_WriteCommand(0xB0 | Y); //设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位 } /* @brief OLED清屏 @param 无 @retval 无 / void OLED_Clear(void) { uint8_t i, j; for (j = 0; j < 8; j++) { OLED_SetCursor(j, 0); for(i = 0; i < 128; i++) { OLED_WriteData(0x00); } } } /* @brief OLED显示一个字符 @param Line 行位置,范围:1~4 @param Column 列位置,范围:1~16 @param Char 要显示的一个字符,范围:ASCII可见字符 @retval 无 / void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char) { uint8_t i; OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i]); //显示上半部分内容 } OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i + 8]); //显示下半部分内容 } } /* @brief OLED显示字符串 @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param String 要显示的字符串,范围:ASCII可见字符 @retval 无 / void OLED_ShowString(uint8_t Line, uint8_t Column, char String) { uint8_t i; for (i = 0; String[i] != ‘\0’; i++) { OLED_ShowChar(Line, Column + i, String[i]); } } / @brief OLED次方函数 @retval 返回值等于X的Y次方 / uint32_t OLED_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y–) { Result = X; } return Result; } / @brief OLED显示数字(十进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~4294967295 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十进制,带符号数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:-2147483648~2147483647 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) { uint8_t i; uint32_t Number1; if (Number >= 0) { OLED_ShowChar(Line, Column, ‘+’); Number1 = Number; } else { OLED_ShowChar(Line, Column, ‘-’); Number1 = -Number; } for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十六进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~0xFFFFFFFF @param Length 要显示数字的长度,范围:1~8 @retval 无 / void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i, SingleNumber; for (i = 0; i < Length; i++) { SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16; if (SingleNumber < 10) { OLED_ShowChar(Line, Column + i, SingleNumber + ‘0’); } else { OLED_ShowChar(Line, Column + i, SingleNumber - 10 + ‘A’); } } } /* @brief OLED显示数字(二进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~1111 1111 1111 1111 @param Length 要显示数字的长度,范围:1~16 @retval 无 / void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + ‘0’); } } /* @brief 显示BMP图片 @param 图片大小:128×64 @param 起始点坐标(x,y) @param x的范围0~127 @param y的范围0~7 @retval 无 */ void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]) { unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0;y<y1;y++) { OLED_SetCursor(y,x0); for(x=x0;x<x1;x++) { OLED_WriteData(BMP[j++]); } } } /** @brief OLED初始化 @param 无 @retval 无 */ void OLED_Init(void) { uint32_t i, j; for (i = 0; i < 1000; i++) //上电延时 { for (j = 0; j < 1000; j++); } OLED_WriteCommand(0xAE); //关闭显示 OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); //设置多路复用率 OLED_WriteCommand(0x3F); OLED_WriteCommand(0xD3); //设置显示偏移 OLED_WriteCommand(0x00); OLED_WriteCommand(0x40); //设置显示开始行 OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置 OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置 OLED_WriteCommand(0xDA); //设置COM引脚硬件配置 OLED_WriteCommand(0x12); OLED_WriteCommand(0x81); //设置对比度控制 OLED_WriteCommand(0xCF); OLED_WriteCommand(0xD9); //设置预充电周期 OLED_WriteCommand(0xF1); OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别 OLED_WriteCommand(0x30); OLED_WriteCommand(0xA4); //设置整个显示打开/关闭 OLED_WriteCommand(0xA6); //设置正常/倒转显示 OLED_WriteCommand(0x8D); //设置充电泵 OLED_WriteCommand(0x14); OLED_WriteCommand(0xAF); //开启显示 OLED_Clear(); //OLED清屏 }该代码为我的OLED.C #ifndef __OLED_H #define __OLED_H #include “main.h” void OLED_Init(void); void OLED_Clear(void); void OLED_I2C_Start(void); void OLED_I2C_Stop(void); void OLED_I2C_SendByte(uint8_t Byte); void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char); void OLED_ShowString(uint8_t Line, uint8_t Column, char *String); void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length); void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); #endif这段代码为OLED.H #ifndef __OLED_FONT_H #define __OLED_FONT_H #include “main.h” /OLED字模库,宽8像素,高16像素/ const uint8_t OLED_F8x16[][16]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00, 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00, 0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00, 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//’ 7 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00, 0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00, 0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00, 0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04, 0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, 0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, 0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, 0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, 0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, 0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, 0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00, 0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, 0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00, 0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00, 0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00, 0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00, 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00, 0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00, 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00, 0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00, 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00, 0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00, 0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00, 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00, 0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00, 0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00, 0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 64 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00, 0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, 0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00, 0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00, 0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00, 0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00, 0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00, 0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00, 0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, 0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80, 0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02, 0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00, 0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94 }; #endif这段代码为我的OLED.Font.h。基于这三个OLED相关驱动代码,实现基于STM32 HAL库,使用STM32CUBEMX进行引脚配置,keil运行代码,生成hex文件,Proteus展示实验结果,实现对来自外部两路正交的方波进行计数,然后计数结果用Proteus里的OLED12864I2C显示(没有使用I2C,使用PB6,PB7模拟SCL,SDA,基于我上述提供的OLED相关代码)。给出实现流程。 回答 向我提问的人太多了。正在努力扩容中,请稍后再试。 #include “OLED_Font.h” #include “OLED.h” /引脚配置/ #define OLED_W_SCL(x) HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, (GPIO_PinState)(x)) #define OLED_W_SDA(x) HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, (GPIO_PinState)(x)) /** @brief I2C开始 @param 无 @retval 无 / void OLED_I2C_Start(void) { OLED_W_SDA(1); OLED_W_SCL(1); OLED_W_SDA(0); OLED_W_SCL(0); } /* @brief I2C停止 @param 无 @retval 无 / void OLED_I2C_Stop(void) { OLED_W_SDA(0); OLED_W_SCL(1); OLED_W_SDA(1); } /* @brief I2C发送一个字节 @param Byte 要发送的一个字节 @retval 无 / void OLED_I2C_SendByte(uint8_t Byte) { uint8_t i; for (i = 0; i < 8; i++) { OLED_W_SDA(Byte & (0x80 >> i)); OLED_W_SCL(1); OLED_W_SCL(0); } OLED_W_SCL(1); //额外的一个时钟,不处理应答信号 OLED_W_SCL(0); } /* @brief OLED写命令 @param Command 要写入的命令 @retval 无 / void OLED_WriteCommand(uint8_t Command) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x00); //写命令 OLED_I2C_SendByte(Command); OLED_I2C_Stop(); } /* @brief OLED写数据 @param Data 要写入的数据 @retval 无 / void OLED_WriteData(uint8_t Data) { OLED_I2C_Start(); OLED_I2C_SendByte(0x78); //从机地址 OLED_I2C_SendByte(0x40); //写数据 OLED_I2C_SendByte(Data); OLED_I2C_Stop(); } /* @brief OLED设置光标位置 @param Y 以左上角为原点,向下方向的坐标,范围:0~7 @param X 以左上角为原点,向右方向的坐标,范围:0~127 @retval 无 / void OLED_SetCursor(uint8_t Y, uint8_t X) { OLED_WriteCommand(0xB0 | Y); //设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位 } /* @brief OLED清屏 @param 无 @retval 无 / void OLED_Clear(void) { uint8_t i, j; for (j = 0; j < 8; j++) { OLED_SetCursor(j, 0); for(i = 0; i < 128; i++) { OLED_WriteData(0x00); } } } /* @brief OLED显示一个字符 @param Line 行位置,范围:1~4 @param Column 列位置,范围:1~16 @param Char 要显示的一个字符,范围:ASCII可见字符 @retval 无 / void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char) { uint8_t i; OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i]); //显示上半部分内容 } OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ’ '][i + 8]); //显示下半部分内容 } } /* @brief OLED显示字符串 @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param String 要显示的字符串,范围:ASCII可见字符 @retval 无 / void OLED_ShowString(uint8_t Line, uint8_t Column, char String) { uint8_t i; for (i = 0; String[i] != ‘\0’; i++) { OLED_ShowChar(Line, Column + i, String[i]); } } / @brief OLED次方函数 @retval 返回值等于X的Y次方 / uint32_t OLED_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y–) { Result = X; } return Result; } / @brief OLED显示数字(十进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~4294967295 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十进制,带符号数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:-2147483648~2147483647 @param Length 要显示数字的长度,范围:1~10 @retval 无 / void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) { uint8_t i; uint32_t Number1; if (Number >= 0) { OLED_ShowChar(Line, Column, ‘+’); Number1 = Number; } else { OLED_ShowChar(Line, Column, ‘-’); Number1 = -Number; } for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + ‘0’); } } /* @brief OLED显示数字(十六进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~0xFFFFFFFF @param Length 要显示数字的长度,范围:1~8 @retval 无 / void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i, SingleNumber; for (i = 0; i < Length; i++) { SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16; if (SingleNumber < 10) { OLED_ShowChar(Line, Column + i, SingleNumber + ‘0’); } else { OLED_ShowChar(Line, Column + i, SingleNumber - 10 + ‘A’); } } } /* @brief OLED显示数字(二进制,正数) @param Line 起始行位置,范围:1~4 @param Column 起始列位置,范围:1~16 @param Number 要显示的数字,范围:0~1111 1111 1111 1111 @param Length 要显示数字的长度,范围:1~16 @retval 无 / void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + ‘0’); } } /* @brief 显示BMP图片 @param 图片大小:128×64 @param 起始点坐标(x,y) @param x的范围0~127 @param y的范围0~7 @retval 无 */ void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]) { unsigned int j=0; unsigned char x,y; if(y1%8==0) y=y1/8; else y=y1/8+1; for(y=y0;y<y1;y++) { OLED_SetCursor(y,x0); for(x=x0;x<x1;x++) { OLED_WriteData(BMP[j++]); } } } /** @brief OLED初始化 @param 无 @retval 无 */ void OLED_Init(void) { uint32_t i, j; for (i = 0; i < 1000; i++) //上电延时 { for (j = 0; j < 1000; j++); } OLED_WriteCommand(0xAE); //关闭显示 OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); //设置多路复用率 OLED_WriteCommand(0x3F); OLED_WriteCommand(0xD3); //设置显示偏移 OLED_WriteCommand(0x00); OLED_WriteCommand(0x40); //设置显示开始行 OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置 OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置 OLED_WriteCommand(0xDA); //设置COM引脚硬件配置 OLED_WriteCommand(0x12); OLED_WriteCommand(0x81); //设置对比度控制 OLED_WriteCommand(0xCF); OLED_WriteCommand(0xD9); //设置预充电周期 OLED_WriteCommand(0xF1); OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别 OLED_WriteCommand(0x30); OLED_WriteCommand(0xA4); //设置整个显示打开/关闭 OLED_WriteCommand(0xA6); //设置正常/倒转显示 OLED_WriteCommand(0x8D); //设置充电泵 OLED_WriteCommand(0x14); OLED_WriteCommand(0xAF); //开启显示 OLED_Clear(); //OLED清屏 }该代码为我的OLED.C #ifndef __OLED_H #define __OLED_H #include “main.h” void OLED_Init(void); void OLED_Clear(void); void OLED_I2C_Start(void); void OLED_I2C_Stop(void); void OLED_I2C_SendByte(uint8_t Byte); void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char); void OLED_ShowString(uint8_t Line, uint8_t Column, char *String); void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length); void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length); void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]); #endif这段代码为OLED.H #ifndef __OLED_FONT_H #define __OLED_FONT_H #include “main.h” /OLED字模库,宽8像素,高16像素/ const uint8_t OLED_F8x16[][16]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00, 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00, 0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00, 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//’ 7 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00, 0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00, 0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00, 0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04, 0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, 0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, 0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, 0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, 0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, 0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, 0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00, 0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, 0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00, 0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00, 0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00, 0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00, 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00, 0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00, 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00, 0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00, 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00, 0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00, 0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00, 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00, 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00, 0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00, 0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00, 0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 64 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00, 0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, 0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00, 0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00, 0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00, 0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00, 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00, 0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00, 0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00, 0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, 0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80, 0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00, 0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02, 0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00, 0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94 }; #endif这段代码为我的OLED.Font.h。基于这三个OLED相关驱动代码,实现基于STM32 HAL库,使用STM32CUBEMX进行引脚配置,keil运行代码,生成hex文件,Proteus展示实验结果,实现对来自外部两路正交的方波(该方波为弦波经迟滞比较器后形成的方波,幅值为400mv)进行计数,然后计数结果用Proteus里的OLED12864I2C显示(没有使用I2C,使用PB6,PB7模拟SCL,SDA,基于我上述提供的OLED相关代码)。给出实现流程。

// GND 电源地 // VCC 接5V或3.3v电源 // SCL 接PA5(SCL) // SDA 接PA7(SDA) // RES 接PB0 // DC 接PB1 // CS 接PA4 // BL 接PB10 #define RED 0xf800 #define GREEN 0x07e0 #define BLUE 0x001f #define WHITE 0xffff #define BLACK 0x0000 #define YELLOW 0xFFE0 #define GRAY0 0xEF7D #define GRAY1 0x8410 #define GRAY2 0x4208 #define LCD_CTRLA GPIOA #define LCD_CTRLB GPIOB #define LCD_SCL GPIO_Pin_5 //PB13--->>TFT --SCL/SCK #define LCD_SDA GPIO_Pin_7 //PB15 MOSI--->>TFT --SDA/DIN #define LCD_CS GPIO_Pin_4 //MCU_PB11--->>TFT --CS/CE #define LCD_LED GPIO_Pin_10 //MCU_PB9--->>TFT --BL #define LCD_RS GPIO_Pin_1 //PB11--->>TFT --RS/DC #define LCD_RST GPIO_Pin_0 //PB10--->>TFT --RST //#define LCD_CS_SET(x) LCD_CTRL->ODR=(LCD_CTRL->ODR&~LCD_CS)|(x ? LCD_CS:0) #define LCD_SCL_SET LCD_CTRLA->BSRR=LCD_SCL #define LCD_SDA_SET LCD_CTRLA->BSRR=LCD_SDA #define LCD_CS_SET LCD_CTRLA->BSRR=LCD_CS #define LCD_LED_SET LCD_CTRLB->BSRR=LCD_LED #define LCD_RS_SET LCD_CTRLB->BSRR=LCD_RS #define LCD_RST_SET LCD_CTRLB->BSRR=LCD_RST #define LCD_SCL_CLR LCD_CTRLA->BRR=LCD_SCL #define LCD_SDA_CLR LCD_CTRLA->BRR=LCD_SDA #define LCD_CS_CLR LCD_CTRLA->BRR=LCD_CS #define LCD_LED_CLR LCD_CTRLB->BRR=LCD_LED #define LCD_RST_CLR LCD_CTRLB->BRR=LCD_RST #define LCD_RS_CLR LCD_CTRLB->BRR=LCD_RS #define LCD_DATAOUT(x) LCD_DATA->ODR=x; #define LCD_DATAIN LCD_DATA->IDR; #define LCD_WR_DATA(data){\ LCD_RS_SET;\ LCD_CS_CLR;\ LCD_DATAOUT(data);\ LCD_WR_CLR;\ LCD_WR_SET;\ LCD_CS_SET;\ } void LCD_GPIO_Init(void); void Lcd_WriteIndex(u8 Index); void Lcd_WriteData(u8 Data); void Lcd_WriteReg(u8 Index,u8 Data); u16 Lcd_ReadReg(u8 LCD_Reg); void Lcd_Reset(void); void Lcd_Init(void); void Lcd_Clear(u16 Color); void Lcd_SetXY(u16 x,u16 y); void Gui_DrawPoint(u16 x,u16 y,u16 Data); unsigned int Lcd_ReadPoint(u16 x,u16 y); void Lcd_SetRegion(u16 x_start,u16 y_start,u16 x_end,u16 y_end); void LCD_WriteData_16Bit(u16 Data); 解释以上代码

#ifndef __ADXL345_H #define __ADXL345_H #include "sys.h" /*****************辰哥单片机设计****************** STM32 * 文件 : ADXL345传感器h文件 * 版本 : V1.0 * 日期 : 2024.8.15 * MCU : STM32F103C8T6 * 接口 : 见代码 * BILIBILI : 辰哥单片机设计 * CSDN : 辰哥单片机设计 * 作者 : 辰哥 **********************BEGIN***********************/ /***************根据自己需求更改****************/ //ADXL345引脚宏定义 #define ADXL345_SCL_PORT GPIOB #define ADXL345_SCL_PIN GPIO_Pin_7 #define ADXL345_SCL_GPIO_CLK RCC_APB2Periph_GPIOB #define ADXL345_SDA_PORT GPIOB #define ADXL345_SDA_PIN GPIO_Pin_6 #define ADXL345_SDA_GPIO_CLK RCC_APB2Periph_GPIOB #define ADXL345_IIC_SCL PBout(7) //SCL #define ADXL345_IIC_SDA PBout(6) //SDA #define ADXL345_READ_SDA PBin(6) //输入SDA /*********************END**********************/ #define X_AXLE 0 //x轴 #define Y_AXLE 1 //y轴 #define Z_AXLE 2 //z轴 #define slaveaddress 0xA6 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改 // ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A #define THRESH_TAP 0X1D //敲击中断阈值(用于正常敲击检测) // 16g模式中,62.5mg/Bit #define OFSX 0X1E //X轴偏移寄存器 15.6mg/Bit 0xff = 4g #define OFSY 0X1F //Y轴偏移寄存器 15.6mg/Bit 0xff = 4g #define OFSZ 0X20 //Z轴偏移寄存器 15.6mg/Bit 0xff = 4g #define DUR 0x21 //敲击阈值时间 625uS/Bit #define LATENT 0X22 //敲击事件到时间窗口的延迟时间,在此期间 // 可检测第二次敲击时间 1.25mg/Bit #define WINDOW 0X23 //敲击窗口,延迟时间满后的时间量,在此期间 // 能开始进行第二次有效敲击 1.25mg/Bit #define THRESH_ACT 0X24 //检测活动的阈值,活动事件的幅度与该寄存器 // 的值进行比较 62.5mg/Bit #define THRESH_INACT 0X25 //检测静止的阈值,静止事件的幅度与该寄存器 // 的值进行比较 62.5mg/Bit #define TIME_INACT 0X26 //加速度时间量小于该寄存器的值表示静止 1S/Bit #define ACT_INACT_CTL 0X27 //Bit 7,3 ACT交流/直流[INACT交流/直流]:0选择直流耦合;1使能交流耦合 直流时将 // 当前加速度值直接与THRESH_ACT和THRESH_INACT // 进行比较,确定检测到的是活动还是静止 // 6,2 ACT_X使能[INACT_X使能]:设置为1,使能X轴参与检测活动或静止;活动检测时, // 所有轴为逻辑"或",有任意轴超过阈值时,活动功能触发 // 禁止检测时,所有轴为逻辑"与",只有当所有轴低于阈值 // 时,静止功能触发 // 5,1 ACT_Y使能[INACT_Y使能]:与X轴类似 // 4,0 ACT_Z使能[INACT_Z使能]:与X轴类似 #define THRESH_FF 0X28 //阈值,用于自由落体检测,所有轴加速度与该寄存器值比较 // ,以确定是否发生自由落体 62.5mg/Bit,建议300mg与600mg之间 #define TIME_FF 0X29 //维持THRESH_FF阈值的最小时间,以生成自由落体中断 5mS/Bit #define TAP_AXES 0X2A // Bit 7:4 0 // 3 抑制 两次敲击之间出现大于THRESH_TAP值得加速度,设置抑制会抑制双击检测 // 2 TAP_X使能 设置为1时,使能X轴进行敲击检测,0时排除该轴的敲击检测 // 1 TAP_Y使能 设置为1时,使能Y轴进行敲击检测,0时排除该轴的敲击检测 // 0 TAP_Z使能 设置为1时,使能Z轴进行敲击检测,0时排除该轴的敲击检测 #define ACT_TAP_STATUS 0X2B /*只读寄存器*/ // Bit 7 0 // 6,2 ACT_X来源,TAP_X来源:表示涉及敲击或活动事件的第一轴,设置为1时,对应事件参与 // 设置为0时,对应未参与.不会自动清零,新数据覆盖,中断清零前 // 应读取该寄存器 // 5,1 ACT_Y来源,TAP_Y来源:与X相似 // 4,0 ACT_Z来源,TAP_Z来源:与X相似 // 3 休眠设置为1时,器件进入休眠状态 #define BW_RATE 0X2C // Bit 7:5 0 // 4 LOW_POWER 低功耗位,0选择正常模式,1进入低功耗模式 // 3:0 速率位 #define POWER_CTL 0X2D // Bit 7,6 0 // 5 链接 设置1时,延迟活动开始,直到检测到静止.检测到活动后,禁止检测开始,活动 // 检测停止,设置时动态链接活动和静止交替检测;设置0时静止与活动同时检测 // 4 AUTO_SLEEP 设置1时自动休眠,检测出静止后,进行休眠模式,活动使能后被唤醒 // 3 测量 0待机 1测量模式 // 2 休眠 0普通 1休眠 // 1,0 唤醒(休眠模式下的读取频率) "00":8HZ "01":4HZ "10":2HZ "11":1HZ #define INT_ENABLE 0X2E //中断使能配置 // Bit 7 DATA_READY // 6 SINGLE_TAP // 5 DOUBLE_TAP // 4 Activity // 3 Inactivity // 2 FREE_FALL 自由落体中断 // 1 Watermark // 0 Overrun #define INT_MAP 0X2F //中断映射 自读寄存器 //位与INT_ENABLE对应,,设置为0,该中断映射到INT1引脚;设置为1,该中断映射到INT2引脚 #define INT_SOURCE 0X30 //中断来源 //位与INT_ENABLE对应,1表示该功能触发 #define DATA_FORMAT 0X31 // Bit 7 SELF_TEST 设置1,自测力应用至传感器,造成输出数据转换;0时禁用自测力 // 6 SPI 1设置为3线SPI模式,0时设置4线SPI模式 // 5 INT_INVERT 0时中断高电平有效,1时低电平有效 // 4 0 // 3 FULL_RES 1时设置全分辨率模式,输出以4mg/Bit增加;0时为10位模式 // 2 Justify 1为左对齐模式;8为右对齐模式,并带有符号扩展 // 1:0 范围位 "00"±2g "01"±4g "10"±8g "11"±16g #define DATAX0 0X32 #define DATAX1 0X33 //与DATAX0组成x轴输出数据(二进制补码),DATAX1为高位,4mg/Bit #define DATAY0 0X34 #define DATAY1 0X35 //与DATAY0组成Y轴输出数据(二进制补码),DATAY1为高位,4mg/Bit #define DATAZ0 0X36 #define DATAZ1 0X37 //与DATAZ0组成Z轴输出数据(二进制补码),DATAZ1为高位,4mg/Bit #define FIFO_CTL 0X38 // Bit 7,6 FIFO_MODE "00" 旁路模式 // "01" FIFO模式 可收集最多32个值,然后停止收集数据 // "10" 流模式 FIFO保存最后32个数据值,FIFO满时,新数据覆盖最早数据(先进先出) // "11" 触发器 通过触发位触发,FIFO在触发事件前保存最后的数据样本,然后 // 继续收集数据直到填满;填满后,不再收集新数据 // 5 触发位 0链接触发器模式下的触发事件至INT1,1链接至INT2 // 4:0 样本 功能取决于FIFO模式:FIFO模式时,指定触发水印中断需要的FIFO条目数 // 流模式时,指定触发水印中断需要的FIFO条目数 // 触发器模式:指定触发事件之前在FIFO缓冲区要保留的FIFO样本数 // 样本位设置为0时,不管哪种FIFO模式,立即在INT_SOURCE寄存器设置水印状态位 #define FIFO_STATUS 0X39 /*只读寄存器*/ // Bit 7 FIFO_TRIG FIFO_TRIG为1时表示有触发事件发生 // 6 0 // 5:0 条目位 报告FIFO存储的数据值的数量 //#define slaveaddress 0XA6//write #define regaddress 0XA7//read #define DEVICE_ID 0X00 void ADXL345_IIC_SDA_Mode(u8 mode);//ADXL345引脚输出模式控制 void ADXL345_IIC_SDA_OUT(void); void ADXL345_IIC_SDA_IN(void); void ADXL345_IIC_Init(void); void ADXL345_IIC_Start(void); void ADXL345_IIC_Stop(void); void ADXL345_IIC_Ack(void); void ADXL345_IIC_NAck(void); u8 ADXL345_IIC_Wait_Ack(void); void ADXL345_IIC_Send_Byte(u8 txd); u8 ADXL345_IIC_Read_Byte(u8 ack); void ADXL345_Init(void); u8 adxl345_read_reg(u8 addr); void adxl345_write_reg(u8 addr,u8 val); void adxl345_read_data(short *x,short *y,short *z); void adxl345_read_average(float *x,float *y,float *z,u8 times); void ADXL345_Start(void); void ADXL345_Stop(void); void get_angle(float *x_angle,float *y_angle,float *z_angle); #endif从引脚的设置详细说明计步功能的实现

在下面代码中加入PL0语言输入输出扩展 这是.h文件 #include <stdio.h> #define norw 11 // no. of reserved words #define txmax 100 // length of identifier table #define nmax 14 // max. no. of digits in numbers #define al 10 // length of identifiers #define amax 2047 // maximum address #define levmax 3 // maximum depth of block nesting #define cxmax 2000 // size of code array #define nul 0x1 #define ident 0x2 #define number 0x4 #define plus 0x8 #define minus 0x10 #define times 0x20 #define slash 0x40 #define oddsym 0x80 #define eql 0x100 #define neq 0x200 #define lss 0x400 #define leq 0x800 #define gtr 0x1000 #define geq 0x2000 #define lparen 0x4000 #define rparen 0x8000 #define comma 0x10000 #define semicolon 0x20000 #define period 0x40000 #define becomes 0x80000 #define beginsym 0x100000 #define endsym 0x200000 #define ifsym 0x400000 #define thensym 0x800000 #define whilesym 0x1000000 #define dosym 0x2000000 #define callsym 0x4000000 #define constsym 0x8000000 #define varsym 0x10000000 #define procsym 0x20000000 enum object { constant, variable, proc }; enum fct { lit, opr, lod, sto, cal, Int, jmp, jpc // functions }; /* lit 0, a : load constant a opr 0, a : execute operation a lod l, a : load variable l, a sto l, a : store variable l, a cal l, a : call procedure a at level l Int 0, a : increment t-register by a jmp 0, a : jump to a jpc 0, a : jump conditional to a */ typedef struct { enum fct f; // function code long l; // level long a; // displacement address } instruction; char* err_msg[] = { /* 0 */ "", /* 1 */ "Found ':=' when expecting '='.", /* 2 */ "There must be a number to follow '='.", /* 3 */ "There must be an '=' to follow the identifier.", /* 4 */ "There must be an identifier to follow 'const', 'var', or 'procedure'.", /* 5 */ "Missing ',' or ';'.", /* 6 */ "Incorrect procedure name.", /* 7 */ "Statement expected.", /* 8 */ "Follow the statement is an incorrect symbol.", /* 9 */ "'.' expected.", /* 10 */ "';' expected.", /* 11 */ "Undeclared identifier.", /* 12 */ "Illegal assignment.", /* 13 */ "':=' expected.", /* 14 */ "There must be an identifier to follow the 'call'.", /* 15 */ "A constant or variable can not be called.", /* 16 */ "'then' expected.", /* 17 */ "';' or 'end' expected.", /* 18 */ "'do' expected.", /* 19 */ "Incorrect symbol.", /* 20 */ "Relative operators expected.", /* 21 */ "Procedure identifier can not be in an expression.", /* 22 */ "Missing ')'.", /* 23 */ "The symbol can not be followed by a factor.", /* 24 */ "The symbol can not be as the beginning of an expression.", /* 25 */ "", /* 26 */ "", /* 27 */ "", /* 28 */ "", /* 29 */ "", /* 30 */ "", /* 31 */ "The number is too great.", /* 32 */ "There are too many levels." }; char ch; // last character read unsigned long sym; // last symbol read char id[al+1]; // last identifier read long num; // last number read long cc; // character count long ll; // line length long kk, err; long cx; // code allocation index char line[81]; char a[al+1]; instruction code[cxmax+1]; char word[norw][al+1]; unsigned long wsym[norw]; unsigned long ssym[256]; char mnemonic[8][3+1]; unsigned long declbegsys, statbegsys, facbegsys; struct { char name[al+1]; enum object kind; long val; long level; long addr; }table[txmax+1]; char infilename[80]; FILE* infile; // the following variables for block long dx; // data allocation index long lev; // current depth of block nesting long tx; // current table index // the following array space for interpreter #define stacksize 50000 long s[stacksize]; // datastore 这是.c文件 // pl/0 compiler with code generation #include <stdlib.h> #include <string.h> #include "pl0.h" void error(long n) { long i; printf("Error=>"); for (i = 1; i <= cc-1; i++) { printf(" "); } printf("|%s(%d)\n", err_msg[n], n); err++; } void getch() { if(cc == ll) { if(feof(infile)) { printf("************************************\n"); printf(" program incomplete\n"); printf("************************************\n"); exit(1); } ll = 0; cc = 0; printf("%5d ", cx); while((!feof(infile)) && ((ch=getc(infile))!='\n')) { printf("%c", ch); ll = ll + 1; line[ll] = ch; } printf("\n"); ll = ll + 1; line[ll] = ' '; } cc = cc + 1; ch = line[cc]; } void getsym() { long i, j, k; while(ch == ' ' || ch == '\t') { getch(); } if(isalpha(ch)) // identified or reserved { k = 0; do { if(k < al) { a[k] = ch; k = k + 1; } getch(); } while(isalpha(ch) || isdigit(ch)); if(k >= kk) { kk = k; } else { do { kk = kk-1; a[kk] = ' '; } while(k < kk); } strcpy(id, a); i = 0; j = norw - 1; do { k = (i+j)/2; if(strcmp(id, word[k]) <= 0) { j = k - 1; } if(strcmp(id, word[k]) >=0) { i = k + 1; } } while(i <= j); if(i-1 > j) { sym = wsym[k]; } else { sym = ident; } } else if(isdigit(ch)) // number { k = 0; num = 0; sym = number; do { num = num * 10 + (ch - '0'); k = k + 1; getch(); } while(isdigit(ch)); if(k > nmax) { error(31); } } else if(ch == ':') { getch(); if(ch == '=') { sym = becomes; getch(); } else { sym = nul; } } else if(ch == '<') { getch(); if(ch == '=') { sym = leq; getch(); } else if(ch == '>') { sym=neq; getch(); } else { sym = lss; } } else if(ch == '>') { getch(); if(ch == '=') { sym=geq; getch(); } else { sym=gtr; } } else { sym = ssym[(unsigned char)ch]; getch(); } } void gen(enum fct x, long y, long z) { if(cx > cxmax) { printf("program too long\n"); exit(1); } code[cx].f = x; code[cx].l = y; code[cx].a = z; cx = cx + 1; } void test(unsigned long s1, unsigned long s2, long n) { if (!(sym & s1)) { error(n); s1 = s1 | s2; while(!(sym & s1)) { getsym(); } } } void enter(enum object k) // enter object into table { tx = tx + 1; strcpy(table[tx].name, id); table[tx].kind = k; switch(k) { case constant: if(num > amax) { error(31); num = 0; } table[tx].val = num; break; case variable: table[tx].level = lev; table[tx].addr = dx; dx = dx + 1; break; case proc: table[tx].level = lev; break; } } long position(char* id) // find identifier id in table { long i; strcpy(table[0].name, id); i=tx; while(strcmp(table[i].name, id) != 0) { i = i - 1; } return i; } void constdeclaration() { if(sym == ident) { getsym(); if(sym == eql || sym == becomes) { if(sym == becomes) { error(1); } getsym(); if(sym == number) { enter(constant); getsym(); } else { error(2); } } else { error(3); } } else { error(4); } } void vardeclaration() { if(sym == ident) { enter(variable); getsym(); } else { error(4); } } void listcode(long cx0) // list code generated for this block { long i; for(i=cx0; i<=cx-1; i++) { printf("%10d%5s%3d%5d\n", i, mnemonic[code[i].f], code[i].l, code[i].a); } } void expression(unsigned long); void factor(unsigned long fsys) { long i; test(facbegsys, fsys, 24); while(sym & facbegsys) { if(sym == ident) { i = position(id); if(i==0) { error(11); } else { switch(table[i].kind) { case constant: gen(lit, 0, table[i].val); break; case variable: gen(lod, lev-table[i].level, table[i].addr); break; case proc: error(21); break; } } getsym(); } else if(sym == number) { if(num>amax) { error(31); num=0; } gen(lit,0,num); getsym(); } else if(sym == lparen) { getsym(); expression(rparen|fsys); if(sym==rparen) { getsym(); } else { error(22); } } test(fsys,lparen,23); } } void term(unsigned long fsys) { unsigned long mulop; factor(fsys|times|slash); while(sym==times || sym==slash) { mulop = sym; getsym(); factor(fsys|times|slash); if(mulop == times) { gen(opr,0,4); } else{ gen(opr,0,5); } } } void expression(unsigned long fsys) { unsigned long addop; if(sym==plus || sym==minus) { addop=sym; getsym(); term(fsys|plus|minus); if(addop==minus) { gen(opr,0,1); } } else { term(fsys|plus|minus); } while(sym==plus || sym==minus) { addop=sym; getsym(); term(fsys|plus|minus); if(addop==plus) { gen(opr,0,2); } else { gen(opr,0,3); } } } void condition(unsigned long fsys) { unsigned long relop; if(sym==oddsym) { getsym(); expression(fsys); gen(opr, 0, 6); } else { expression(fsys|eql|neq|lss|gtr|leq|geq); if(!(sym&(eql|neq|lss|gtr|leq|geq))) { error(20); } else { relop=sym; getsym(); expression(fsys); switch(relop) { case eql: gen(opr, 0, 8); break; case neq: gen(opr, 0, 9); break; case lss: gen(opr, 0, 10); break; case geq: gen(opr, 0, 11); break; case gtr: gen(opr, 0, 12); break; case leq: gen(opr, 0, 13); break; } } } } void statement(unsigned long fsys) { long i,cx1,cx2; if(sym==ident) { i=position(id); if(i==0) { error(11); } else if(table[i].kind!=variable) // assignment to non-variable { error(12); i=0; } getsym(); if(sym==becomes) { getsym(); } else { error(13); } expression(fsys); if(i!=0) { gen(sto,lev-table[i].level,table[i].addr); } } else if(sym==callsym) { getsym(); if(sym!=ident) { error(14); } else { i=position(id); if(i==0) { error(11); } else if(table[i].kind==proc) { gen(cal,lev-table[i].level,table[i].addr); } else { error(15); } getsym(); } } else if(sym==ifsym) { getsym(); condition(fsys|thensym|dosym); if(sym==thensym) { getsym(); } else { error(16); } cx1=cx; gen(jpc,0,0); statement(fsys); code[cx1].a=cx; } else if(sym==beginsym) { getsym(); statement(fsys|semicolon|endsym); while(sym==semicolon||(sym&statbegsys)) { if(sym==semicolon) { getsym(); } else { error(10); } statement(fsys|semicolon|endsym); } if(sym==endsym) { getsym(); } else { error(17); } } else if(sym==whilesym) { cx1=cx; getsym(); condition(fsys|dosym); cx2=cx; gen(jpc,0,0); if(sym==dosym) { getsym(); } else { error(18); } statement(fsys); gen(jmp,0,cx1); code[cx2].a=cx; } test(fsys,0,19); } void block(unsigned long fsys) { long tx0; // initial table index long cx0; // initial code index long tx1; // save current table index before processing nested procedures long dx1; // save data allocation index dx=3; tx0=tx; table[tx].addr=cx; gen(jmp,0,0); if(lev>levmax) { error(32); } do { if(sym==constsym) { getsym(); do { constdeclaration(); while(sym==comma) { getsym(); constdeclaration(); } if(sym==semicolon) { getsym(); } else { error(5); } } while(sym==ident); } if(sym==varsym) { getsym(); do { vardeclaration(); while(sym==comma) { getsym(); vardeclaration(); } if(sym==semicolon) { getsym(); } else { error(5); } } while(sym==ident); } while(sym==procsym) { getsym(); if(sym==ident) { enter(proc); getsym(); } else { error(4); } if(sym==semicolon) { getsym(); } else { error(5); } lev=lev+1; tx1=tx; dx1=dx; block(fsys|semicolon); lev=lev-1; tx=tx1; dx=dx1; if(sym==semicolon) { getsym(); test(statbegsys|ident|procsym,fsys,6); } else { error(5); } } test(statbegsys|ident,declbegsys,7); } while(sym&declbegsys); code[table[tx0].addr].a=cx; table[tx0].addr=cx; // start addr of code cx0=cx; gen(Int,0,dx); statement(fsys|semicolon|endsym); gen(opr,0,0); // return test(fsys,0,8); listcode(cx0); } long base(long b, long l) { long b1; b1=b; while (l>0) // find base l levels down { b1=s[b1]; l=l-1; } return b1; } void interpret() { long p,b,t; // program-, base-, topstack-registers instruction i; // instruction register printf("start PL/0\n"); t=0; b=1; p=0; s[1]=0; s[2]=0; s[3]=0; do { i=code[p]; p=p+1; switch(i.f) { case lit: t=t+1; s[t]=i.a; break; case opr: switch(i.a) // operator { case 0: // return t=b-1; p=s[t+3]; b=s[t+2]; break; case 1: s[t]=-s[t]; break; case 2: t=t-1; s[t]=s[t]+s[t+1]; break; case 3: t=t-1; s[t]=s[t]-s[t+1]; break; case 4: t=t-1; s[t]=s[t]*s[t+1]; break; case 5: t=t-1; s[t]=s[t]/s[t+1]; break; case 6: s[t]=s[t]%2; break; case 8: t=t-1; s[t]=(s[t]==s[t+1]); break; case 9: t=t-1; s[t]=(s[t]!=s[t+1]); break; case 10: t=t-1; s[t]=(s[t]<s[t+1]); break; case 11: t=t-1; s[t]=(s[t]>=s[t+1]); break; case 12: t=t-1; s[t]=(s[t]>s[t+1]); break; case 13: t=t-1; s[t]=(s[t]<=s[t+1]); } break; case lod: t=t+1; s[t]=s[base(b,i.l)+i.a]; break; case sto: s[base(b,i.l)+i.a]=s[t]; printf("%10d\n", s[t]); t=t-1; break; case cal: // generate new block mark s[t+1]=base(b,i.l); s[t+2]=b; s[t+3]=p; b=t+1; p=i.a; break; case Int: t=t+i.a; break; case jmp: p=i.a; break; case jpc: if(s[t]==0) { p=i.a; } t=t-1; } } while(p!=0); printf("end PL/0\n"); } int main() { long i; for(i=0; i<256; i++) { ssym[i]=nul; } strcpy(word[0], "begin "); strcpy(word[1], "call "); strcpy(word[2], "const "); strcpy(word[3], "do "); strcpy(word[4], "end "); strcpy(word[5], "if "); strcpy(word[6], "odd "); strcpy(word[7], "procedure "); strcpy(word[8], "then "); strcpy(word[9], "var "); strcpy(word[10], "while "); wsym[0]=beginsym; wsym[1]=callsym; wsym[2]=constsym; wsym[3]=dosym; wsym[4]=endsym; wsym[5]=ifsym; wsym[6]=oddsym; wsym[7]=procsym; wsym[8]=thensym; wsym[9]=varsym; wsym[10]=whilesym; ssym['+']=plus; ssym['-']=minus; ssym['*']=times; ssym['/']=slash; ssym['(']=lparen; ssym[')']=rparen; ssym['=']=eql; ssym[',']=comma; ssym['.']=period; ssym[';']=semicolon; strcpy(mnemonic[lit],"LIT"); strcpy(mnemonic[opr],"OPR"); strcpy(mnemonic[lod],"LOD"); strcpy(mnemonic[sto],"STO"); strcpy(mnemonic[cal],"CAL"); strcpy(mnemonic[Int],"INT"); strcpy(mnemonic[jmp],"JMP"); strcpy(mnemonic[jpc],"JPC"); declbegsys=constsym|varsym|procsym; statbegsys=beginsym|callsym|ifsym|whilesym; facbegsys=ident|number|lparen; printf("please input source program file name: "); scanf("%s",infilename); printf("\n"); if((infile=fopen(infilename,"r"))==NULL) { printf("File %s can't be opened.\n", infilename); exit(1); } err=0; cc=0; cx=0; ll=0; ch=' '; kk=al; getsym(); lev=0; tx=0; block(declbegsys|statbegsys|period); if(sym!=period) { error(9); } if(err==0) { // interpret(); } else { printf("errors in PL/0 program\n"); } fclose(infile); return (0); }

头文件代码如下: #ifndef _SERVO_CONTROL_H_ #define _SERVO_CONTROL_H_ #include "stm32f4xx_hal.h" #include <stdbool.h> #include <stdint.h> #include "usart.h" #define FRAME_HEADER 0x55 //帧头 #define CMD_SERVO_MOVE 0x03 //舵机移动指令 #define CMD_ACTION_GROUP_RUN 0x06 //运行动作组指令 #define CMD_ACTION_GROUP_STOP 0x07 //停止动作组指令 #define CMD_ACTION_GROUP_SPEED 0x0B //设置动作组运行速度 #define CMD_GET_BATTERY_VOLTAGE 0x0F //获取电池电压指令 extern bool isUartRxCompleted; extern uint8_t LobotRxBuf[16]; extern uint16_t batteryVolt; extern void receiveHandle(void); typedef struct _servo_ { uint8_t ID; uint16_t Position; } servo; void moveServo(uint8_t servoID, uint16_t Position, uint16_t Time); void moveServosByArray(servo servos[], uint8_t Num, uint16_t Time); void moveServos(uint8_t Num, uint16_t Time, ...); void runActionGroup(uint8_t numOfAction, uint16_t Times); void stopActionGroup(void); void setActionGroupSpeed(uint8_t numOfAction, uint16_t Speed); void setAllActionGroupSpeed(uint16_t Speed); #endif 报错: *** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil\MDK536\ARM\ARMCC\Bin' compiling ServoControl.c... ..\Drivers\ServoControl\Include\ServoControl.h(16): error: #130: expected a "{" extern bool isUartRxCompleted; ..\Drivers\ServoControl\Include\ServoControl.h(21): warning: #12-D: parsing restarts here after previous syntax error typedef struct _servo_ { ..\Drivers\ServoControl\Include\ServoControl.h(22): warning: #177-D: variable "ID" was declared but never referenced uint8_t ID; ..\Drivers\ServoControl\Include\ServoControl.h(23): warning: #177-D: variable "Position" was declared but never referenced uint16_t Position; ..\Drivers\ServoControl\Include\ServoControl.h(24): error: #77-D: this declaration has no storage class or type specifier } servo; ..\Drivers\ServoControl\Include\ServoControl.h(27): error: #757: variable "servo" is not a type name void moveServosByArray(servo servos[], uint8_t Num, uint16_t Time); ..\Drivers\ServoControl\Include\ServoControl.h(33): warning: #1-D: last line of file ends without a newline #endif ..\Drivers\ServoControl\Source\ServoControl.c(50): error: #757: variable "servo" is not a type name void moveServosByArray(servo servos[], uint8_t Num, uint16_t Time) ..\Drivers\ServoControl\Source\ServoControl.c: 4 warnings, 4 errors "..\Drivers\ServoControl\Source\ServoControl.c" - 4 Error(s), 4 Warning(s).

大家在看

recommend-type

Xilinx ISE rs_decoder_ipcore and encoder License

Xilinx ISE RS编码解码IP核的License
recommend-type

毕业设计&课设-一个基于Matlab的PET仿真和重建框架,具有系统矩阵的分析建模,能够结合各种数据….zip

matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随
recommend-type

MATLAB机械臂简单控制仿真(Simulink篇-总).zip

MATLAB下机器人可视化与控制---simulink篇中的简单例子,在Simulink中做了预定义轨迹的运动和Slider Gain控制的运动,用GUI控制的关节代码在MATLAB下机器人可视化与控制
recommend-type

使用 GCC 构建 STM23F0 ARM 项目的模板源码

使用 GCC 构建 STM23F0 ARM 项目的模板源码,具体请看 README
recommend-type

详细说明 VC++的MFC开发串口调试助手源代码,包括数据发送,接收,显示制式等29782183com

详细说明 VC++的MFC开发串口调试助手源代码,包括数据发送,接收,显示制式等29782183com

最新推荐

recommend-type

计算机网络学习中学员常见问题与改进方法

计算机网络学习中学员常见问题与改进方法+
recommend-type

美国国际航空交通数据分析报告(1990-2020)

根据给定的信息,我们可以从中提取和分析以下知识点: 1. 数据集概述: 该数据集名为“U.S. International Air Traffic data(1990-2020)”,记录了美国与国际间航空客运和货运的详细统计信息。数据集涵盖的时间范围从1990年至2020年,这说明它包含了长达30年的时间序列数据,对于进行长期趋势分析非常有价值。 2. 数据来源及意义: 此数据来源于《美国国际航空客运和货运统计报告》,该报告是美国运输部(USDOT)所管理的T-100计划的一部分。T-100计划旨在收集和发布美国和国际航空公司在美国机场的出入境交通报告,这表明数据的权威性和可靠性较高,适用于政府、企业和学术研究等领域。 3. 数据内容及应用: 数据集包含两个主要的CSV文件,分别是“International_Report_Departures.csv”和“International_Report_Passengers.csv”。 a. International_Report_Departures.csv文件可能包含了以下内容: - 离港航班信息:记录了各航空公司的航班号、起飞和到达时间、起飞和到达机场的代码以及国际地区等信息。 - 航空公司信息:可能包括航空公司代码、名称以及所属国家等。 - 飞机机型信息:如飞机类型、座位容量等,这有助于分析不同机型的使用频率和趋势。 - 航线信息:包括航线的起始和目的国家及城市,对于研究航线网络和优化航班计划具有参考价值。 这些数据可以用于航空交通流量分析、机场运营效率评估、航空市场分析等。 b. International_Report_Passengers.csv文件可能包含了以下内容: - 航班乘客信息:可能包括乘客的国籍、年龄、性别等信息。 - 航班类型:如全客机、全货机或混合型航班,可以分析乘客运输和货物运输的比例。 - 乘客数量:记录了各航班或航线的乘客数量,对于分析航空市场容量和增长趋势很有帮助。 - 飞行里程信息:有助于了解国际间不同航线的长度和飞行距离,为票价设置和燃油成本分析提供数据支持。 这些数据可以用于航空客运市场分析、需求预测、收益管理等方面。 4. 数据分析和应用实例: - 航空流量分析:通过分析离港航班数据,可以观察到哪些航线最为繁忙,哪些机场的国际航空流量最大,这有助于航空公司调整航班时刻表和运力分配。 - 市场研究:乘客数据可以揭示不同国家和地区之间的人口流动趋势,帮助航空公司和政府机构了解国际旅行市场的需求变化。 - 飞机利用率:结合飞机机型和飞行频率信息,可以对特定机型的使用率进行分析,评估飞机维护需求和燃油效率。 - 安全监管:通过对比不同航空公司和航班的安全记录,监管机构可以更有效地评估航空公司的安全性能,并采取必要的监管措施。 5. 技术和方法论: 分析此类数据通常涉及数据清洗、数据整合、统计分析、时间序列分析、预测建模等数据科学方法。使用Excel、SQL、R、Python等工具进行数据处理和分析是常见的做法。例如,可以使用Python的Pandas库来清洗和准备数据,使用Matplotlib和Seaborn库来可视化数据,然后利用Scikit-learn或Statsmodels库来构建预测模型。 通过以上知识点的提取和分析,我们可以理解到“U.S. International Air Traffic data(1990-2020)-数据集”的重要性,它不仅记录了跨越30年的航空交通数据,还为各种分析和应用提供了详实的基础信息。对于航空业从业者、政策制定者、研究人员以及数据分析师来说,这是一个极具价值的数据资源。
recommend-type

统计学视角:深入理解最小二乘法的概率论基础

# 1. 最小二乘法的基本概念 最小二乘法(Least Squares Method, LSM)是统计学和数据分析中广泛使用的一种数学优化技术。其主要目的是通过最小化误差的平方和来寻找数据的最佳函数匹配。这种方法最早由高斯提出,但在工程、物理、经济和其他领域中有着广泛的应用。 在本章中,我们将首先了
recommend-type

vscode中使用Codeium

<think>好的,我需要回答用户如何在VSCode中使用Codeium插件的问题。首先,我需要回顾用户提供的引用内容,看看是否有相关信息。用户提供的引用[1]提到了Codeium Chat可以解释代码中的问题,引用[2]提到了在IDEA中的一些问题,可能对VSCode的安装有帮助。用户还提到了安装步骤、基本功能、常见问题等。 首先,我应该分步骤说明安装过程,包括在VSCode扩展商店搜索Codeium并安装。然后,登录部分可能需要用户访问仪表板获取API密钥,引用[2]中提到登录问题,可能需要提醒用户注意网络或权限设置。 接下来是基本功能,比如代码自动补全和Chat功能。引用[1]提到C
recommend-type

UniMoCo:统一框架下的多监督视觉学习方法

在详细解析“unimoco”这个概念之前,我们需要明确几个关键点。首先,“unimoco”代表的是一种视觉表示学习方法,它在机器学习尤其是深度学习领域中扮演着重要角色。其次,文章作者通过这篇论文介绍了UniMoCo的全称,即“Unsupervised, Semi-Supervised and Full-Supervised Visual Representation Learning”,其背后的含义是在于UniMoCo框架整合了无监督学习、半监督学习和全监督学习三种不同的学习策略。最后,该框架被官方用PyTorch库实现,并被提供给了研究者和开发者社区。 ### 1. 对比学习(Contrastive Learning) UniMoCo的概念根植于对比学习的思想,这是一种无监督学习的范式。对比学习的核心在于让模型学会区分不同的样本,通过将相似的样本拉近,将不相似的样本推远,从而学习到有效的数据表示。对比学习与传统的分类任务最大的不同在于不需要手动标注的标签来指导学习过程,取而代之的是从数据自身结构中挖掘信息。 ### 2. MoCo(Momentum Contrast) UniMoCo的实现基于MoCo框架,MoCo是一种基于队列(queue)的对比学习方法,它在训练过程中维持一个动态的队列,其中包含了成对的负样本。MoCo通过 Momentum Encoder(动量编码器)和一个队列来保持稳定和历史性的负样本信息,使得模型能够持续地进行对比学习,即使是在没有足够负样本的情况下。 ### 3. 无监督学习(Unsupervised Learning) 在无监督学习场景中,数据样本没有被标记任何类别或标签,算法需自行发现数据中的模式和结构。UniMoCo框架中,无监督学习的关键在于使用没有标签的数据进行训练,其目的是让模型学习到数据的基础特征表示,这对于那些标注资源稀缺的领域具有重要意义。 ### 4. 半监督学习(Semi-Supervised Learning) 半监督学习结合了无监督和有监督学习的优势,它使用少量的标注数据与大量的未标注数据进行训练。UniMoCo中实现半监督学习的方式,可能是通过将已标注的数据作为对比学习的一部分,以此来指导模型学习到更精准的特征表示。这对于那些拥有少量标注数据的场景尤为有用。 ### 5. 全监督学习(Full-Supervised Learning) 在全监督学习中,所有的训练样本都有相应的标签,这种学习方式的目的是让模型学习到映射关系,从输入到输出。在UniMoCo中,全监督学习用于训练阶段,让模型在有明确指示的学习目标下进行优化,学习到的任务相关的特征表示。这通常用于有充足标注数据的场景,比如图像分类任务。 ### 6. PyTorch PyTorch是一个开源机器学习库,由Facebook的人工智能研究团队开发,主要用于计算机视觉和自然语言处理等任务。它被广泛用于研究和生产环境,并且因其易用性、灵活性和动态计算图等特性受到研究人员的青睐。UniMoCo官方实现选择PyTorch作为开发平台,说明了其对科研社区的支持和对易于实现的重视。 ### 7. 可视化表示学习(Visual Representation Learning) 可视化表示学习的目的是从原始视觉数据中提取特征,并将它们转换为能够反映重要信息且更易于处理的形式。在UniMoCo中,无论是无监督、半监督还是全监督学习,最终的目标都是让模型学习到有效的视觉表示,这些表示可以用于下游任务,如图像分类、目标检测、图像分割等。 ### 8. 标签队列(Label Queue) UniMoCo通过标签队列维护受监管的标签,这可能意味着对于那些半监督或全监督学习的任务,模型在进行对比学习时,会参考这些来自标签队列的数据。标签队列机制能帮助模型更好地利用有限的标注数据,增强模型的泛化能力。 ### 结论 UniMoCo的提出,以及其官方PyTorch实现的发布,将对计算机视觉领域产生深远影响。它不仅提供了一个统一的对比学习框架,使得从无监督到全监督的学习过程更加灵活和高效,而且为研究者们提供了一个强力的工具,以便更好地探索和实现各种视觉任务。UniMoCo的研究和应用前景,为机器学习尤其是深度学习在视觉领域的研究和实践提供了新的视角和可能。
recommend-type

【MATLAB算法精讲】:最小二乘法的实现与案例深度分析

# 1. 最小二乘法的基本原理 最小二乘法是一种数学优化技术,它通过最小化误差的平方和来寻找数据的最佳函数匹配。其核心思想是选择一条曲线,使得所有观察点到这条曲线的距离之和最小。这种方法广泛应用于统计学、信号处理、工程学和经济学等领域,尤其适用于需要通过一组数据点来确定函数参数的情况。 ## 1.1 统计学视角下的最小二乘法 在统计学中,最小二乘法经常用于
recommend-type

Idea使用教程+jdk配置

<think>好的,我现在需要回答用户关于IntelliJ IDEA使用教程和JDK配置方法的问题。首先,用户明确提到了参考站内引用中的内容,引用[1]和引用[2]都涉及JDK的配置步骤,但看起来这些引用内容可能来自其他问题或文档,可能与当前问题不完全相关,但用户希望我利用这些信息来组织回答。 首先,我需要确认IntelliJ IDEA配置JDK的基本步骤,并整合用户提供的引用内容。引用[1]提到选择JDK安装根目录,例如D:\develop\Java\jdk-17,这说明配置时需要定位到JDK的主目录。引用[2]则提到了通过New按钮选择JDK版本,并完成项目创建,这部分可能涉及到项目设置
recommend-type

GitHub入门实践:审查拉取请求指南

从提供的文件信息中,我们可以抽取以下知识点: **GitHub入门与Pull Request(PR)的审查** **知识点1:GitHub简介** GitHub是一个基于Git的在线代码托管和版本控制平台,它允许开发者在互联网上进行代码的托管和协作。通过GitHub,用户可以跟踪和管理代码变更,参与开源项目,或者创建自己的私有仓库进行项目协作。GitHub为每个项目提供了问题跟踪和任务管理功能,支持Pull Request机制,以便用户之间可以进行代码的审查和讨论。 **知识点2:Pull Request的作用与审查** Pull Request(PR)是协作开发中的一个重要机制,它允许开发者向代码库贡献代码。当开发者在自己的分支上完成开发后,他们可以向主分支(或其他分支)提交一个PR,请求合入他们的更改。此时,其他开发者,包括项目的维护者,可以审查PR中的代码变更,进行讨论,并最终决定是否合并这些变更到目标分支。 **知识点3:审查Pull Request的步骤** 1. 访问GitHub仓库,并查看“Pull requests”标签下的PR列表。 2. 选择一个PR进行审查,点击进入查看详细内容。 3. 查看PR的标题、描述以及涉及的文件变更。 4. 浏览代码的具体差异,可以逐行审查,也可以查看代码变更的概览。 5. 在PR页面添加评论,可以针对整个PR,也可以针对特定的代码行或文件。 6. 当审查完成后,可以提交评论,或者批准、请求修改或关闭PR。 **知识点4:代码审查的最佳实践** 1. 确保PR的目标清晰且具有针对性,避免过于宽泛。 2. 在审查代码时,注意代码的质量、结构以及是否符合项目的编码规范。 3. 提供建设性的反馈,指出代码的优点和需要改进的地方。 4. 使用清晰、具体的语言,避免模糊和主观的评论。 5. 鼓励开发者间的协作,而不是单向的批评。 6. 经常审查PR,以避免延迟和工作积压。 **知识点5:HTML基础** HTML(HyperText Markup Language)是用于创建网页的标准标记语言。它通过各种标签(如`<p>`用于段落,`<img>`用于图片,`<a>`用于链接等)来定义网页的结构和内容。HTML文档由元素组成,这些元素通过开始标签和结束标签来标识。例如,`<p>This is a paragraph.</p>`。HTML的最新版本是HTML5,它引入了许多新的元素和API,增强了对多媒体、图形和本地存储的支持。 **知识点6:GitHub Pages功能介绍** GitHub Pages是一个静态站点托管服务,允许用户直接从GitHub仓库中发布个人、组织或项目的网站。你可以通过设置一个专门的分支来存放你的网站源代码,然后利用GitHub Pages的设置选项,选择分支并发布你的网站。发布的网站将可以通过一个自定义的URL访问,这个URL通常是`username.github.io/repo-name`的格式。这为开发者提供了一个简单而快速的方法来搭建个人或项目的展示页面。 **知识点7:简单的游戏开发实践** 文件描述中提到了一个基于项目的学习活动,通过游戏的形式,让入门人员体验操作和理解基本的游戏开发概念。在这个活动中,参与者通过键盘操作控制形状的旋转和移动,目标是创建无空隙的完整行,这涉及到游戏逻辑、用户输入处理和图形界面显示等基础知识。该活动可能使用了HTML、JavaScript和CSS等前端技术实现,参与者通过实践操作来学习如何编程,并理解基本的游戏设计原理。
recommend-type

【R语言高级教程】:最小二乘法从入门到精通

# 1. 最小二乘法的理论基础 最小二乘法是数学优化技术之一,广泛应用于统计学、数据分析和工程学等领域。其核心思想在于找到一条直线(或曲线),使得所有观测点到该直线的垂直距离之和最小,即误差平方和最小。这一方法不仅简单易行,而且可以有效减少异常值对模型的影响,使得参数估计更加稳定。 ## 1.1 最小二乘法的数学表述 在最基本的线性回归模型中,最小二乘法通过最小化误差的平方和来寻找最
recommend-type

cadence画PCB时改变线长

<think>好的,我现在需要帮助用户解决在Cadence PCB设计中调整走线长度的问题。首先,我得回想一下用户提到的引用内容,尤其是引用1、2和3,里面提到了实时显示走线长度、约束导向设计以及过孔对长度的影响。用户可能已经知道如何显示长度,现在想知道如何调整它们。 用户的问题是如何调整走线长度以满足特定需求,比如等长布线或时序要求。我应该先分步骤说明不同的调整方法,比如手动调整、使用自动优化工具、蛇形走线,以及设置约束管理器中的规则。 记得引用中的信息,比如引用2提到的约束导向环境和实时长度显示,所以需要提到约束管理器的使用。引用3讨论了过孔对长度的影响,调整过孔数量可能也是一种方法。