最新日志

发表于:2007-3-12 16:10:51
标签:无标签

0

基于L64724的卫星解码机顶盒设计

基于L64724的卫星解码机顶盒设计

1 概述

数字压缩技术的发展,为卫星数字视频广播提供了有力的技术支持。目前虽然尚未形成全球公认的标准,但欧洲DVB-S的提出,无疑是一种可资参考的方案。L64724正是基于这一标准由LSI公司推出的一种性能较全面的数字视频卫星解码芯片。

对系统设计者来讲,L64724能以最低的成本实现最大集成度和灵活性,而且在使用时外接元件最少。

2 性能特点

L64724具有以下特性:

●可支持DVB和DSS系统;

●BPSK/QPSK速率可达45兆波特;

●内有滚降系数为20%和35%的平方根升余弦匹配滤波器;

●具有可工作在1~45兆波特之间的反失真滤器,无须切换至外接SAM或低通滤波器;

●可在片进行数字时钟同步和数字载波同步;

●能通过芯片上的微控制器自动获取解调模式和调谐控制;

●可用集成锁相环保证时钟同步;

●具有快速信道切换模式;

●内含自动增益控制电源;

●内含可编程维特比译码模块,包括1/2,2/3,3/4,5/6,6/7,7/8等各种速率,并能实现自动同步;

●内含(204/188),(146/130)RS译码器;

●可编程实现解交织、RS译码和解扰的同步;

●对信道性能检测可自动监控;

●卷积解交织的深度为12;

●其串行主机接口与LSI逻辑串行控制总线接口兼容;

●具有降压模式。

3 L64724的内部结构和引脚说明

3.1 内部结构

图1所示是L64724的内部功能图,它主要包含两个模块:BPSK/QPSK解调器和FEC译码器。图1中,数据和地址总线以上的部分为BPSK/QPSK解调器,以下为FEC译码器。

BPSK/QPSK解调器是从相位解调制的模拟信号中抽取数字信号。

FEC译码模块是一个完整的采用维特比内码和RS外码的前向纠错译码器。该译码器包含了所有可能的同步,以及解交织和解扰功能。

3.2 封装及管脚说明

L64724有100-脚PQFP和80-脚TQFP两种封装形式。表1所列是常用的关键管脚说明。

点击看大图

4 L64714的应用说明

L64724的工作参数有直流和交流以及电容等参数。在通常情况下,各参数都不能用到极限情况,否则可能导致芯片的永久损坏。L64724的重要工作参数如表2所列。

点击看大图

由于该芯片的参数要求较高,因此,建议用户将直流供电电压VDD设置在3.14~3.47V之间,工作温度TA范围为0~70℃,机箱温度Tc为0~85℃。在TA=25℃,VIN=3.3V,频率为1MHz时,最好使用5pF垢电容作为输入电容CIN和输出电容COUT。

点击看大图

5 L64724的典型应用

L64724的使用,首先必须注意其内部或外部的各种接口,包括信道接口、信道时钟接口、信道数据输出接口、PLL接口、A/D接口、AGC/时钟控制接口、微控制器接口、控制信号接口等。其中信道接口(channel interface)用于从卫星调谐电路接收输入信号,信道时钟用来标示数据时钟,为上升沿触发。信道数据输出接口是L64724送出数据的通路。在译码器机顶盒的实现电路中,该接口一般应连接到复用器的输入口。微控制器接口用于将芯片与微控制器相连。控制信号接口用来控制L64724的工作。

L64724是一种可编程逻辑器件,我们可以通过对其接口和内部寄存器设置的改变来使其满足不同的需要。需时钟和输入数据是决定电路稳定性的关键。

5.1 数据和时钟控制方案

如图2所示,L64724中的输入时钟信号CLK可用来实现信道译码系统中的可能配置,它由外部晶振产生,同时由CLK通过内部锁相环PLL来产生采样时钟PCLK,以便用来驱动模数转换器(ADC)、解调器、前向纠错(FEC)等三个模块。PCLK最高可工作在90MHz左右。由晶振产生的CLK可作为PLL的基准时钟,一般在15~60MHz之间。控制时钟LCLK是PLL经CLK-DIV2分频得到的,即LCLK=CLK/CLK-DIV2。

5.2 L64724的应用电路

L64724是一种功能很全面的芯片,笔者在电路的应用过程中深深体会到了它优越灵活的性能。L64724主要用于卫星数字电视接收机实现电路,它是按欧洲的DVB标准中的卫星传输方案来设计的。用这种芯片可在接收机盒的设计中起到事半功倍的效果。图3所示是一种机顶盒设计的电路方案,它主要包含三部分,其核心部分是由L64724组成的卫星译码器,还有由L64008组成的将MPEG-2码流传输到去复用器的电路以及由L64005构成的视频/音频译码器。当电路接收到由卫星传来的信号后,由调谐电路选出有用信号送入L64724,在信号进入L64724之后先由前端将模拟信号采样变为数字信号,并在L64724内部进行可编程设定所需参数,在达到规定性能指标后,再通过串行总线控制传入L64008去复用器进行处理。最后与DRAM交换数据并将结果送入L64005经视频译码后变为所需的音频和视频信号并分两路输出。而图3中的串行数据总线则通过编程控制片内各单元,片内各单元的信息获得均由该总线提供。

5.3 电路设计中的参数配置

在L64724的应用中,可通过微控制器接口对片内的参数进行配置,以达到最优性能。为方便读者应用。表3提供了一组分别适用于高、低数据速度的QPSK解调和FEC的配置参数,该配置是经实验验证较为优化的一组参数,可供读者参考。

6 结束语

该卫星解码接收电路可在上述电路中对L64724的参数进行设定,包括对传输速率、ADC采样频率、晶振频率、内码的码率等进行编程控制。对于不同的参数配置,各引脚的接法也有所不同,同时还应注意芯片的工作条件,以免使芯片遭到永久性损坏。本文所介绍的电路及参数均经实践验证,是一种较为优化的电路配置,也是卫星传输体系中高清晰数字电视接收机的核心电路。

 
本文摘自《国外电子元器件》
 
 

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(714)
发表于:2007-3-6 10:24:10
标签:无标签

1

struct用法深入探索

1. struct的巨大作用

  面对一个人的大型C/C++程序时,只看其对struct的使用情况我们就可以对其编写者的编程经验进行评估。因为一个大型的C/C++程序,势必要涉及一些(甚至大量)进行数据组合的结构体,这些结构体可以将原本意义属于一个整体的数据组合在一起。从某种程度上来说,会不会用struct,怎样用struct是区别一个开发人员是否具备丰富开发经历的标志。

  在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。

  经验不足的开发人员往往将所有需要传送的内容依顺序保存在char型数组中,通过指针偏移的方法传送网络报文等信息。这样做编程复杂,易出错,而且一旦控制方式及通信协议有所变化,程序就要进行非常细致的修改。

  一个有经验的开发者则灵活运用结构体,举一个例子,假设网络或控制协议中需要传送三种报文,其格式分别为packetA、packetB、packetC:

...

1. struct的巨大作用

  面对一个人的大型C/C++程序时,只看其对struct的使用情况我们就可以对其编写者的编程经验进行评估。因为一个大型的C/C++程序,势必要涉及一些(甚至大量)进行数据组合的结构体,这些结构体可以将原本意义属于一个整体的数据组合在一起。从某种程度上来说,会不会用struct,怎样用struct是区别一个开发人员是否具备丰富开发经历的标志。

  在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。

  经验不足的开发人员往往将所有需要传送的内容依顺序保存在char型数组中,通过指针偏移的方法传送网络报文等信息。这样做编程复杂,易出错,而且一旦控制方式及通信协议有所变化,程序就要进行非常细致的修改。

  一个有经验的开发者则灵活运用结构体,举一个例子,假设网络或控制协议中需要传送三种报文,其格式分别为packetA、packetB、packetC:

struct structA
{
 int a;
 char b;
};

struct structB
{
 char a;
 short b;
};

struct structC
{
 int a;
 char b;
 float c;
}

  优秀的程序设计者这样设计传送的报文:

struct CommuPacket
{
 int iPacketType;  //报文类型标志
 union      //每次传送的是三种报文中的一种,使用union
 {
  struct structA packetA;
  struct structB packetB;
  struct structC packetC;
 }
};

  在进行报文传送时,直接传送struct CommuPacket一个整体。

  假设发送函数的原形如下:

// pSendData:发送字节流的首地址,iLen:要发送的长度
Send(char * pSendData, unsigned int  iLen);
发送方可以直接进行如下调用发送struct CommuPacket的一个实例sendCommuPacket:
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
假设接收函数的原形如下:
// pRecvData:发送字节流的首地址,iLen:要接收的长度
//返回值:实际接收到的字节数
unsigned int Recv(char * pRecvData, unsigned int  iLen);

  接收方可以直接进行如下调用将接收到的数据保存在struct CommuPacket的一个实例recvCommuPacket中:

Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );

  接着判断报文类型进行相应处理:

switch(recvCommuPacket. iPacketType)
{
    case PACKET_A:
    …    //A类报文处理
    break;
    case PACKET_B:
    …   //B类报文处理
    break;
    case PACKET_C:
    …   //C类报文处理
    break;
}

  以上程序中最值得注意的是

Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );

  中的强制类型转换:(char *)&sendCommuPacket、(char *)&recvCommuPacket,先取地址,再转化为char型指针,这样就可以直接利用处理字节流的函数。

  利用这种强制类型转化,我们还可以方便程序的编写,例如要对sendCommuPacket所处内存初始化为0,可以这样调用标准库函数memset():

memset((char *)&sendCommuPacket,0, sizeof(CommuPacket));

2. struct的成员对齐

  Intel、微软等公司曾经出过一道类似的面试题:

1. #include <iostream.h>

2. #pragma pack(8)
3. struct example1
4. {
5. short a;
6. long b;
7. };

8. struct example2
9. {
10. char c;
11. example1 struct1;
 12. short e;   
13. };
14. #pragma pack()

15. int main(int argc, char* argv[])
16. {
 17. example2 struct2;

18. cout << sizeof(example1) << endl;
19. cout << sizeof(example2) << endl;
20. cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2)
<< endl;

