代码:pyhon生成word/wps文档(单片机流水灯实验)

import os, pythoncom, win32com.client as win32

# ---------------------- 工具函数 ----------------------
def get_or_add_style(doc, name):
    try:
        return doc.Styles(name)
    except:
        return doc.Styles.Add(Name=name, Type=1)  # 1=段落样式

# ---------------------- 主程序 ----------------------
pythoncom.CoInitialize()
try:
    app = win32.Dispatch("Word.Application")
except:
    app = win32.Dispatch("Kwps.Application")
app.Visible = True
doc = app.Documents.Add()

# Word 常数
wdCollapseEnd = 0
wdStory = 6
wdWord9TableBehavior = 1
wdAutoFitContent = 1
wdFormatDocumentDefault = 12

# ---------- 1. 建立样式 ----------
def make_styles():
    # 实验标题
    s = get_or_add_style(doc, "濮工_实验标题")
    s.Font.NameFarEast = s.Font.Name = "黑体"
    s.Font.Size = 18
    s.Font.Bold = True
    pf = s.ParagraphFormat
    pf.Alignment = 1          # 居中
    pf.SpaceBefore = 18
    pf.SpaceAfter = 12
    pf.LineSpacingRule = 0    # 单倍

    # 一级标题
    s = get_or_add_style(doc, "濮工_一级标题")
    s.Font.NameFarEast = s.Font.Name = "黑体"
    s.Font.Size = 14
    s.Font.Bold = True
    pf = s.ParagraphFormat
    pf.Alignment = 0
    pf.SpaceBefore = 12
    pf.SpaceAfter = 6
    pf.LineSpacingRule = 0

    # 二级标题
    s = get_or_add_style(doc, "濮工_二级标题")
    s.Font.NameFarEast = s.Font.Name = "黑体"
    s.Font.Size = 12
    s.Font.Bold = True
    pf = s.ParagraphFormat
    pf.Alignment = 0
    pf.SpaceBefore = 6
    pf.SpaceAfter = 3
    pf.LineSpacingRule = 0

    # 正文
    s = get_or_add_style(doc, "濮工_正文")
    s.Font.NameFarEast = s.Font.Name = "宋体"
    s.Font.Size = 10.5
    pf = s.ParagraphFormat
    pf.FirstLineIndent = app.CentimetersToPoints(0.74)  # 2 字符
    pf.LineSpacingRule = 3      # 多倍
    pf.LineSpacing = 1.25       # 1.25 倍
    pf.Alignment = 0            # 默认居左,避免继承公式的居中

    # 图题注
    s = get_or_add_style(doc, "濮工_图题注")
    s.Font.NameFarEast = s.Font.Name = "宋体"
    s.Font.Size = 9
    pf = s.ParagraphFormat
    pf.Alignment = 1
    pf.SpaceAfter = 6
    pf.LineSpacingRule = 0

    # 表题注
    s = get_or_add_style(doc, "濮工_表题注")
    s.Font.NameFarEast = s.Font.Name = "宋体"
    s.Font.Size = 9
    pf = s.ParagraphFormat
    pf.Alignment = 1
    pf.SpaceBefore = 6
    pf.LineSpacingRule = 0

make_styles()

# ---------- 2. 顺序写内容 ----------
rng = doc.Range()
rng.Collapse(wdCollapseEnd)

def write(style, text, newline=True):
    rng.Style = style
    rng.Text = text
    if newline:
        rng.InsertParagraphAfter()
    rng.Collapse(wdCollapseEnd)

# 标题
write(doc.Styles("濮工_实验标题"), "实验13 单片机流水灯实验")

# 一、实验目的
write(doc.Styles("濮工_一级标题"), "一、实验目的")
for t in ["1. 掌握51系列单片机(如STC89C52)的基本工作原理及IO口控制方法;",
          "2. 学会使用Keil C51软件编写简单的单片机控制程序,掌握程序下载流程;",
          "3. 理解流水灯的实现逻辑,能通过硬件连接和软件调试实现LED灯的循环点亮效果;",
          "4. 熟悉面包板、导线、电阻等元件的使用,提升硬件搭建与故障排查能力。"]:
    write(doc.Styles("濮工_正文"), t)

# 二、实验仪器
write(doc.Styles("濮工_一级标题"), "二、实验仪器")
for t in ["1. 核心设备:STC89C52单片机开发板(或最小系统板)、USB下载线、Keil C51软件(V4.7及以上版本);",
          "2. 电子元件:红色LED灯(8个)、1kΩ限流电阻(8个)、面包板(1块)、杜邦线(20根,含公对母、公对公);",
          "3. 辅助工具:万用表(1台,用于检测电路通断)、镊子(1把);",
          "4. 示意图:"]:
    write(doc.Styles("濮工_正文"), t)
write(doc.Styles("濮工_图题注"), "图13-1 单片机流水灯实验硬件连接示意图")

