PA2作为时钟线,PA3作为数据线。因为要用作定时输出,所以用到了定时中断程序,请各位帮我看看,程序可能乱了点,主要是看看SHT部分,PWM、定时那些都没有问题的了。不胜感激!!<br /><br /><br /><br />#include <pic.h><br />#include <pic16f81x.h><br />#include <math.h><br />#include <stdio.h><br /><br />char s_write_byte(unsigned char value);<br />char s_read_byte(unsigned char ack);<br />void s_transstart(void);<br />void s_connectionreset(void);<br />char s_softreset(void);<br />char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum);<br />char s_write_statusreg(unsigned char *p_value);<br />char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);<br />void calc_sth11(float *p_humidity ,float *p_temperature);<br />float calc_dewpoint(float h,float t);<br />void PWM_Initial(void);<br />void PWM_Display(int PWMOut92, int PWMOut10);<br />void Timer1_Initial(void);<br />void interrupt isr(void);<br /><br />static bit SCK @ (unsigned)&PORTA*8+2;<br />static bit DATA @ (unsigned)&PORTA*8+3;<br /><br />//------------------------------------------------------------------------------<br />// modul-var<br />//------------------------------------------------------------------------------<br />enum {TEMP,HUMI};<br /><br />#define noACK 0<br />#define ACK 1<br /> //adr command r/w<br />#define STATUS_REG_W 0x06 //000 0011 0<br />#define STATUS_REG_R 0x07 //000 0011 1<br />#define MEASURE_TEMP 0x03 //000 0001 1<br />#define MEASURE_HUMI 0x05 //000 0010 1<br />#define RESET 0x1e //000 1111 0<br /><br />char PWM92,PWM10;<br />unsigned int n_Scan=0,pwm=0;<br />float dew_point;<br />unsigned char err,chksum;<br />unsigned int humi_vali=0,temp_vali=0;<br />float humi_valf,temp_valf;<br /><br />main()<br />{<br /> TRISA = 0x00; <br /> TRISB = 0x00;<br /> PORTB = 0x0FF; <br /> <br /> PWM_Initial(); // PWM Initial<br /> Timer1_Initial(); // Timer1 Initial<br /> PEIE=1; // Enable Peripheral Interupts<br /> GIE =1; // Enable Global Interrupt<br /> <br /> s_connectionreset();<br /> while(1)<br /> {<br /> //<br /> }<br />}<br /><br /><br />void PWM_Initial(void)<br />{<br /> PR2=0x0F9;<br /> CCPR1L=0x7F;<br /> CCP1CON=0x20;<br /> TRISB=0x00;<br /> T2CON=0x05;<br /> CCP1CON|=0x0F;<br />}<br /><br /><br />void PWM_Display(int PWMOut92, int PWMOut10)<br />{<br /> CCPR1L=PWMOut92;<br /> CCP1CON&=0x0CF;<br /> CCP1CON|=PWMOut10; <br />} <br /><br /><br />void Timer1_Initial(void)<br />{<br /> OPTION=0x87; // Falling Edge of INT Pin,WDT Fosc/128<br /> PSA=1; // WDT Fosc/128<br /> T1CON=0x00; // Internal Clock(Fosc/4)<br /> TMR1H=0x0FC; <br /> TMR1L=0x2E; // 1ms<br /> TMR1IF=0; // Clear TIMER1 Interrupt Flag<br /> TMR1IE=1; // Enable TIMER1 Interrupt<br /> TMR1ON=1; // Start Timing<br />}<br /><br /><br />void interrupt isr(void)<br />{<br /> if (TMR1IF==1) // TIMER1 Interrupt Subroutine<br /> {<br /> TMR1IF=0;<br /> TMR1H=0x0FC;<br /> TMR1L=0x2E;<br /> n_Scan+=1;<br /> CLRWDT(); // WDT Clear<br /> <br /> if (n_Scan==1000) <br /> {<br /> PORTB=0x0FF;<br /> CLRWDT(); // WDT Clear<br /> }<br /> <br /> if (n_Scan==1500) <br /> {<br /> PORTB=0x01;<br /> //pwm=200;<br /> if(pwm==1000)<br /> {<br /> pwm=0;<br /> }<br /> PWM10=(char)(pwm&(0x03));<br /> PWM10=PWM10<<4;<br /> PWM92=pwm>>2;<br /> PWM_Display(PWM92,PWM10);<br /> }<br /> <br /> if (n_Scan==2000) <br /> {<br /> PORTB=0x02;<br /> err=0;<br /> err+=s_measure((unsigned char*) &humi_vali,&chksum,HUMI); //measure humidity<br /> //err+=s_measure((unsigned char*) &temp_vali,&chksum,TEMP); //measure temperature<br /> //if(err!=0) <br /> //{s_connectionreset();}<br /> if(err==0)<br /> {<br /> //humi_vali=1500;<br /> //temp_vali=10000; <br /> humi_valf=(float)humi_vali; //converts integer to float<br /> temp_valf=(float)temp_vali; //converts integer to float<br /> calc_sth11(&humi_valf,&temp_valf); //calculate humidity, temperature<br /> pwm=(unsigned int) (humi_valf*10);<br /> }<br /> }<br /> <br /> if (n_Scan==7000) <br /> {<br /> PORTB=0x03;<br /> }<br /> <br /> if (n_Scan==8000) <br /> {<br /> PORTB=0x04;<br /> }<br /> <br /> if (n_Scan==8999) // <br /> {<br /> PORTB=0x0;<br /> n_Scan=0; <br /> }<br /> }<br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />char s_write_byte(unsigned char value)<br />//----------------------------------------------------------------------------------<br />// writes a byte on the Sensibus and checks the acknowledge <br />{ <br /> unsigned char i,error=0; <br /> for (i=0x80;i>0;i/=2) //shift bit for masking<br /> { if (i & value) DATA=1; //masking value with i , write to SENSI-BUS<br /> else DATA=0; <br /> SCK=1; //clk for SENSI-BUS<br /> NOP();NOP();NOP(); //pulswith approx. 5 us <br /> SCK=0;<br /> }<br /> DATA=1; //release DATA-line<br /> SCK=1; //clk #9 for ack <br /> error=DATA; //check ack (DATA will be pulled down by SHT11)<br /> SCK=0;<br /> return error; //error=1 in case of no acknowledge<br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />char s_read_byte(unsigned char ack)<br />//----------------------------------------------------------------------------------<br />// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" <br />{ <br /> unsigned char i,val=0;<br /> DATA=1; //release DATA-line<br /> TRISA3=1;<br /> for (i=0x80;i>0;i/=2) //shift bit for masking<br /> { SCK=1; //clk for SENSI-BUS<br /> if (DATA) val=(val | i); //read bit <br /> SCK=0; <br /> }<br /> TRISA3=0;<br /> DATA=!ack; //in case of "ack==1" pull down DATA-Line<br /> SCK=1; //clk #9 for ack<br /> NOP();NOP();NOP(); //pulswith approx. 5 us <br /> SCK=0; <br /> DATA=1; //release DATA-line<br /> return val;<br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />void s_transstart(void)<br />//----------------------------------------------------------------------------------<br />// generates a transmission start <br />// _____ ________<br />// DATA: |_______|<br />// ___ ___<br />// SCK : ___| |___| |______<br />{ <br /> DATA=1; SCK=0; //Initial state<br /> NOP();<br /> SCK=1;<br /> NOP();<br /> DATA=0;<br /> NOP();<br /> SCK=0; <br /> NOP();NOP();NOP();<br /> SCK=1;<br /> NOP();<br /> DATA=1; <br /> NOP();<br /> SCK=0; <br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />void s_connectionreset(void)<br />//----------------------------------------------------------------------------------<br />// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart<br />// _____________________________________________________ ________<br />// DATA: |_______|<br />// _ _ _ _ _ _ _ _ _ ___ ___<br />// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______<br />{ <br /> unsigned char i; <br /> DATA=1; SCK=0; //Initial state<br /> for(i=0;i<9;i++) //9 SCK cycles<br /> { SCK=1;<br /> SCK=0;<br /> }<br /> s_transstart(); //transmission start<br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />char s_softreset(void)<br />//----------------------------------------------------------------------------------<br />// resets the sensor by a softreset <br />{ <br /> unsigned char error=0; <br /> s_connectionreset(); //reset communication<br /> error+=s_write_byte(RESET); //send RESET-command to sensor<br /> return error; //error=1 in case of no response form the sensor<br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)<br />//----------------------------------------------------------------------------------<br />// reads the status register with checksum (8-bit)<br />{ <br /> unsigned char error=0;<br /> s_transstart(); //transmission start<br /> error=s_write_byte(STATUS_REG_R); //send command to sensor<br /> *p_value=s_read_byte(ACK); //read status register (8-bit)<br /> *p_checksum=s_read_byte(noACK); //read checksum (8-bit) <br /> return error; //error=1 in case of no response form the sensor<br />}<br /><br /><br />//----------------------------------------------------------------------------------<br />char s_write_statusreg(unsigned char *p_value)<br />//----------------------------------------------------------------------------------<br />// writes the status register with checksum (8-bit)<br />{ <br /> unsigned char error=0;<br /> s_transstart(); //transmission start<br /> error+=s_write_byte(STATUS_REG_W);//send command to sensor<br /> error+=s_write_byte(*p_value); //send value of status register<br /> return error; //error>=1 in case of no response form the sensor<br />}<br /><br /> <br />//----------------------------------------------------------------------------------<br />char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)<br />//----------------------------------------------------------------------------------<br />// makes a measurement (humidity/temperature) with checksum<br />{ <br /> unsigned error=0;<br /> unsigned int i;<br /><br /> s_transstart(); //transmission start<br /> PORTB=0x0;<br /> switch(mode){ //send command to sensor<br /> case TEMP : error+=s_write_byte(MEASURE_TEMP);<br /> <br /> break;<br /> case HUMI : error+=s_write_byte(MEASURE_HUMI);<br /> <br /> break;<br /> default : break; <br /> }<br /> for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement<br /> if(DATA) error+=1; // or timeout (~2 sec.) is reached<br /> *(p_value) =s_read_byte(ACK); //read the first byte (MSB)<br /> *(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)<br /> *p_checksum =s_read_byte(noACK); //read checksum<br /> return error;<br />}<br /><br /><br />//----------------------------------------------------------------------------------------<br />void calc_sth11(float *p_humidity ,float *p_temperature)<br />//----------------------------------------------------------------------------------------<br />// calculates temperature [癈] and humidity [%RH] <br />// input : humi [Ticks] (12 bit) <br />// temp [Ticks] (14 bit)<br />// output: humi [%RH]<br />// temp [癈]<br />{ const float C1=-4.0; // for 12 Bit<br /> const float C2=+0.0405; // for 12 Bit<br /> const float C3=-0.0000028; // for 12 Bit<br /> const float T1=+0.01; // for 14 Bit @ 5V<br /> const float T2=+0.00008; // for 14 Bit @ 5V <br /><br /> float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit <br /> float t=*p_temperature; // t: Temperature [Ticks] 14 Bit<br /> float rh_lin; // rh_lin: Humidity linear<br /> float rh_true; // rh_true: Temperature compensated humidity<br /> float t_C; // t_C : Temperature [癈]<br /><br /> t_C=t*0.01 - 40; //calc. temperature from ticks to [癈]<br /> rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]<br /> rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]<br /> if(rh_true>100)rh_true=100; //cut if the value is outside of<br /> if(rh_true<0.1)rh_true=0.1; //the physical possible range<br /><br /> *p_temperature=t_C; //return temperature [癈]<br /> *p_humidity=rh_true; //return humidity[%RH]<br />}<br /><br /><br />//--------------------------------------------------------------------<br />float calc_dewpoint(float h,float t)<br />//--------------------------------------------------------------------<br />// calculates dew point<br />// input: humidity [%RH], temperature [癈]<br />// output: dew point [癈]<br />{ float logEx,dew_point;<br /> logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);<br /> dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);<br /> return dew_point;<br />}<br /><br /><br /><br /><br />
|