21. return 0;
22. }

  问程序的输入结果是什么?

  答案是:

8
16
4

  不明白?还是不明白?下面一一道来:

2.1 自然对界

  struct是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如array、struct、union等)的数据单元。对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。缺省情况下,编译器为结构体的每个成员按其自然对界(natural alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。

  自然对界(natural alignment)即默认对齐方式,是指按结构体的成员中size最大的成员对齐。

  例如:

struct naturalalign
{
 char a;
 short b;
 char c;
};

  在上述结构体中,size最大的是short,其长度为2字节,因而结构体中的char成员a、c都以2为单位对齐,sizeof(naturalalign)的结果等于6;

  如果改为:

struct naturalalign
{
 char a;
 int b;
 char c;
};

  其结果显然为12。

2.2指定对界

  一般地,可以通过下面的方法来改变缺省的对界条件:

  · 使用伪指令#pragma pack (n),编译器将按照n个字节对齐;
  · 使用伪指令#pragma pack (),取消自定义字节对齐方式。

  注意:如果#pragma pack (n)中指定的n大于结构体中最大成员的size,则其不起作用,结构体仍然按照size最大的成员进行对界。

  例如:

#pragma pack (n)
struct naturalalign
{
 char a;
 int b;
 char c;
};
#pragma pack ()

  当n为4、8、16时,其对齐方式均一样,sizeof(naturalalign)的结果都等于12。而当n为2时,其发挥了作用,使得sizeof(naturalalign)的结果为8。

  在VC++ 6.0编译器中,我们可以指定其对界方式(见图1),其操作方式为依次选择projetct > setting > C/C++菜单,在struct member alignment中指定你要的对界方式。

点击看大图

图1:在VC++ 6.0中指定对界方式

  另外,通过__attribute((aligned (n)))也可以让所作用的结构体成员对齐在n字节边界上,但是它较少被使用,因而不作详细讲解。

2.3 面试题的解答

  至此,我们可以对Intel、微软的面试题进行全面的解答。

  程序中第2行#pragma pack (8)虽然指定了对界为8,但是由于struct example1中的成员最大size为4(long变量size为4),故struct example1仍然按4字节对界,struct example1的size为8,即第18行的输出结果;

  struct example2中包含了struct example1,其本身包含的简单数据成员的最大size为2(short变量e),但是因为其包含了struct example1,而struct example1中的最大成员size为4,struct example2也应以4对界,#pragma pack (8)中指定的对界对struct example2也不起作用,故19行的输出结果为16;

  由于struct example2中的成员以4为单位对界,故其char变量c后应补充3个空,其后才是成员struct1的内存空间,20行的输出结果为4。

3. C和C++间struct的深层区别

  在C++语言中struct具有了“类” 的功能,其与关键字class的区别在于struct中成员变量和函数的默认访问权限为public,而class的为private。

  例如,定义struct类和class类:

struct structA
{
char a;

}
class classB
{
      char a;
      …
}

  则:

struct A a;
a.a = 'a';    //访问public成员,合法
classB b;
b.a = 'a';    //访问private成员,不合法

  许多文献写到这里就认为已经给出了C++中struct和class的全部区别,实则不然,另外一点需要注意的是:

  C++中的struct保持了对C中struct的全面兼容(这符合C++的初衷——“a better c”),因而,下面的操作是合法的:

//定义struct
struct structA
{
char a;
char b;
int c;
};
structA a = {'a' , 'a' ,1};    //  定义时直接赋初值

  即struct可以在定义的时候直接以{ }对其成员变量赋初值,而class则不能,在经典书目《thinking C++ 2nd edition》中作者对此点进行了强调。

4. struct编程注意事项

  看看下面的程序:

1. #include <iostream.h>

2. struct structA
3. {
4. int iMember;
5. char *cMember;
6. };

7. int main(int argc, char* argv[])
8. {
9. structA instant1,instant2;
10.char c = 'a';
   
11. instant1.iMember = 1;
12. instant1.cMember = &c;
 
13.instant2 = instant1;
 
14.cout << *(instant1.cMember) << endl;
 
15.*(instant2.cMember) = 'b';
 
16. cout << *(instant1.cMember) << endl;
 
17. return 0;
}

  14行的输出结果是:a
  16行的输出结果是:b

  Why?我们在15行对instant2的修改改变了instant1中成员的值!

  原因在于13行的instant2 = instant1赋值语句采用的是变量逐个拷贝,这使得instant1和instant2中的cMember指向了同一片内存,因而对instant2的修改也是对instant1的修改。

  在C语言中,当结构体中存在指针型成员时,一定要注意在采用赋值语句时是否将2个实例中的指针型成员指向了同一片内存。

  在C++语言中,当结构体中存在指针型成员时,我们需要重写struct的拷贝构造函数并进行“=”操作符重载。

点击此处查看原文 >>

系统分类: 软件开发   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(1222)
发表于:2006-9-29 11:18:17
标签:无标签

1

google的另类用法

在搜索框上输入:

  "indexof/"inurl:lib

  再按搜索你将进入许多图书馆,并且一定能下载自己喜欢的书籍。

  在搜索框上输入:

  "indexof/"cnki

  再按搜索你就可以找到许多图书馆的CNKI、VIP、超星等入口!

  在搜索框上输入:

  "indexof/"ppt

  再按搜索你就可以突破网站入口下载powerpint作品!

  在搜索框上输入:

  "indexof/"mp3

  再按搜索你就可以突破网站入口下载mp3、rm等影视作品!

  在搜索框上输入:

  "indexof/"swf

  再按搜索你就可以突破网站入口下载flash作品!

  在搜索框上输入:

  "indexof/"要下载的软件名

  再按搜索你就可以突破网站入口下载软件!

  注意引号应是英文的!

  再透露一下,如果你输入:

  "indexof/"AVI

  这样就可以下载AVI格式的视频文件了喔

第二篇突破封锁之看世界

  用Google看世界!!!只要你在Google里输入特殊的关键字,就可以搜到数千个摄象头的IP地址!通过他你就可以看到其所摄的实时影象!!

  在google里输入:

  inurl:"viewerframe?mode="

  随便打开一个,然后按提示装一个插件,就可以看到了!!!

  

第三篇突破封锁之Google是黑客的乐园

  三则黑客的Google搜索技巧简介

  大家都知道,Google毫无疑问是当今世界上最强大的搜索引擎。然而,在黑客手中,它也是一个秘密武器,它能搜索到一些你意想不到的信息。赛迪编者把他们进行了简单的总结不是希望您利用他去攻击别人的网站,而是利用这些技巧去在浩如烟海的网络信息中,来个大海捞针,寻找到对您有用的信息。

  如果您是一名普通网民,您可以使用黑客的技巧扩大自己的视野,提高自己的检索效率;如果您是一名网管,请您赶快看看您的网站是否做好了对下面黑客探测手段的防范措施,如果没有就赶快来个亡羊补牢,毕竟隐患胜于明火,防范胜于救灾;如果您是一名黑客,相信您早以在别的黑客站点上见过类似的方法,这篇文章对您没什么用处,这里的技巧对您是小儿科,菜鸟级!您可以节省宝贵的时间做更有意义的事情,这篇文章您不用看了,到别处去吧!

  搜索URL

  比如我们提交这种形式:passwd.txtsite:virtualave.net

  看到了什么?是不是觉得太不可思议了!有很多基于CGI/PHP/ASP类型的留言板存在这种问题。有时我们得到密码甚至还是明码的!管理员或许太不负责了,或许安全防范的意识太差了,如果你是网络管理员,赶快检查一下不要让恶意攻击者捡了便宜。不要太相信DES加密,即使我们的密码经过DES加密的密码,黑客们还是可以通过许多破解软件来搞定。

  这次我们能得到包含密码的文件。“site:virtualave.net”意思是只搜索virutalave.net的URL。virutalave.net是一个网络服务器提供商。

  同样,我们可以搜索一些顶级域名,比如:.net.org.jp.in.gr

  config.txtsite:.jp

  admin.txtsite:.tw

  搜索首页的目录

  首页是非常有用的,它会提供给你许多有用的信息。

  我们提交如下的形式:

  "Indexof/admin"

  "Indexof/secret"

  "Indexof/cgi-bin"site:.edu

  你可以自己定义搜索的首页字符。这样就可以获得许多信息。

  搜索特定的文件类型

  比如你想指定一种文件的类型,可以提交如下形式:

  filetype:.docsite:.milclassified

  这个就是搜索军方的资料,你可以自定义搜索。

第四篇突破封锁之Google的特殊功能

  1、查询电话号码

  Google的搜索栏中最新加入了电话号码和美国街区地址的查询信息。

  个人如想查找这些列表,只要填写姓名,城市和省份。

  如果该信息为众人所知,你就会在搜索结果页面的最上方看到搜索的电话和街区地址

  你还可以通过以下任何一种方法找到该列表:

  名字(或首位大写字母),姓,电话地区号

  名字(或首位大写字母),姓,邮递区号

  名字(或首位大写字母),姓,城市(可写州)

  名字(或首位大写字母),姓,州

  电话号码,包括区号

  名字,城市,州

  名字,邮递区号

  2、查找PDF文件

  现在GOOGLE的搜索结果中包括了PDF文件。尽管PDF文件不如HTML文件那么多,但他们经常具备一些其他文件不具备的高质量信息

  为了显示一个搜索结果是PDF文件而不是网页,PDF文件的标题开头显示蓝色文本。

  这就是让你知道ACRTOBATREADER程序会启动来阅读文件

  如果你的计算机没装有该程序,计算机会指导你去能免费下载该程序的网页。

  使用PDF文件时,相关的网页快照会由“TEXTVERSION”代替,它是PDF文档的复制文件,该文件除去了所有格式化命令。

  如果你在没有PDF链接的情况下想看一系列搜索结果,只要在搜索栏中打上-inurldf加上你的搜索条件。

  3、股票报价

  用Google查找股票和共有基金信息,只要输入一个或多个NYSE,NASDAQ,AMEX或

  共有基金的股票行情自动收录机的代码,也可以输入在股市开户的公司名字。

  如果Google识别出你查询的是股票或者共有基金,它回复的链接会直接连到高质量的金融信息提供者提供的股票和共有基金信息。

  在你搜索结果的开头显示的是你查询的股市行情自动收录器的代码。如果你要查找一家公司的名字(比如,INTEL),请查看“股票报价”在Google搜索结果的金融栏里会有那个公司的主页的链接(比如,WWW.INTEL.COM)。

  Google是以质量为基础来选择和决定金融信息提供者的,包括的因素有下载速度,用户界面及其功能。

  4、找找谁和你链接

  有些单词如果带有冒号就会有特殊的意思。比如link:操作员。查询link:siteURL,就会显示所有指向那个URL的网页。举例来说,链接www.Google.com会向你显示所有指向GOOGLE主页的网页。但这种方法不能与关键字查询联合使用。

  5、查找站点

  单词site后面如果接上冒号就能够将你的搜索限定到某个网站。具体做法是:在c搜索栏中使用site:sampledomain.com这个语法结构。比如,在斯坦福找申请信息,输入:

  admissionsite:www.stanford.edu

  6、查找字典释意

  查找字典释意的方法是在搜索栏中输入你要查询的内容。在我们根据要求找到所有的字典释意都会标有下划线,位于搜索结果的上面,点击链接你会找到字典提供者根据要求给出的相关定义。

  7、用GOOLGE查找地图

  想用Google查找街区地图,在Google搜索栏中输入美国街区地址,包括邮递区号或城市/州(比如165大学大街PALOALTOCA)。通常情况下,街区地址和城市的名字就足够了。

  当Google识别你的要求是查找地图,它会反馈给你有高质量地图提供者提供的链接,使你直接找到相关地图。我们是以质量为基础选择这些地图提供者。值得注意的是Google和使用的地图信息提供者没有任何关联。

点击此处查看原文 >>

系统分类: 自由话题   |    用户分类:    |    来源: 无分类

评论(1) | 阅读(1462)
发表于:2006-8-31 16:42:52
标签:无标签

0

做单片机开发,必须跳出芯片型号!

如题!很多人在谈单片机开发时,经常会将重点放在某一款芯片上,其实这是非常不理智的一种做法,芯片只是一种工具,方法才是根本。在做项目的时候,应该关注的是项目的功能和性能要求,然后采用反推法来分析要实现这些功能需要什么样的资源,采用什么方法或算法,这才是关键!特别是在解决各种问题时,设计思想,原理和方法是最重要的,而且是通用的,只要确定了思路和方法,用何种MCU只是实现和表达的方法不同而已。因此,我个人认为,MCU本身的资料若不做项目是完全不需要看的,毫无意义,但是,一些理论上的知识和基本知识则是必须要了解的,比如数据结构,数据库(不是指Foxbase,Orcale),操作系统(不是Windows,Linux),模拟和数字电路基础等,这些才是有可能真正提高你能力和设计水平的东西,更重要的是有助于提高你的创新的能力!

红***部分为 alanfang's Blog 内容,以下补充个人另解:

确实,搞系统设计,暂且不谈什么windows这么大的主板级系统设计,就以8位或16位单片机而言,道理一样,不能被仅仅查到的单片机作为核心然后向外扩展设计,想想现在是什么时代拉,哈哈,转眼的功夫,更高级的芯片横空出世咯~~~~

就像 alanfang's Blog 所说,从系统的功能性能要求入手,暂且抛开单片机型号,只有这样才能使设计的系统不为单片机所累,美其名曰“移植性更强,适应性更广”!

但对于小的系统,尤其是考虑成本且单片机外围电路很少的情况下,以上原则可以不理睬,因为好多单片机已经固化若干功能,具有较高的性价比。

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 无分类

评论(3) | 阅读(1289)
发表于:2006-8-29 9:57:19
标签:无标签

2

城市智能安防系统新型终端监控器的研制

城市智能安防系统新型终端监控器的研制
成都迅尔科技有限公司 金虹

前言

随着国民经济的迅速发展和城市规模的不断扩大,工商企业逐渐增多,新建居住小区不断涌现,流动人口迅速增加,这些既带来了经济的繁荣和人民生活水平的不断提高,也给整个城市的综合管理及安全保障带来了许多的负面影响和问题。火灾、盗抢、煤气泄漏等严重影响了人民的生命财产安全和正常生活秩序。如何提高大中城市整体安全防范体系,增强城市综合管理能力,是摆在政府相关部门的一项重要课题。

对此,我们在分析、比较国内外类似系统和产品的实际应用后,推出了《城市智能安防综合管理系统》,该系统采用计算机及网络拓朴技术,以城市监控管理中心为枢纽,以智能控制终端为服务对象,从建立调度、监控、综合管理以及信息发布等多方面实现科学化、系统化和数字化,充分利用现代遥感技术(RS)、地理信息系统技术(GIS)、办公自动化技术(OA)、全球定位系统技术(GPS)和现代通讯、网络技术,建立、健全一个全局性的《城市智能安防综合管理系统》。该系统现已在省会中心城市建网试用,效果良好。

新型终端监控器是与控制中心双向实时数据交换、本地控制执行、随时提供相关用户终端信息的控制单元,是城市智能安防综合管理系统网络的重要组成部分。


图1 系统构架图

总体设计方案和主要技术功能

新型终端监控器设计主要从安保监控管理子系统应用和用户脱网单独使用考虑,满足双向数据传输和本地服务需求,确保控制器稳定可靠,用户操作简便实用,减少误报,提高出警准确性。

①:采用世界著名IC微电脑芯片,功能完善,集成度高,抗干扰性强,EMC(电磁兼容性)优良。

②:率先使用来电显示检测电路,主动识别监控来电和用户私人电话,降低振铃声对用户的干扰。

③:集双音多频自动拨号电路和解码电路,满足与网络双向数据传输和个人单独监控使用。

④:智能警情排序设计,可根据报警优先等级自动识别处理。 ⑤:微电脑内含永久记忆体,断电永久保存当前工作参数,来电时保持原工作状态。

⑥:适合多规格多型号传感器输入,对开关量信号及脉冲电信号输入均能有效处理,微电脑内含10位模/数转换单元,输入信号分辨率最小可达4mV,大大提高了报警器工作可靠性,有效防止误报。

⑦:监控器设计有多项自检电路,对主要功能随时在线检测,故障上报及本地提示。⑧:配有工程键盘安装接口和用户红外遥控器,满足不同用途需求。


硬件电路设计功能框图

点击看大图
图2 硬件功能框图

主要电路设计简介

自动摘机电话接口电路

硬件原理如图3所示,整流桥提供极性变换,光电耦合器TLP521-1电路单元提供铃流检测,三极管Q1、Q2电路单元提供摘机负载和双音多频(DTMF)输出功能。工作时单片机设置端口RB0为中断输入下降沿有效,RB1为输出控制端口。在无来电时,RB0呈高电平,无信号跳变,当有铃流来到时,光电耦合器TLP521-1导通,RB0呈现低电平,经多次有效中断计数后,确认铃流有效,则RB1输出高电平,驱动高压三极管Q2导通,经负载回路使极性变换后电压降至DC 8V左右,自动摘机完成。该工作电路简单实用,工作稳定可靠,接口电路负载特性符合电信有关标准,改变了以往常用的用1:1隔离变压器做摘机接口的电路特点,降低了成本,提高了可生产性。

来电显示检测电路


图3 自动摘机电话接口电路图

图4 来电显示检测电路

BELL202数据流协议

来电显示(即主叫号码识别)现已成为电话通信中的一项重要功能,在许多交换机和客户服务呼叫中心都是不可缺少的,普通电话用户大多也已开通,但具体使用在安保监控系统中却鲜有报道。我公司在城市智能安防系统新型终端监控器中率先开发应用此项技术,对提高系统整体性能和改善客户服务奠定了良好的基础。

主叫号码识别是一种按V.23或BELL202数据流协议(即Caller ID),把主叫电话号码等信息在电话的呼叫阶段传给被叫客户的一种方法,典型的Caller ID协议由下列三个层次组成:

物理层:通过物理层异步传输8位字符,含起始位和停止位及6位数据。数据链路层:链路层是将内容数据帧组合成一个数据包,数据格式如下:

点击看大图

示意层:数据格式如下:

点击看大图

FSK(频移键控)

FSK(频移键控)是数据在电话线上进行二进制传输的一种调制方法,是用不同的载波频率来表示二进制数据"0"和"1",具有数据传送效率高,抗干扰能力好的特点。

电路原理和工作过程

在该单元电路中,我公司设计采用美国MITEL公司的MT88E39的FSK(频移键控)解码芯片。该器件为16PinSOIC封装,5个输入脚,8个输出脚,1对电源脚,1个内部连接脚,具体如下:

(1)第1、2脚:运放的模拟输入端IN+和IN-,FSK调制信号即由此输入。

(2) 第3脚(GS):运放增益调整端。

(3) 第4脚(VRE):参考电压输出端(2.5V)。

(4) 第5脚(CAP):外接0.1 F瓷片电容器接入端(另一端接地)。

(5)第6、7脚(OSC1和OSC2):晶振的连接端OSC1和OSC2。OSC1时钟输入,OSC2是时钟输出端。

(6)第9脚(DCLK):在不同工作方式,有不同功能。在模式0,它是串行数据输出位同步时钟,在无FSK信号输入时,其为高电平;在有信号时,其上升沿指示数据位已稳定,可以被读取。在模式1,它作输入端,需与微处理器的读信号相连。

(7)第10脚(DATA):串行数据输出端,在无FSK信号输入时,其为高电平;在有信号时,每字节按低位在前,高位在后送出。

(8) 第11脚(/DR):一个数据字准备好标志信号,即输出字同步时钟。

(9) 第12脚(/CD):在指定的时间内,载波被检测标志。

(10)第13脚(PWDN):低功耗运行控制输入端。高电平禁止,此时运放、振荡器及内部电路不工作。

(11)第14脚(MODE):工作模式选择输入端,分为模式0和模式1。两钟模式的不同仅在于数据输出与微处理器的接口方式,模式0使用较多。

(12)第15脚(IC),内部连接端,行数据输出端。

(13)第8、16脚(Vss、Vdd):一对电源脚。


图5 音频拨号电路

图6 主流程流程图

在电路中,我们选择MT88E39为工作方式0, 禁用低功耗模式,数据信号(DATA)接收波特率为1200B/s。 当检测到有效振铃信号后,单片机端口RA1随时监测MT88E39第9脚DCLK, 有下降沿跳变时,端口RA2以1200的波特率(单片机内部定时)从MT88E39第10脚DATA(数据输出)取得有效数据,按照上述BELL202数据流协议格式分析后即完成来电显示识别工作。


实例分析

此实例为从四川省成都电信局接受到的FSK数据,主叫号是手机13980881870,被叫号是85141190,来电显示采样数据为:0X55,0X55……0X55,0X55,0XFB,0X04,0X13,0X310X30,0X31,0X38,0X31,0X30,0X30,0X35,0X31,0X33,0X39,0X38,0X30,0X38,0X38,0X31,0X38,0X37,0X30,0X53数据解释:①信道有效数据:0X55,0X55……0X55,0X55 数目从24个至 32个不等,与首次振铃起始有关②起始信号:0XFB 此数据每次采样均有变化③信息类型:0X04④数据长度:0X13⑤通话时间ASCⅡ码:0X31,0X30,0X31,0X38,0X31,0X30,0X30,0X35分析为10月18日10时05分⑥主叫手机号13980881870:0X31,0X33,0X39,0X38,0X30,0X38,0X38,0X31,0X38,0X37,0X30⑦校验和:0X53

音频拨号电路

音频拨号电路中的DTMF双音多频拨号IC选用的是台湾和泰科技股份有限公司的HT9200A。该芯片系列有HT9200A,HT9200F,HT9200B等系列,其中9200A输入信号为串口接收方式;9200F与9200A 接收方式相同,但时钟只允许外输入,芯片增加了片选起始信号;9200B输入信号则为4线并口接收方式。考虑到成本和系统要求,我们选用了HT9200A款,由于DTMF输出端双音多频幅度不够,所以增加了一级三极管驱动,效果良好。


 
本文摘自《世界电子元器件》

点击此处查看原文 >>

系统分类: 消费电子   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(15888)
发表于:2006-8-29 9:44:29
标签:无标签

1

模拟I2C总线多主通信研究与软件设计

作 者:■ 西安电子科技大学 郑旭阳 李兵兵 黄新平

摘要:介绍模拟I2C总线的多主节点通信原理,并提出一种新的实现方法。这种采用延时接收比较来实现仲裁的方法,可使不具有I2C接口的普通微控制器(MCU)能够实现模拟I2C总线的多主通信,同时对I2C总线的推广起到了积极作用。

关键词:模拟I2C总线 仲裁 多主通信

  I2C总线(Inter IC BUS)是Philips公司推出的双向两线串行通信标准。由于它具有接口少、通信效率高等优点,现已得到广泛的应用\[1~3\]。它除了可以进行简单的单主节点通信外,还可以应用在多主节点的通信系统中。在多主节点通信系统中,如果两个或者更多的主节点同时启动数据传输,总线具有冲突检测和仲裁功能,保证通信正常进行并防止数据破坏。现在许多微控制器(MCU)都具有I2C总线接口,能方便地进行I2C总线设计。对于没有I2C总线接口的MCU,可以采用两条I/O接口线进行模拟\[2,3\]。目前,一些介绍模拟I2C的资料主要讲的是在单主节点系统中进行的通信,这使得模拟I2C总线的应用具有一定的局限性。本文根据总线仲裁的思想,提出一种多主节点通信的思想及实现流程。

1 I2C总线系统简介[1~3]

  I2C总线系统是由SCL(串行时钟)和SDA(串行数据)两根总线构成的。该总线有严格的时序要求,总线工作时,由串行时钟线SCL传送时钟脉冲,由串行数据线SDA传送数据。总线协议规定,各主节点进行通信时都要有起始、结束、发送数据和应答信号。这些信号都是通信过程中的基本单元。总线传送的每1帧数据均是1个字节,每当发送完1个字节后,接收节点就相应给一应答信号。协议规定,在启动总线后的第1个字节的高7位是对从节点的寻址地址,第8位为方向位(“0”表示主节点对从节点的写操作;“1”表示主节点对从节点的读操作),其余的字节为操作数据。图1列出I2C总线上几个基本信号的时序。

  图1中包括起始信号、停止信号、应答信号、非应答信号以及传输数据“0”和数据“1”的时序。起始信号就是在SCL线为高时SDA线从高变化到低;停止信号就是在SCL线为高时SDA线从低变化到高;应答信号是在SCL为高时SDA为低;非应答信号相反,是在SCL为高时SDA为高。传输数据“0”和数据“1”与发送应答位和非应答位时序图是相同的。

  图2表示了一个完整的数据传送过程。在I2C总线发送起始信号后,发送从机的7位寻址地址和1位表示这次操作性质的读写位,在有应答信号后开始传送数据,直到发送停止信号。数据是以字节为单位的。发送节点每发送1个字节就要检测SDA线上有没有收到应答信号,有则继续发送,否则将停止发送数据。

2 I2C总线的仲裁

  在多主的通信系统中。总线上有多个节点,它们都有自己的寻址地址,可以作为从节点被别的节点访问,同时它们都可以作为主节点向其他的节点发送控制字节和传送数据。但是如果有两个或两个以上的节点都向总线上发送启动信号并开始传送数据,这样就形成了冲突。要解决这种冲突,就要进行仲裁的判决,这就是I2C总线上的仲裁。

        

  I2C总线上的仲裁分两部分:SCL线的同步和SDA线的仲裁。SCL同步是由于总线具有线“与”的逻辑功能,即只要有一个节点发送低电平时,总线上就表现为低电平。当所有的节点都发送高电平时,总线才能表现为高电平。正是由于线“与”逻辑功能的原理,当多个节点同时发送时钟信号时,在总线上表现的是统一的时钟信号。这就是SCL的同步原理。

  SDA线的仲裁也是建立在总线具有线“与”逻辑功能的原理上的。节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致。是,继续发送;否则,退出竞争。图3中给出了两个节点在总线上的仲裁过程。SDA线的仲裁可以保证I2C总线系统在多个主节点同时企图控制总线时通信正常进行并且数据不丢失。总线系统通过仲裁只允许一个主节点可以继续占据总线[1]。

  图3是以两个节点为例的仲裁过程。DATA1和DATA2分别是主节点向总线所发送的数据信号,SDA为总线上所呈现的数据信号,SCL是总线上所呈现的时钟信号。当主节点1、2同时发送起始信号时,两个主节点都发送了高电平信号。这时总线上呈现的信号为高电平,两个主节点都检测到总线上的信号与自己发送的信号相同,继续发送数据。第2个时钟周期,2个主节点都发送低电平信号,在总线上呈现的信号为低电平,仍继续发送数据。在第3个时钟周期,主节点1发送高电平信号,而主节点2发送低电平信号。根据总线的线“与”的逻辑功能,总线上的信号为低电平,这时主节点1检测到总线上的数据和自己所发送的数据不一样,就断开数据的输出级,转为从机接收状态。这样主节点2就赢得了总线,而且数据没有丢失,即总线的数据与主节点2所发送的数据一样,而主节点1在转为从节点后继续接收数据,同样也没有丢掉SDA线上的数据。因此在仲裁过程中数据没有丢失。
        
                  图3两个主节点的仲裁过程

3 多主通信的原理及其实现流程

  多主通信就是在总线上有多个节点。这些节点既可以作为主节点访问其他的节点,也可以作为从节点被其他节点访问。当有多个节点同时企图占用总线时,就需要总线的仲裁。对于模拟I2C总线系统,怎样实现总线的仲裁是现在研究模拟I2C总线系统的难点。文献\[4\]提出在系统中增加1根BUSY线,在占用总线之前先检测BUSY线,看总线是否被占用。若总线空闲,则设置BUSY线并向总线上传送数据;否则,接收数据,直到总线空闲时才占有总线。这种实现多主通信的方法有两个缺点:① 因为I2C最大的优点就是接口少、效率高,这样做不仅增加了使用资源而且减少了I2C总线的优势;② 当主节点数比较多时,等待时间比较长,效率不高。本设计根据总线的仲裁原理,提出一种基于延时比较的仲裁方法。当主节点想要占用总线时,先检测总线上是否空闲,如果总线是空闲的就发送数据。在发送数据的同时,将总线上的数据接收并与发送的数据进行比较。如果不同,说明总线上同时还存在其他节点,于是就退出;否则,一直到发送完数据。这种方法既体现了I2C总线的高效性,同时还具有良好的扩展性。
              
                  图4多主通信流程

  图4给出了基于延时比较的多主通信流程,其中MCU作为从节点部分的流程在图5中给出。在节点发送起始信号之前先要检测一下总线上是否为空闲状态(BUSY是否为0)。这里使用的检测方法是,持续检测一段时间看总线上的电平是否一直为高,若是说明总线上为闲状态,否则说明有其他的节点正在使用总线,要等一段时间再发送。当总线空闲时,发送起始信号,接着发送要访问的从节点的地址字节。每发送1位数据就接收比较1次,看发送和接收的是否一致,若是则继续,否则跳出到从节点的接收状态。如果没有产生冲突,MCU作为主节点继续发送数据,直到任务结束,然后发送停止信号并返回。如果数据不一样,MCU将跳转到从节点状态。由于在跳转到从节点接收状态的过程中累加器(ACC)和工作寄存器(Ri)的数据没有发生变化,所以数据没有丢失,作为从节点可以继续接收总线上的数据。这样整个通信的过程没有中断,数据也没有丢失。
              
                 图5从节点部分的流程

  图5给出了从节点的流程。进入从节点时,要将BUSY置为高,说明MCU现在正在工作,不能完成其他的任务。在MCU作为从节点完成接收任务后,要将BUSY置为低。MCU在接收到寻址字节后与自己的地址字节进行比较。如果是访问自己的就进入到下面的接收程序,否则跳出。在访问自己的时候,还要判断主节点是读取数据还是写数据,以便进入相应的程序。在写字节的子程序中,从节点每发送1个字节的数据后都要察看是否有应答信号(ACK),有则说明数据接收到了;否则要跳出等待,重新发送。在读字节的子程序中,每接收1个字节的数据就要发送1个应答信号(ACK),以示接收正常,否则主节点将停止继续发送。在现有的资料中,关于从节点的原理和源代码比较少,这里给出作为从节点时写字节子程序的源代码。由于篇幅有限其他的子程序没有列出。

4 部分源代码


  本节是在MCU多主通信中的部分源代码。多主通信的实现中有几个难点和重点。一是在作为主节点时的写字节子程序,里面要包括发送的每位数据和总线的数据进行比较并做出判断。如果数据不同,要跳出并进入从节点的状态。由于子程序返回主程序时改变的只是PC的值而累加器(ACC)和工作寄存器(Ri)里面的值是不变的,因此MCU进入从机状态后继续接收总线剩下的数据,这样总线的数据并没有丢失。二是作为从节点时的写字节的子程序。由于时钟线是由主节点的MCU控制的,所以怎样根据SCL线来读取SDA线的数据是其中的一个难点。三是在具有子地址的从节点关于是写字节还是读字节时的判断。如果是写字节时主节点会给出新的起始信号,并再次发送从节点的地址数据。这时从节点需要做出判断是读取数据还是写数据,并进入相应的子程序。这里给出以上三个重点和难点的子程序的源代码,以供读者参考。这些源代码经实践证明都是正确的。

  主节点的写字节子程序:
;其中的NOP可根据时钟的快慢自己加减
  WRBYTE:MOV R0,#08H
      CLR BUSY;将BUSY值清零
  WLP:  RLC A;取数据位
  JC   WR1
      SJMP WR0;判断数据位
  WLP1: DJNZ R0,WLP
      NOP
  OUT1: RET
  WR1:  SETB SDA;发送1
      NOP
      SETB  SCL
      MOV  C,SDA;判断是否与发送的数据相同
      JC   GOON
      SETB  BUSY
      AJMP  OUT1
  GOON: NOP
      NOP
      NOP
      CLR SCL
      SJMP WLP1
  WR0:  CLR SDA;发送0
      NOP
      SCL
      NOP
      NOP
      NOP
      NOP
      NOP
      CLR
      SCL
  SJMP  WLP1
  从节点的写字节子程序(返回为ACK):
  SWRBYTE:MOV R0,#08H
  WAGAIN: RRC A
      MOV B,#37H
  WWAIT1: JB SCL,WWAIT1;等待SCL为低
      JC WR1;判断是发送“1”还是发送“0”
      SETB SDA;发送“1”
      AJMP COM
  WR1:  CLR SDA;发送“0”
  COM:  DJNZ R0,WWAIT2;判断是否发送完毕
  WWAIT3: JNB SCL,WWAIT3;发送完毕等待应答信号
  WWAIT4: JB SCL,WWAIT4
  WWAIT5: JNB SCL,WWAIT5
      CLR ACK
      JB  SDA,ST0
      SETB ACK
  ST0:  RET;返回
  WWAIT2: JNB SCL,WWAIT2;等待SCL为高
      SJMP WAGAIN
      从节点的读字节同时判断是否有起始信号的子程序。如果有起始信号,则转为写字节子程序:
  SRDBYTE:MOV R0,#08H
      SETB 20H;设置标志位判断是读还是写
      SETB SDA;释放总线
  RWAITJ: JNB SCL,RWAITJ;等待SCL为高
      MOV C,SDA;从总线上读取数据
      RRC A;存入累计器
      DEC R0
      MOV C,ACC.7;判断是否为起始信号
      JNC RWAITJ1;为低继续读取数据
  REWAIT: JNB SCL,RWAITJ1;开始判断是否为起始信号
      JB  SDA,REWAIT
      CLR 20H;是,则清标志位并返回
      AJMP SjRDOUT
  RWAITJ1:JB SCL,RWAITJ1;等待SCL为低
  RWAITJ3:JNB SCL,RWAITJ3;等待SCL为高
      MOV C,SDA
      RRC A
      DJNZ R0,RWAITJ2
  SjRDOUT:RET
  RWAITJ2:JB SCL,RWAITJ2;等待SCL为低继续读数据
      SJMP RWAITJ3

5 总结

  根据总线协议中的仲裁原理,提出的基于延时比较的模拟I2C多主通信的方法,不仅能够体现了I2C总线的高效性,而且还具有良好的扩展性。它使普通不具有I2C接口的MCU可以应用在多主通信的系统中,既增加了普通MCU的使用范围,又突破了模拟I2C总线的应用局限性,为I2C总线的推广起到了积极的作用。

                 参考文献

1 The I2CBus Specification, Version 2.1. January, 2000. http://www.philips.com
2 张昆,邱扬,刘浩. 基于CPLD的系统中I2C总线的设计. 电子技术应用,2003(11)
3 何立民. I2C总线应用系统设计. 北京:北京航空航天大学出版社,1995
4 张冬梅,藩仕彬,何为民. 模拟I2C总线多主通信的通用软件包. 单片机与嵌入式系统应用, 2003(12)

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 无分类

评论(1) | 阅读(2500)
发表于:2006-8-29 9:41:07
标签:无标签

1

构造一个51单片机的实时操作系统

构造一个51单片机的实时操作系统
长沙市希麦特电子科技有限公司 彭光红

目前,大多数的产品开发是在基于一些小容量的单片机上进行的,51系列单片机,是我国目前使用最多的单片机系列之一,有非常广大的应用环境与前景,多年来的资源积累,使51系列单片机仍是许多开发者的首选。针对这种情况,近几年涌现出许多基于51内核的扩展芯片,功能越来越齐全,速度越来越快,也从一个侧面说明了51系列单片机在国内的生命力。

多年来我们一直想找一个合适的实时操作系统,作为自己的开发基础。根据开发需求,整合一些常用的嵌入式构件,以节约开发时间,尽最大可能地减少开发工作量;另外,要求这个实时操作系统能非常容易地嵌入到小容量的芯片中。毕竟,大系统是少数的,而小应用是多数而广泛的。显而易见,μC/OS-Ⅱ是不太适合于以上要求的,而Keil C所带的RTX Tiny不带源代码,不具透明性,至于其FULL版本就更不用说了。

1 Keil C51与重入问题

说到实时操作系统,就不能不考虑重入问题。对于PC机这样的大内存处理器而言,这似乎并不是一个很麻烦的问题,借用μC/OS-Ⅱ RTOS的说法,即要求在重入的函数内,使用局部变量。但51系列单片机堆栈空间很小,仅局限在256字节之内,无法为每个函数都分配一个局部堆空间,正是由于这个原因,Keil C51使用了所谓的可覆盖技术:

(1)局部变量存储在全局RAM空间(不考虑扩展外部存储器的情况);
(2)在编译链接时,即已经完成局部变量的定位;
(3)如果各函数之间没有直接或间接的调用关系,则其局部变量空间便可覆盖。

正是由于以上的原因,在Keil C51环境下,纯粹的函数如果不加处理(如增加一个模拟栈),是无法重入的。那么在Keil C51环境下,如何使其函数具有可重入性呢?下面分析在实时操作系统下面,任务的基本结构与模式:

void TaskA(void*ptr){
UINT8 val_a;
//其他一些变量定义
do{
//实际的用户任务处理代码
}while(1);
}
void TaskB(void*ptr){
UINT8 val_b;
//其他一些变量定义
do{
Funcl();
//其他实际的用户任务处理代码
}while(1);
}
void Funcl(){
UINT8 val_fa;
//其他变量的定义
//函数的处理代码
}

在上面的代码中,TaskA与TaskB并不存在直接或间接的调用关系,因而其局部变量val_a与val_b便是可以被互相覆盖的,即其可能都被定位于某一个相同的RAM空间。这样,当TaskA运行一段时间,改变了val_a后,TaskB取得CPU控制权并运行时,便可能会改变val_b。由于其指向相同的RAM空间,导致TaskA重新取得CPU控制权时,val_a的值已经改变,从而导致程序运行不正确,反过来亦然。另一方面,Funch()与TaskB有直接的调用关系,因而其局部变量val_fa与val_b不会被互相覆盖,但也不能保证其局部变量val_fa不会与TaskA或其他任务的局部变量形成可覆盖关系。

将val_a、val_b以及val_fa等局部变量定义为静态变量(加上static指示符)可以解决这一问题。但问题是,定义大量的static类型变量,将导致RAM空间的大量占用,有可能直接导致RAM空间不够用。尤其是在一些小容量的单片机内,一般只有128或256字节,大量的静态变量定义,在如此小的RAM资源状况下显然就不太合适了。由此而有了另一种的解决方法,如下代码所示:

void TaskC(void){
UINT8 x,y;
while(1){
OS_ENTER_CRITICAL();
x=GetX(); (1)
y=GetY(); (2)
//任务的其他代码
OS_EXIT_CRITICAL(); (3)
OSSleep(100); (4)
}
}

以上代码TaskC中使用了临界保护的方法来保护代码不被中断占先,确实有效地解决了RAM空间太小,不宜大量定义静态变量的问题;然而如果每个任务都采用此种结构,任务一开始,就关闭中断,将使实时性得不到保证。事实证明,这种延时是相当可观的。用一个实例来说明,如果想在系统中使用一个动态刷新的LED显示器,就难以保证显示的稳定与连续,哪怕在系统中是使用一个单独的定时器来做这一工作(进入临界区后,EA=0)。其次,这种结构事实上将占先的任务调度转化为非占先的任务调度。实际上如果在(3)与(4)之间没有碰巧发生中断并导致一个任务调度,那就可以理解为是任务主动放弃CPU的控制。如果在(3)和(4)之间碰巧产生了一个中断并导致了一个任务调度,只是执行了一次多余的任务调度而已,而且并不希望在(3)之后发生2次深圳多次的任务调度,相信读者也有这一愿望。

除此之外,还可以发现任务的一个特点:当任务从(1)重新开始时,局部变量x和y是一个什么值并不在乎,即x和y即使在(3)之后改变了,也已经不再重要,不会影响程序的正确性。其实这一特点也是大部分任务,至少是大部分任务的大部分局部变量的一个共性--如果任务在整个执行过程中,不会(被占先)放弃CPU控制权,则其局部变量大多数并不需要进行特别的保护,即其作用域只是任务的当次执行,针对上面的代码,就是临界保护区内的代码区域。
2 实时操作系统要不要占先

有上面的分析,如果要保持一个函数可重入,就得使用静态变量,系统的RAM资源将是一个严峻的考验,如果使用临界区来保护运行环境,系统的实时性又得不到保证,而且有将占先式任务调度转为非占先任务调度之虞。显然,使用静态变量简单,但是更多的不适用性,对将来功能的调整也是一个阻碍,一般不被采用。那么,就只能从环境保护上来下功夫了,但是果真只能以进入临界区牺牲系统的实时性来保证任务不被占先?下面看看临界保护这一方法的基本思路:

(1)在一个任务中,如果局部变量在其作用域内不被占先切换,则这些变量在任务被剥夺了CPU控制权后,不关心其值也不会影响任务的正确执行;
(2)使用临界区保护,可以达到上面所提到的要求;
(3)由此导致的实时性能与占先切换的减弱可以接受。

由此可知,不被占先的是任务保护局部变量的关键。既然如此,何不舍弃占先式的任务调度?这不失为一个好的出发点。针对Keil C51,非占先式任务调度,可能是一种更好的方法,更能协调51系列的单片机的既定资源,下面编写这样一个系统:

(1)使用非占先式任务调度;
(2)可以在小容量的芯片中使用,开发目标是,即使是8051这样小的芯片,也可使用这个实时操作系统;
(3)支持优先级调度,尽可能保证其实时性。

3 实时操作系统的实现

基于以上的分析与目的,今日完成了这个操作系统。在堆栈上借用RTX的管理方法,即当前任务使用全部的堆空间,如图1所示。

3.1 堆栈的初始化与任务的创建

堆栈的初始化实际是初始化OSTaskStackBotton数组,并将当前任务指定为空闲任务,下一个运行任务指定为最高优先级任务,即优先级为零的任务。初始化时,将SP的值存入OSTaskStackBotton[0],SP+2的值存入OSTaskStackBotton[1],依此类推。而任务是调用OSTaskCreate函数建立的,实际上只是将任务(假设为n号任务)的地址填入到对应OSTaskStackBotton[n]所指向的位置,并将SP向后移动2个字节,如图2所示。

为什么要以这样一种规律而不是其他的方式呢?这样由于在任务建立后,还未进行任务调度之前,各任务的堆栈实际上是它们自身的地址,因而其堆栈深度为2,为了程序的简便而直接填入。

void main(void){
OSInit(); /*初始化OSTaskStackBotton队列*/
TMOD=(TMOD&0XF0)|0X01;
TL0=0xBF;
TH0=0xFC;
TR0=1;
ET0=1;
TF0=0;
OSTaskCreate(TaskA,NULL,0);
OSTaskCreate(TaskB,NULL,1);
OSTaskCreate(TaskC,NULL,2);
OSStart();
}
上面这段代码中,所有任务建立后,便调用OSStart()开始任务调度。OSStart()是一个宏定义,如下所示:
#define OSStart() do{\
OSTaskCreate(TaskIdle,NULL,OS_MAX_TASKS);\
EA=1;\
return;\
}while(0)

