从零开始学单片机全过程(四)

本文分享了从零开始学习单片机的过程,重点介绍了一款自制字幕机的软件编程经验。包括解决显示问题、提高扫描频率、合理安排行显示时间和使用子程序优化代码等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从零开始学单片机全过程(四)
(声明:属于个人体会,不涉及任何商业目的,请转载时注明出处,谢谢)
 作者:field01@163.com
 
四、软件编程篇
对软件编程的一些体会
我开做的第一软件是,静态的显示一个汉字,所以一直有这样的问题。字的颜色的深浅有些问题。后来看到别的同学已经有人做出了滚动字幕,于是让我加紧了对软件的开发,把显示问题放了一下。在软件开发中我又遇见了一些问题,就是原来用的编译软件masm51,编译出来的.hex文件不能直接通过isp下载线烧写到芯片,总是说没有找到000000001记录,开始时,我就下了一个hex转换成bin的小工具转换解决了此问题,但每编译一次都需要繁琐的dos命令行操作,使我下定决心,更换开发环境。我下了keil51开发环境,但是在上面只用它来做汇编的开发,我知道,他是专门来开发c的,但是不知道怎么用c,就暂时用它来做汇编的开发,也去图书馆了本keil 的书来,了解了其调试开发的用法。发现用keil编译生成的.hex文件,可以被isp下载线很好的支持,现在,我调试一个程序就只要按两下按钮就可以了,极大地方便了我的开发。
开始,一上来就进行字幕机的开发,让我根本没有见到什么成效,显示器上一直视乱码。估计是显示的时间问题。又查阅了相关的资料,直到了,显示器要让人眼能够看到图像,必须让扫描频率高于视觉暂留频率16Hz以上,为了消除鬼影(TBLANK),在切至下一行扫描线时,必须把上一行关闭一段时间(约50us)。有了这两个概念后,我的软件设计思路就基本有了。
就是每秒钟,至少在显示器上输出16帧图像,每扫描一行图像后要停留50us。我的设计思路是就打到16帧的额定帧数,是16*16的点阵,16帧做字幕机的话,正好走完一个汉字。
每帧所用的时间=1000(毫秒)/16帧=62.5毫秒/帧
一帧由16个扫描行组成
行显示时间=62.5*1000(微秒)/16行=3906.25us/行
然后再减去每行50微秒的暗时间,和子程序运行时间,我把行亮的时间设置为3000微秒,灭的时间设为50微秒
这样就完成了时间的计算问题。
接下来的编程问题,我运用了很多的子程序,每个问题都划分成更细微的问题,大概是受了学java语言面向对象编程思想的影响。比如说读取一个字ReadWord,我把它分成了两部去做,先写了一个读取一个字ReadByte的子程序,然后再让ReadWord,来调用两次ReadByte。这样程序就很好纠错,结构清晰了。
还有这次用汇编的开发过程,也让我更进一步的了解到了计算机的原理。才确确实实的是和硬件在打交道了。发现汇编里面就是程序的结构化不够清晰,循环,判断,等操作的出口与如口都要自己操作,主要是要解决好出口与入口的问题。   CJNE可以解决汇编程序的判断问题,用jmp解决出口问题,写汇编,我的体会是,写了汇编时脑子一定要清醒,你要了解程序运行的每一个状态,某一个寄存器的状态,这样,所写程序运行的结果菜会如你所愿。
从总体上看来,我的这个字幕机的软件制作过程中,有两个难点。
第一:16位的数据指针的控制问题。在101个命令中我就发现了INC DPTR 和 MOV DPTR,#data,两个可以改变dptr命令的指令,后来用直接寻址的方法,直接加减DPTR的两个寄存器82h和83h很好的解决了DPTR的控制问题。
第二: 就是在最后的数据区盘尾标示上,我开始时用的是10101010B这个字节判尾,后来发现汉字码中有这个表示.后来又试验了几个,汉字中都与他又重码,我原本已经打算重写一个判尾子程序了,就是把尾部的32个数据全部读入,判断空字节数是否达到了32,但这个代码量也不小。但在最后几次试验中使我找到了     0CFH这个尾标识汉字中好像没有重码。(2005年11月 修改 发现并非如此,cf也有重码)然后我就使用了这个代码。后来听老师说0CFH是常用的汉字判尾标识,这真是殊途同归。
最后,为了多方借个汉字,我进行了一点代码的优化,比如吧开发时多定义的一些变量删除,让代码区更小些,然后再把一些原来用送立即数的清零方式(占两个字节的指令)改为用ANL A,MOV P1,A;的方式(占一个字节的指令来代替)。
还有汉字的点阵提取是使用一个叫“提取汉字点阵程序v1.1”的程序完成的,所以对字幕的修改非常的方便。一些相关的制作参考资料我附在随文档的光盘中了。
 
五、总结
通过这次对单机的学习,一方面使我基本对单片机有了些了解,但我觉得很重要的一方面是使我懂得了一套解决问题的方法,面对问题,可以先分析,然后再查阅相关资料,正式可行性,让后解决问题。渐渐的可以独立的解决一些问题,在解决问题中成长题高。
 
 
 
附录1 开发实战中相对应的程序源代码
;字幕机员程序
ORG 00H;
CALL CLRP02;    P0,P2清零
MOV P1,A;
MOV DPTR,#TAB;
DISPLAY:
   JMP EOF;
   ;判断数据指针是否到了数据区的尾部
   EOFRET:
          ;EOF的返入口
   CALL ZHEN;
  
   MOV R3,#01EH;     数据指针退30格 ,从 下一行开始重新扫描;
   DECDPTRLH:CALL DECDPTR;
   DJNZ R3,DECDPTRLH
