\chapter{软件设计} \section{总体方案} 该系统的信号检测与数据传送部分,涉及的软件部分较少。主要是 2051 单片机数据串行通信及通信协议的程序设计。 对于 2051 的程序设计\cite{cn12},由于所需实现的功能较简单,采用汇编的形式。编译器采用 Keil 7.02b。该编译器是 51 系列单片机程序设计的常用工具,既可用汇编,也支持 C 语言编译。同时具有完善的调试功能。 \section{程序流图} \begin{figure}[!ht] \centering \begin{tikzpicture} [ every node/.style = { font = \small, minimum height = 2.5em } ] \node [draw, rectangle, minimum width = 11em, minimum height = 2em] (a) at (0,0) {初始参数设置}; \node [draw, rectangle, minimum width = 11em, rounded corners = 1.2em, below = of a] (b) {等待中断}; \node [draw, rectangle, minimum width = 11em, diamond, aspect=3, below = of b] (c) {中断服务程}; \node [draw, rectangle, minimum width = 11em, diamond, aspect=3, below = of c, yshift = 2ex] (d) {读取 P1 口值}; \node [draw, rectangle, minimum width = 11em, rectangle, below = of d, minimum height = 2em] (e) {发送数据帧}; \node [draw, rectangle, minimum width = 11em, diamond, aspect=3, below = of e] (f) {延时$\qty{200}\ms$}; \node [draw, rectangle, minimum width = 11em, rectangle, below = of f, minimum height = 2em, yshift = 2ex] (g) {清中断标志}; \node [draw, rectangle, minimum width = 10em, rounded corners = 1.2em, below = of g] (h) {中断返回}; \draw [->] (a.south) -- (b.north); \draw [->] (b.south) -- (c.north); \draw [->] (c.south) -- (d.north); \draw [->] (d.south) -- (e.north); \draw [->] (e.south) -- (f.north); \draw [->] (f.south) -- (g.north); \draw [->] (g.south) -- (h.north); \draw [->] (h.east) --++ (1,0) |- (b.east); \end{tikzpicture} \caption{串行发送流程图} \label{5-1} \end{figure} \section{模块说明} \begin{enumerate} \item 主程序: \begin{lstlisting}[basicstyle=\linespread{1.32}\small\ttfamily\selectfont, breaklines=true] MAIN: MOV SP,#0X60 ;堆栈初始化 CALL INIT ;各寄存器参数设置 MOV 40H,#0x01 ;打靶次数置 1 AJMP $ ;等待中断 \end{lstlisting} \item 初始化程序: \begin{lstlisting}[basicstyle=\linespread{1.32}\small\ttfamily\selectfont, breaklines=true] INIT: MOV TMOD,#0X21;波特率发生器 MOV TL1,#0XFD ;波特率 9600bps MOV TH1,#0XFD CLR ET1 ;禁止 timer1 SETB PT1 ;时钟 1 优先级:高 MOV SCON,#0x40;串口工作模式 1,SM2=0,REN=0 MOV PCON,#0 ;波特率 9600bps SETB EA ;中断允许 CLR PS ;关闭串口中断 CLR ES ;串口优先级:低 SETB EX0 ;开外部中断 INT0 SETB IT0 ;下降沿有效 CLR PX0 ;INT0 优先级:低 SETB TR1 ;时钟 1 开始计数 RET \end{lstlisting} \item 中断服务程序: \begin{lstlisting}[basicstyle=\linespread{1.32}\small\ttfamily\selectfont, breaklines=true] _INT0: ;ISR 中断服务程序 NOP CALL DELAY_2MS;同步延时 MOV P1,#0xff ;读 P1 口前先置 1 MOV A,P1 ;读 P1 口 CALL INT0_SEND RET \end{lstlisting} \item 数据帧传送子程序: \begin{figure}[htbp] \centering\small \setstretch{1.4} \caption{数据帧格式} \begin{tabular}{|*{4}{>{\centering\arraybackslash}p{.22\linewidth}|}} \hline 标志位SYNC & 打靶次数 & 打靶成绩 & 校验位CHECKSUM\\ \hline \#0x30 & TIMES & RESULT & TIMES\ensuremath+RES\\ \hline \end{tabular} \end{figure} \clearpage 例:30 02 15 17(十六进制) 表示第二次打靶,击中第 21 号(对应环数:7 环 偏移方向:右上)。 \begin{lstlisting}[basicstyle=\linespread{1.32}\small\ttfamily\selectfont, breaklines=true] INT0_SEND: ;数据帧传送子程序 PUSH ACC ;保护 ACC CLR A ADD A,#0X30 CALL UART_SEND ;发送标志位 MOV A,40H CALL UART_SEND ;发送打靶次数 POP ACC CALL UART_SEND ;发送打靶成绩 ADD A,#0X30 ADD A,0040H CALL UART_SEND ;发送校验位 INC 0040H ;打靶次数累加 1 CALL DELAY_200MS;延时 200ms CLR EX0 ;关外部中断 CLR IE0 ;清INT0外部中断请求标志位—防止外部中断寄存 而引起多次中断。 SETB EX0 ;开中断 RETI \end{lstlisting} \item 串行发送字节 \begin{lstlisting}[basicstyle=\linespread{1.32}\small\ttfamily\selectfont, breaklines=true] UART_SEND: ;串行发送一个字节 MOV SBUF,A JNB TI,$ ;等待发送完毕 CLR TI ; RET \end{lstlisting} \item 定时程序: \begin{lstlisting}[basicstyle=\linespread{1.32}\small\ttfamily\selectfont, breaklines=true] DELAY_2MS: ;用定时器延时 2ms MOV R7,#21;21 DLY1:MOV R6,#42 DLY2:DJNZ R6,DLY2 DJNZ R7,DLY1 RET DELAY_10MS: ;调用 DELAY_2MS,实现延时 10ms MOV R5,#5 DLY: CALL DELAY_2MS DJNZ R5,DLY RET \end{lstlisting} \end{enumerate}