首先,它创建了一个空闲任务并打开中断,然后便返回。返回到那里了呢?我们知道,空闲任务是优先级最低的任务,当调OSTaskCreate建立时,会将其地址填入到SP的位置,并把SP向后移动2个字节(见图2及说明),因而此时处在堆栈顶端的,一定是空闲任务TaskIdle。这就使得这里的return一定会返回到空闲任务。至此,系统进入正常运行状态。

3.2 任务的切换

任务的切换分两种情况,在当前任务优先级低于下一个取得CPU的控制权的任务时,将下一个取得CPU控制权的任务的栈顶到当前任务的栈顶之间的内容向RAM空间的高端搬移,以空出全部的RAM空间作下一个任务的堆空间,同时更新对应的OSTaskStackBotton,使其指向新的正确任务的堆栈栈底。如果当前任务的优先级高于下一个任务的优先级,则作相反的搬移,如图3与图4所示。



所有任务必须主动调用OSSleep,放弃CPU的控制权。任务调用OSSleep后,将选择优先级最高的就绪任务运行。

(编者注:实时操作系统源代码见本刊网站www.mesnet.com.cn。)

结语

系统完成后,内核的代码量在400多个字节左右,占用1个定时器中断及小量的内存空间。系统设置容量为8个任务,用户实际可用任务为7个,能够满足一般需求,也达到了在小容量芯片中应用的开发要求。由于没有采用占先式的任务调度,除开全程相关的个别任务的一些局部变量外,其他局部变量已经不存在覆盖关系,由于是任务主动放弃CPU控制权,对于个别需要保护的变量单独进行处理也变得容易。在系统中,全程不需要反复地开关中断,实时性能也很好。对个别时序要求严格的外设(如DS18B20)除外。

