积分规则 网站地图 帮助中心    
嵌入式软件 单 片 机 DSP 存储器 传感控制 光电显示
嵌入式硬件 CPLD/FPGA SOPC AD/DA 接口电路 模拟设计
I C设计 通信产品 汽车电子 电源产品 消费电子 数控系统
工业控制 军工/航天 安防产品 医疗电子 计算机外设 测试测量
供应 I C
求购 公司库

  IC 求购 销售 公司 论文 DATASHEET 参考设计 论坛
当前位置: 电子技术 >> 单片机 >> 应用论文
  相关分类: 相关文章 | 应用论文 | 新产品 | 下载 |
单片机全数字信号发生器的软件设计
 
作者:未知   来源:本站原创    点击数:99   更新时间:2008-9-2
您可以添加到网摘 让更多人关注此文章:

    

本仪器的程序主要由键盘、显示程序、AT24C01A读写程序、信号产生程序等部分组成。以下对部分功能作一些分析。
一、键盘程序
  本仪器需要调整的数值范围较大,因此,“增加”和“减少”键必须具有快速连加和快速连减的功能,否则调整速度太慢。这种键盘可以用多种方法来实现,关键在于设计一个正确的程序结构,图1是一种实现方法的流程图。
 
图1 流程图
  程序工作时,不断地扫描键盘,第一次扫描到有键按下后如常规键盘一样,进行键值处理,处理完毕,不等待键盘释放,直接退出键盘程序。当又一次执行到键盘程序,如果检测到键还被按着,就不再直接去键值处理程序,而是将一个计数器加1,直接返回主程序,如此循环,直到计数到一个定值(如500,表示键盘程序已被执行了500次),如果键还被按着,说明用户有连加(或连减)要求,程序即将计数器减去一个数值(如30),然后进行键值处理。这样,以后键盘程序每执行30次,就执行一次键值处进程序,实现了第一次启动时间较长,以后快速连续动作的要求。如果检测到键已被释放,则清除所有标志,将计数器清零,准备下一次按键处理。
  程序开始时定义了两个常量:Qdsj和Ljsj,如下所示
const  uint  Qdsj=500; /*与首次启动连加(减)功能的时间有关*/
const  uint  Ljsj=30;  /*与连加(减)的速度有关*/
  这两个常量与第一次启动及连加、减的速度有关,具体数值应根据实际情况试验后确定。下面是部分键处理程序,注意其中这两个变量的使用。
