本應(yīng)用筆記介紹如何使用MAXQ2000微控制器控制直流風(fēng)扇速度,并通過(guò)熱敏電阻或i按鈕?監(jiān)測(cè)溫度。
介紹
MAXQ2000具有眾多的特性,可以創(chuàng)建多種有用的應(yīng)用,例如通過(guò)脈寬調(diào)制(PWM)控制風(fēng)扇的速度。MAXQ2000的眾多特性包括帶PWM和串行外設(shè)接口(SPI)的定時(shí)器。?)和1-Wire功能。本應(yīng)用筆記描述了如何使用MAXQ2000驅(qū)動(dòng)風(fēng)扇,并通過(guò)PWM實(shí)時(shí)改變風(fēng)扇速度。該過(guò)程需要使用Maxim的另一種產(chǎn)品,即MAX1407多通道數(shù)據(jù)采集系統(tǒng)(DAS)。利用SPI,MAXQ2000可以與MAX1407通信(包含16位模數(shù)轉(zhuǎn)換器[ADC]和數(shù)模轉(zhuǎn)換器[DAC])。作為使用熱敏電阻的替代方法,MAXQ2000的1-Wire總線主控器可與溫度i按鈕(DS1920)配合使用。
概述
該程序在MAXQ2000評(píng)估板(修訂版B)上運(yùn)行,借助溫度i按鈕(DS1920)或外部熱敏電阻。MAXQ2000評(píng)估板(修訂版B)包括一個(gè)LCD顯示屏、兩個(gè)按鈕、一個(gè)MAX1407 ADC、兩個(gè)UART、三個(gè)定時(shí)器、1-Wire和許多其他特性。程序使用LCD顯示屏、按鈕和MAX1407或1-Wire讀取溫度。此外,還需要直流風(fēng)扇和適用的驅(qū)動(dòng)電路、熱敏電阻和電源。MAXQ2000評(píng)估板將驅(qū)動(dòng)外部電路控制風(fēng)扇速度。LCD顯示屏顯示當(dāng)前溫度,并定期從攝氏度到華氏度變化。按鈕允許用戶更改風(fēng)扇的低速和全速溫度閾值。
檢測(cè)溫度的默認(rèn)方法是使用i按鈕,但如果正確的i按鈕不可用或通信出現(xiàn)問(wèn)題,程序通過(guò)MAXQ2000的SPI使用熱敏電阻來(lái)獲取溫度讀數(shù)。i按鈕(DS1920)是一款溫度檢測(cè)1-Wire器件。該程序?qū)L1005-5744-103-SA熱敏電阻與MAX1407配合使用。
讀取溫度后,將顯示被發(fā)送到LCD,并根據(jù)溫度讀數(shù)調(diào)整PWM占空比。
程序中有兩個(gè)閾值,最低溫度和最高溫度。如果溫度低于最低溫度閾值,風(fēng)扇關(guān)閉;如果高于最大溫度閾值,則風(fēng)扇設(shè)置為其最大速度。如果溫度介于最小閾值和最大閾值之間,則速度與兩個(gè)溫度閾值之間的分?jǐn)?shù)距離成正比。
兩個(gè)閾值可通過(guò)標(biāo)記為SW4和SW5的兩個(gè)按鈕進(jìn)行配置。SW4 切換閾值以更改 - 基本或最大值。為更改選擇的閾值顯示在數(shù)值數(shù)據(jù)和 C/F 字符之間。下劃線表示將更改基本閾值,而高劃線表示將更改最大閾值。SW5 將當(dāng)前選擇的閾值增加 1。每更改一個(gè)閾值,就會(huì)重新計(jì)算風(fēng)扇速度。
該應(yīng)用需要使用MAXQ2000上三個(gè)定時(shí)器中的兩個(gè)。定時(shí)器1專用于通過(guò)熱敏電阻定期檢查溫度,而定時(shí)器0使用P6.5的PWM輸出來(lái)控制風(fēng)扇。定時(shí)器1不能用于PWM,因?yàn)樗哂信cMAX1407通信期間使用的硬件資源。
硬件設(shè)置
圖1.將熱敏電阻硬件連接到MAXQ2000評(píng)估板。
首先,使用RL1005-5744-103-SA熱敏電阻和10kΩ電阻構(gòu)建熱敏電阻設(shè)置。這是通過(guò)首先將J7引腳7和8連接到熱敏電阻的一側(cè)來(lái)完成的。在熱敏電阻的另一側(cè)連接J1引腳7的導(dǎo)線。接下來(lái),將J10的引腳1和地之間的7kΩ電阻連接(J71的引腳72或2接地)。如果使用i按鈕選項(xiàng),則應(yīng)將i按鈕放置在i按鈕夾DS9094FS(或類似器件)中,該夾子應(yīng)焊接到電路板的1-Wire部分。接下來(lái),通過(guò)打開(kāi) SW6.2 和 SW6.5 啟用按鈕。液晶顯示屏連接到J3。為了通過(guò)熱敏電阻讀取溫度,打開(kāi)SW3的全部,以便與MAX1407通信。MAX1407的ADC部分將來(lái)自熱敏電阻的模擬信號(hào)轉(zhuǎn)換為可用于計(jì)算溫度的數(shù)字值。使用 i 按鈕需要 JU7 和 JU8 上的跳線以及 i按鈕夾。
圖2.用于將 PWM 輸出連接到風(fēng)扇的可能硬件設(shè)置。
解釋軟件定義和包含
#define PWMFREQ 1000 // Change this for desired PWM frequency #define CPUFREQ 13500000 // Change this to match current clock // frequency #define MIN_TICKS 0 // Minimum number of timer ticks // for fan to overcome static friction #define POLLING_INTERVAL 500 // Number of milliseconds between // temperature checks
以下是編譯時(shí)要檢查的一些基本定義:
#define LCD0_PATTERN_C 0x039 #define LCD0_PATTERN_F 0x071 #define LCD_PATTERN_0 0x03F #define LCD_PATTERN_1 0x006 #define LCD_PATTERN_2 0x05B #define LCD_PATTERN_3 0x04F #define LCD_PATTERN_4 0x066 #define LCD_PATTERN_5 0x06D #define LCD_PATTERN_6 0x07D #define LCD_PATTERN_7 0x007 #define LCD_PATTERN_8 0x07F #define LCD_PATTERN_9 0x067 int PATTERNS[] = { LCD_PATTERN_0, LCD_PATTERN_1, LCD_PATTERN_2, LCD_PATTERN_3, LCD_PATTERN_4, LCD_PATTERN_5,LCD_PATTERN_6, LCD_PATTERN_7, LCD_PATTERN_8, LCD_PATTERN_9 };
使用上述定義,數(shù)字的LCD顯示非常容易。LCD 圖案是預(yù)定義的,然后添加到名為 PATTERNS 的數(shù)組中以供檢索。顯示某個(gè)數(shù)字就像:
LCD2 = PATTERNS[desired_digit];
定時(shí)器 1 初始化
T2V1 = 0xFFFF - (CPUFREQ/128/1000*POLLING_INTERVAL); // Set reload value. T2R1 = T2V1; // Set current timer value T2C1 = 0x00000; // Set compare value T2CFG1_bit.T2DIV = 7 // Set Divide mode to Divide by 128 T2CNA1_bit.TR2 = 1; // Start Timer T2CNA1_bit.T2POL0 = 1; // Set polarity high T2CNA1_bit.ET2 = 1; // Enable timer interrupts T2CNB1_bit.T2OE1 = 1; // Enable timer output IMR_bit.IM4 = 1; // Enable interrupts from module 4
定時(shí)器1負(fù)責(zé)定期檢查溫度。初始值 (T2V1) 的設(shè)置取決于溫度輪詢之間的時(shí)間長(zhǎng)度(以毫秒 (POLLING_INTERVAL) 為單位)。在兩行不同的行上完成計(jì)算的原因是防止值變得太大而寄存器無(wú)法處理。T2R1 指定計(jì)時(shí)器在達(dá)到 65,535 時(shí)返回的值。T2C1 設(shè)置為低于重新加載值 (T2R0) 以確保它永遠(yuǎn)不會(huì)生成中斷。T2CFG1 是配置許多計(jì)時(shí)器選項(xiàng)的寄存器。計(jì)時(shí)器的時(shí)鐘分頻設(shè)置為將系統(tǒng)時(shí)鐘除以 128,這意味著系統(tǒng)時(shí)鐘的每 128 個(gè)周期相當(dāng)于計(jì)時(shí)器的 1 個(gè)周期。系統(tǒng)時(shí)鐘也可以除以,然后將 2 個(gè)計(jì)時(shí)器周期的時(shí)間量(以 1 的冪為單位)相乘。T2CNA1 是定時(shí)器 0 本身的寄存器。這將啟動(dòng)定時(shí)器運(yùn)行并啟用定時(shí)器中斷,而 T2CNB1 使能定時(shí)器的輸出。最后,啟用模塊 4 中的中斷。
定時(shí)器 0 初始化
T2V0 = 0xFFFF - (CPUFREQ / PWMFREQ); // Set current timer value T2R0 = T2V0; // Set reload value T2C0 = T2R0+1; // Set compare value to reload value +1 T2CNA0_bit.T2OE0 = 0; // Turns PWM output off T2CNA0_bit.T2POL0 = 0; // Changes polarity of PWM so it starts "off" T2CNA0_bit.T2OE0 = 1; // Turns PWM output on T2CFG0 = 0x00; // Set timer divide at 1
下一個(gè)要初始化的項(xiàng)目是定時(shí)器0,它控制PWM,并通過(guò)它控制風(fēng)扇。計(jì)時(shí)器 0 是一個(gè) 16 位計(jì)時(shí)器,與計(jì)時(shí)器 1 完全相同。當(dāng)定時(shí)器達(dá)到比較值時(shí)(即,當(dāng) T2V0 == T2C0 時(shí)),端口引腳狀態(tài)反轉(zhuǎn)。當(dāng)定時(shí)器重新加載時(shí),端口引腳也會(huì)反轉(zhuǎn)(圖3)。T2V0 設(shè)置計(jì)時(shí)器的初始值,而 T2R2 設(shè)置重新加載值,兩者都設(shè)置為 0xFFFF - (CPU 頻率/PWM 頻率)。此計(jì)算用于更輕松地將代碼移植到具有不同 CPU 時(shí)鐘速度的系統(tǒng)或更改所需的 PWM 頻率。
圖3.端口引腳圖。
子選項(xiàng) T2EO0 可確保 PWM 的輸出關(guān)閉,以便改變極性 (T2POL0)。當(dāng)極性開(kāi)關(guān)設(shè)置為0時(shí),PWM的啟動(dòng)狀態(tài)為關(guān)閉;如上圖所示。T2CFG0 確保計(jì)時(shí)器不會(huì)劃分系統(tǒng)時(shí)鐘,并告訴計(jì)時(shí)器將 T2V0 與 T2C0 進(jìn)行比較。
getADCReading負(fù)責(zé)將模擬信號(hào)轉(zhuǎn)換為數(shù)字值。下面列出了從熱敏電阻讀取溫度的步驟。
sendSPI(RD_ADC); // Read the 1407's ADC register. spiData = sendSPI(0x0FF); spiData |= 0x01; // Set the start conversion bit. sendSPI(WR_ADC); // Write the new value back into sendSPI(spiData); // the 1407 register. do { sendSPI(RD_STAT); // Read the 1407's Status register. spiData = sendSPI(0x0FF); } while((spiData & 0x02) == 0x00); // Bit 1 indicates AtoD conversion complete. sendSPI(RD_DATA); // Send the command to read the 1407's Data register. SPICF = 0x04; // Set up SPI to 16-bit mode. spiData = sendSPI(0x0FFFF); // Read the Data register. SPICF = 0x00; // Put SPI back into 8-bit mode. return spiData;
液晶屏初始化
//LCRA_bit.FRM = 7; // Set up frame frequency. //LCRA_bit.LCCS = 1; // Set clock source to HF/128. //LCRA_bit.DUTY = 0; // Set up static duty cycle. //LCRA_bit.LRA = 0; // Set R-adj to 0. //LCRA_bit.LRIGC = 1; // Select external LCD drive power. LCRA = 0x03E0; // Do all configuration changes at once LCFG_bit.PCF = 0x0F; // Set up all segments as outputs. LCFG_bit.OPM = 1; // Set to normal operation mode. LCFG_bit.DPE = 1; // Enable display. LCD1 = 0x08;
為了顯示當(dāng)前溫度,您必須打開(kāi)LCD顯示屏。前五行被注釋掉了代碼,因?yàn)樗鼈円驯粔嚎s成一個(gè)語(yǔ)句。LCRA是LCD調(diào)整寄存器,它控制LCD顯示設(shè)置。更改 FRM 設(shè)置幀頻率;有了這個(gè),您可以降低頻率并使用更少的功率。幀頻率是用于在 LCD 上顯示的電源頻率。LCCS 將 LCD 時(shí)鐘分頻更改為 128。Duty 將顯示設(shè)置為靜態(tài),這意味著顯示輸出永遠(yuǎn)不會(huì)更改。LCFG 是 LCD 配置寄存器。由于LCD只需要顯示,因此將PCF更改為0x0F會(huì)將LCD中的所有段設(shè)置為輸出。將 OPM 和 DPE 設(shè)置為 1 將分別打開(kāi) LCD 并啟用顯示器。LCD1 = 0x08顯示下劃線,表示按鈕將增加最小閾值。通過(guò)下面的兩行簡(jiǎn)單操作,LCD顯示屏現(xiàn)在處于活動(dòng)狀態(tài)并準(zhǔn)備好顯示。
LCRA = 0x03E0; LCFG = 0xF3;
所有需要做的就是將值(如PATTERNS[數(shù)字]中的項(xiàng)目)加載到LCD寄存器中,這是非??焖俸腿菀椎?。
按鈕初始化
EIE1 = 0x84; // enable interrupts 15 and 10 EIES1 = 0x84; // set up edge transitions IMR_bit.IM1 = 1; // turn on interrupts for module 1
現(xiàn)在是時(shí)候初始化按鈕了。與按鈕相關(guān)的中斷是 10 和 15,對(duì)應(yīng)于 EIE4(外部中斷使能 80)上的 1 和 1(十六進(jìn)制)。EIE1 啟用這些外部中斷,而 EIES1(外部中斷邊沿選擇 1)將中斷觸發(fā)器設(shè)置為下降沿(按下按鈕)。如果將其清除為零,則釋放按鈕是觸發(fā)中斷的操作。IMR 是中斷掩碼寄存器,它跟蹤允許中斷的模塊,IM1 啟用模塊 1 的中斷。
按鈕中斷
按鈕允許用戶更改base_temp和max_temp閾值。SW4(中斷 10)更改將要更改的閾值,而 SW5(中斷 15)將閾值增加 1。如果max_temp達(dá)到 149,則自身降低到 base_temp+1。如果base_temp比max_temp低 50,則base_temp變?yōu)?<>。
#pragma vector = 1 __interrupt void pushButtonInterrupt() { if (EIF1 & 0x04) //interrupt 10 // Modify which threshold to changed { if(last_state == 0) // Modify max_temp instead of base_temp { LCD1 = 0x01; // Change display to underscore last_state = 1; } else // Modify base_temp instead of max_temp { LCD1 = 0x08; last_state = 0; //Change display to overscore } }
“#pragma vector = 1”是一個(gè)編譯器指令,指示此函數(shù)處理來(lái)自模塊 1 的任何中斷,模塊 <> 是外部中斷的來(lái)源。
pushButtonInterrupt 函數(shù)首先檢查觸發(fā)了哪個(gè)中斷。中斷 10 0x04中斷,中斷 15 0x80。如果要更改閾值,則會(huì)更改切換并更新顯示。如果是閾值增量器,則閾值增加 1。如果閾值已達(dá)到其上限,則繞到下限。
if (EIF1 & 0x80) //interrupt 15 // Increase threshold for base or max temps { if(last_state == 0) { // Increase base_temp if(base_temp < (max_temp -1)) { ++base_temp; if(base_temp > 99) // If over 99, print 1 for 100's place LCD4 = 0x40; else LCD4 = 0; // Else print nothing LCD3 = getLCDDigit( (base_temp /10) %10); // Print 10's digit LCD2 = getLCDDigit(base_temp %10); // Print 1's digit } else if (base_temp == max_temp -1) // If base temp is going to equal max temp { // set base temp to 50 instead of increasing base_temp = 50; LCD3 = getLCDDigit(5); // Print 50 to display LCD2 = getLCDDigit(0); } }
如果正在修改閾值,它將檢查last_state的值。當(dāng)last_state為零時(shí),base_temp被修改;否則max_temp將被修改。如果base_temp正好小于 max_temp 50,則程序?qū)ase_temp包裝為任意值 <>。
else if (last_state == 1) // Increase max_temp { if(max_temp < 149) { ++max_temp; if(max_temp > 99) LCD4 = 0x40; //show 100s digit else LCD4 = 0; LCD2 = getLCDDigit(max_temp %10); // Show 1s digit LCD3 = getLCDDigit( (max_temp / 10) %10); // Show 10s digit } else { if (max_temp == 149) // If max_temp is at limit then cycle max_temp = base_temp+1; // to be 1 degree over base temp if(max_temp > 99) LCD4 = 0x40; // Clear 100s digit else LCD4 = 0; LCD2 = getLCDDigit(max_temp %10); // Show 1s digit LCD3 = getLCDDigit( (max_temp / 10) %10); // Show 10s digit } } xplier = ( (CPUFREQ/PWMFREQ) / (max_temp - base_temp)); // Re-calculate multiplier } EIF1 = 0; // Clear External Interrupt Flag
按鈕中斷的這一部分更改max_temp閾值。它增加max_temp直到等于 149,然后它環(huán)繞起來(lái)變得比 base_temp 大 1。如果base_temp是65,那么max_temp將是66。
新增加/換行的值會(huì)短暫顯示在LCD上,以便用戶知道它已更改。下次計(jì)時(shí)器重新加載時(shí),LCD 會(huì)變回溫度,并使用溫度更新顯示。
更改閾值后,將重新計(jì)算 xplier。xplier 是確定 T2C1 值的乘數(shù)。在按鈕中斷完成之前,它會(huì)清除 EIF1(外部中斷標(biāo)志 1),以便為下一次中斷做好準(zhǔn)備。
定時(shí)器 1 中斷
#pragma vector = 4 __interrupt void timer1Interrupt() { T2CNA1_bit.TR2 = 0; // Stop the timer. if(++count == 20) // Change the units occasionally. { count = 0; celsius = ~celsius; } readTemp(); //Get and display the current temperature. T2CNB1_bit.TF2 = 0; //Clear the overflow flag. T2CNB1_bit.TCC2 = 0; //Clear the overflow flag. // output an 'alive' blip with the first decimal point, LCD0.7 if (count & 1) LCD0 = LCD0 | 0x80; else LCD0 = LCD0 & 0x7F; T2CNA1_bit.TR2 = 1; // Start the timer. }
注意:如果還使用了定時(shí)器 2,則此函數(shù)將針對(duì)定時(shí)器 2 的中斷運(yùn)行,因?yàn)槎〞r(shí)器 2 也位于模塊 4 中。
將 TR2 設(shè)置為 0 將關(guān)閉計(jì)時(shí)器,然后檢查計(jì)數(shù)是否等于 20。計(jì)數(shù)用于定期將顯示從華氏度更改為攝氏度。readTemp() 調(diào)用負(fù)責(zé)讀取溫度的函數(shù)。readTemp 完成后,將清除指示可能的計(jì)時(shí)器溢出(TF2 和 TCC2)的標(biāo)志。if 語(yǔ)句檢查計(jì)數(shù)基本上會(huì)在每次檢查溫度時(shí)創(chuàng)建一個(gè)“刻度”。此“勾號(hào)”是啟用或禁用單位字符左側(cè)的小數(shù)點(diǎn)。這對(duì)于了解檢查的頻率和速度以及溫度保持不變時(shí)運(yùn)行非常有用。最后,計(jì)時(shí)器再次啟動(dòng)。
功能
readTemp() 函數(shù)負(fù)責(zé)讀取和顯示溫度,以及驅(qū)動(dòng) PWM。
if(readiButtonTemp(&temp)==FALSE) // Check to see if the device can be found { // If there is no iButton device found adc = getADCReading(); // Read the thermistor value. temp = convertToTemp(adc); // Convert this value to degrees Celsius. } showTemp(temp); // Display temperature drivePWM(temp); // Update fan speed
它做的第一件事是嘗試從1-Wire或i按鈕器件獲取溫度。如果沒(méi)有有效的1-Wire溫度器件或通信中發(fā)生錯(cuò)誤,則使用熱敏電阻讀取溫度。讀取溫度后,通過(guò)調(diào)用函數(shù) showTemp,將 LCD 顯示屏更新為最新讀數(shù)。之后,驅(qū)動(dòng)PWM相應(yīng)地改變風(fēng)扇的速度。
float convertToTemp(unsigned int adc) { double temp = -0.00135477 * (double)adc + 69.17; return (float)temp; }
convertToTemp將MAX1407的讀數(shù)轉(zhuǎn)換為攝氏度。請(qǐng)注意,該公式給出了接近室溫的近似值,并且不補(bǔ)償熱敏電阻隨溫度的非線性變化。
void showTemp(int temp) { LCFG_bit.DPE = 0; // disable display. // Clear the display of everything but the temperature units (F or C). LCD0 = ( (celsius == 0) ? LCD0_PATTERN_F : LCD0_PATTERN_C); // clear the digits LCD1 = LCD2 = LCD3 = LCD4 = 0; if(last_state == 0) // Display correct threshold being edited LCD1 = 0x08; else LCD1 = 0x01;
showTemp 函數(shù)做的第一件事是將單位系統(tǒng)寫入顯示器,然后通過(guò)將 LCD 寄存器設(shè)置為 0 來(lái)清除顯示器中的所有數(shù)字。然后,它顯示表示要通過(guò)按鈕編輯的閾值的過(guò)劃線或下劃線。
if(celsius == 0) { temp = CtoF(temp); // Convert to Fahrenheit } if (temp > 199) // If temperature is 200+ { temp = temp % 200; } if(temp > 99) // If the temperature is 100+ { show100s(); // Show a '1' on the LCD. temp -= 100; // Adjust the temperature variable. } LCD3 = getLCDDigit(temp / 10); // show the 10's place on the LCD LCD2 = getLCDDigit(temp % 10); // show the 1's place on the LCD LCFG_bit.DPE = 1; // Enable display.
如果當(dāng)前單位系統(tǒng)為華氏度,則溫度通過(guò)函數(shù) CtoF 轉(zhuǎn)換為華氏度。如果 temp 超過(guò) 100,則顯示 1 表示 100 的數(shù)字,并在顯示屏上顯示其他數(shù)字。
drivePWM是通過(guò)改變PWM比較值來(lái)設(shè)置風(fēng)扇功率的功能。
T2CNA0_bit.TR2 = 0; // Turn timer off T2CNA0_bit.T2OE0 = 0; // Turns PWM output off T2CNA0_bit.T2POL0 = 0; // Changes polarity of PWM so that it starts out off T2CNA0_bit.T2OE0 = 1; // Turns PWM output on T2V0 = T2R0; // Manually reload timer value
此序列關(guān)閉風(fēng)扇,然后手動(dòng)重新加載計(jì)時(shí)器值。下面,代碼設(shè)置風(fēng)扇的實(shí)際速度。如果溫度低于base_temp閾值,則風(fēng)扇設(shè)置為可能的最低設(shè)置,否則它會(huì)檢查溫度是否高于最大閾值,在這種情況下,風(fēng)扇設(shè)置為最高設(shè)置。最后,如果溫度在閾值之間,則根據(jù)度數(shù)計(jì)算風(fēng)扇的速度。然后計(jì)時(shí)器重新打開(kāi)。
圖4.頂部輸出正常,而底部跡線是可能的,如果計(jì)時(shí)器未停止并手動(dòng)重新加載。
在更新比較值和重新加載值時(shí)禁用計(jì)時(shí)器以避免無(wú)意中反轉(zhuǎn)輸出非常重要。圖 4 顯示了兩種類型的輸出。頂部輸出是正常的,而底部的圖形是可能的,如果計(jì)時(shí)器沒(méi)有停止并手動(dòng)重新加載。發(fā)生的情況是,新的比較值高于當(dāng)前定時(shí)器值,當(dāng)定時(shí)器最終達(dá)到新的比較值時(shí),端口引腳狀態(tài)反轉(zhuǎn),定時(shí)器繼續(xù)。但是,由于狀態(tài)變化是不需要的,因此它具有反轉(zhuǎn)定時(shí)器輸出極性的效果。
if(temp <= base_temp) // Below this temperature the fan is off { // Force port pin P6.5 low PO6 &= 0xDF; } else { if( temp >= max_temp ) // Beyond this temperature the fan is full speed { // Force port pin P6.5 high PO6 |= 0x20; } else // Set the fan speed according to temperature { T2C0 = 65535 - ((temp - base_temp) * xplier); if( (65535 - T2C0) < MIN_TICKS) T2C0 = 65535 - MIN_TICKS; T2CNA0_bit.TR2 = 1; // Restart timer } }
高于base_temp閾值的每一度都有自己的速度,該速度基于所需的PWM占空比和兩個(gè)閾值之間的范圍。MIN_TICKS是最小定時(shí)器周期數(shù),PWM 輸出必須很高才能使風(fēng)扇以最低速度運(yùn)行。風(fēng)扇速度隨著溫度的升高而線性增加。速度變化率僅在閾值變化時(shí)發(fā)生變化。例如,base_temp 和 max_temp 的默認(rèn)閾值分別為 75 和 85。這意味著 xplier(每度風(fēng)扇速度的增加)為 1350。如果閾值分別更改為 75 和 90,則 xplier 將為 900,這意味著每個(gè)度數(shù)的風(fēng)扇速度增加較少。效率越低,風(fēng)扇越平滑。
void main() { initTimer1(); // Initialize timer1 for thermistor/iButton polling initTimer0(); // Initialize timer0 for PWM output init1407(); // Initialize the 1407 initOW(); // Initialize the 1-Wire subsystem initLCD(); // Initialize LCD display initPushButtons(); // Initialize pushbuttons __enable_interrupt(); // Enable global interrupts while(1); }
main 函數(shù)調(diào)用初始化函數(shù)并啟用全局中斷。程序本身是中斷驅(qū)動(dòng)的,因此它會(huì)處于 while 循環(huán)中,直到中斷觸發(fā)。
結(jié)論
MAXQ2000是一款高性能微控制器,具有許多有用的功能。溫度驅(qū)動(dòng)的風(fēng)扇控制應(yīng)用是使用MAXQ2000的PWM、1-Wire和SPI功能的一個(gè)很好的例子。當(dāng)這些功能與按鈕和LCD顯示屏等交互式元素相結(jié)合時(shí),可能的應(yīng)用數(shù)量幾乎是無(wú)限的。
審核編輯:郭婷
-
微控制器
+關(guān)注
關(guān)注
48文章
7559瀏覽量
151486 -
轉(zhuǎn)換器
+關(guān)注
關(guān)注
27文章
8707瀏覽量
147256 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3250瀏覽量
114882
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論