注:本文所说的重入不一定是严格意义上的重入,很大程度上仅指函数被打断后再次进入时,程序能正确运行,并不是说其环境变量没有改变。

 
本文摘自《单片机与嵌入式系统应用》

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(1293)
发表于:2006-8-29 9:38:52
标签:智能仪表  CAN  

1

智能仪表的CAN接口设计

智能仪表的CAN接口设计
王文华
(辽宁机电职业技术学院 机械系,辽宁 丹东 118002)

1 前沿

在计算机数据传输领域内,长期以来使用RS-232通信标准,尽管被广泛的使用,但却是一种低数据率和点对点的数据传输标准,无能力支持更高层次的计算机之间的功能操作。同时,在复杂或大规模应用中(如工业现场控制或生产自动化领域),需要使用大量的传感器、执行器和控制器等,它们通常分布在非常广的范围内,所以,在最底层的确需要一种造价低廉而又能适应工业现场环境的通信系统,现场总线(Field Bus)就是在这种背景下应运而生的。

现场总线是连接智能现场设备和自动化系统的数字式、双向传输、多分支结构的通信网络,现场总线技术自上世纪70年代诞生至今,由于它在减少系统线缆,简化系统安装、维护和管理,降低系统的投资和运行成本,增强系统性能等方面的优越性,引起人们的广泛注意,得到大范围的推广。

