happy2058 发表于 2020-5-4 10:39 这个应该考虑电源供电的稳定性,是不是电源供电不足? 另外在跑程序时,IO会不断变化,测出的电压是不准的。 如果检测都没有问题,可以考虑用电平转换器,而不是在三极管基级加电阻,这个无论怎么加,都不会有任何作用 |
在上图中,应将10k电阻器放在左侧5V电源下方,然后连接到IO和晶体管的基极,注意,在连接IO之前,添加一个1k电阻器。 在晶体管发射极和右侧5V之间,添加一个300 ohm的电阻器以限制LED电流。 IO被拉低以点亮LED,电流计算如下:在发射器上,(5V-1V)/ 300 ohm〜13.3mA; 在基极上,Vb = 5-1-0.3 = 3.7V,IO电流I = 3.7V-0.2 / 1k = 3.5mA,上拉电阻器电流I_pull_up =(5-3.7)/ 10k = 0.13mA,晶体管 基本电流Ib = 3.5mA-0.13mA = 3.37mA,LED电流I_LED = 13.3mA-3.37mA = 9.93mA; |
odfggf 发表于 2020-5-3 16:25 谢谢你哦 |
星际尘埃 发表于 2020-5-3 17:27 嗯,谢谢你,我好好理解一下 |
odfggf 发表于 2020-5-3 16:00 谢谢你,之前不太明白,只知道为了得到一个电压才接电阻 |
上拉电阻:+5V---电阻---IO口。 图一:IO 0V。窜两电阻至5V。先当于两个电阻(10K,1K)分压,1K电阻分到的电压驱动三极管,也就是三极管E和B之间的电压为5*(1/11)约0.5V,三极管不导通。所以led不亮。 图二:三极管e极和B极电压降约5V,三极管导通,LED亮。 其它的图同理。就不分析了。 至于图3会亮。应该是8550有关。8550的EB压降只要达到1.2V就会导通。 最后,如果要加上拉电阻,避免出现LED在单片机待机状态下信号错误。就在10K电阻的另一端直接接+5V就行。这样,10K就是上拉电阻。你那个1K的电阻是并联在三极管BE极之间的。起到的是分压作用。不是上拉作用。 |
单片机输出低电平时,通过IC内部下拉到地。当输出高电平时,由内部上拉至vcc。三极管导通电压Vbe一般0.5到0.8v之间。 1/4.电流经上拉通过IC内部回流到地。vbe电压为上拉电阻电压,不考虑IC内部下拉分压时。粗略计算Vbe也无法满足导通电压,因而截至。 2/3.Vbe足以满足导通电压,因而不论高低电平都回导通。 5.就更不必说了。 |
本帖最后由 odfggf 于 2020-5-3 16:56 编辑 PNP导通的条件就是B级低于E级,5张图说的其实是PNP的偏置电阻。偏置电阻用1K,和10K串联分压,B级电压高于4.3V,不够PNP导通条件。 图中这几个10K电阻,是PNP的B级限流电阻,取值1K---4.7K,都足以满足3极管的开关2种状态,点亮数码管。在单片机数字电路当中,只需要考虑3极管的开关2种状态,放大等别的状态不需要,所以只需要给b级接一个限流电阻就行了,别的不需要 |
![]() |
程序如下 #include <reg52.h> // 0 1 2 3 4 5 6 7 8 9 unsigned char LED8DATA_One[10] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; // 段选高位 底位 unsigned char LED8DATA_Two[4] = {0xef, 0xdf, 0xbf, 0x7f}; //unsigned char LED8DATA_Two[4] = {0xff, 0xff, 0xff, 0xff}; // 测试用全给1 unsigned char led[4] = {0x00}; int minute=60 ,sec=0; //60分钟 unsigned int Counter=0; void LEDDATA(unsigned char MM, unsigned char jj) { P0 = MM; P2= jj; } void Time1_Init() //定时器1中断 1毫秒 { TMOD |= 0X10; TMOD &= 0XDF; //TMOD = 0X10; TH1 = 0XFC; TL1 = 0X66; TR1 = 1; } void int_Init() { ET1 = 1; EA = 1; } void main() { unsigned char k=0; Time1_Init(); int_Init(); while (1) { led[3] = sec % 10; led[2] = sec / 10 % 10; led[1] = minute % 10; led[0] = minute / 10 % 10; if (k < 4) { k++; } else { k = 0; } LEDDATA(LED8DATA_One[led[k]],LED8DATA_Two[k]); if (500 < Counter) LEDDATA(LED8DATA_One[led[k]]^0X80,LED8DATA_Two[k]); //时钟显示 } } void interrupt_time_1() interrupt 3 //60分钟倒数中断 { TH1 = 0XFC; TL1 = 0X66; Counter++; if (1000 == Counter) { Counter = 0; sec--; if(sec<0) { sec=59; } if (sec == 59) { minute--; } } } |