Hallo, bin grad dabei mit Hilfe des DS18S20 die Temperatur auszulesen. Erstmal nur testweise. Benutze dafür einen Atmega32 mit 16MHz auf dem Pollinboard + Addonboard. Das ganze geschieht in C und sieht so aus:
1 | /*
|
2 | * main.c
|
3 | *
|
4 | * Created on: 15.07.2010
|
5 | * Author: cesupa
|
6 | */
|
7 | |
8 | #include <avr/io.h> |
9 | #include <util/delay.h> |
10 | #include <stdlib.h> |
11 | #include "lcd_addonboard.h" |
12 | |
13 | /* Thermometer Connections (At your choice) */
|
14 | #define PORT PORTD
|
15 | #define DDR DDRD
|
16 | #define PIN PIND
|
17 | #define DQ PD6
|
18 | /* Utils */
|
19 | #define INPUT_MODE() DDR&=~(1<<DQ)
|
20 | #define OUTPUT_MODE() DDR|=(1<<DQ)
|
21 | #define LOW() PORT&=~(1<<DQ)
|
22 | #define HIGH() PORT|=(1<<DQ)
|
23 | |
24 | |
25 | |
26 | uint8_t reset(); |
27 | uint8_t write_bit(uint8_t bit); |
28 | uint8_t read_bit(); |
29 | uint8_t read_byte(); |
30 | unsigned char rom_c[8],scratch_pad[9]; |
31 | |
32 | void write_byte(uint8_t byte); |
33 | |
34 | int main() |
35 | {
|
36 | uint8_t z=0; |
37 | char string[20]; |
38 | |
39 | lcd_init(); |
40 | if(!reset()) |
41 | lcd_str("DS18S20 found"); |
42 | else
|
43 | lcd_str("FAILURE"); |
44 | |
45 | write_byte(0xcc); |
46 | write_byte(0x44); |
47 | _delay_ms(1000); |
48 | |
49 | if(!reset()) |
50 | {
|
51 | write_byte(0xcc); |
52 | write_byte(0xbe); |
53 | for(z=0;z<9;z++) |
54 | {
|
55 | scratch_pad[z]=read_byte(); |
56 | }
|
57 | |
58 | |
59 | lcd_str(itoa(scratch_pad[8],string,10)); |
60 | }
|
61 | else
|
62 | lcd_str("FAILURE_2"); |
63 | |
64 | while(1); |
65 | return 0; |
66 | }
|
67 | |
68 | uint8_t reset() |
69 | {
|
70 | uint8_t i=0; |
71 | //Pull line low and wait for 480uS
|
72 | |
73 | OUTPUT_MODE(); |
74 | LOW(); |
75 | _delay_us(480); |
76 | //Release line and wait for 60uS
|
77 | INPUT_MODE(); |
78 | LOW(); |
79 | |
80 | _delay_us(70); |
81 | |
82 | //Store line value and wait until the completion of 480uS period
|
83 | i=(PIN & (1<<DQ)); |
84 | OUTPUT_MODE(); |
85 | LOW(); |
86 | _delay_us(410); |
87 | |
88 | //Return the value read from the presence pulse (0=OK, 1=WRONG)
|
89 | return i; |
90 | |
91 | }
|
92 | |
93 | uint8_t write_bit(uint8_t bit) |
94 | {
|
95 | //Pull line low for 1uS
|
96 | OUTPUT_MODE(); |
97 | LOW(); |
98 | |
99 | _delay_us(1); |
100 | //If we want to write 1, release the line (if not will keep low)
|
101 | if(bit) INPUT_MODE(); |
102 | //Wait for 60uS and release the line
|
103 | _delay_us(119); |
104 | INPUT_MODE(); |
105 | return 0; |
106 | }
|
107 | |
108 | uint8_t read_bit() |
109 | {
|
110 | uint8_t bit; |
111 | //Pull line low for 1uS
|
112 | OUTPUT_MODE(); |
113 | LOW(); |
114 | |
115 | _delay_us(1); |
116 | //Release line and wait for 14uS
|
117 | INPUT_MODE(); |
118 | _delay_us(14); |
119 | //Read line value
|
120 | bit=PIN&(1<<DQ); |
121 | //Wait for 45uS to end and return read value
|
122 | _delay_us(105); |
123 | return bit; |
124 | |
125 | }
|
126 | |
127 | unsigned char read_byte() |
128 | {
|
129 | uint8_t i=0; |
130 | unsigned char n=0; |
131 | |
132 | for(i=0;i<8;i++) |
133 | {
|
134 | if(read_bit()) n|=0x01 << 1; |
135 | }
|
136 | return n; |
137 | }
|
138 | |
139 | void write_byte(uint8_t byte) |
140 | {
|
141 | uint8_t i=8; |
142 | while(i--){ |
143 | //Write actual bit and shift one position right to make the next bit ready
|
144 | write_bit(byte&1); |
145 | byte>>=1; |
146 | }
|
147 | |
148 | }
|
Wenn ich mir die Bytes des Scratchpads ausgeben lasse, steht auf dem LCD ständig eine "2" da....ich hab leider keine Ahnung woran das liegen könnte. Bitte um Hilfe. Gruß Paul