CAN是一种有效支持分布式控制或实时控制的串行通信网络,最初是由德国BOSCH公司为汽车监控、控制系统设计的。由于CAN总线本身的特点,其应用范围目前已不再局限于汽车行业,而向过程工业、机械工业、纺织机械、农用机械、机器人、数控机床、医疗器械、传感器及智能仪表等领域发展。

智能仪表是自动化学科的重要组成部分。随着科学技术的迅速发展,尤其是微电子、计算机和通信技术日新月异的变化,智能仪表逐渐向数字化、网络化和智能化方向发展。智能仪表一方面可以进行人机对话及与外部仪器设备对话,通过现场总线接入自动测试系统;另一方面,使用者借助面板上的键盘和显示屏,可用对话方式选择测量功能,设置参数。当然,通过总线中的工业计算机也可获得测量节点的数据。

2 CAN的接口设计

CAN总线是一种串行数据通信协议,在CAN总线通信接口中集成了CAN协议的物理层和数据链路层功能,可以完成对通信数据的成帧处理。CAN总线接口的具体电路如图1所示。

笔者用SJA1000作为流量计的CAN控制器,与CPU(单片机)的I/O口直接相连,再通过PCA82C250组成CAN总线。这种结构很容易实现CAN网络节点中的信息收发,从而实现对现场的控制。

