⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 or100_sw_else.c

📁 用STC单片机实现光发射机的自动增益控制
💻 C
字号:
#include <myheadfile.h>
#define DISPLAY_FLASH_FREQ 200		//显示报警时的数码管闪烁频率

//LED显示字符表,控制LED显示不同字符
char code DISPLAY_TABLE[14] = {
		0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc7,0x89,};  
	//  0     1    2     3    4    5   6    7    8    9    -   (空)   L    H 

// 接收光功率码表 0.1dBm 
signed char code OP_POWdbm_TAB[220] = {
   		-96,-93,-91,-88,-86,-83,-81,-79,-77,-75,-73,-71,-70,-68,
   		-66,-65,-63,-62,-61,-59,-58,-57,-55,-54,-53,-52,-51,-50,
  		-49,-48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-39,-38,-37,
   		-36,-35,-35,-34,-33,-33,-32,-31,-30,-30,-29,-28,-28,-27,
   		-27,-26,-25,-25,-24,-24,-23,-22,-22,-21,-21,-20,-20,-19,
   		-19,-18,-18,-17,-17,-16,-16,-15,-15,-14,-14,-13,-13,-12,
		-12,-11,-11,-11,-10,-10, -9, -9, -9, -8, -8, -7, -7, -7,
		 -6, -6, -5, -5, -5, -4, -4, -3, -3, -3, -2, -2, -2, -1,
		 -1, -1,  0,  0,  0,  1,  1,  1,  2,  2,  2,  3,  3,  3,
		  4,  4,  4,  4,  5,  5,  5,  6,  6,  6,  7,  7,  7,  7,
		  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11, 11, 11,
		 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15,
		 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18,
		 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21,
		 21, 21, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 24, 24,
		 24, 24, 24, 25, 25, 25, 25, 25, 25, 25};
		 
//0.1mW
unsigned char code OP_POWmw_TAB[220] = {
   	  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
      2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
      3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
      4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
      5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
      6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
      8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9,
      9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,
     10,10,10,10,10,10,10,10,10,10,10,11,11,11,
     11,11,11,11,11,11,11,11,11,11,12,12,12,12,
     12,12,12,12,12,12,12,13,13,13,13,13,13,13,
     13,13,13,13,13,13,13,13,14,14,14,14,14,14,
     14,14,14,14,14,14,14,15,15,15,15,15,15,15,
     15,15,15,15,15,15,15,16,16,16,16,16,16,16,
     16,16,17,17,17,17,17,17,17,17,17,17,17,17,
     17,17,17,18,18,18,18,18,18,18};		 
		 		 
/* 电平控制对应码表 */
	//0.2dB步进

unsigned char code AttToPWM0[86] = {
	 	1,19,28,36,40,45,53,57,63,68,73,79,82,88,92,96,102,107,
		111,114,119,123,128,132,135,138,141,145,149,152,155,158,160,164,
		166,169,172,175,177,179,181,183,185,187,188,190,191,193,195,196,
		197,199,200,201,203,204,205,206,207,208,210,211,211,212,213,214,
		215,216,217,218,219,
		220,220,221,221,222,222,223,223,224,224,225,225,226,226,227				
		 };		 //初调
		 
unsigned char code AttToPWM1[86] = {
	 	87,90,94,88,95,96,87,93,89,96,92,88,96,92,93,90,92,87,86,
		94,90,88,94,91,89,89,95,92,90,93,91,93,92,89,94,90,93,88,
		94,93,91,90,89,87,92,89,94,93,90,93,96,89,92,95,88,91,93,
		94,95,96,87,87,96,95,95,94,94,93,92,92,91,
		90,99,90,99,90,99,90,99,90,99,90,99,90,99,90,		
		 };	    //细调		 


// 电平码表 
unsigned char code RF_LEVEL_TABLE[22] = {
		10,11,12,13,14,15,17,19,22,26,31,37,44,54,68,81,106,122,156,168,192
		};

//实际电平 采样电压 采样值 
	//92    0.20   10
	//93    0.21   11
	//94    0.22   12
	//95    0.25   13
	//96    0.26   14
	//97    0.30   15
	//98    0.33   17
	//99    0.38   19
	//100   0.43   22
	//101   0.51   26
	//102   0.61   31
	//103   0.74   37
	//104   0.87   44
	//105   1.06   54
	//106   1.33   68
	//107   1.60   81
	//108   2.08   106
	//109   2.40   122
	//110   3.06   156
	//111   3.3    168
	//112   3.85   192

unsigned char code TEMPE_TABLE[20] ={11
	
	
	}; 



//光功率检测
//输入:光功率的采样(平均后)值
//输出:10倍的光功率,有符号char型,单位为dBm
//功能描述:根据输入AD值,查表
signed char OpticalPowerDetect(unsigned char optical_power_sample)
{
	signed char optical_power;
	
	if(optical_power_sample<14) optical_power_sample =14;
	if(optical_power_sample>233) optical_power_sample = 233;
	optical_power = OP_POWdbm_TAB[optical_power_sample - 14];// 查表取值,optical_power_sample-14可以参见excel表格,optical_power_sample的值是0~255范围,以optical_power_sample的值为查表的下标
	                       //然而码表OP_POWdbm_TAB[]中的首元素是excel表中optical_power_sample=14对应的值,该值对应OP_POWdbm_TAB[0],所以真实值=OP_POWdbm_TAB[optical_power_sample - 14]
	return(optical_power); 
}
//同上,只不过输出为unsigned char单位为0.1mW
unsigned char OpPowDetect_mW(unsigned char optical_power_sample)
{
	unsigned char optical_power;
	
	if(optical_power_sample<14)  optical_power_sample = 14;
	if(optical_power_sample>233) optical_power_sample = 233;
	optical_power = OP_POWmw_TAB[optical_power_sample - 14];

	return(optical_power); 
}

