本人之前使用STC32G12K128具有8K 字节内部扩展RAM (xdata) 来计算 e 常数,精确到小数点后9858位。所用的公式为:
![]()
此公式需要两个分项,独立计算后相加,每一分项各占4K RAM。如果有办法只用一个分项,则全部8K RAM都用来计算 e 的近似值,岂不是更好!
翻查资料,发现苹果公司其中一位创办人史蒂芬·沃兹尼克 (Steve Wozniak) 在1981年写了一篇文章 (参见 BYTE杂志, 1981年6月号 392页),宣称使用47K RAM Apple II 电脑计算e 常数精确到小数点后116,000位,他使用的公式只有一个分项。当中只考虑 e 常数的分数部分 efrac:
![]()
![]()
因为

重复使用以上恒等式,可用以下渐近分数式求 efrac:

e 小数部分的渐近分数: ![]()
简单来说, 计算e 常数只需两个动作,除 n 及加1。只要有足够大的 n, 令e常数精确到小数点后某一个位便可以。例如,要e常数精确到小数点后19,720位,n 初始值必须大于 5909,因为 1/5909! = 1.2164×10^-19722,而本程序选取n 的初始值为5911。
2进制小数点后位数与10进制小数点后位数的转换
我们可以将二进制小数点后位数转换为十进制小数点后位数。公式如下:
log10 X = log 256 X × log10 256
因此,10进制小数点后位数 = 单片机内部扩展 RAM 大小 × 2.408
= 8K × 2.408
= 19,726
为了避免在计算中出现四舍五入误差,最终只计算e常数精确到小数点后19,720位。
STC32G12K128 (8051) 串口设定
计算结束后,单片机把结果用串口送出PC。设定如下:
单片机串口1 (P3.1是TxD,P3.0是RxD)
PC COM1 设定: 14400 bps, 8, None, 1, None
串口1 Mode1的波特率由定时器控制。TMOD (地址 89H) 为定时器/计数器控制寄存器,其功能是设置定时器/计数器的方式。

GATE:0 定时器由软件控制位 TR1或TR0 来控制启动;1时INT1/INT0为高,TR1/TR0为1时才开定时器1/0。
C/T:0 为定时器;1 为计数器 (对T1/T0外部脉冲进行计数) 。
| M1 |
M0 |
工作模式 |
工作模式说明 |
| 0 |
0 |
Mode 0 |
16 位自动重载 TH1/0,TL1/0模式。 |
| 0 |
1 |
Mode 1 |
16 位不自动重载模式。 |
| 1 |
0 |
Mode 2 |
两个8位,TL1/0自动重载TH1/0的重载值。 |
| 1 |
1 |
Mode 3 |
T1停止工作。T0 不可屏蔽中断的16位自动重载模式。 |

波特率产生方式
使用 Timer1 的 Mode 2 作为波特率产生器,即是8位自动重载模式。TL1、TH1 为Timer1定时器/计数器的计数寄存器,其地址为8BH、8DH。不同的TH1重载值产生不同的波特率。以FOSC = 24.000 MHz为例,需要波特率 14400:
TH1=256-(24000000/32/14400)=256-52=204=0xCC
SBUF 寄存器为串口缓冲器,地址为 99H,使用同一个地址的两个寄存器构成的。一个为发送数据用的缓冲器,另一个寄存器为接收数据用的缓冲器。
SCON 为串口控制寄存器,其地址为 98H,其功能是设置串口工作方式与标志。

SM0、SM1控制串口的4种工作方式:
| SM0 |
SM1 |
方式 |
功能说明 |
| 0 |
0 |
Mode 0 |
8位同步移位寄存器方式 (用于扩展IO) |
| 0 |
1 |
Mode 1 |
8位异步收发,波特率可变 (由定时器控制) |
| 1 |
0 |
Mode 2 |
9位异步收发,波特率为 ÷64 或 ÷32 |
| 1 |
1 |
Mode 3 |
9位异步收发,波特率可变 (由定时器控制) |
SM2:用于多处理器通信,通常置 0。
REN: 1 允许串口接收;0 禁止串口接收。
TB8:发送的第9位数据,用于Mode2、Mode3,一般作为奇偶校验位使用。
RB8:接收的第9位数据,用于Mode2、Mode3,一般作为奇偶校验位使用。
TI:发送中断标志位,发送结束时硬件置1,注意TI必须由软件清零。
RI:接收中断标志位,接收结束时硬件置1,注意RI必须由软件清零。
串口初始化子程序
注意:STC32G12K128的工作频率定为 24.000 MHz。
INIT_UART:
MOV SCON, #0x50 ; 串口1Mode 1,波特率由定时器控制,允许串口接收
MOV TMOD, #0x20 ; Timer1 Mode 2 工作模式,8位自动重载模式
MOV AUXR, #0x40 ; T1x12=1, Timer1 1T mode (FOSC/1 不分频)
MOV TH1, #0xCC
MOV TL1, #0xCC ; TH1=256-(24000000/32/14400)=256-52=204=0xCC
SETB TR1 ; 启动Timer1
RET
送出数据至串口子程序
SEND:
MOV SBUF, A ; 累加器内的字符送到SBUF (发送数据用的缓冲器)

最低0.47元/天 解锁文章
1018

被折叠的 条评论
为什么被折叠?



