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