11.05.2015r.
Laboratorium z Mikrokontrolerów
Termometr z MSP
Termin: Poniedziałek 11.15-12.45
Prowadzący: Dr hab. inż. Janusz Janiczek
Wykonał: Marcin Bury 207560
1. Opis projektu :
Z cel mojego projektu wybrałem stworzenie termometru. Termometr miał mierzyć i wyświetlać wyniki pomiaru na wyświetlaczu LCD 2x16. Projekt został zrealizowany przy użyciu MSP430(MSP430G2553) oraz czujnika temperatury DS18B20(może mierzyć od -55 do 125 C z magistralą 1Wire.Do pomocy w złożeniu projektu posłużyłem się płytką stykową i kabelkami. Projekt został napisany w języku C w programie Code Compresor Studio.
2.Schemat blokowy
3. Kod programu
/*Poiar temepratury na czujniku DS18B20*/
#include <msp430g2553.h> // wzystkie potrzebne includy
#include <stdint.h>
#include "onewire.h" // implementacja magistrali 1Wire
#include "delay.h" // opóźnienia (do zabaw z czujnikiem)
#include "hd44780.h" // standardowy sterownik LCD, gotowa biblioteka
// konfiguuracja portów
void ow_portsetup() {
OWPORTDIR |= OWPORTPIN; // ustawieniea porrtu na Launchpadzie
OWPORTOUT |= OWPORTPIN; // wyjście
OWPORTREN |= OWPORTPIN; // referencje
}
// konfiguracja odczytu
float ReadDS1820 ( void )
23. {
24. unsigned int i; // zmien bez znak i
25. uint16_t byte = 0;
26. for(i = 16; i > 0; i--){
27. byte >>= 1;
28. if (onewire_read_bit()) { // odczyt z 1wire
29. byte |= 0x8000;
30. }
31. }
32. return byte; // co nam funkcja zwraca
33. }
34.
35. // odczytywanie z 1wire
36. float GetData(void)
37. {
38. uint16_t temp;
39. onewire_reset();
40. onewire_write_byte(0xcc); // przeskocz komendy ROM
41. onewire_write_byte(0x44); // convert T command
42. OW_HI
43. DELAY_MS(750); // mamy ustaiwnia domsle czyli zabawa z czasmi co
najmieni 750 ns dla rozdzienczości 12- bitowej ( bo czujnik 18B20 )
44. onewire_reset();
45. onewire_write_byte(0xcc); // przeskoczkomendy ROM
46. onewire_write_byte(0xbe); // czytanie polecenia
47. temp = ReadDS1820(); //przpisanie do wartości Read... do temp
48. if(temp<0x8000){ // sprawdzanie temperatur +/-
49. return(temp*0.0625);
50. }
51. else
52. {
53. temp=(~temp)+1;
54. return(temp*0.0625);
55. }
56. }
57.
58. int onewire_reset()
59. {
60. OW_LO // odwołnie do konfiguracj porrtów
61. DELAY_US(480); // trzeba odczekać miniimum 480us ( zabaw z czasem )
62. OW_RLS
63. DELAY_US(40); // slave musi odczekać 15-60us
64. if (OWPORTIN & OWPORTPIN) return 1; // nasz slave powinien popchnąć linie
do stanu "0"
65. DELAY_US(300); // slave TX jak jest impuls 60-240us
66. if (!(OWPORTIN & OWPORTPIN)) return 2; // uwolnienie lini od slave
67. return 0;
68. }
69.
70.
71.
72. void onewire_write_bit(int bit)
73. {
74. // DELAY_US(1); // recovery, min 1us
75. OW_HI
76. if (bit) {
77. OW_LO
78. DELAY_US(5); // max 15us
79. OW_RLS // wjeście
80. DELAY_US(56);
81. }
82. else {
83. OW_LO
84. DELAY_US(60); // min 60us
85. OW_RLS // wejście
86. DELAY_US(1);
87. }
88. }
89.
90.
91.
92. int onewire_read_bit()
93. {
94. int bit=0;
95. // DELAY_US(1); // recovery, min 1us
96. OW_LO
97. DELAY_US(5); // wstrzymaj min 1us
98. OW_RLS
99. DELAY_US(10); // 15us window
100. if (OWPORTIN & OWPORTPIN) {
101. bit = 1;
102. }
103. DELAY_US(46); //restet odczytu
104. return bit;
105. }
106.
107.
108.
109. void onewire_write_byte(uint8_t byte) // odczyt bajtu z 1wire
110. {
111. int i;
112. for(i = 0; i < 8; i++)
113. {
114. onewire_write_bit(byte & 1);
115. byte >>= 1;
116. }
117. }
121. uint8_t onewire_read_byte()
122. {
123. unsigned int i;
124. uint8_t byte = 0;
125. for(i = 0; i < 8; i++)
126. {
127. byte >>= 1;
128. if (onewire_read_bit()) byte |= 0x80;
129. }
130. return byte;
131. }
132.
133. int main()
134. {
135. WDTCTL = WDTPW + WDTHOLD; //starndardowe zatrzymanie WDoga
136. BCSCTL1 = CALBC1_1MHZ; // czestotliwości
137. DCOCTL = CALDCO_1MHZ;
138. InitializeLcm(); // Inicjalizacja ekranu
139. ClearLcmScreen(); // Funkcja czyszcznia ekranu i ustawieni
kursora na początek
140. ow_portsetup();
141.
142. for(;;){ // konfiguracja LCD 2x16 co na jakiej pozycji
143. LcmSetCursorPosition(0,0);
144. PrintStr("M.Bury");
145. LcmSetCursorPosition(0,10);
146. PrintStr("Temp");
147. LcmSetCursorPosition(1,0);
148. PrintStr("Stopnie :");
149. HD44780_outdec(GetData()*10, 1);
153. }
154. }
Kod pliku hd44780.h ( konfiguracja portów na LaunchPadzie)
// hd44780.h - konfiguracja pinów wyświtlacza
#ifndef HD44780_H_
#define HD44780_H_
#define LCM_DIR P1DIR
#define LCM_OUT P1OUT
//piny z danymi - konfiguracja
#define LCM_PIN_RS BIT0 // P1.0
#define LCM_PIN_EN BIT1 // P1.1
#define LCM_PIN_D7 BIT7 // P1.7
#define LCM_PIN_D6 BIT6 // P1.6
#define LCM_PIN_D5 BIT5 // P1.5
#define LCM_PIN_D4 BIT4 // P1.4
#define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 |
LCM_PIN_D5 | LCM_PIN_D4))
#define FALSE 0
#define TRUE 1
void LcmSetCursorPosition(char Row, char Col);
void ClearLcmScreen();
void InitializeLcm(void);
void PrintStr(char *Text);
void HD44780_outdec(long data, unsigned char ndigits);
#endif /* HD44780_H_ */
Kod pliku hg44780.c
//
// MSP430 LCD obsługa
//
#include "msp430g2553.h"
#include "hd44780.h"
/* funkcja której używamy zawsze gdy kożystamy z odniesień od LCD
* parametr void zwraca vois d */
void PulseLcm()
{
LCM_OUT &= ~LCM_PIN_EN; // EN w stan niski
__delay_cycles(200);
LCM_OUT |= LCM_PIN_EN; // En w stan wysoki
__delay_cycles(200);
LCM_OUT &= (~LCM_PIN_EN); // En wznowu w stan niski
__delay_cycles(200);
}
/* wysyłanie danych w trybie 4 bitowym, mwięc dane przesyłena muszą być w 2
kawałkach, najpierw wyokie (high) a potem niskie
*/
/* parametr:
ByteToSend - pojedynczy bit do wysłania
IsData - wysyła TRUE jak bit ma dane i FALSE jak ma kommende
zwraca : void*/
dByte(char ByteToSend, int IsData)
{
// clear dla wszystkie piny wyjściwe
LCM_OUT &= (~LCM_PIN_MASK);
//
// ustawienie stanów wysokich
// DB7 - DB4 ustawienie bitów P1.7 - P1.4
// po prze operacje przpisania
LCM_OUT |= (ByteToSend & 0xF0);
if (IsData == TRUE)
{
LCM_OUT |= LCM_PIN_RS;
}
else
{
LCM_OUT &= ~LCM_PIN_RS;
}
// ustaiwnien wejściowego V, i odczytu ich
PulseLcm();
//
// ustawienie stanów niskich
// DB7 - DB4 ustawienie bitów P1.7 - P1.4
// po prze operacje przpisania
LCM_OUT &= (~LCM_PIN_MASK);
LCM_OUT |= ((ByteToSend & 0x0F) << 4);
if (IsData == TRUE)
{
LCM_OUT |= LCM_PIN_RS;
}
else
{
LCM_OUT &= ~LCM_PIN_RS;
}
PulseLcm();
}
// ustawienie kursora na wyświtlaczu
// parametry
// Row -
// Col -
// zwraca - void
void LcmSetCursorPosition(char Row, char Col)
{
char address;
// konstrukcja adresu (Row, Col) pair
if (Row == 0)
{
address = 0;
}
else
{
address = 0x40;
}
address |= Col;
SendByte(0x80 | address, FALSE);
}
// czysci ekran i daje kursor na 1 miejsce
// Parameters:
void ClearLcmScreen()
{
//
// Clearuje i na 1 mijsce
//
SendByte(0x01, FALSE);
SendByte(0x02, FALSE);
}
//
// Routine Desc:
//
//inicjalizuje LCP po daniu napięcia ( procedura musi być wykonana 2 krotnie bo
gdzy 2 zródła zalilania dla MCu i LCM
//
void InitializeLcm(void)
{
//
// ustaiwnie konfukuracji pinów MSP i wszystkie w stan niski
IR |= LCM_PIN_MASK;
LCM_OUT &= ~(LCM_PIN_MASK);
__delay_cycles(100000);
LCM_OUT &= ~LCM_PIN_RS;
LCM_OUT &= ~LCM_PIN_EN;
LCM_OUT = 0x20;
PulseLcm();
// ustawinei 4 bitów wejsciowych
SendByte(0x28, FALSE);
//
// wyśiwtlacz działa i kursor ustawiony
//
SendByte(0x0E, FALSE);
// ruch kursora auto inkrementacja
SendByte(0x06, FALSE);
}
void PrintStr(char *Text)
{
char *c;
c = Text;
while ((c != 0) && (*c != 0))
{
SendByte(*c, TRUE);
c++;
}
}
void HD44780_outdec(long data, unsigned char ndigits){
unsigned char sign, s[6];
unsigned int i;
sign = ' ';
if(data < 0) {
sign='-';
data = -data;
}
i = 0;
do {
s[i++] = data % 10 + '0';
if(i == ndigits) {
s[i++]='.';
}
} while( (data /= 10) > 0);
s[i] = sign;
for (i = 0; i<5; i++){
SendByte(s[4-i], TRUE);
}
}
// testy wyswitlacza
void hd44780_test(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
InitializeLcm();
ClearLcmScreen();
PrintStr("witamy");
LcmSetCursorPosition(1,0);
PrintStr("jestok ");
while (1)
{
__delay_cycles(1000);
}
4.Podsumowanie:
Projekt został wykonany poprawnie. Wyniki pomiaru są wyświetlane na wyświetlaczu. Jest Wyświetlane Stopnie_:''wartość''. Projekt został oddany 1 tydzień po terminie.