SJA1000的AD0-AD7连接到MSP420F149的P0口,INT接到P1.0,CS接到P1.1,RD连接到P1.2,WR连到P1.3,ALE连到P1.4,SJA1000的RX0与TX0分别通过2个CNW137型高速光耦与PCA82C250相连后,再连到CAN总线上。

PCA82C250为CAN总线收发器,是CAN控制器与CAN总线的接口器件,对CAN总线以差分方式发送,其RS引脚用于选择PCA82C250的工作方式:高速方式和斜率方式。RS接地为高速,RS引脚串接1只电阻器后再接地,用于控制上升和下降斜率,从而减小射频干扰。RS引脚接高电平,PCA82C250处于等待状态。此时发送器关闭,接收器处于低电流工作,可以对CAN总线上的显性位做出反应来通知CPU。实验数据表明15kΩ-200kΩ为串联电阻器较理想的取值范围,在这种情况下,可以用平行线或双绞线作为总线,本设计中PCA82C250的斜率电阻为30kΩ。

CNW137为高速光耦,最高速度为10Mb/s,用于保护SJA1000型CAN总线控制器。CAN总线的终端匹配电阻器起相当重要的作用,不合适的电阻器会使数据通信的抗干扰性及可靠性大大降低甚至无法通信,理想的阻值范围为108Ω-132Ω,该设计使用的阻值为124Ω。

2.1 SJA1000的功能

CAN通信协议主要由CAN控制器完成。SJA1000是适用于汽车和一般工业环境控制器局域网(CAN)的高集成度控制器,具有完成高性能通信协议所要求的全部特性,具有简单总线连接的SJA1000可完成物理层和数据链路层的所有功能,应用层功能可由微控制器完成,SJA1000为其提供了多用途的接口。

SJA1000是Philips公司PCA82C200型CAN控制器的后续产品,在软件和引脚上均与PCA82C200兼容,并增加了许多新的功能,性能更佳。尤其适用于对系统优化、诊断和维护要求比较高的场合。

SJA1000的功能框图如图2所示,由以下几部分构成:接口管理逻辑;发送缓冲器,能够存储1个完整的报文(扩展的或标准的);验收滤波器;接收FIFO;CAN核心模块。