//光AGC
//输入:10倍的光功率,有符号char型
//输出:无
//功能描述:根据输入的光功率,查表,调用PWM控制硬件(电调衰减)
void OpticalAgc(signed char optical_power)
{
unsigned char optical_AGC_ATT;
unsigned int temp;
	if(optical_power < -60)			// 光功率小于-6.0dbm 
			optical_AGC_ATT = 0;	// 电调衰减器不衰减
	else if(optical_power > 25)		// 如果光功率大于2.5dbm
			optical_AGC_ATT = 67;	// 电调衰减器最大衰减(6db)
	else if(optical_power < 0)		// 当接收光功率处于-6dbm~0dbm之间的时候
	{
		optical_power = -optical_power;       //光功率增加1db,射频衰减2db,测试数据为0.2db一档,optical_power比实际数据放大10倍
		optical_AGC_ATT = 60 - optical_power; //假设光功率为-4db,此时optical_power为-40,optical_AGC_ATT =60-40=20,由于是-6db起控,所以光功率增加了2db,射频应该衰减4db,optical_AGC_ATT =4/0.2=20  
	}
	else							// 在0-2.5dBm之间
		optical_AGC_ATT = 60 + optical_power;	


	temp = CCAP1H*2 + AttToPWM1[optical_AGC_ATT] + 2;		//写入PWM寄存器的值取平均
	CCAP1H = temp/3;
	temp = CCAP0H*2 + AttToPWM0[optical_AGC_ATT] + 2;
	CCAP0H = temp/3;
 
}

//显示,仅以dBm显示光功率
//输入:10倍的光功率,有符号char型
//输出:无
//功能描述:根据输入的光功率,扫描三位数码管(以定时器0为计数器,大约30ms扫描一位),首位为符号位(正值时不显示),两位有效值
void Display(signed char optical_power)
{
	unsigned char display_DIG;   //显示数码管位号
	unsigned char display_BUF[3];   //显示缓冲区
	unsigned char display_val;   //显示值	
	static bit display_flag=0;   //显示标志,当=0时,数码管点亮,=1时数码管熄灭
	static unsigned char display_count;  //内部计数器,用于扫描三位数码管和闪烁

	display_count++;
	
	if(optical_power < -65)       //光功率小于-6.5dbm
	{
		if((display_count%DISPLAY_FLASH_FREQ)>(DISPLAY_FLASH_FREQ/2))
			 display_flag = 1;	//LED闪烁
		else display_flag = 0;
		
		display_BUF[0] = 12;				// 显示 "L--"
		display_BUF[1] = 10;
		display_BUF[2] = 10;
	} 
	else if(optical_power > 25)				//光功率大于2.5dbm
	{
		if((display_count%DISPLAY_FLASH_FREQ)>(DISPLAY_FLASH_FREQ/2))
			 display_flag = 1;	//LED闪烁
		else display_flag = 0;
		
		display_BUF[0] = 13;				// 显示 "H--"
		display_BUF[1] = 10;
		display_BUF[2] = 10;
	}
	else if(optical_power < 0)				//光功率介于-6.5与0dBm之间
	{
		display_flag = 0;
		display_BUF[0] = 10;				// 小于0则第一位显示“-”
		display_BUF[1] = 0x80 - optical_power/10;	//显示小数点
		display_BUF[2] = (-optical_power)%10;
	}
	else									//光功率介于0与2.5dBm之间
	{
		display_flag = 0;
		display_BUF[0] = 11;				// 大于0则第一位不显示
		display_BUF[1] = 0x80 + optical_power/10;	//显示小数点
		display_BUF[2] = optical_power%10;
	}	

	display_DIG = display_count % 3;
	dig1 = (display_DIG==0) ? display_flag : 1;		//轮换显示:如果当前计数为0则显示第1个数码管(或者闪烁)
	dig2 = (display_DIG==1) ? display_flag : 1;
	dig3 = (display_DIG==2) ? display_flag : 1;

	display_val = display_BUF[display_DIG];
	if(display_val >= 0x80)		  //判断是否大于0x80(前面要显示小数点的时候都加上了0x80)
	{
		led_dp = 0;			          //显示小数点
		display_val &= 0x7f;		  //去掉加上的0x80      
	}
	else led_dp = 1;
	
	P2 = DISPLAY_TABLE[display_val]; 		 //控制P2口的各个I/O口输出不同的电平以显示数值
}



//输出RF电平检测
//输入:输出RF电平的采样(平均后)值
//输出:RF电平,无符号char型,单位为dBu
//功能描述:查表结果与输入AD值做比较,只到找到对应的输出电平值
unsigned char RfLevel(unsigned char rf_level_sample)
{
	
	signed char rf_level;
	
	rf_level=0;
	if (rf_level_sample > 200)  //如果输出电平过高,最大就显示113dbuv
		rf_level = 113;
	else
	{
		if(rf_level_sample > 9)    // 该电平码表中记录的采样值是从10开始的,也就是说采样值超过9就开始查表,小于9就rf_level=0
		{
	  		while (RF_LEVEL_TABLE[rf_level] < rf_level_sample) // 依次查表,从首元素开始查表
	  			rf_level++;        // 只要大于后一个元素的值,就取前一个元素的值
			rf_level += 92;   // 之前有赋值rf_level = 0 ,将rf_level当作查表的下标,与真实的rf_level值相差92
		}
	}
	return(rf_level);

}


unsigned char GetTemperature(unsigned char tempe_sample)
{
	unsigned char temperature;
	
	temperature = TEMPE_TABLE[tempe_sample];
	return(temperature);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -