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

📄 znjh.c

📁 1.atmegal 16单片机程序。编译环境为codevisionAVR C, 1)单总线方式采集温湿度。 2)A/D转换 3)屏幕显示和LED灯闪烁。 4)按键控制
💻 C
📖 第 1 页 / 共 4 页
字号:

  //dlmsed(1);
  delay_ms(1);

  //要不要
  tmwbyte(0xcc,flag); //发送0xcc
  tmwbyte(0x48,flag); //读高速暂存存储器,第0页
  tmwbyte(0x00,flag);

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //watchdog();
  //dlmsed(1);
  delay_ms(1);

  tmwbyte(0xcc,flag);  //发送温度转换命令
  tmwbyte(0x44,flag);
  delay_ms(20);  //增加复位前延时.2004.4.21

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //watchdog();
  //dlmsed(1);
  delay_ms(1);   //原来延时已1ms,是否时间太短,资料说应延时温度转换命令及电压转换命令发出后,
                 //主机需等待10~20ms,以使DS2438完成温度及电压转换;同时,若采用寄生电源供电,
                 //应将总线拉高,以保证充足的能量供应。

  tmwbyte(0xcc,flag);  //发送电压转换命令
  tmwbyte(0xb4,flag);
  delay_ms(20);  //增加复位前延时.2004.4.21

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //delay_ms(4000); //add

  //dlmsed(1);
  delay_ms(1);

  //要不要?
  tmwbyte(0xcc,flag);  //发送恢复存储器
  tmwbyte(0xb8,flag);
  tmwbyte(0x00,flag);

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //watchdog();
  //dlmsed(1);
  delay_ms(1);

  tmwbyte(0xcc,flag); //发送读高速暂存存储器,第0页
  tmwbyte(0xbe,flag);
  tmwbyte(0x00,flag);

  p1[i]=tmrbyte(flag);   //接收五字节数据,第一字节丢弃,读(状态/配置寄存器,温度低位寄存器,
                     //                                湿度高位寄存器,电压低位寄存器,电压高位寄存器)
  p1[i++]=tmrbyte(flag);

  p1[i++]=tmrbyte(flag);
  p1[i++]=tmrbyte(flag);
  p1[i++]=tmrbyte(flag);


  //以下读湿度
  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //watchdog();
  //dlmsed(1);
  delay_ms(1);

  tmwbyte(0xcc,flag);  //发送写高速暂存存储器,第0页
  tmwbyte(0x4e,flag);
  tmwbyte(0x00,flag);
  tmwbyte(0x00,flag); //第一字节写0

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //dlmsed(1);
  delay_ms(1);

  //这三步要不要?
  tmwbyte(0xcc,flag);  //拷贝高速暂存存储器,第0页
  tmwbyte(0x48,flag);
  tmwbyte(0x00,flag);

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //watchdog();
  //dlmsed(1);
  delay_ms(1);

  tmwbyte(0xcc,flag);  //电压转换  
  tmwbyte(0xb4,flag);
  delay_ms(20);  //延时20ms

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //delay_ms(2000); //add

  //dlmsed(1);
  delay_ms(1);

  //这三步要不要?
  tmwbyte(0xcc,flag);  //恢复存储器,第0页
  tmwbyte(0xb8,flag);
  tmwbyte(0x00,flag);

  for(ret=0,jj=0;ret==0&&jj<10;jj++) ret=reset(flag);   //复位  
  if ( ret == 0 ) return -1;

  //watchdog();
  //dlmsed(1);
  delay_ms(1);

  tmwbyte(0xcc,flag);  //读高速暂存存储器,第0页
  tmwbyte(0xbe,flag);
  tmwbyte(0x00,flag);

  p1[i]=tmrbyte(flag);  //接收五字节,保留最后两字节,(即电压低位寄存器,电压高位寄存器)
  p1[i]=tmrbyte(flag);
  p1[i]=tmrbyte(flag);
  p1[i++]=tmrbyte(flag);
  p1[i]=tmrbyte(flag);
  //EA=1;
  return 1;
}
*/

////////////////////////////////////////////////////////////////////////////////////

//add 2004.7.15,A/D方式采集温湿度
void InitADC(void)
{
	//时钟范围要求在50KHz到200KHz之间.
	ADMUX = 0xC0;//0x40;//0x00;
	//ADCSRA = 0x85;      //ADCSRA低三位选择ADC时钟,101为32分频,用于4Mhz内部时钟
	//ADCSRA = 0x86;      //                         110为64分频,用于11.0592Mhz外部时钟         
	ADCSRA = 0x83;//
	//DDRA.5 = IN;
//	DDRA.7 = IN;
}

int StartADC(unsigned char port,float *result)
{
	int i;
	unsigned char status,MyAdmux;
	unsigned short data,dataH;
	float Vin;

	ADMUX &= 0xe0;
	ADMUX |= port;
	ADCSRA |= 0x40; //把第六位置为1,开始转换.
	for (i=0;i<2000;i++) {
		delay_ms(1); //delay_us(1);		测使用2004.8.4
		status = ADCSRA;
		//if ( (status&0x40)== 0 ) break;
		if ( (status&0x10)==0x10 && (status&0x40)==0  ) break;
	}
	if ( i >= 2000 ) return -1;

	//读结果
	data = ADCL;
	dataH = ADCH;
	ADCSRA |= 0x10; //清ADIF
	MyAdmux = ADMUX;

	//sprintf(str,"%d:%d %d",port,data,dataH);
	//lcd_str(3,str);
	//delay_ms(5000);

	dataH &= 0x03;
	dataH = dataH<<8;
    data += dataH;
	Vin = 2.56*data;//5*data;
	Vin /= 1024;
	*result = Vin;

	return 0;
}

#define ADC_TEMP_PORT 5
#define ADC_HUMI_PORT 7

int ReadADCTempHumi(float *wd,float *sd)
{
	float Vwd=0,Vsd=0;
	float aa,bb;
	int ret;

    if ( (ret=StartADC(ADC_TEMP_PORT,&Vwd)) != 0 ) return ret;
	delay_ms(1);
	if ( (ret=StartADC(ADC_HUMI_PORT,&Vsd)) != 0 ) return ret;

    //if ( (ret=StartADC(0x1e,&aa)) != 0 ) return ret;
	//if ( (ret=StartADC(0x1f,&bb)) != 0 ) return ret;

	*wd = Vwd*100-1.5; //温度
	*sd = 100*Vsd/3; //湿度
	return 0;
}

//add 2004.7.15,A/D方式采集温湿度


void data_init(void)
{
    nSecondCount=0;
    n100msCount=0;

    //T_out=T_in=TH_ref-3;
    //TH_ref,TL_ref;
    //H_out=H_in=H_ref;
    //H_ref;

    //inTempValue[0]=inTempValue[1]=inTempValue[2]=0;
    //inHumiValue[0]=inHumiValue[1]=inHumiValue[2]=0;
    //outTempValue[0]=outTempValue[1]=outTempValue[2]=0;
    //outHumiValue[0]=outHumiValue[1]=outHumiValue[2]=0;
	//SamplePos = 0;

   // menulayer=0; //菜单层 0:没有 1:第一层 2:第二层
   // oprstatus=0;  //0:没有菜单操作 1:菜单选择 2:具体命令	
   // selectpos=0;

	errflag = 0; //错误清0
}



void ProcCom(char *recvbuf);

unsigned short oldhead=0;
void proc_recv(void)
{
	unsigned int i;
	char buf[SIZE_OF_INBUF+2];
	unsigned short findflag=0;
	unsigned short pos;

	if ( oldhead == inhead ) {
		if ( nSecondCount >= UARTRecvCount+65 ) {//超时
			intail = oldhead;
		}
		return;
	}
	UARTRecvCount = nSecondCount;
	RecvMsgCount = nSecondCount;

	i = 0;
	pos = intail;
	while ( pos != inhead ) {
		buf[i] = inbuf[pos];
		if ( buf[i] == '\r' ) {
			findflag = 1;		
			break;
		}
		i++;
		pos = (pos+1)%SIZE_OF_INBUF;
	}
	if ( findflag == 0 ) { //没找到
		oldhead = pos;
		return;
	}

	buf[i] = '\0';
	intail = (pos+1)%SIZE_OF_INBUF;
	oldhead = intail;

	ProcCom(buf);
}