2.2 82C250
SJA1000的一端与单片机相连,另一端与CAN总线相连。但是,为了提高单片机对CAN总线的驱动能力,可以把82C250作为CAN控制器和物理总线间的接口,以提供对总线的差动发送能力和对CAN控制器的差动接收能力。82C250的主要特性如下:
与ISO/DIS11898标准兼容;
高速(最高可达1Mb/s);
具有抗汽车环境下的瞬间干扰和保护总线的能力;
降低射频干扰的斜率控制;
热保护功能;
防止电池与地之间发生短路;
低电流待机方式;
某个节点掉电不会影响总线;
可有110个节点相连接。
3 CAN通信程序
SJA1000操作期间,在上电之前必须配置控制线路(中断、复位、片选等)建立与CAN控制器之间通信的硬件连接。初始化、CAN通信采用中断方式数据发送和接收子程序,其流程如图3、图4和图5所示。



如果在上电后独立CAN控制器在引脚17得到1个复位脉冲(低电平),它就能够进入复位模式。在对SJA1000寄存器设计前,CAN控制器通过读复位模式/请求标志来检查是否已进入复位模式,因为要配置信息的寄存器只有在复位模式才能写入,并涉及到对控制寄存器(CR)、验收码寄存器(ACR)、验收屏蔽寄存器(AMR)、总线定时寄存器(BTRO和BTR1)和输出控制寄存器(OCR)的初始化编程。

时钟分频寄存器可以选择BasicCAN或PeliCAN工作模式,设置CLKOUT因该使能用来选择频率,设置是否使用旁路CAN输入比较器和是否使用TX1输出用为专门的接收中断输出。

验收代码和验收屏蔽寄存器的设置可以过滤信息,为收到的信息定义验收代码;为与验收代码相关位比较定义验收屏蔽代码。

总线定时寄存器定义总线上的位速率。输出控制寄存器定义CAN总线输出引脚TX0和TX1的输出模式,定义TX0和TX1输出引脚配置是悬空、下拉、上拉或推挽以及极性。中断寄存器设置允许识别的中断源。

4 结束语

多个智能仪表通过CAN接口与PC连成总线网,其系统运行良好。这种基于现场总线的智能仪表系统抗干扰性强,性能可靠,无论是测量速度、精确度和自动化程序还是性价比都是传统仪表不能比拟的,是今后仪器仪表发展的方向。

 
本文摘自《国外电子元器件》

点击此处查看原文 >>

系统分类: 工业控制   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(1514)
发表于:2006-8-29 9:37:45
标签:430  操作系统  

0

基于MSP430F149单片机的实时多任务操作系统

基于MSP430F149单片机的实时多任务操作系统


1 RTOS的基本概念

实时多任务操作系统(RTOS-Real Time Operating System)是根据操作系统的工作特性而言的。实时是指物理进程的真实时间。实时操作系统是指具有实时性,能支持实时控制系 统工作的操作系统。首要任务是调度一切可利用的资源完成实时控制任务,重要特点是要满足对时间的限制和要求。

实时操作系统中的任务(Task)有四种状态:运行(Executing),就绪(Ready),挂起(Suspended),休眠(Dormant)。

运行:获得CPU控制权。

就绪:进入任务等待队列。通过调度转为运行状态。

挂起:任务发生阻塞,移出任务等待队列,等待系统实时事件的发生而唤醒。从而转为就 绪或运行。

休眠:任务完成或错误等原因被清除的任务。也可以认为是系统中不存在了的任务。

某一时刻,系统中只能有一个任务在运行状态。各任务按级别通过时间片分别获得对CPU的访问权。

RTOS内核按照任务的调度机制可以分为两种:一种是占先式内核,一种是非占先式内核。

占先式内核:当一个低优先级的任务正在运行时,一个高优先级的任务就绪,那么RTOS就会把低优先级的任务挂起,来运行高优先级的任务。等高优先级的任务执行了一个循环挂起之后,再回到低优先级任务的断点继续运行。也就是说,任务的优先级越高,响应起来越及时。

非占先式内核:当一个低优先级的任务在运行时,一个高优先级的任务就绪,RTOS不会把CPU切换给高优先级的任务,必须等低优先级的任务执行了一个循环挂起之后,再由RTOS根据所有就绪任务的优先级判断将CPU切到哪个任务。

绝大多数商业RTOS, 以及著名的开放源码的uC/OS-II操作系统,都采用的是占先式内核,它的优点是实时性要比非占先式内核高。

在RTOS中,一般情况下,每个任务都一无限循环,每循环一次,任务挂起一段时间,以供调度程序把这段时间交给优先级更高的其它就绪任务,让其它任务运行(如图1)。当所有任务都挂起时,RTOS把任务切到空闲任务来执行。

空闲任务是一个系统任务,它一般是一个空的循环,优先级最低,也从来不会挂起。

2 在MSP430上使用RTOS的意义

一般的观点认为,MSP430上使用RTOS是没有意义的。这是可以理解的,因为MSP430的硬件资源有限(以MSP430F149为例,只有2KRAM),任何商业操作系统都不可能移植到MSP430上。目前在MSP430上得到应用的RTOS,只有 uC/OS-II,但使用uC/OS-II 必须有昂贵的C编译器,这严重限制了其在MSP430上的使用。

正是基于以上情况,笔者在应用MSP430过程中,编写了一个基于MSP430F149的RTOS,暂定名为M430/OS。它占用RAM量少、代码短小,稍加改动就可适用于大多数其它MSP430单片机。

在MSP430单片机系统上使用M430/OS,对系统有以下意义:

1) 实现软件设计的模块化。可将不同的功能模块编制成相应的任务,由操作系统按级别调用,不必为先执行哪个功能、后执行哪个功能而费神。

2) 更能合理、有效地利用CPU有限的资源。按任务的重要程度安排任务的级别,能够保证最重要的任务执行得最及时。

3) 大大降低系统故障率。低优先级的任务发生阻塞时,高优先级的的任务的执行不受影响。

3 M430/OS在MSP430F149上的实现

3.1 功能特点
  
M430/OS有以下特点:

1) 采用占先式内核,即高优先级的任务可以从低优先级任务"抢"回CPU控制权;

2) 每个任务都单独开辟一个任务栈;

3) 每个任务占十几到几百个字节的任务堆栈,任务栈的大小可以根据任务中现场数据、局部变量和嵌套调用的情况估算;

4) 每个任务各占一个优先级,不支持两个任务有相同的优先级;

5) 不支持信号量、邮箱功能;

6) 任务状态只有三种:运行(Executing),就绪(Ready),挂起(Suspended);

7) 系统占用RAM量=((任务个数+1)×4)+6个字节,不包括任务堆栈;

8) 代码量少,目前版本的代码共有87行汇编代码,256字节目标代码;

9) 理论最多支持126个任务;

10)任务锁定功能:在一段低优先级的代码中,不想让操作系统把CPU权切换到别的任务,这时可以把这代码锁定,在运行这段码时,就不会引起任务切换;

11)任务唤醒功能:在一个任务中产生一个的事件来触发其它任务运行(如果被触发的任务优先级高的话,就会马上运行)。

3.2 系统函数介绍

1) OS_Init:多任务初始化,进行任务栈(任务栈的结构见图3)、任务延时计数、任务状态的初始化。初始化完成后,系统直接切换到最高优先级的任务,多任务系统启动。

2) OS_Time_Dly:把当前任务挂起一段指定时间让其它任务运行。

3) OS_Sched:任务调度,它先把每个任务的延时数减1,然后再找出最高优先级的就绪任务,并切换到这个就绪任务。如果无就绪任务,就切换到空闲任务。

4) OS_Free_Task:空闲任务,是一个很重要的系统任务,当所有任务都挂起时,来运行此任务。它主要是对一个计数器Free_Count一直进行累加,用户可以根据这个计数器来计算出CPU的利用率来。

5) OS_Task_Lock:锁定任务调度,禁止任务调度。主要用来锁定在低优先级中的一些为可重入的代码或一些重要代码。

6) OS_Task_Unlock:解锁任务调度,和上面的子程序功能相反。

7) OS_Task_Wakeup:唤醒指定优先级的任务,并产生一次任务调度,如果被唤醒任务的优先级比当前运行的任务的优先级高,就会任务切换到被唤醒的任务中,否则等待下一个调度时机。

3.3 主要功能的实现

a) 任务初始化

系统加电运行后,首先对硬件资源进行初始化,接着就要对多任务进行初始化了。主要是初始化每个任务的任务栈、每个任务的时钟滴数和堆栈指针位置。我们把每个任务栈都初始化成图2形式:

任务栈的初始化如下程序(r11是用来初始任务堆栈的一个指针,r10是一个循环计数器):

mov.w     #(栈底 + 2) , r11

clr.w     Task_Tick(r10)     ;清0时钟滴嗒数

mov.w     #任务首地址 , 0(r11)  ;把任务地址压入堆栈

mov.w     SR , -2(r11)      ;把标志寄存器放入任务栈

mov.w     r11 , Task_SP(r10)

sub.w     #现场所占的字节数 , Task_SP(r10) ;SP位置放入堆栈

初始化完任务栈之后,就把堆栈指针指向最高任务先级任务栈的任务首地址处,再执行ret返回,这样,多任务就启动开了。如下程序:

mov.w     #09feh , sp      ;最高优先级的任务栈任务首地址位置

ret                  ;返回到最高优先级的任务

任务初始化的流程见图3。

b) 时钟节拍

时钟节拍由MSP430F149的TimerA产生,TimerA工作于上升模式,CCR0中是TimerA计数最大值。TimerA初始化代码如下:

bis.w     #(TASSEL1+TACLR+MC_1),&TACTL

mov.w     2(sp),&CCR0   ;计数最大值,此值决定时钟节拍

bis.w     #CCIE,&CCTL0

c) 任务调度

应用程序调用OS_init进行初始化后,直接切换到最高优先级的任务。

每个任务在运行一个循环后执行OS_Time_Dly挂起。这是通过把该任务的延时数填到该任务的Task_Tick中,然后再执行任务调度程序实现的。

任务调度就是在定时中断时对所有任务的Task_Tick减1,然后再接优先级高低的顺序查找Task_Tick减到0的任务,并直接跳到任务切换程序。

下面的一段是任务切换程序(r10的内容是就绪任务的标志,由调度程序找出):

pushALL              ;把当前任务现场入栈

mov.b     Now_Task,r11    ;当前任务标志放r11

mov.w     sp,Task_SP(r11)  ;保存当前任务堆栈指针

