📄 pc temperature control .c
字号:
end
//**********************************************************
//Reads Temperature Sensors
// This function reads the ADC result from the temperature sensors.
// It continuously muxes between the different sensors and
// alternatingly gets their readings and sets up for the next one.
void ReadTemp(void)
begin
time4=t4; //reset the task timer
// reads current sensor
tempsensor[sensornum] = ADCH;
fpcurrtemp[sensornum] = getTemp(tempsensor[sensornum]);
//switch to next sensor and starts next conversion
if( sensornum++ == (MAXFAN-1) ) sensornum = 0;
ADMUX = 0b00100000 | sensornum;
ADCSR.6 = 1;
end
//**********************************************************
//PWM Pulse Stretching
// If fan is running in PWM mode, then we need to run it at full power
// periodically in order to get RPM information. It sets the f_readrpm
// flag to 1 so the interrupt will gather RPM for the PWM fan.
void PWMPulseStretch(void)
begin
time6=t6; //reset the task timer
//use pulse stretching to handle pwm rpm monitoring
if( (fanmode[1] == pwm) && (fpcurrtemp[1] > t_fpmintemp[1]) ) {
OCR0 = 255; //drive PWM at full power
TCCR0 = 0b01101011; //clear OC0 on upcount
f_readrpm[1] = 1; //read rpm signals flag
pwmcnt = 0;
}
end
//**********************************************************
//Displays to LCD
// This function outputs the fan + temperature status to the LCD in
// an alternating fashion.
void DispLCD(void)
begin
time1=t1; //reset the task timer
//toggle between different fan info
if( lcddispnum++ == (MAXFAN-1) ) lcddispnum = 0;
//current rpm + temperature
lcd_clear();
sprintf( lcd_buffer, "%d: %4d rpm %2.0fF", lcddispnum+1, rpm[lcddispnum], fpcurrtemp[lcddispnum] );
lcd_gotoxy(0,0);
lcd_puts( lcd_buffer );
end
//**********************************************************
//Displays fan controller information to the computer terminal
void DispScreen(void)
begin
time2=t2;
//prints out title and mode on the hyperterminal
while ( !t_ready );
sprintf(t_buffer, "\f\n\rFan Controller (");
puts_int();
while ( !t_ready );
if( opmode == auto ) sprintf( t_buffer, "auto, " );
else sprintf( t_buffer, "user, " );
puts_int();
while ( !t_ready );
if( inputmode == wireless ) sprintf( t_buffer, "wireless)\n\r" );
else sprintf( t_buffer, "terminal)\n\r" );
puts_int();
//prints fan status
for( i = 0; i < MAXFAN; i++ ) {
while ( !t_ready );
if( (f_lockedrotor[i] == t_lockedrotor) && (fpcurrtemp[i] > t_fpmintemp[i]) && ((fanmode[i] != off) ||
(opmode == user)) )
sprintf(t_buffer, "Fan%d: %4drpm %4.1fF min=%3.0f max=%3.0f - FAULT detected!\n\r",
i+1, rpm[i], fpcurrtemp[i], t_fpmintemp[i], t_fpalarmtemp[i]);
else
sprintf(t_buffer, "Fan%d: %4drpm %4.1fF min=%3.0f max=%3.0f\n\r",
i+1, rpm[i], fpcurrtemp[i], t_fpmintemp[i], t_fpalarmtemp[i]);
puts_int();
}
//prints user prompt
while ( !t_ready );
sprintf(t_buffer, "> %s", r_buffer);
puts_int();
end
//**********************************************************
//Serial port input from the computer
// Gets commands from the keyboard and parses them.
void Sysadmin(void)
begin
time3=t3;
//get user input
if ( r_ready )
begin
sscanf(r_buffer, "%c%d", &cmd, &val1);
gets_int();
switch( cmd ) begin
//set pwmspeed
case 'a': t_fpmintemp[0] = val1; break;
case 'b': t_fpalarmtemp[0] = val1; break;
case 'c': t_fpmintemp[1] = val1; break;
case 'd': t_fpalarmtemp[1] = val1; break;
case 'o': opmode = opmode ^ 1;
if( opmode == auto ) f_readrpm[1] = 0;
break;
case 'f': if( val1 == 1 ) {
if( fanmode[0] == off ) fanmode[0] = dac;
else fanmode[0] = off;
}
if( val1 == 2 ) {
if( fanmode[1] == off ) fanmode[1] = pwm;
else fanmode[1] = off;
}
break;
case 't': tachdivider = val1; break;
end
end
end
//**********************************************************
//Initialize program settings
// Sets up port pins, timers, flags, and interrupts.
void initialize(void)
begin
//temperature and rpm sensing
DDRA = 0x84; //A.2 = enable DAC fan
PORTA = 0xff;
//dac, pwm, mode output and wireless toggle input
DDRB = 0xfd;
PORTB = 0x00;
//lcd output
DDRC = 0xff;
PORTC = 0xff;
//serial and status lights and alarm
DDRD = 0xff;
PORTD = 0xff;
//serial setop for debugging using printf, etc.
UCSRB = 0x18;
UBRRL = 207; //4800
putsf("\r\nCornell Starting...\r\n");
//set up timer 0 for PWM
TCNT0 = 0;
OCR0 = 0;
TCCR0 = 0b01001011; //prescalar to CLK, CTC, PWM, init with no OC0 operation
//set up timer 2 for time based scheduler
TCNT2 = 0;
OCR2 = 24; //0.1 ms
TIMSK = 1<<7; //turn on timer 2 cmp-match ISR
TCCR2 = 0b00001011; //prescalar to CLK / 64
//init the task timers
time1=t1;
time2=t2;
time3=t3;
time4=t4;
time5=t5;
time6=t6;
counttime = 10;
//lcd stuff
lcd_init(LCDwidth); //initialize the display
lcd_clear(); //clear the display
putsf("\r\nLCD init complete...\r\n");
//temperature reading stuff
sensornum = 0;
ADMUX = 0b00100100; //use port A.4 for input (left aligned)
ADCSR = 0b11000111; //prescalar to 1/128*16Mhz = 125kHz, start conversion
fproomtemp = (inittemp * opampGain / Arefvolt) * 255.0; //calibrate roomtemp with sensor 1
for( i = 0; i < MAXFAN; i++ ) {
t_fpmintemp[i] = 72; //initial thresholds
t_fpalarmtemp[i] = 80;
t_mintemp[i] = 72;
t_alarmtemp[i] = 80;
}
//fan speed and failure detection stuff
for( i = 0; i < MAXFAN; i++ ) {
tachhi[i] = 0;
tachlo[i] = 0;
f_readrpm[i] = 1;
f_lockedrotor[i] = 0;
}
f_readrpm[1] = 0; //fan 2 is a pwm fan
//selects fan modes
opmode = auto;
inputmode = computer;
fanmode[0] = dac;
fanmode[1] = pwm;
//pwm and dac stuff
dacout = 0;
pwmspeed = 0;
pwmcnt = 0;
//transmit and receive flags
r_ready = 0;
t_ready = 1;
rstate = start;
datain = 0;
//crank up the ISRs
#asm
sei
#endasm
//serial port input
gets_int();
//our fan
tachdivider = 2;
end
Transmitter code
Below is the transmitter code:
//
// Cornell 2005
// Edward Lo and Sihan Goi
// ECE476 final project
// Temperature sensor and fan wireless transmitter
//
#include <Mega32.h>
#include <stdio.h>
#include <stdlib.h>
//I like these definitions
#define begin {
#define end }
//task scheduling timers
#define t1 30 //30 ms debounce state machine
//wireless packet definitions (maintain DC balance)
#define start_packet 0b10100110
#define stop_packet 0b11010010
enum { NoPush, MaybePush, Pushed, MaybeNoPush };
unsigned int time1; //task scheduling timeout counter
unsigned char buttons, buttons2, inbutton; //saves the button press
unsigned char butstate; //debounce state machine
unsigned char cdata; //data byte to transmit
void initialize(void); //set everything up
void getInput(void); //debounce buttons
//**********************************************************
//Timer0 compare ISR
// Simply ticks down the task timers.
interrupt [TIM0_COMP] void timer0_compare(void)
{
if (time1>0) --time1;
}
//**********************************************************
//Transmit the data byte
// Encapsulates the data packet with a start and end packet.
// Send 0xaa's to setup receiver gain.
void senddata(void)
{
//setup the receiver for proper gain and sync
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xaa);
putchar(0xff);
putchar(0x00);
//send data
putchar(start_packet);
putchar(cdata);
putchar(stop_packet);
cdata = 0;
}
//**********************************************************
//Button debouncing state machine
// Gets the button presses into "inbutton" and then encodes it
// into the "cdata" variable. This becomes the data packet.
void getInput(void)
{
time1=t1;
//button debounce
switch( butstate )
begin
case NoPush:
buttons = PINA;
if( ~buttons != 0 ) butstate = MaybePush; break;
case MaybePush:
buttons2 = PINA;
if( buttons2 == buttons )
begin
butstate = Pushed;
inbutton = ~buttons;
end
else butstate = NoPush;
break;
case Pushed:
buttons2 = PINA;
if( buttons2 == buttons ) butstate = Pushed;
else butstate = MaybeNoPush; break;
case MaybeNoPush:
buttons2 = PINA;
if( buttons2 == buttons ) butstate = Pushed;
else
begin
butstate = NoPush;
inbutton = 0;
end
break;
end
//parse input
switch( inbutton ) {
case 0b10000000:
case 0b01000000:
case 0b00100000:
case 0b00010000: cdata = 0b10000000 | (inbutton >> 1) | 0b10;
inbutton = 0;
break;
case 0b00000001: cdata = 0b10000110;
inbutton = 0;
break;
}
}
//**********************************************************
//Main program
// Debounce buttons and send presses to serial port.
void main(void)
{
initialize();
while(1)
{
if( time1 == 0 ) getInput(); //get debounced input
if( cdata != 0 ) senddata(); //transmits button press
}
}
//**********************************************************
//Get everyting started
void initialize(void)
{
//setup ports
DDRA = 0x00; // buttons
PORTA = 0xff; // pull-up resistors
DDRD = 0xff; // output for status light and transmitter
PORTD = 0xff; // power status on
//serial setop for debugging using printf, etc.
UCSRB = 0x18;
UBRRL = 207; //4800
//setup timer0 for 1ms
TIMSK = 2;
OCR0 = 249;
TCCR0 = 0b00001011;
//initialize timers
time1 = t1;
time2 = t2;
//setup debounce states
butstate = NoPush;
inbutton = 0;
cdata = 0;
#asm ("sei");
//turns on LED
PORTD.7 = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -