我需要使用AVR ATMEGA88开发一个简单的温度计。我正在使用我发现的库来读取热电偶的温度(用max6675键入k)。我可以使用函数gettemp()正确读取温度,但是当我在结果值上使用运算符时,它返回0。
因为函数返回0.25摄氏度的值,我需要除以4,我还需要将值分成两部分以显示在七段显示器上。
我的代码:
#include <avr/io.h>
#include <util/delay.h>
#include "max6675.h"
/*
Max6675 library by Tobias Schlegel, 5.2009
www.tobias-schlegel.de
Report bugs to tobias@drschlegel.de
This software is deliveres as-is and comes with absolute NO warranty.
This software is published under GNU license.
*/
uint16_t gettemp(void); //Functie declaratie
void initavr(void);
// Geeft temperatuur per 0.25 graden celsius.
uint16_t gettemp(void) { //Haal de temperatuur op
uint8_t bit = 0, bitnr = 12; //Variabelen
uint8_t foo1 = 0;
uint16_t Rohdata = 0;
CS_Port &= ~(1 << CS); //Chip select anlegen
for (foo1 = 0; foo1 < 16; foo1++) { //16 Bits Uitlezen
bit = 15 - foo1; //Die Aktuelle Bitnr berechnen.
SCK_Port |= (1 << SCK); //SCK hi
if ((bit <= 14) && (bit >= 3)) { //Einfach mal die 12 relevanten von den 16 Bits ausfiltern
if ((SO_Pin & (1 << SO))) { //WENN SO 1 ist, dann...
bitnr--; //z�hlen wir runter...
Rohdata |= (1 << bitnr); // und schieben eine 1 an bit x
} else { //WENN dem NICHT so ist, dann...
bitnr--; //z�hlen wir runter...
Rohdata &= ~(1 << bitnr); //und schieben eine 0 an bit x
}
} else { //weis au nimmer, was das soll.
bitnr = 12;
}
SCK_Port &= ~(1 << SCK); //SCK LO
}
CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.
return Rohdata; //Geeft de temperatuur terug
}
// getTC() returns 0 if Thermocouple is not connected, 255 if thermocouple is connected
// (to enable this feature T- must be connected to GND)
uint8_t getTC(void) {
uint8_t TC = 0;
uint8_t foo1 = 0;
CS_Port &= ~(1 << CS); //Chip select anlegen
for (foo1 = 0; foo1 < 16; foo1++) { //16 Bits einlesen //Die Aktuelle Bitnr berechnen.
SCK_Port |= (1 << SCK); //SCK hi
if (foo1 == 2) { //das 3. bit ist f�r uns relevant.
if ((SO_Pin & (1 << SO))) { //Geeft 0 wanneer er geen thermocouple gedeteceerd wordt
TC = 0;
} else { //Geeft 255 wanneer er een thermocouple gedeteceerd wordt
TC = 255;
}
}
SCK_Port &= ~(1 << SCK); //SCK LO
}
CS_Port |= (1 << CS); //CS HI
return TC; //Geeft 0 of 255 afhankelijk of thermocouple is gedetecteerd
}
//Initialiseert de MAX6675 en de IO-pins
void init_6675(void) { //AVR initialiseren
SO_DDR &= ~(1 << SO);
CS_DDR |= (1 << CS);
SCK_DDR |= (1 << SCK); //IOs instellen
SO_Port |= (1 << SO); //Pullups aan. (Belangrijk voor de MAX6675)
CS_Port |= (1 << CS); //CS HI Poort afkomstig uit de configuratie
SCK_Port &= ~(1 << SCK); //SCK LO
}
void updateTemp(void) {
const uint16_t numbers[10] = {0b11000000, 0b11111001, 0b10010010, 0b10110000, 0b10101001, 0b10100100, 0b10000100, 0b11110001, 0b10000000, 0b10100000}; //Numbers on 7Segment
uint16_t temperature = gettemp() / 4; //Get temperature and divide by 4 to get degrees celcius
//Split number to display on 7segment
uint16_t single = temperature % 10;
uint16_t decimal = (temperature - single) / 10;
// uint16_t test = 344 / 4; //Test value - this display correctly on 7segment
// uint16_t single = test % 10;
// uint16_t decimal = (test - single) / 10;
for (int i = 0; i < 1000; i++){
PORTB = 0b00000010;
PORTD = numbers[single];
_delay_ms(1);
PORTB = 0b00000100;
PORTD = numbers[decimal];
_delay_ms(1);
}
}
int main(void) {
DDRD |= 0b11111111; //Alle D poorten op output
DDRC |= 0b00011111; //
DDRB |= 0b11001110; //
init_6675(); //Initialiseer de MAX6675
while (1) {
uint8_t isThereATC = getTC();
if (isThereATC == 0) {
PORTB = 0b01000000; //No Thermocouple
PORTD = 0b11111111;
}
else if (isThereATC == 255) {
updateTemp();
}
else {
PORTD = 0b11111111; //Error
}
_delay_ms(2000);
}
return 0;
}
我知道我的热电偶有效,因为如果我不使用操作器并使用LED来显示温度范围是正常的。
编辑:
问题出现在以下功能中。我使用temperature = gettemp() / 4
来获取温度。这会返回0。
void updateTemp(void) {
const uint16_t numbers[10] = {0b11000000, 0b11111001, 0b10010010, 0b10110000, 0b10101001, 0b10100100, 0b10000100, 0b11110001, 0b10000000, 0b10100000}; //Numbers on 7Segment
uint16_t temperature = gettemp() / 4; //Get temperature and divide by 4 to get degrees celcius
//Split number to display on 7segment
uint16_t single = temperature % 10;
uint16_t decimal = (temperature - single) / 10;
// uint16_t test = 344 / 4; //Test value - this display correctly on 7segment
// uint16_t single = test % 10;
// uint16_t decimal = (test - single) / 10;
for (int i = 0; i < 1000; i++){ //Display on 7Segment
PORTB = 0b00000010;
PORTD = numbers[single]; //Number right
_delay_ms(1);
PORTB = 0b00000100;
PORTD = numbers[decimal]; //Number left
_delay_ms(1);
}
}
EDIT2:
我将除数除以4,并使用以下代码确定temperature
if (temperature == 0){
PORTB = 0b10000000; //Green LED
PORTD = 0b11111111;
}
else if (temperature > 0 && temperature < 100) {
PORTB = 0b00000100; //Blue LED
PORTD = 0b11111111;
}
else {
PORTB = 0b00001000; //Red LED
PORTD = 0b11111111;
}
希望你能帮助我。