JMP DISPLAY;
EOF:MOV A,#00H;      判断数据指针是否到了数据区的尾部
    MOVC A,@A+DPTR;
    CJNE A,#0CFH,EOFRET;
    MOV DPTR,#TAB;     
    JMP EOFRET; 
ZHEN: MOV R2,#010H;   显示一帧,一个画面
      ZHEN1:CALL CLRP02;
       CALL RW
       MOV R6,#5
          D1:MOV R7,#248;
          DJNZ R7,$
            DJNZ R6,D1;
       CALL CLRP02;
       MOV R7,#25;
       DJNZ R7,$;
            INC P1;
      DJNZ R2,ZHEN1;
      RET
RW:       CALL RB;   READ A WORD 读取一个字,两个byte
   MOV 21H,A;
   CALL RB;
   MOV 22H,A;
   JMP QUAA;
   QUAARET:
   MOV P0,21H;
   MOV P2,22H;
   RET;
QUAA:    
   ;消除显示时尾因为末尾标记而产生的字幕结束时的拖尾
   MOV A,21H;
   CJNE A,#0CFH,QUAARET;
   MOV 21H,#00H;
   JMP QUAARET;
RB:         MOV A,#00H;READ BYTE读取一个byte
     MOVC A,@A+DPTR;
     INC DPTR;
     RET;
CLRP02:   ANL A,#00H;
   MOV P2,A;    P0,P2清零
   MOV P0,A;
   RET
DECDPTR:
   ;DPTR减一
   CALL C82H0;    判断
   DEC 82H;
   RET
C82H0:
   ;看82h(DPL)的值是减到了零    考虑83h(DPH)退位
   MOV A,82H;
   JZ TUIWEI83H;   DPH退位
   RET
TUIWEI83H:
   ;DPH退位(DPTR高字节)
   DEC 83H;
   RET
TAB:
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
;------------过渡头数据------------
;数据区,可以直接填入汉字的点阵编码,无需修改程序
DB 0CFH;尾标示
;------------过渡尾数据--------------
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
DB 00H,00H,00H,00H,00H,00H,00H,00H
END;
 
附录2 参考资料在盘上的位置
文件夹 PATH 列表
卷序列号码为 0006FE80 50CE:704B
E:.
├─我在文曲星上开发的一个500行的basic小程序完全独立开发
└─附从零开始学单片机学习及关参考资料
    ├─2个Hex转Bin的小程序
    ├─IC芯片的技术资料
    │  ├─atmel89c51
    │  ├─atmel89s51
    │  └─SN74LS138N
    ├─单片机自学资料
    │  ├─document
    │  ├─smcu.51.net
    │  └─www.01mcu.com
    │      └─mcu_cai
    │          └─experiment
    │              └─soft
    ├─发光二极管相关资料
    │  ├─发光二极管(LED)_files
    │  ├─电子技术天地--超高亮度发光二极管TLC-58_files
    │  ├─飞达光学 - 光学论文 - 半导体发光二极管(LED)_files
    │  │  └─bdun_files
    │  └─飞达光学 - 光学论文 - 白色LED的开发和应用_files
    │      └─bdun_files
    ├─开发工具资料
    │  ├─isp下载线相关资料
    │  └─自制ez51编程器制作参考资料
    └─提取汉字点阵程序
从零开始 单片机 语言 刘建清 出版社: 国防工业出版社 发行时间: 2007 年01月 内容简介: 本书定位于让初者从零起步,轻松单片机高级编程C语言以及实战技术。书中首先简要介绍了8051单片机的主要构成,然后重点介绍了单片机Cx51高级编程语言开发与仿真环境的使用方法,透彻地分析了Cx51的语法结构,并给出了大量实例。书中大多数实例和全部实验都经过了实验板的验证。 本书可供具有一定单片机基础的初者,以及广大从事单片机应用系统开发研制的工技术人员阅读,也可以作为有关院校相关专业的教参考用书。 目录: 第一章 单片基础知识  第一节 51系列单片机概述  第二节 80C51单片机的内部结构和外部引脚  第三节 80C51单片机的内部结构和外部引脚  第节 51系列单片机的并行输入/输出接口  第五节 80C51单片机的时钟电路和复位电路 第二章 单片机C语言入门  第一节 认识C语言  第二节 简单C语言  第三节 单片机C语言开发步骤 第三章 单片机实验硬件环境的建立  第一节 单片机实验板  第二节 单片机仿真器  第三节 单片机编程器 第章 Keli Cx51软件的使用  第一节 Keil Cx51简介  第二节  Keil Cx51软件的安装   第三节 uVision2集成开发环境  第节 常用窗口介绍 第五章 Cx51数据与运算  第一节 标识符和关键字  第二节 数据类型  第三节 常量  第节 变量   第五节 运算符和表达式 第六章  Cx51的基本语句  第一节 表达式语句和复合语句   第二节 条件选择语句   第三节 循环语句 第七章 Cx51函数  第一节 函数的分类和定义   第二节 函数的参数和返回值  第三节 函数的调用  第节 函数变量的存储方式和种类 第八章 Cx51构造数据类型  第一节 数组  第二节 指针  第三节 结构  第节 共用体  第五节 枚举 第九章 单片机中断、定时器串行口的C语言编程  第一节 单片机中断系统C语言编程   第二节 定时/计数器及实验  第三节 串行数据通信技术及实验  第十章 单片机实用接口C语言编程技术  第一节 LED显示器接口   第二节 链盘接口   第三节 LCD显示器接口   第节 I2C总线接口  第五节 A/D和D/A转换接口   第六节 单片机应用技术综合实例 附录一 运算符的优先级和结合性 附录二 Keil Cx51编译器常见警告与错误信息的解决方法
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值