找回密码
 立即注册
查看: 207|回复: 3

SDCC 如何获取内部基准电压的值 | 问 doubao.com

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2026-01-02 09:35:12
已绑定手机

1

主题

0

回帖

5

积分

新手上路

积分
5
发表于 2026-1-2 09:41:35 来自手机 | 显示全部楼层 |阅读模式
用sdcc 一直无法获取到内部基准电压的值,
而用keil c51 就没问题,
求助sdcc 该如何获取 idata 和 code 存储器存储的值?

1000138659.png
1000138203.png
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:403
  • 最近打卡:2026-05-10 15:24:05

849

主题

1万

回帖

2万

积分

管理员

积分
23234
发表于 2026-1-2 10:29:01 | 显示全部楼层
你在 DEEPSEEK.COM / DOUBAO.COM 中问

KEIL C51 语句 如下:
......

SDCC 如何写
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:885
  • 最近打卡:2026-05-10 01:21:02

14

主题

1364

回帖

7390

积分

论坛元老

积分
7390
发表于 2026-1-4 22:08:15 | 显示全部楼层
我们首先需要将Keil C51的代码转换为SDCC的代码。主要注意以下几点:

头文件:SDCC中通常使用#include <8051.h>或对应芯片的头文件,但这里我们使用STC8H,可能需要特定的头文件,但原代码使用的是reg51.h,我们可能需要替换为SDCC兼容的STC8头文件,或者使用通用方法。

特殊功能寄存器(SFR)的定义:在SDCC中,SFR的定义方式与Keil不同。SDCC使用__sfr、__sbit等关键字,或者使用绝对地址定位。

中断函数:SDCC中使用__interrupt关键字,并且中断号可能有所不同。

内存空间:在Keil中,使用code关键字表示程序存储区,而在SDCC中,使用__code或者const,并且访问方式可能不同。

位变量:SDCC支持位变量,但声明方式可能不同,使用__bit。

由于原代码中使用了STC8G1K08等芯片的内部参考电压地址,这些地址位于代码区(code),在SDCC中访问代码区需要使用__code关键字。

另外,原代码中定义了一个指向int的指针BGV,并将其指向代码区的某个地址。在SDCC中,我们需要将BGV声明为指向__code int的指针。

由于SDCC的标准库中没有intrins.h,但原代码中并没有使用该头文件中的函数,所以可以去掉。

我们假设使用SDCC编译STC8系列芯片,并且使用对应的头文件。但是,如果没有合适的头文件,我们可以使用绝对地址定义SFR。

下面我们开始转换:

步骤:

替换头文件:由于SDCC没有reg51.h,我们可以使用8051.h,但为了支持STC8的扩展SFR,我们需要自定义SFR。

定义SFR:使用__sfr定义AUXR以及PxM0、PxM1。

修改中断函数为SDCC格式。

修改BGV的声明,使用__code int *。

修改主函数中的初始化部分。

注意:SDCC中,中断函数使用__interrupt(中断号)的方式,且中断号可能与Keil不同。对于UART中断,在51系列中通常是中断4,但需要确认。

由于原代码是针对STC8G1K08,我们假设使用SDCC编译,并且使用large或huge模式,因为代码地址可能超过2K。

下面给出转换后的代码:

