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

📄 or100_hw.c

📁 用STC单片机实现光发射机的自动增益控制
💻 C
字号:
//#define DEBUG

#include <myheadfile.h>
//#include <STC12C5410.H>
#include <intrins.h>


extern unsigned char sample_data_G[];
unsigned char Adc8Filt(unsigned char, unsigned char);

//sbit	GATE485 = P3^7;			// 485输出控制,1:开门

void enES_un485trans(void)		//禁止发送并允许串口中断
{
//	GATE485 = 0;
	ES = 1;	
}

void unES_en485trans(void)		//禁止串口中断并允许发送
{
	ES = 0;	
//	GATE485 = 1;
}



void Initital(void)
{
unsigned char i,j;
	
	P1M0 = 0x9f; P1M1 = 0x00;	//P1口设置,P1.0-P1.4,P1.7高阻输入(ADC),其余标准IO
	P3M0 = 0x00; P3M1 = 0x00;	//P3口设置,标准I/O模式
	P2M0 = 0x00; P2M1 = 0x00;	//P2口设置,标准I/O模式

	PCON = 0x80;	//  SMOD = 1
	SCON =	0x50;	//  串口初始化 8,N, 定时器1为波特率发生器,清发送和接收标志
	AUXR = 0x40;	//  T1x12=1,T1工作在全速模式; T0x12=0,T0工作在12分频模式
	TMOD = 0x21;	//  设置定时器1为8位自动重装定时器,定时器0为16位计数方式
	TH1 = 0xfa;		//  定时器1的初值,波特率38400
	TL1 = 0xfa;
	TI   = 0;
	TR1 = 1;		// 起动定时器1                
//	ES = 1;			// 允许串口中断
	enES_un485trans(); 				//禁止发送并允许串口中断
	
	CMOD = 0x02;		//bit0=0:计数器溢出不中断,bit1-2:时钟选择Fosc/2(3.6864M晶体下应7.2K),bit7=0:IDLE时也计数
	CCON = 0x40;		//清除CCON中的状态位,启动计数器(CR=1)
	CCAPM0 = 0x42;	  //8位PWM输出//PWM工作模式
	CCAPM1 = 0x42;	  //8位PWM输出

//定时器0要设置成这样的方式
	TH0 = TIMER0_OV;	
	TL0 = 0x0;		//
//	PT0 = 0x1;
	ET0  = 0;		//在串口中断中查询而不采用定时器中断的方式
	TR0  = 0;

//---------------下面上电期间指示灯闪烁,期间做AD采样,以便取个相对稳定的AD采样的平均值
	for(i=0;i<255;i++)
	{
		for(j = 0; j < CHANEL_SUM; j++)  sample_data_G[j] = Adc8Filt(sample_data_G[j], j);		//ADC并平均	
	}
//------------------------------

//	RF_GATE = 1;			// open RF output
	EA = 1;

}


/*************************************************************************/
/*任务定义:ADC和平均                                                       */
/*输入:本次采样前的平均值,本次采样的AD通道号                               */
/*输出:当前AD通道的新平均值                                                 */
/*平均算法:当前AD通道的新平均值=本次采样前的平均值的3/4 + 新采样值的1/4 */

/*************************************************************************/
unsigned char  Adc8Filt(unsigned char prefilt_data, unsigned char adindex)
{
unsigned char temp , newfilt_data;

	ADC_CONTR = 0x88+adindex ;	// start ADC

#ifndef DEBUG
		while(!(ADC_CONTR&0x10));	// wait until AD convert over
#endif

	newfilt_data = ADC_DATA;
	temp = prefilt_data-(prefilt_data>>2); 		//以前平均的结果的3/4
	newfilt_data = temp + (newfilt_data>>2);	//加新采样值的1/4
	return(newfilt_data);
	
}