# 三、实验原理
write(doc.Styles("濮工_一级标题"), "三、实验原理")
write(doc.Styles("濮工_二级标题"), "1. 单片机IO口控制原理")
write(doc.Styles("濮工_正文"), "51系列单片机的P1口为8位准双向IO口,可直接作为输出口使用。当IO口输出低电平时(接近0V),外接LED灯通过限流电阻形成回路,LED点亮;当IO口输出高电平时(接近5V),回路中电流极小,LED熄灭。通过控制P1口各引脚的高低电平变化,可实现LED灯的亮灭控制。")
write(doc.Styles("濮工_二级标题"), "2. 流水灯实现逻辑")
write(doc.Styles("濮工_正文"), "采用“循环移位+延时”的方式实现流水灯效果:通过程序让P1口的低电平信号按固定顺序(如从P1.0到P1.7,即左移;或从P1.7到P1.0,即右移)依次切换,每次切换后保持一定时间(由延时函数实现),从而形成“流水”视觉效果。")
write(doc.Styles("濮工_二级标题"), "3. 核心公式(延时时间计算)")
write(doc.Styles("濮工_正文"), "若单片机晶振频率为11.0592MHz(常用频率),机器周期T机 = 12/f晶振,其中f晶振为晶振频率。延时函数的延时时间t可近似表示为:")

# 核心修正:公式段处理(居中)
formula_rng = rng.Duplicate  # 复制当前光标位置,专门用于公式
formula_rng.Style = doc.Styles("濮工_正文")
formula_rng.ParagraphFormat.Alignment = 1  # 公式段居中
formula_rng.Text = "t ≈ N × T机   "
formula_rng.InsertParagraphAfter()
# 光标移到公式下方,恢复居左
rng.MoveEnd(Unit=wdStory)
rng.Collapse(wdCollapseEnd)
rng.ParagraphFormat.Alignment = 0  # 确保后续文本居左

# 写入“式中N…”,此时已默认居左
write(doc.Styles("濮工_正文"),
      "式中N为延时函数中指令执行的总周期数,本实验中通过Keil软件自动计算,设定单次延时时长为500ms,确保流水效果清晰可见。")

# 四、实验内容及步骤
write(doc.Styles("濮工_一级标题"), "四、实验内容及步骤")
write(doc.Styles("濮工_二级标题"), "1. 实验前准备")
for t in ["(1)硬件准备:检查单片机开发板、LED灯、电阻等元件是否完好;用万用表检测限流电阻阻值是否为1kΩ,排除损坏元件;",
          "(2)软件准备:在电脑上安装Keil C51软件,完成软件注册与环境配置(如选择“Atmel”→“AT89C52”芯片型号);",
          "(3)电路连接:将单片机P1口(P1.0~P1.7)通过杜邦线接面包板,LED正极经1kΩ电阻接5V电源,负极接对应P1口引脚,确保电源正负极无接反。"]:
    write(doc.Styles("濮工_正文"), t)

# 五、数据及处理结果
write(doc.Styles("濮工_一级标题"), "五、数据及处理结果")
write(doc.Styles("濮工_表题注"), "表13-1 单片机流水灯实验数据记录表")
# 插入表格
table_rng = rng.Duplicate
table = doc.Tables.Add(table_rng, 4, 6, AutoFitBehavior=wdAutoFitContent)
table.Borders.Enable = True
# 表头
hdr = ["实验序号", "流水模式", "延时时长(ms)", "LED点亮顺序", "实验现象描述", "是否正常"]
for i, h in enumerate(hdr, 1):
    table.Cell(1, i).Range.Text = h
# 数据
rows = [["1", "左移", "500", "P1.0→P1.1→…→P1.7", "8个LED从左到右依次循环点亮", ""],
        ["2", "左移(修改延时)", "200", "P1.0→P1.1→…→P1.7", "流水速度加快,点亮间隔缩短", ""],
        ["3", "右移(修改程序)", "500", "P1.7→P1.6→…→P1.0", "8个LED从右到左依次循环点亮", ""]]
for r, row_data in enumerate(rows, 2):
    for c, txt in enumerate(row_data, 1):
        table.Cell(r, c).Range.Text = txt
# 居中
for r in range(1, 5):
    for c in range(1, 7):
        table.Cell(r, c).Range.ParagraphFormat.Alignment = 1
# 光标移到表格下方
app.Selection.EndKey(Unit=wdStory)
app.Selection.InsertParagraphAfter()
rng = app.Selection.Range

write(doc.Styles("濮工_正文"), "数据处理与分析:")
write(doc.Styles("濮工_正文"), "1. 对比实验1和2:延时时长从500ms缩短至200ms,流水周期从4s(8×500ms)缩短至1.6s(8×200ms),验证“延时时长与流水速度成反比”;")
write(doc.Styles("濮工_正文"), "2. 实验3通过修改程序中“led << 1”为“led >> 1”,实现右移流水,说明单片机IO口控制的灵活性。")

# 六、思考题
write(doc.Styles("濮工_一级标题"), "六、思考题")
for t in ["1. 单片机IO口输出高电平时LED不亮,输出低电平时LED亮,其电路原理是什么?若将LED的正负极接反,会出现什么现象?",
          "2. 若想实现“LED灯闪烁2次后再流水”的效果,需要在程序中添加哪些逻辑?",
          "3. 实验中1kΩ限流电阻的作用是什么?若去掉限流电阻直接连接LED,可能会导致什么问题?"]:
    write(doc.Styles("濮工_正文"), t)

# ---------- 保存 ----------
save_path = os.path.join(os.path.expanduser("~"), "Desktop", "单片机流水灯实验讲义2.docx")
doc.SaveAs(save_path, FileFormat=wdFormatDocumentDefault)
print("已生成:", save_path)
posted @ 2025-11-12 13:26  wangya216  阅读(14)  评论(0)    收藏  举报