void ProcCom(char *recvbuf)
{
   char keyword[30];
   unsigned char com,pos;
   unsigned int a1,a2,a3,a4,a5,a6,a7,a8;
   unsigned int a0,a21;

   if ( !SeperateStr(recvbuf,0,keyword,sizeof(keyword)) ) return;
   com = atoi(keyword);

   switch(com) {
   case COM_UpdData:
	   //命令字+温度标准+温度上限+温度下限+双启温度+湿度标准值+加湿阀值+除湿阀值
       //    + 空调降温结束条件,低于上限几度 + 空调升温结束条件,高于下限几度+
       //      风扇延时时长(内外温度相等后,延时的时长(单位分))    
	   pos = 1;
	   if ( !SeperateStr(recvbuf,pos++,keyword,sizeof(keyword)) ) goto error;  //温度标准
	   a0 = atoi(keyword);	   
	   if ( a0 > 50 || a0 < 10 ) goto error;
	   //赋值
	    sysprm.nTemp = a0; //add
	    WriteSysPrm();
	    sprintf(str,"%d\r",COM_RespOK);
        put_buf(str);
	   //发送设置正确消息
	   return;
   case COM_GetData:
	    sprintf(str,"%d+%d+%d+%d+%d+%d+%d+%d\r",COM_GetDataResp,
			sysprm.nTemp,sysprm.nTempHigh,sysprm.nTempLow,sysprm.nTempDualOn,
			sysprm.nHumidity,sysprm.nHumiLow,sysprm.nHumiHigh );
		    //sysprm.nLetdownNum,sysprm.nRiseNum,sysprm.nDelayNum);
		put_buf(str);
		return;
   case COM_StartSample:
	   pos = 1;
	   if ( !SeperateStr(recvbuf,pos++,keyword,sizeof(keyword)) ) goto error;
	   sample_interval = atoi(keyword);
	   if ( sample_interval < 5 ) {
		   sprintf(str,"%d\r",COM_RespError);
	   } else {
	       sample_flag = 1;
		   sprintf(str,"%d\r",COM_RespOK);
	   }
	   put_buf(str);
	   return;	
   case COM_EndSample:
	   sample_flag = 0;
	   sprintf(str,"%d\r",COM_RespOK);
	   put_buf(str);
	   return;
   case COM_GetStatus:
       //命令字+温度情况+湿度情况+空调降温状况+空调升温状况+风扇状况+加湿机状况+除湿机状况
	   sprintf(str,"%d+0+0+0+0+0+0+0\r",COM_GetStatusResp);
	   put_buf(str);
	   return;
   case COM_SendClock:
   case COM_AdjustClockRsp:
	   pos = 1;
	   if ( !SeperateStr(recvbuf,pos++,keyword,sizeof(keyword)) ) goto error;
	   if ( strlen(keyword) != 14 ) {
		   sprintf(str,"%d\r",COM_RespError);
	   } else {
		   SREG &= 0x7f; //关中断
		   t.second = atoi(&keyword[12]);
		   keyword[12] = '\0';
		   t.minute = atoi(&keyword[10]);
		   keyword[10] = '\0';
		   t.hour = atoi(&keyword[8]);
		   keyword[8] = '\0';
		   t.date = atoi(&keyword[6]);
		   keyword[6] = '\0';
		   t.month = atoi(&keyword[4]);
		   keyword[4] = '\0';
		   t.year = atoi(keyword);		   
		   SREG |= 0x80; //开中断
		   recvtime=1; //收到时间
		   sprintf(str,"%d\r",COM_RespOK);
	   }
	   if (com==COM_SendClock) put_buf(str);
	   return;
   case COM_GetClock:
	   sprintf(str,"%d+%04d%02d%02d%02d%02d%02d\r",
		   COM_GetClockResp,t.year,t.month,t.date,t.hour,t.minute,t.second);
	   put_buf(str);
	   return;

   case COM_SetDevice:
	   sprintf(str,"%d\r",COM_RespOK);
       put_buf(str);
	   return;

   case COM_SetAlarmCondition:
	   sprintf(str,"%d\r",COM_RespOK);
       put_buf(str);
	   return;

   case COM_GetAlarmCondition:
	   sprintf(str,"%d+%d+%d+%d+%d+%d+%d\r",
		   COM_GetAlarmConditionResp,sysprm.nTempAirconTimer,sysprm.nTempAirconAllTimer,
		   sysprm.nTempWindTimer,sysprm.nTempWindAllTimer,
		   sysprm.nHumiTimer,sysprm.nHumiAllTimer);
	   put_buf(str);
	   return;
   case COM_ReadSensorInterval:
	   pos = 1;
	   if ( !SeperateStr(recvbuf,pos++,keyword,sizeof(keyword)) ) goto error;  
	   a1 = atoi(keyword);
	   //if ( a1<5 || a1>180) goto error;
	   if ( a1 <= 0 ) goto error;
	   readinterval = a1;
	   sprintf(str,"%d\r",COM_RespOK);
	   put_buf(str);
	   return;
   
   case COM_ResetEtr186:  //复位ETR186
	   //ResetEtr186();
		//开始点复位灯
		StartResetCount = nSecondCount;
		SetOnResetLed();

		//复位ETR186
		RecvMsgCount = nSecondCount;
		ResetEtr186();
	   return;
   
   case COM_LinkMsg:
	   return;

   case COM_UpdTel:
	   //命令字+号码1+号码2
	   pos = 1;
	   if ( !SeperateStr(recvbuf,pos++,keyword,sizeof(keyword)) ) goto error;
		strncpy(sysprm.tel1,keyword,13);
		sysprm.tel1[13] = '\0';
	   if ( !SeperateStr(recvbuf,pos++,keyword,sizeof(keyword)) ) goto error;
		strncpy(sysprm.tel2,keyword,13);
		sysprm.tel2[13] = '\0';
	    WriteSysPrm();
	    sprintf(str,"%d\r",COM_RespOK);
        put_buf(str);
	    //发送设置正确消息
	    return;
   }
error:
   //发送不成功
   sprintf(str,"%d\r",COM_RespError);
   put_buf(str);
}