void wr_eeprom(unsigned char lenth, unsigned char *object)
{
	#define		BYTE_READ		1;
	#define		BYTE_PROGRAM	2;
	#define		SECT_ERASE 		3;
	#define		ENABLE_ISP		0x84;		//最高位为1:允许ISP操作;WAIT_TIME=4(4M以下晶振)

//	extern unsigned char code CurrentSet[];

	unsigned char i;
	EA = 0;			//关中断
//---------- 以下扇区擦除 ------------
		ISP_CONTR = ENABLE_ISP;
		ISP_CMD   = SECT_ERASE;     		
		ISP_ADDRH = 0x12;     		//地址固定为最后一个扇区0x1200
		ISP_ADDRL = 0x0; 

		ISP_TRIG  = 0x46;
		ISP_TRIG  = 0xb9;			//这条命令执行后IAP立即启动
		//NOP						//必须要等待一下

//---------- 以下扇区写 ------------		

//		ISP_CONTR = ENABLE_ISP;
		ISP_CMD   = BYTE_PROGRAM;     		
		ISP_ADDRH = 0x12;     		//地址固定为最后一个扇区0x1200
		ISP_ADDRL = 0x0;
		for(i=0;i<=lenth;i++)
		{		
			ISP_DATA  = *object;
			ISP_TRIG  = 0x46;
			ISP_TRIG  = 0xb9;			//这条命令执行后IAP立即启动
			//NOP						//必须要等待一下
			ISP_ADDRL++;				//由于只在一个扇区内进行写操作,所以高位地址不会变
			object++;
		}
		
//---------- 以下撤消写状态 ------------	
		ISP_CONTR = 0x0;
		ISP_CMD   = 0x0; 
		ISP_TRIG  = 0x0;

	EA = 1;		//开中断
}
	

/*
//================以下部分是针对DS1820的程序======================

//--------延时约1.1us:晶体是3.6864M--------
void delay1us(unsigned int useconds) 
{
	for(;useconds>0;useconds--); 
} 

//-------------DS1820复位---------------------- 
void ow_reset(void) 
 { 
//  unsigned char presence; 
	DQ15 = 0;		//pull DQ line low 
	delay1us(480);	// leave it low for 480us, but it also can work good by shorten as this
	DQ15 = 1;		// allow line to return high 
	delay1us(15); 	// wait for presence 15-60us
//  presence = DQ;	// get presence signal 
	delay1us(300);	// wait for end of timeslot 480us, but it also can work good by shorten as this
//  return(presence);	// presence signal returned 
 } // 0=presence 1 = no part 


//--------------向 1-WIRE 总线上写一个字节 
void write_byte(unsigned char val) 
{ 
unsigned char i; 
	for(i=8; i>0; i--)
	{ 
		DQ15 = 0;		// pull DQ low to start timeslot
		DQ15 = val&0x01;
		delay1us(20);	// hold value for remainder of timeslot 
		DQ15 = 1;
		val = val>>1; 
		delay1us(1); 	//a minimum of a 1-μs recovery time between individual write cycles
	} 
} 


//--------------从 1-wire 总线上读取一个字节 
unsigned char read_byte(void) 
{ 
unsigned char i;
unsigned char value15;

	value15 = 0;
	for(i=8;i>0;i--) 
	{ 
		value15 = value15>>1;
		DQ15 = 0; // pull DQ low to start timeslot
		_nop_();
		DQ15 = 1; // then return high 
		delay1us(2);
		if(DQ15) value15|=0x80;
		delay1us(1); 		//a minimum of a 1-μs recovery time between individual write cycles
	} 

	return(value15); 
} 


//--------------读取两个DS1820温度----------------------
//输出:unsigned char,对应0-127.5度
//输出:由于温度不可能达到128度低于0度,也就是说DS1820的低8位就足够了
unsigned char Rd_DS1820(void) 
 { 
unsigned char temp15;
	ow_reset(); 
	write_byte(0xCC); // Skip ROM 
	write_byte(0xBE); // Read ScrATch Pad 
	temp15 = read_byte();			//低8位温度 
//	temp16 = read_byte();			//高8位温度

	ow_reset(); 
	write_byte(0xCC); 				//Skip ROM 
	write_byte(0x44); 				// Start next Conversion
	
	return(temp15>>1);				//(DS1820是以0.5度为单位的),所以要除以2
 } 
*/

⌨️ 快捷键说明

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