漏极开路是驱动电路的输出三极管的发射极开路,可以通过外接的上啦电阻提高驱动能力。 这种输出用的是一个场效应三极管或金属氧化物管(MOS),这个管子的栅极和输出连接,源极接公共端,漏极悬空(开路)什么也没有接,因此使用时需要接一个适当阻值的电阻到电源,才能使这个管子正常工作,这个电阻就叫上拉电阻。
漏极开路输出,一般情况下都需要外接上拉电阻,以使电路输出呈现三态之高阻态,例如,在有些芯片的引脚就定义为漏极开路输出;还有一些带漏极开路输出的反向器等都需要外接上拉电阻才能正常工作。
.什么是推挽结构
一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止,要实现线与需要用OC(open collector)门电路。如果输出级的有两个三极管,始终处于一个导通、一个截止的状态,也就是两个三级管推挽相连,这样的电路结构称为推拉式电路或图腾柱(Totem- pole)输出电路(可惜,图无法贴上)。当输出低电平时,也就是下级负载门输入低电平时,输出端的电流将是下级门灌入T4;当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经 T3、D1 拉出。这样一来,输出高低电平时,T3 一路和 T4 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。供你参考。
推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小 效率高。输出既可以向负载灌电流,也可以从负载抽取电流。
#ifndef
#ifndef x #define x ... #endif
这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等 #ifndef x
//先测试x是否被定义过 #define x
//如果没有定义下面就定义x并执行下面的语句
... #endif
//如果已经定义了则执行#endif后面的语句
条件指示符#ifndef检查预编译常量在前面是否已经被定义。如果在前面没有被定义,则条件指示符的值为真,于是从#ifndef到#endif之间的所有语句都被包含进来进行处理。相反,如果#ifndef指示符的值为假,则它与#endif指示符之间的行将被忽略。条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译。
.h文件和.c文件 2007-04-17 20:44
H文件和C文件怎么用呢?一般来说,H文件中是declare(声明),C文件中是define(定义)。因为C文件要编译成库文件(Windows下是.obj/.lib,UNIX下是.o/.a),如果别人要使用你的函数,那么就要引用你的H文件,所以,H文件中一般是变量、宏定义、枚举、结构和函数接口的声明,就像一个接口说明文件一样。而C文件则是实现细节。
H文件和C文件最大的用处就是声明和实现分开。这个特性应该是公认的了,但我仍然看到有些人喜欢把函数写在H文件中,这种习惯很不好。(如果是C++话,对于其模板函数,在VC中只有把实现和声明都写在一个文件中,因为VC不支持export关键字)。而且,如果在H文件中写上函数的实现,你还得在makefile中把头文件的依赖关系也加上去,这个就会让你的makefile很不规范。
最后,有一个最需要注意的地方就是:带初始化的全局变量不要放在H文件中! 例如有一个处理错误信息的结构: char* errmsg[] = {
/* 0 */ \"No error\ /* 1 */ \"Open file error\
/* 2 */ \"Failed in sending/receiving a message\ /* 3 */ \"Bad arguments\
/* 4 */ \"Memeroy is not enough\ /* 5 */ \"Service is down; try later\ /* 6 */ \"Unknow information\
/* 7 */ \"A socket operation has failed\ /* 8 */ \"Permission denied\
/* 9 */ \"Bad configuration file format\ /* 10 */ \"Communication time out\ ...... ...... };
请不要把这个东西放在头文件中,因为如果你的这个头文件被5个函数库(.lib或是.a)所用到,于是他就被链接在这5个.lib或.a中,而如果你的一个程序用到了这5个函数库中的函数,并且这些函数都用到了这个出错信息数组。那么这份信息将有5个副本存在于你的执行文件中。如果你的这个errmsg很大的话,而且你用到的函数库更多的话,你的执行文件
也会变得很大。
正确的写法应该把它写到C文件中,然后在各个需要用到errmsg的C文件头上加上 extern char* errmsg[]; 的外部声明,让编译器在链接时才去管他,这样一来,就只会有一个errmsg存在于执行文件中,而且,这样做很利于封装。
我曾遇到过的最疯狂的事,就是在我的目标文件中,这个errmsg一共有112个副本,执行文件有8M左右。当我把errmsg放到C文件中,并为一千多个C文件加上了extern的声明后,所有的函数库文件尺寸都下降了20%左右,而我的执行文件只有5M了。一下子少了3M啊。 [ 备注 ] —————
有朋友对我说,这个只是一个特例,因为,如果errmsg在执行文件中存在多个副本时,可以加快程序运行速度,理由是errmsg的多个复本会让系统的内存换页降低,达到效率提升。像我们这里所说的errmsg只有一份,当某函数要用errmsg时,如果内存隔得比较远,会产生换页,反而效率不高。
这个说法不无道理,但是一般而言,对于一个比较大的系统,errmsg是比较大的,所以产生副本导致执行文件尺寸变大,不仅增加了系统装载时间,也会让一个程序在内存中占更多的页面。而对于errmsg这样数据,一般来说,在系统运行时不会经常用到,所以还是产生的内存换页也就不算频繁。权衡之下,还是只有一份errmsg的效率高。即便是像logmsg这样频繁使用的的数据,操作系统的内存调度算法会让这样的频繁使用的页面常驻于内存,所以也就不会出现内存换页问题了。
二、关于const的具体作用
——const作用就灵活了,一个表达式中const放置的位置不同,效果可能就不一样了。下面分具体情况分
析(当然,所举的情况并非覆盖全部情况) A。const最经常的用法
1.为了防止传递的函数参数不被修改,在调用函数的形参中用const关键字. //Example ->
int FindNum(const int array[], int num, int conut);//声明函数 //code...
int FindNum(const int array[], int num, int count) {
int i;
int flag = 1;
for (i = 0; (i < count) && flag; i++) {
if (array[i] == num) {
flag = 0; break; } }
return flag; }
//code...
上面这例子中,编译器会把array[]当作常量数据的数组看待。所以,假如你不小心给数组赋值,那么
,编译器就会报错了。因此,当你不需要也不想修改数组的数据时,最好用const把数组定义为常量数组。
2.const可以用来创建数组常量、指针常量、指向常量的指针等: const char ch = 'a';
const int a[5] = {1, 2, 3, 4, 5};
const int *p = a; //a是一个数组的首地址.p是指向常量的指针 int * const p = a; //a是一个数组的首地址.p是指针常量;
const int * const p = a; //a是一个数组的首地址。p是指向常量的指针常量
前两种情况很简单,现在着重分析一下后三种用法,因为这3种情况容易出错,偶就有时候怕用错了 刚脆不用const.
——const int *p = a; //p是指向常量的指针,因此,不可以通过给指针赋值来改变数组
//中的数据,例如: // *p = 10; /*错误*/ // *(p + 2) = 1; /*错误*/
//假如指向常量指针可以改变值,那么,就等于也改变了数组的数
//据了。假如你不理解,偶倒有一个办法让你理解,你就想你和一
//个人绑在一起,有可能你移动了位置而他不跟着你移动吗!哈哈
——int * const p = a; //看这表达式,const的位置和第一个不同吧!他们的用法和作用
//就完全不一样了。这时候p是指针常量,我们知道,指针是指向
//了一个数组的首地址,那么,它的位置就不可以改变了。但是你
//现在应该和第一个表达式比较了,现在的数组并不是常量数组,
//所以数组的数据是可以改变的,而指针这时候它是不可以移动的
//,指向数组第一个数据,所以它可以而且只可以改变数组第一个
//数据的值。这一点请别误解,指针常量只是它的地址不可以改变
//,并不是它指向的内容一定不可以改变,这一点切记!
//好啦。假如你又不理解,偶又有一个比较形象的例子来说明:
//假如有一个固定的人拉着另外一个人的手,注意,固定的人相当
//于他是不可以由其他人来替换的。但是他可以拉其他人的手啊,
//并不一定规定他必须拉同一个人的手啊。现在你应该可以有个比
//较深的印象和理解吧:P
//下面举几个例子帮助理解: // *p = 2; /*可以*/ // *(p+1) = 10; /*可以*/ // p++; /*不可以*/
——const int * const p = a; //假如前面两种表达式的本质你理解了,这种表达式你来理解根本
//没有问题,const现在有两个,而且一个const的位置是第一种情 //况的位置,第二个const是第二种情况的位置,所以这表达式的功 //能就是前两种情况的作用总合。这里不多说!
//下面举几个例子帮助理解: // *p = 2; /*不可以*/ // *(p + 2) = 10; /*不可以*/ // p++; /*不可以*/ B。const并不会阻止参数的修改
之所以把这作为一点来谈,就是因为有一些朋友可能会以为在函数参数中用了const就一定不可以改变
参数,这实际上是错误的理解,因为,它并不阻止参数的修改,下面举个简单的例子来阐述一下;
#include void ChangeStr(const char *String); int main(void) { char str[] = \"The C programme\"; Change(str); printf(str); system(\"Pause\"); return 0; } void ChangeStr(const char *String) { char *Source = (char *)String; while (*Source) { *Source = toupper(*Source); Source++; } } //end 上面的程序把字符串中的每个字符都转换成大写字母了。因为*String把地址给了*Source,而 *Source的值的改变编译器并不干涉,可能有的编译器会发出警告之类。上面的程序只是为了说明const并不会阻止 参数的修改,如果象上面程序那样,个人感觉没什么意义,只会让人容易混乱而已。 关于CONST的用法和理解本人也就只能说这么多了,当然,很可能有更多高级或者少用的用法,由于水平 和经验有限,确实不能再说些什么。 CRC字节型算法 比特型算法逐位进行运算,效率比较低,不适用于高速通信的场合。数字通信系统(各种通信标准)一般是对一帧数据进行CRC校验,而字节是帧的基本单位。最常用的是一种按字节查表的快速算法。该算法基于这样一个事实:计算本字节后的CRC码,等于上一字节余式CRC码的低8位左移8位,加上上一字节CRC右移8位和本字节之和后所求得的CRC码。如果我们把8位二进制序列数的CRC(共256个)全部计算出来,放在一个表里 ,编码时只要从表中查找对应的值进行处理即可。 CRC-ITU的计算算法如下: a.寄存器组初始化为全\"1\"(0xFFFF)。 b.寄存器组向右移动一个字节。 c.刚移出的那个字节与数据字节进行异或运算,得出一个指向值表的索引。 d.索引所指的表值与寄存器组做异或运算。 f.数据指针加1,如果数据没有全部处理完,则重复步骤b。 g.寄存器组取反,得到CRC,附加在数据之后。 CRC-ITU的验证算法如下: a.寄存器组初始化为全\"1\"(0xFFFF)。 b.寄存器组向右移动一个字节。 c.刚移出的那个字节与数据字节进行异或运算,得出一个指向值表的索引。 d.索引所指的表值与寄存器组做异或运算。 e.数据指针加1,如果数据没有全部处理完,则重复步骤b (数据包括CRC的两个字节)。 f.寄存器组的值是否等于“Magic Value”(0xF0B8),若相等则通过,否则失败。 下面是通用的CRC-ITU查找表以及计算和验证CRC的C语言程序: // CRC-ITU查找表 const u16 crctab16[] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78, }; // 计算给定长度数据的16位CRC。 u16 GetCrc16(const byte* pData, int nLength) { u16 fcs = 0xffff; // 初始化 while(nLength>0) { fcs = (fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xff]; nLength--; pData++; } return ~fcs; // 取反 } // 检查给定长度数据的16位CRC是否正确。 bool IsCrc16Good(const byte* pData, int nLength) { u16 fcs = 0xffff; // 初始化 while(nLength>0) { fcs = (fcs >> 8) ^ crctab16[(fcs ^ *pData) & 0xff]; nLength--; pData++; } return (fcs == 0xf0b8); // 0xf0b8是CRC-ITU的\"Magic Value\" } 使用字节型算法,前面出现的PPP帧FCS计算和验证过程,可用下面的程序片断实现: byte ppp[13] = {0xFF, 0x03, 0xC0, 0x21, 0x04, 0x03, 0x00, 0x07, 0x0D, 0x03, 0x06, 0x00, 0x00}; u16 result; // 计算CRC result = GetCrc16(ppp, 11); // 填写FCS,先低后高 ppp[11] = result & 0xff; ppp[12] = (result >> 8) & 0xff; // 验证FCS if(IsCrc16Good(ppp, 13)) { ... ... } 该例中数据长度为11,说明CRC计算并不要求数据2字节或4字节对齐。 至于查找表的生成算法,以及CRC-32等其它CRC的算法,可参考RFC 1661, RFC 3309等文档。需要注意的是,虽然CRC算法的本质是一样的,但不同的协议、标准所规定的初始化、移位次序、验证方法等可能有所差别。 #include unsigned char crc8_table[256] = { 0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97, 0x88, 0xb9, 0xea, 0xdb, 0x4c, 0x7d, 0x2e, 0x1f, 0x21, 0x10, 0x43, 0x72, 0xe5, 0xd4, 0x87, 0xb6, 0xa9, 0x98, 0xcb, 0xfa, 0x6d, 0x5c, 0x0f, 0x3e, 0x73, 0x42, 0x11, 0x20, 0xb7, 0x86, 0xd5, 0xe4, 0xfb, 0xca, 0x99, 0xa8, 0x3f, 0x0e, 0x5d, 0x6c, 0x52, 0x63, 0x30, 0x01, 0x96, 0xa7, 0xf4, 0xc5, 0xda, 0xeb, 0xb8, 0x89, 0x1e, 0x2f, 0x7c, 0x4d, 0xe6, 0xd7, 0x84, 0xb5, 0x22, 0x13, 0x40, 0x71, 0x6e, 0x5f, 0x0c, 0x3d, 0xaa, 0x9b, 0xc8, 0xf9, 0xc7, 0xf6, 0xa5, 0x94, 0x03, 0x32, 0x61, 0x50, 0x4f, 0x7e, 0x2d, 0x1c, 0x8b, 0xba, 0xe9, 0xd8, 0x95, 0xa4, 0xf7, 0xc6, 0x51, 0x60, 0x33, 0x02, 0x1d, 0x2c, 0x7f, 0x4e, 0xd9, 0xe8, 0xbb, 0x8a, 0xb4, 0x85, 0xd6, 0xe7, 0x70, 0x41, 0x12, 0x23, 0x3c, 0x0d, 0x5e, 0x6f, 0xf8, 0xc9, 0x9a, 0xab, 0xcc, 0xfd, 0xae, 0x9f, 0x08, 0x39, 0x6a, 0x5b, 0x44, 0x75, 0x26, 0x17, 0x80, 0xb1, 0xe2, 0xd3, 0xed, 0xdc, 0x8f, 0xbe, 0x29, 0x18, 0x4b, 0x7a, 0x65, 0x54, 0x07, 0x36, 0xa1, 0x90, 0xc3, 0xf2, 0xbf, 0x8e, 0xdd, 0xec, 0x7b, 0x4a, 0x19, 0x28, 0x37, 0x06, 0x55, 0x64, 0xf3, 0xc2, 0x91, 0xa0, 0x9e, 0xaf, 0xfc, 0xcd, 0x5a, 0x6b, 0x38, 0x09, 0x16, 0x27, 0x74, 0x45, 0xd2, 0xe3, 0xb0, 0x81, 0x2a, 0x1b, 0x48, 0x79, 0xee, 0xdf, 0x8c, 0xbd, 0xa2, 0x93, 0xc0, 0xf1, 0x66, 0x57, 0x04, 0x35, 0x0b, 0x3a, 0x69, 0x58, 0xcf, 0xfe, 0xad, 0x9c, 0x83, 0xb2, 0xe1, 0xd0, 0x47, 0x76, 0x25, 0x14, 0x59, 0x68, 0x3b, 0x0a, 0x9d, 0xac, 0xff, 0xce, 0xd1, 0xe0, 0xb3, 0x82, 0x15, 0x24, 0x77, 0x46, 0x78, 0x49, 0x1a, 0x2b, 0xbc, 0x8d, 0xde, 0xef, 0xf0, 0xc1, 0x92, 0xa3, 0x34, 0x05, 0x56, 0x67}; unsigned char get_value( unsigned short crc ) { unsigned char i = 0; for(i = 0; i < 9; i++ ) { if( (crc&0x0100) !=0 ) { crc*=2; crc^=0x31; } else { crc*=2; } } return (unsigned char)crc; } void init_tabl() { unsigned short i = 0; for ( i = 0; i < 0x100; i++ ) { crc8_table[i] = get_value(i); if ( !(i%8) ) { printf( \"\\n\" ); } printf( \"0x%.2x, \ crc8_table[i] ); } } unsigned char count_crc8( unsigned char* pbuf, eed ) { unsigned char* data = pbuf; unsigned char crc = seed; while ( len-- ) { crc = crc8_table[crc^*(data++)]; } return crc; } int len, unsigned char s void main() { unsigned char data[32] = {1,2,3,4,5,6,7,8,9,10}; unsigned char crc_v = 0; crc_v = count_crc8( data, 31, 0 ); data[31] = crc_v; crc_v = count_crc8( data, 32, 0 ); } ActiveX ActiveX 是一个打开的集成平台,为开发人员、 用户和 Web生产商提供了一个快速而简便的在 Internet 和 Intranet 创建程序集成和内容的方法。 使用 ActiveX, 可轻松方便的在 Web页中插入 多媒体效果、 交互式对象、以及复杂程序,创建用户体验相当的高质量多媒体 CD-ROM 。 根据微软权威的软件开发指南MSDN(Microsoft Developer Network)的定义,ActiveX插件以前也叫做OLE控件或OCX控件,它是一些软件组件或对象,可以将其插入到WEB网页或其它应用程序中。 滤波电容用在电源整流电路中,用来滤除交流成分。使输出的直流更平滑。 去耦电容用在放大电路中不需要交流的地方,用来消除自激,使放大器稳定工作。 旁路电容用在有电阻连接时,接在电阻两端使交流信号顺利通过。 1.关于去耦电容蓄能作用的理解 1)去耦(耦合就是指两个或两个以上的实体相互依赖于对方的一个量度,就是两者之间存在相互关联,即说两者耦合)电容主要是去除高频如RF信号的干扰,干扰的进入方式是通过电磁辐射。 而实际上,芯片附近的电容还有蓄能的作用,这是第二位的。 你可以把总电源看作密云水库,我们大楼内的家家户户都需要供水, 这时候,水不是直接来自于水库,那样距离太远了, 等水过来,我们已经渴的不行了。 实际水是来自于大楼顶上的水塔,水塔其实是一个buffer的作用。 如果微观来看,高频器件在工作的时候,其电流是不连续的,而且频率很高, 而器件VCC到总电源有一段距离,即便距离不长,在频率很高的情况下, 阻抗Z=i*wL+R,线路的电感影响也会非常大, 会导致器件在需要电流的时候,不能被及时供给。 而去耦电容可以弥补此不足。 这也是为什么很多电路板在高频器件VCC管脚处放置小电容的原因之一 (在vcc引脚上通常并联一个去藕电容,这样交流分量就从这个电容接地。) 2)有源器件在开关时产生的高频开关噪声将沿着电源线传播。去耦电容的主要功能就是提供 一 个局部的直流电源给有源器件,以减少开关噪声在板上的传播和将噪声引导到地 2.旁路电容和去耦电容的区别 去耦:去除在器件切换时从高频器件进入到配电网络中的RF能量。去耦电容还可以为器件 供局部化的DC电压源,它在减少跨板浪涌电流方面特别有用。 旁路:从元件或电缆中转移出不想要的共模RF能量。这主要是通过产生AC旁路消除无意的能量进入敏感的部分,另外还可以提供基带滤波功能(带宽受限)。 我们经常可以看到,在电源和地之间连接着去耦电容,它有三个方面的作用:一是作为本集成电路的蓄能电容;二是滤除该器件产生的高频噪声,切断其通过供电回路进行传播的通路;三是防止电源携带的噪声对电路构成干扰。 在电子电路中,去耦电容和旁路电容都是起到抗干扰的作用,电容所处的位置不同,称呼就不一样了。对于同一个电路来说,旁路(bypass)电容是把输入信号中的高频噪声作为滤除对象,把前级携带的高频杂波滤除,而去耦(decoupling)电容也称退耦电容,是把输出信号的干扰作为滤除对象。 旁路电容 [编辑本段] 定义 可将混有高频电流和低频电流的交流电中的高频成分旁路掉的电容,称做“旁路电容”。 例如当混有高频和低频的信号经过放大器被放大时,要求通过某一级时只允许低频信号输入到下一级,而不需要高频信号进入,则在该级的输出端加一个适当大小的接地电容,使较高频率的信号很容易通过此电容被旁路掉(这是因为电容对高频阻抗小),而低频信号由于电容对它的阻抗较大而被输送到下一级放大 对于同一个电路来说,旁路(bypass)电容是把输入信号中的高频噪声作为滤除对象,把前级携带的高频杂波滤除,而去耦(decoupling,也称退耦)电容是把输出信号的干扰作为滤除对象。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [编辑本段] 去耦电容电路电源和地之间的有两个作用 一方面是本集成电路的蓄能电容,另一方面旁路掉该器件的高频噪声。数字电路中典型的去耦电容值是0.1μF。这个电容的分布电感的典型值是5μH。0.1μF的去耦电容有5μH的分布电感,它的并行共振频率大约在7MHz左右,也就是说,对于10MHz以下的噪声有较好的去耦效果,对40MHz以上的噪声几乎不起作用。1μF、10μF的电容,并行共振频率在20MHz以上,去除高频噪声的效果要好一些。每10片左右集成电路要加一片充放电电容,或1个蓄能电容,可选10μF左右。最好不用电解电容,电解电容是两层薄膜卷起来的,这种卷起来的结构在高频时表现为电感。要使用钽电容或聚碳酸酯电容。去耦电容的选用并不严格,可按C=1/F,即10MHz取0.1μF,100MHz取0.01μF。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [编辑本段] 旁路电容和去耦电容的区别和作用 一般设计的板子上IC 的每个电源管脚附近都会放置一个电容作去耦电容,以减小电源阻抗??那么此IC的某些高速信号是否会把此电容作为高频电流的旁路电容 呢? 请大侠详细解释一下旁路电容和去耦电容。 我认为去耦电容和旁路电容没有本质的区别,电源系统的电容本来就有多种用途,从为去除电源的耦合噪声干扰的角度看,我们可以把电容称为去耦电容(Decoupling),如果从为高频信号提供交流回路的角度考虑,我们可以称为旁路电容(By-pass).而滤波电容则更多的出现在滤波器的电路设计里.电源管脚附近的电容主要是为了提供瞬间电流,保证电源/地的稳定,当然,对于高速信号来说,也有可能把它作为低阻抗回路,比如对于CMOS电路结构,在0->1的跳变信号传播时,回流主要从电源管脚流回,如果信号是以地平面作为参考层的话,在电源管脚的附近需要经过这个电容流入电源管脚.所以对于PDS(电源分布系统)的电容来说,称为去耦和旁路都没有关系,只要我们心中了解它们的真正作用就行了 双向稳压二极管 其实就像两个稳压二极管负端对负端接上。 如图,当双向稳压二极管的A端接电压正,K端接电压负,左边的稳压二极管是正向导通,相当于一个普通二极管,在上面的压降是0.7V,而右边的才是作为稳压二极管。所以这个双向稳压二极管所稳定的电压是0.7V+右边稳压值。 而反过来,双向稳压二极管的k端接电压正,A端接电压负时候。右边的稳压二极管正向导通,左边的稳压二极管作为稳压二极管。 8 因篇幅问题不能全部显示,请点此查看更多更全内容