void Key()/*键处理*/
{     ……
        if(!KeyValue)        
        {
…无键按下,清除一切标志退出
        }
        if(KeyMark)     /*第一次检测到按键吗?*/
        {   KeyCounter++;   /*不是第一次(KeyMark已是1了)*/
            if(Qdsj==KeyCounter) /*连续按着已有Qdsj次了*/
            {   KeyCounter-=Ljsj; /*减去Ljsj次*/
             KeyProcess(KeyValue,1);   /*键值处理*/    
            }
            else{ return ; }   /* 如果按着还没有到Qdsj*/
        }
        else /*第一次检测到有键按下*/ 
        { mDelay(10);     /*延时10毫秒*/
…再次检测
            if(!KeyValue)
{… 清除一切标志并返回}
}         
二、小数点的处理
  要在LED数码管上显示小数点,可以有两种选择,一种方式是在显示0.1~0.9时用小数显示,而在显示1~500时不显示小数点,这种方式编程略麻烦一些;另一种是使用定点的方式显示小数点,即不论是在0.1~0.9Hz段,还是1~500Hz段,均在倒数第二位点亮小数点,这种显示方式比较简单,本机采用了第二种方式。
  通常,用高级语言编程时,可以用浮点型数据来表示小数,但本程序并没有这样来处理。因为单片机的资源有限,而浮点型数据的表达方式与其他数据的表达方式很不相同,无论是存储还是运算,都相当占用资源,因而在单片机中能不用浮点型数据就尽量不要使用。这里我们将所有的频率设定值扩大10倍,即所要求的频率值是0.1~500Hz,但在单片机内部用1~5000来表示。如果频率设定值小于10,每按一次键,频率设定值就加或减1,如果频率设定值大于等于10,每按一次按键就加或减10。例如,当前频率设定值为100,按一下“增加”键,该值就会变为110,相当于频率设定值由10变为11;如果当前设定值为9,按一下“减少”键,该值变为8,相当于频率值由0.9变到了0.8。在根据频率设定值计算定时常数时,只要将被除数扩大10倍即可,程序中是这样表示的: 
ltemp=1000000;  
ltemp*=10; //由于plsd被放大了10倍,故被除数也放大10倍
……
  在显示频率设定值时,点亮倒数第二位的数码管上的小数点,显示程序中有这样的程序行:
if(Counter1==1) //如果当前正在显示倒数第二位时
{ if(!PlSl) //如果是要求显示频率
   DispCode=DispCode&0xbf; /*点亮小数点*/

  由于P0.6与小数点位相连,所以不论待显示的数是多少,该位被清零后,小数点就能被点亮。要将该位清零,只要将字形码与0xbf(10111111)相与即可。
三、AT24C01A的读写
  AT24C01A芯片是具有I2C接口的EEPROM,由于89C51单片机没有I2C接口,因此,必须用I/O口模拟I2C时序。这里仅提供作者用C语言编写的接口程序,不对此作更多的介绍。
  使用这一接口程序,只要定义好写常数、读常数及根据硬件连线定义好三个引脚SDA、SCL和WP,然后直接调用读、写函数即可。
#define AddWr   0xa0            /*器件地址选择及写标志*/
#define AddRd   0xa1            /*器件地址选择及读标志*/
sbit    Sda=    P3^7;           /*串行数据*/
sbit    Scl=    P3^6;           /*串行时钟*/
sbit    WP=    P3^5;
  接口程序提供了多字节的读、写函数,其中读函数需要用到三个参数:用于存放读出数据的数组,待读EEPROM的起始地址,字节数;写函数也要用到三个参数:用于存放待写入数据的数组,待写入EEPROM的起始地址,字节数。下面是这两个函数的用法参考:
  RdFromROM(Number,10,2); //从地址10H开始处读出2个字节,存入Numbre数组中。
  WrToROM(Number,10,2); //将Number数组中的2个字节写入EEPROM,地址从10H开始
四、信号产生
  信号发生由定时中断0完成,在定时时间到之后,重置定时常数,接着判断究竟是较高频率还是较低频率,分别予以处理,如果是较高频率,直接取反输出端口即可返回,如果是较低频率,则要进行计数,并判断计数值是否到设定值,如果到了,则取反输出端口,并清零计数器,然后再返回,这部分程序如下 :
void OutWave() interrupt 1 //定时0中断用于波形输出
{ static uint Count; //较低频率时计数用
TH0=CTH0; //重装时间常数
TL0=CTL0;
if(HighLow) //如果是较高频率
{ WaveOut=!WaveOut;
Mczsl++; }
else { Count++;
if(Count>=Plcs)
{ WaveOut=!WaveOut;
Count=0;
Mczsl++; 
} } }
  其中Mczsl是脉冲输出个数的计数值。从程序中还可以看出,每次输出只能得到波形的一半,要么高电平,要么低电平,一个完整的波形需要两次输出才能完成。
  定时中断中所设定的定时常数,预设定计数值(Plcs)都由主程序根据频率设定值计算得到,根据前述原理,对于较低频率的信号和较高频率的信号采用两种不同的方法产生,对于较低频率的信号,定时常数是一个定值,通过改变预设定计数值来达到定时时间,而对于较高频率的信号,直接改变定时常数来改变定时时间。为此,在主程序中根据设定值的大小分别处理,如果设定值大于10Hz,那么是较高频率的算法,只要计算出设定频率值对应的时间,不难得到待设定值,程序中的处理方法是:
ltemp=1000000; 
ltemp*=10; //由于plsd被放大了10倍,故被除数也放大10倍
ltemp/=Plsd; //获得周期(单位微秒)
ltemp/=2; //获得定时常数
  根据t=1/f,计算定时时间,单位是s,而我们所要求的定时时间单位是μs,因此,首先让ltemp等于1000000,又由于Plsd变量在单片机内部被放大10倍,故再将该值扩大10倍,然后用ltemp为被除数,去除以Plsd,得到周期数。由于每次定时中断只能得到一半波形,因此定时数应该是周期数的一半,将周期数除以2,即得到了定时常数。显然,这里没有先计算时间到s,然后再换算为μs,其目的也是为了避免小数运算。
当所设定的频率值小于10Hz时,程序是这样处理的:
CTH0=(65536-1000)/256; 
CTL0=(65536-1000)%256; //否则是在10HZ以下,定时器的定时常数是1ms
HighLow=0;         
Plcs=5000/Plsd; 
  首先将定时常数确定为1000μs,然后将标志位HighLow置0,表示要进行较低频率的处理,最后计算出中断次数。中断次数这样来确定:用10000000/Plsd得到周期数,然后用这个值除以2000即得可,这时除以2000的原因同上述分析,即定时时间为1000μs,最终得到的的周期是2000μs。

 



相关文章
· Microchip推出适用于8位、16位及32位PIC®单片机和...[115]
· 基于SPE61A单片机的非接触式高压验电器的开发[229]
· 多通道智能温湿度测试仪的研制[282]
· 多通道智能温湿度测试仪的研制[226]
· 51系列单片机输出PWM的两种方法[301]
热门评论排行
·VHDL设计中电路简化问题的
·ARM嵌入式系统基础教程(N
·江苏嵌入式Linux教育培训
·ARM处理器应用开发4步骤
·锐极LINUX驱动培训班定于

文章评论
    没有任何评论
*只显示最新10条评论。评论内容只代表网友观点,与本站立场无关。更多评论
发表评论
  * 请先[登陆]再进行评论,谢谢。
评分: 1分 2分 3分 4分 5分
内容: *
发帖须知:
一.所发文章必须遵守《互联网电子公告服务管理规定》;
二.严禁发布供求代理信息,公司介绍,产品信息等广告宣传信息;
三.严禁恶意重复发帖;
四.严禁对个人,实体,民族,国家等进行漫骂,污蔑,诽谤。
 
热点新闻 [更多]
 
全球芯片厂商集体削减开支 
德国一处理器架构开发商指控赛灵思和安
微型燃料电池2年商业化 续
陕西投资50亿元建立西安半导体产业园
富士通微电子推出同时支持MPEG-2
意法半导体(ST)与麻省理工学院微系
高效率 I2C 
新兴半导体技术催生绿色节能的大学校园
电子系统创新促进汽车走向环保与节能
意法CEO携新品巡游中国 
 
热门下载 [更多]
 
[ PCB设计] Protel99教程下载
[ ] 手把手学单片机20个例
[ ] 单片机做的智能台灯
[ ] 单片机入门书
[ ] linux系统移植开发文档
[ ] IC卡的读写程序
[ ] 8051单片机C语言彻底应用
[ 常用软件] 555定时器电路设计软件V1.2
[ 常用软件] 51定时器计算软件
[ ] ARM处理器应用开发4步骤
 
论坛新帖 [更多]
 
[转]教你如何进行电磁兼容设计...
[转]汽车和专业音响原厂设计原...
诺基亚,三星手机原厂图纸和PC...
电子元器件可靠性和失效分析经典...
[建议]FPGA设计技巧与实例...
Xilinx FPGA设计快速...
基于CPLD的各种设计实例和分...
教你如何学会MSP430单片机...
凌阳单片机教程(共8章)非常详...
[建议]学习PIC系列单片机的...

 
赞助商 [更多]
 

ICP许可证号:[粤 05056597]
联系电话:010-82517432 82517615 传真: 010-82517615

版权所有 Copyright © 2006 嵌入式技术网