mov.b     r10,Now_Task    ;就绪任务标志变为当前任务标志

mov.w     Task_SP(r10),sp  ;就绪任务的任务栈指针放入SP

;此时再进行堆栈操作就是对就绪任务的任务栈操作了。

popALL               ;把就绪任务的现场出栈

reti                ;模拟中断返回,返回到就绪任务

任务调度的调度时机有两种:一种是在任务挂起时,一种是定时中断。任务挂起时的任务调度一定会引起任务切换,定时中断就不一定引起任务切换了。因为如果就绪任务是当前正在运行的任务时不会引起切换。正是如此,任务调度是RTOS中执行得最频繁的一个功能,也是最重要的一个功能,所以必须尽量缩减其代码量,尽量用可靠的调度算法来减少任务调度所占的时间。这个子程序的流程见图4。

d) 任务锁和其它功能的实现

任务的加锁与解锁是为了使一些在低优先级任务的不可重入代码或对实时性要求较高的I/O操作在执行中不产生任务切换,这项功能是通过设置一个标志位实现的,当调度程序检查到任务被锁定时,就算有就绪任务也必须等开锁之后才能切换。

如果系统突然产生一个事件要某个挂起的任务来处理,可以在事件产生的程序中调用任务唤醒。它的原理是把Task_Tick清0,然后执行一次任务调度,如果这个任务优先级较高,就直接切换到这个任务里执行了。

总结

M430/OS已在笔者开发的基于MSP430F149的系统上得到应用,运行稳定可靠。该操作系统稍加改动,就可应用于其它MSP430单片机。当然,它的功能还是很有限的,也可能还存在一些尚未暴露的问题,但无论如何,它向我们证明,在MSP430单片机系统中使用RTOS是完全可能的。

 
本文摘自《华强电子世界网》

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(1406)
发表于:2006-8-29 9:35:50
标签:LCD  汉字显示  

2

图形LCD模块ACM19264ASB的汉字显示

图形LCD模块ACM19264ASB的汉字显示
孙志勇,张剑云,刘春生

1引言

在基于单片机的智能系统中,汉字显示模块是很重要的一个组成部分,它应用广泛、操作容易、调试简便。

然而,在单片机上显示汉字也存在几个问题。首先,单片机资源有限,我们不能为了显示汉字占用太多的资源;其次,汉字存储读取比较繁琐,使用不方便;第三,汉字是通过点阵显示出来的,往往与LCD写入方式不一样,这就得进行转换和调整。

值得注意的是,基于单片机的汉字显示不能在字符LCD上实现。使用图形LCD有很多优点,不仅能显示汉字,而且可以实现汉字动态移动和上下滚屏,实现汉字与图形的混合显示,同时功耗低。

2基于单片机的汉字显示原理

2.1汉字字模

汉字一般是以点阵式存储的,如16×16,24×24点阵(即汉字的字模),每个汉字由32字节(16点阵)或72字节(24点阵)描述。根据汉字的不同字体,也可分为宋体字模、楷体字模、黑体字模等等。

汉字的字模其实是汉字字形的图形化。对于16点阵字模,就是把汉字写在一个16×16的网格内,汉字的笔画能过某网格时该网格就对应1,否则该网格对应0,这样每一网格均对应1或0,把对应1的网格连起来看,就是这个汉字。汉字就是这样通过字节表示点阵存储在字库中的。

为了方便查找所需汉字的点阵,每个汉字都与一个双字节的内码一一对应。通过汉字的内码可以计算出它的点阵起始字节。现以16点阵为例说明。

先由内码计算出它在汉字库中的区位码,计算公式为:

区码=内码第一字节-160

位码=内码第二字节-160

再由区位码可以得到它在汉字库中字模第一个字节的位置:
(区码×94+位码)×32 于是,可以向后连续读出由32个字节组成的该字的点阵数据。

2.2汉字显示

汉字占用资源太多(如16点阵,每个汉字就需32字节),因而通常把汉字库放在EEPROM里,需要显示某个汉字时,先算出它的区位码,再求出点阵起始位置,从EEPROM中顺序调出该字的点阵数据,存在缓冲区里,最后依次送往LCD显示,描出该字。需要说明的是汉字存储方式与LCD显示方式有一定差别。

本文使用另一种显示方法,即事先将程序用到的汉字、符号和数码(为了节省显示空间,可以将数码压成8×16点阵),编成一个文本文件,用一段小程序做出相应小的汉字库,这个小字库的汉字点阵数据取自于一般汉字库。再经过转换和调整,得到新的汉字库,最后把新字库固化在EEPROM中。单片机只需按序号读出点阵字节,送往LCD即可显示所需汉字。减轻了单片机的负担,去除了繁琐的查找内码、求起始位置、转换、调整等工作,提高了系统可靠性。

表116点阵汉字字库存储方式

3自定义小字库的制作

典型的汉字库可选用UCDOS下的字库,如16点阵字库HZK16。需要256K空间,用了较大的EEPROM,又不方便读取,而实际应用中需要的汉字又非常少,因而我们可以自己制作小的汉字库,在这个小字库里只包含系统需要的汉字。这样,一方面节省读取时间,另一方面大大地节省了资源。

限于篇幅,这里仅仅给出流程图(假定事先将所需汉字写到了一个文本文件),如图1所示。

4图形点阵液晶显示模块ACM19264ASB的结构与原理

4.1技术参数和性能

1)电源:+5V;
2)显示内容:192(列)×64(行)点阵,可显示图形,也可显示12×4(16点阵)汉字;
3)全屏幕点阵;
4)7种指令;
5)与CPU接口采用8位数据总线并行输入输出和8条控制线。

4.2模块主要外部接口
1)VSS:地;
2)D/I:高时表示DB7~DB0为显示数据,低时表示为显示指令数据;
3)R/W:读写控制;
4)E:使能信号;
5)DB7~DB0:数据线;
6)CS3~CS1:3组列驱动选择器;
7)RESET:复位控制;
8)VEE:负电压驱动。

4.3指令说明,指令字为【R/W,D/I,DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0】

1)显示开关控制【0,0,0,0,1,1,1,1,1,D】,D=1表示开显示,可进行各种显示操作;

2)设置显示起始行【0,0,1,1,A5,A4,A3,A2,A1,A0】,起始行地址可以是0~63的任意一行;

3)设置页地址(即X地址)【0,0,1,0,1,1,1,A2,A1,A0】,8行为一页,模块共64行即8页,0~7可选;

4)设置Y地址【0,0,0,1,A5,A4,A3,A2,A1,A0】,Y可从0~63选,对应CS3~CS1,各包含64列,Y可选择其中一列作读写操作起始列,每操作一次Y自动加1;

5)读状态【1,0,BF,0,ON/OFF,RST,0,0,0,0】,其中BF为忙标志,BF=1表示内部正进行操作,不接受外部指令,ON/OFF为显示控制触发器状态,ON/OFF=1为开显示,数据就显示在屏幕上,RST=1表示内部正进行初始化,不接受任何指令和数据;

6)写显示数据【0,1,D7,D6,D5,D4,D3,D2,D1,D0】,写入显示数据存储单元进行显示,Y地址指针自动加1;

7)读显示数据【1,1,D7,D6,D5,D4,D3,D2,D1,D0】,读出数据,Y自动加1。

4.4模块主要硬件构成说明

图形显示LCD模块ACM19264ASB的内部结构

如图2所示。IC4为行驱动器,IC3~IC1为列驱动器,各驱动器含有如下功能器件:指令寄存器(IR),数据寄存器(DR),忙标志(BF),显示控制触发器(DFF),XY地址计数器,显示数据RAM(DDRAM),Z地址计数器(即行扫描计数器,扫完一行自动加1,0~63循环,故可实现滚屏显示)。

4.5显示数据存储单元地址表

表2示出显示数据存储单元地址。

表2图形显示LCD模块ACM19264ASB的DDRAM地址表

5汉字库到LCD的调整与转换

从表1和表2可以看出,汉字库点阵需要经过调整和转换才能显示在LCD上。具体地讲,需要先从行点阵转换到列点阵,再翻转180°。相应程序如下:

先将#include加到头文件中,然后设置数组:

unsignedintfarHzLib[16*1000];转换前的汉字库点阵数组,双字节写入unsignedintfarHzXLib[8*2000];转换后的汉字库点阵数组,单字节写入 这里,转换前的汉字库数组每次按双字节写入16位点阵数据,快捷方便,转换后的汉字库数组按单字节写入。 最后把转换子程序函数加到主程序后面即可。转换子程序如下:voidHZ_TZH(){

inti,j,k,GetBit;for(k=0;k{for(i=0;i<16;i++);先转换低16字节{for(j=7;j>=0;j--){GetBit=(HzLib[16*k+j]>>(15-i))-(HzLib[16*k+j]>>(16-i))*2;取每个字节的相同位,实现行到列的转换HzXLib[i+32*k]+=GetBit<时,高低位顺序倒转180°}}for(i=16;i<32;i++);再转换高16字节{for(j=15;j>=8;j--){GetBit=(HzLib[16*k+j]>>(31-i))-(HzLib[16*k+j]>>(32-i))*2HzXLib[i+32*k]+=GetBit<<(j-8)}}}}

6汉字显示应用举例

图3示出汉字显示的典型应用框图。

CPLD用来扩展I/O口,单片机通过CPLD读取汉字库EEPROM点阵数组,缓存到SRAM中,然后依次写入LCD显示出来,键盘用来输入指令与改变数据。

使用过程中应注意几个问题:

1)LCD分3个区CS1~CS3分别选中写入,确定显示位置后,先选中对应区CS再写入;
2)该型号LCD每行只能显示24个汉字,到边界时注意加一个判断程序,防止显示位置出错;
3 )程序中可能用到数码,为了节省显示空间,可以事先将数码压成8×16点阵,添加到EEPROM汉字库后面。 本系统在信号源产生系统中,已成功使用,速度快,程序简捷,没有出现误码等问题。

 
本文摘自《电子元器件应用》

点击此处查看原文 >>

系统分类: 单片机   |    用户分类:    |    来源: 无分类

评论(0) | 阅读(1744)
总共 , 当前 /,2下一页