/*
void proc_send(void)
{
	unsigned char i;
	while ( tail!=head ) {		
		for(i=0;i<10;i++) {
			if ( UARTSendChar(sendbuf[tail]) ) {
				tail = ( tail+1)%MAX_SENDBUF_NUM;
				break;
			}
			delay_us(200);
		}
		if ( i >= 10 ) return;
		delay_us(10);
	}
}

void put_buf(char *msg)
{
	int len,space,i;

	len = strlen(msg);
	if ( tail==head ) space=MAX_SENDBUF_NUM-1;
	else {
		if ( head>tail) space=MAX_SENDBUF_NUM-(head-tail)-1;
		else  space = MAX_SENDBUF_NUM-(MAX_SENDBUF_NUM+head-tail)-1;
	}
	if ( len > space ) return; //调掉
	for (i=0;i<len;i++) {
		sendbuf[head] = msg[i];
		head = (head+1)%MAX_SENDBUF_NUM;
	}	
}
*/

void StartSend(void)
{
   unsigned char aa,cChar;

   aa = UCSRB;
   if( (aa&(1<<UDRIE)) == 0 )
   {
	   if ( outtail != outhead ) {
		   cChar = outbuf[outtail];
		   outtail = ( outtail+1)%SIZE_OF_OUTBUF;
		   UDR = cChar;
		   UCSRB |= 1<<UDRIE;
	   }
   }
}

void put_buf(char *string)
{
   int i,len,j;

   len = strlen(string);
   for(i=0;i<len;i++) {
	   for(j=0;j<2000;j++ ) {
		   if ( outhead+1!=outtail ) {
			   outbuf[outhead] = string[i];
			   outhead = (outhead+1)%SIZE_OF_OUTBUF;
			   break;
		   }
		   else delay_us(10);
	   }
	   if ( j >= 2000 ) break;	   
   }
   StartSend();
}



//提取用'*'分开的字符串
//pos 从0开始
int SeperateStr(char *src,int pos,char *dest,int destsize)
{
	char *p,*q;
	int i,len;
	
	q = src;
	p = src;
	for (i=0;i<=pos;i++) {
		p = q;
		while ( *p=='#' || *p=='+' || *p=='\r' || *p=='\n' ) p++;
		q = p;
		while ( !(*q=='+' || *q=='\r' || *q=='\n' || *q=='\0') ) q++;
		if ( q-p <= 0 ) return 0; //没有了
	}
	len = q-p;
	if ( len >= destsize-1)
		len = destsize-1;
	strncpy(dest,p,len);
    dest[len] = '\0';
	return 1;
}


//------------------WatchDog--------------------------------
void EnableWDT(void)
{           
	int i;

	#asm("cli")
	WDTCR = 0x18;
	WDTCR = 0x0f;//f;//f;
	#asm("sei")
                                        
	#asm("wdr");
	//while(1) {
	//	i++;		
	//	delay_us(1);
	//}	
}

⌨️ 快捷键说明

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