以下是转换后的 SDCC 代码:


  1. #include <8051.h>
  2. #include <stdint.h>
  3. #define FOSC        11059200UL
  4. #define BRT         (65536 - FOSC / 115200 / 4)
  5. // 定义特殊功能寄存器
  6. __sfr __at (0x8E) AUXR;
  7. __sfr __at (0x93) P0M1;
  8. __sfr __at (0x94) P0M0;
  9. __sfr __at (0x91) P1M1;
  10. __sfr __at (0x92) P1M0;
  11. __sfr __at (0x95) P2M1;
  12. __sfr __at (0x96) P2M0;
  13. __sfr __at (0xB1) P3M1;
  14. __sfr __at (0xB2) P3M0;
  15. __sfr __at (0xB3) P4M1;
  16. __sfr __at (0xB4) P4M0;
  17. __sfr __at (0xC9) P5M1;
  18. __sfr __at (0xCA) P5M0;
  19. __bit busy;
  20. uint16_t __code *BGV;  // 指向代码存储区的指针
  21. void UartIsr() __interrupt(4)
  22. {
  23.     if (TI)
  24.     {
  25.         TI = 0;
  26.         busy = 0;
  27.     }
  28.     if (RI)
  29.     {
  30.         RI = 0;
  31.     }
  32. }
  33. void UartInit()
  34. {
  35.     SCON = 0x50;
  36.     TMOD = 0x00;
  37.     TL1 = BRT;
  38.     TH1 = BRT >> 8;
  39.     TR1 = 1;
  40.     AUXR = 0x40;
  41.     busy = 0;
  42. }
  43. void UartSend(char dat)
  44. {
  45.     while (busy);
  46.     busy = 1;
  47.     SBUF = dat;
  48. }
  49. void main()
  50. {
  51.     P0M0 = 0x00;
  52.     P0M1 = 0x00;
  53.     P1M0 = 0x00;
  54.     P1M1 = 0x00;
  55.     P2M0 = 0x00;
  56.     P2M1 = 0x00;
  57.     P3M0 = 0x00;
  58.     P3M1 = 0x00;
  59.     P4M0 = 0x00;
  60.     P4M1 = 0x00;
  61.     P5M0 = 0x00;
  62.     P5M1 = 0x00;
  63.     // 根据芯片型号选择正确的地址
  64.     BGV = (uint16_t __code *)0x1FF7;   // STC8G1K08
  65.     // BGV = (uint16_t __code *)0x3FF7;   // Ai8H1K16
  66.     // BGV = (uint16_t __code *)0x7FF7;   // Ai8H8K32U
  67.     // BGV = (uint16_t __code *)0xBFF7;   // Ai8H8K48U
  68.     // BGV = (uint16_t __code *)0xEFF7;   // Ai8H8K60U
  69.     // BGV = (uint16_t __code *)0xFDF7;   // Ai8H8K64U
  70.     // BGV = (uint16_t __code *)0x2FF7;   // Ai8H1K12
  71.     // BGV = (uint16_t __code *)0x43F7;   // Ai8H1K17
  72.     // BGV = (uint16_t __code *)0x5FF7;   // Ai8H1K24
  73.     // BGV = (uint16_t __code *)0x6FF7;   // Ai8H1K28
  74.     // BGV = (uint16_t __code *)0x83F7;   // Ai8H1K33
  75.     UartInit();
  76.     ES = 1;
  77.     EA = 1;
  78.    
  79.     // 读取内部1.19V参考信号源
  80.     UartSend(*BGV >> 8);   // 高字节
  81.     UartSend(*BGV);        // 低字节
  82.     while (1);
  83. }
复制代码






**主要修改点:**

1. **头文件**:
   - 替换 `reg51.h` 为 `8051.h`
   - 替换 `intrins.h` 为 `stdint.h`(用于标准整数类型)

2. **SFR 定义**:
   - SDCC 使用 `__sfr __at (地址)` 语法定义特殊功能寄存器
   - 所有扩展的 SFR 都需要用这种方式定义

3. **位变量**:
   - SDCC 使用 `__bit` 定义位变量

4. **代码区指针**:
   - Keil C51: `int code *`
   - SDCC: `uint16_t __code *`
   - 使用 `uint16_t` 确保处理 16 位数据

5. **编译命令**:
   ```bash
   sdcc -mmcs51 --model-large --stack-auto main.c
   ```
   - `--model-large`:适合较大的 STC8 系列芯片
   - `--stack-auto`:启用自动栈管理

6. **生成的文件**:
   - SDCC 会生成多个文件,主要是 `main.ihx`(Intel HEX 格式)
   - 可以使用 `packihx` 转换为标准 HEX 文件:
     ```bash
     packihx main.ihx > main.hex
     ```

**注意事项:**

1. **芯片型号选择**:根据实际使用的芯片取消注释对应的地址行
2. **头文件路径**:确保 SDCC 能找到 `8051.h` 头文件
3. **内存模型**:对于 STC8 系列,通常需要 `--model-large` 或 `--model-huge` 选项
4. **中断向量**:SDCC 的中断向量表与 Keil 不同,但 UART 中断号 4 是通用的

这个转换后的代码应该可以在 SDCC 中正常编译和运行,用于读取 STC8 系列芯片的内部参考电压。



回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:531
  • 最近打卡:2026-05-10 13:43:17
已绑定手机

108

主题

4377

回帖

9802

积分

荣誉版主

无情的代码机器

积分
9802
发表于 2026-1-5 17:46:24 | 显示全部楼层
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-5-10 23:23 , Processed in 0.106553 second(s), 66 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表