1 | /**
|
2 | ******************************************************************************
|
3 | * @file main.c
|
4 | * @author Reto Lüchinger
|
5 | * @version V0.0.0
|
6 | * @date 30-May-2012
|
7 | * @brief Main Programm, Initialisieren des STM32F4Discovery Boards
|
8 | ******************************************************************************
|
9 | * Dieses Programm liest einen SHT71 FT Sensor aus und lässt LED blinken,
|
10 | * Am Pushbutton hängt ein Interrupt
|
11 | *
|
12 | *
|
13 | ******************************************************************************
|
14 | */
|
15 |
|
16 | /* Includes ------------------------------------------------------------------*/
|
17 | #include "stm32f4xx.h"
|
18 | #include "stm32f4xx_conf.h"
|
19 | #include "stm32f4_discovery.h"
|
20 | /* Private typedef -----------------------------------------------------------*/
|
21 | GPIO_InitTypeDef GPIO_InitStructure, GPIO_SHT;
|
22 | EXTI_InitTypeDef EXTI_InitStructure;
|
23 | /* Private define ------------------------------------------------------------*/
|
24 | #define TMP_ADRESS 0x03
|
25 | #define HUM_ADRESS 0x05
|
26 | #define SDA_read GPIOB->IDR & GPIO_Pin_7 /*GPIO_ReadInputDataBit(GPIOB , GPIO_Pin_7) */
|
27 | /* Private macro -------------------------------------------------------------*/
|
28 | /* Private variables ---------------------------------------------------------*/
|
29 | uint8_t i;
|
30 | /* Private function prototypes -----------------------------------------------*/
|
31 | void setup_I2C(void);
|
32 | void EXTILine0_Config(void);
|
33 | int16_t read_SHT71(uint8_t adr);
|
34 | void Delay(__IO uint32_t nCount);
|
35 | void nop1(void);
|
36 | static void scl_pulse(void);
|
37 | static void scl_hi(void);
|
38 | static void scl_lo(void);
|
39 | static void sda_hi(void);
|
40 | static void sda_lo(void);
|
41 | static uint8_t sda_val(void);
|
42 | static uint8_t crc_value;
|
43 | static uint8_t send(uint16_t b);
|
44 | static uint8_t recv_data(void);
|
45 | static uint8_t recv_crc(void);
|
46 | static void start_SHT(void);
|
47 | uint8_t sht71_start_temp(void);
|
48 | uint8_t sht71_start_humid(void);
|
49 | uint8_t sht71_ready(void);
|
50 | static int16_t result(void);
|
51 |
|
52 | /* Private functions ---------------------------------------------------------*/
|
53 |
|
54 |
|
55 | void Delay(__IO uint32_t nCount) { while(nCount--) { } }
|
56 | void nop1(void){ Delay(5000L); }
|
57 |
|
58 | /**
|
59 | * @brief Main program
|
60 | * @param None
|
61 | * @retval None
|
62 | */
|
63 | int main(void) {
|
64 | float acttemp, acthum, humlin;
|
65 | int16_t mytemp;
|
66 | int16_t myhum;
|
67 | /* Setup of the I2C Interface to SHT71 Sensor */
|
68 | setup_I2C();
|
69 |
|
70 | /* Initialize LEDs mounted on STM32F4-Discovery board */
|
71 | STM_EVAL_LEDInit(LED3);
|
72 | STM_EVAL_LEDInit(LED4);
|
73 | STM_EVAL_LEDInit(LED5);
|
74 | STM_EVAL_LEDInit(LED6);
|
75 |
|
76 | /* Configure EXTI Line0 (connected to PA0 pin = Pushbutton) in interrupt mode */
|
77 | EXTILine0_Config();
|
78 |
|
79 | /* Generate software interrupt: simulate a rising edge applied on EXTI0 line */
|
80 | EXTI_GenerateSWInterrupt(EXTI_Line0);
|
81 |
|
82 |
|
83 |
|
84 | while (1) {
|
85 | /* Feuchte und Temperatur lesen */
|
86 | mytemp = read_SHT71(TMP_ADRESS);
|
87 |
|
88 | acttemp = 0.01 * mytemp - 39.6;
|
89 |
|
90 | myhum = read_SHT71(HUM_ADRESS);
|
91 |
|
92 | humlin = 0.0367 * myhum - 2.0468 - 0.0000015955*myhum*myhum;
|
93 | acthum = (acttemp-25)*(0.01+0.00008*myhum)+humlin;
|
94 | acthum = acthum + 1 -1; // Debugger zeigt Wert nur an, wenn er verwendet wird
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | /* lässt LEDs rotieren
|
100 | *
|
101 | * Dies soll Basis werden für Ampelsteuerung
|
102 | */
|
103 |
|
104 | /* Set Green LED */
|
105 | STM_EVAL_LEDOn(LED4);
|
106 | /* Reset Orange, Red, and Blue LED*/
|
107 | STM_EVAL_LEDOff(LED3);
|
108 | STM_EVAL_LEDOff(LED5);
|
109 | STM_EVAL_LEDOff(LED6);
|
110 | Delay(25000000L);
|
111 |
|
112 | /* Set Orange LED */
|
113 | STM_EVAL_LEDOn(LED3);
|
114 | /* Reset Green, Red, and Blue LED*/
|
115 | STM_EVAL_LEDOff(LED4);
|
116 | STM_EVAL_LEDOff(LED5);
|
117 | STM_EVAL_LEDOff(LED6);
|
118 | Delay(25000000L);
|
119 |
|
120 | /* Set Red LED */
|
121 | STM_EVAL_LEDOn(LED5);
|
122 | /* Reset Green, Orange, and Blue LED*/
|
123 | STM_EVAL_LEDOff(LED4);
|
124 | STM_EVAL_LEDOff(LED3);
|
125 | STM_EVAL_LEDOff(LED6);
|
126 | Delay(25000000L);
|
127 |
|
128 | /* Set Blue LED */
|
129 | STM_EVAL_LEDOn(LED6);
|
130 | /* Reset Green, Orange and Red LED*/
|
131 | STM_EVAL_LEDOff(LED4);
|
132 | STM_EVAL_LEDOff(LED3);
|
133 | STM_EVAL_LEDOff(LED5);
|
134 | Delay(25000000L);
|
135 | }
|
136 | }
|
137 |
|
138 | void setup_I2C(void)
|
139 | {
|
140 | /* GPIO Setup
|
141 | Initialise Pins PB6 and PB7*/
|
142 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
|
143 | GPIO_SHT.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
|
144 | GPIO_SHT.GPIO_Mode = GPIO_Mode_OUT;
|
145 | GPIO_SHT.GPIO_OType = GPIO_OType_OD;
|
146 | GPIO_SHT.GPIO_Speed = GPIO_Speed_2MHz;
|
147 | GPIO_SHT.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
148 | GPIO_Init(GPIOB, &GPIO_SHT);
|
149 |
|
150 | sda_hi(); scl_lo(); // Initial conditions
|
151 | }
|
152 |
|
153 | static void scl_pulse(void) { scl_hi(); nop1(); scl_lo();}
|
154 | static void scl_hi(void) { GPIO_SetBits(GPIOB, GPIO_Pin_6); }
|
155 | static void scl_lo(void) { GPIO_ResetBits(GPIOB, GPIO_Pin_6); }
|
156 | static void sda_hi(void) { GPIO_SetBits(GPIOB, GPIO_Pin_7); }
|
157 | static void sda_lo(void) { GPIO_ResetBits(GPIOB, GPIO_Pin_7); }
|
158 | static uint8_t sda_val(void) {
|
159 | uint8_t v = 0x00;
|
160 | if(SDA_read) {v|=0x01;}
|
161 | return v;
|
162 | }
|
163 |
|
164 | /* calculate CRC value*/
|
165 | static void crc8(uint8_t b) {
|
166 | for (i = 0; i < 8; ++i) {
|
167 | if ((crc_value ^ b) & 0x80) {
|
168 | crc_value <<= 1;
|
169 | crc_value ^= 0x31;
|
170 | }
|
171 | else crc_value <<= 1;
|
172 | b <<= 1;
|
173 | }
|
174 | }
|
175 |
|
176 | static uint8_t send(uint16_t b) {
|
177 | uint8_t ack;
|
178 | crc8(b);
|
179 | // data
|
180 | for (i = 0; i < 8; ++i) {
|
181 | if (b & 0x80) sda_hi();
|
182 | else sda_lo();
|
183 | b <<= 1;
|
184 | nop1();
|
185 | scl_pulse();
|
186 | }
|
187 |
|
188 | // read acknowledge (low)
|
189 | nop1();
|
190 | scl_hi(); nop1();
|
191 | ack = sda_val();
|
192 | scl_lo();
|
193 | return ack;
|
194 | }
|
195 |
|
196 | static uint8_t recv_data(void) {
|
197 | // data
|
198 | uint8_t b;
|
199 | b = 0;
|
200 | for (i = 0; i < 8; ++i) {
|
201 | // data is transmitted MSB first
|
202 | b <<= 1;
|
203 | if (sda_val()) b |= 1;
|
204 | scl_pulse();
|
205 | nop1();
|
206 | }
|
207 |
|
208 | // lo acknowledge
|
209 | sda_lo();
|
210 | nop1();
|
211 | scl_pulse();
|
212 | sda_hi();
|
213 | nop1();
|
214 |
|
215 | crc8(b);
|
216 | return b;
|
217 | }
|
218 |
|
219 | static uint8_t recv_crc(void) {
|
220 | // data
|
221 | uint8_t b;
|
222 | b = 0;
|
223 | for (i = 0; i < 8; ++i) {
|
224 | // CRC is transmitted LSB first
|
225 | b >>= 1;
|
226 | if (sda_val()) b |= 0x80;
|
227 | scl_pulse();
|
228 | nop1();
|
229 | }
|
230 |
|
231 | // hi acknowledge
|
232 | sda_hi();
|
233 | nop1();
|
234 | scl_pulse();
|
235 | nop1();
|
236 | return b;
|
237 | }
|
238 |
|
239 | static void start_SHT(void) {
|
240 | sda_hi(); scl_lo(); // Initial conditions
|
241 | crc_value = 0x00;
|
242 | nop1();
|
243 |
|
244 | // reset communication, 10 clock pulses
|
245 | for (i = 0; i < 10; ++i) { scl_pulse(); nop1(); }
|
246 |
|
247 | /* "Start" Sequence
|
248 | * __ __
|
249 | * SCL _/ \_/ \_
|
250 | * ___ ___
|
251 | * SDA \___/
|
252 | */
|
253 | scl_hi(); nop1(); sda_lo(); nop1();
|
254 | scl_lo(); nop1(); scl_hi(); nop1();
|
255 | sda_hi(); nop1(); scl_lo(); nop1();
|
256 | }
|
257 |
|
258 | uint8_t sht71_start_temp(void) { start_SHT(); return send(TMP_ADRESS) == 0; }
|
259 | uint8_t sht71_start_humid(void) { start_SHT(); return send(HUM_ADRESS) == 0; }
|
260 |
|
261 | static int16_t result(void) {
|
262 | int16_t v;
|
263 | uint8_t crc;
|
264 | // if (!sht71_ready()) return 0;
|
265 | // read senor data high byte, low byte
|
266 | v = recv_data() << 8; v |= recv_data();
|
267 | crc = recv_crc();
|
268 | if (crc != crc_value) return 0;
|
269 | return v;
|
270 | }
|
271 |
|
272 | int16_t read_SHT71(uint8_t adr) {
|
273 | int16_t data;
|
274 |
|
275 | // Start Transmission
|
276 | start_SHT();
|
277 |
|
278 | /* Send Adress
|
279 | * Temperature = 000 00011
|
280 | * Humidity = 000 00101
|
281 | */
|
282 | if (send(adr) != 0x00) return 0xFFFF;
|
283 | while(SDA_read) { }
|
284 | data = result();
|
285 | return data;
|
286 | }
|
287 |
|
288 | void EXTILine0_Config(void)
|
289 | {
|
290 |
|
291 | GPIO_InitTypeDef GPIO_InitStructure;
|
292 | NVIC_InitTypeDef NVIC_InitStructure;
|
293 |
|
294 | /* Enable GPIOA clock */
|
295 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
|
296 | /* Enable SYSCFG clock */
|
297 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
298 |
|
299 | /* Configure PA0 pin as input floating */
|
300 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
301 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
302 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
|
303 | GPIO_Init(GPIOA, &GPIO_InitStructure);
|
304 |
|
305 | /* Connect EXTI Line0 to PA0 pin */
|
306 | SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
|
307 |
|
308 | /* Configure EXTI Line0 */
|
309 | EXTI_InitStructure.EXTI_Line = EXTI_Line0;
|
310 | EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
311 | EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
312 | EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
313 | EXTI_Init(&EXTI_InitStructure);
|
314 |
|
315 | /* Enable and set EXTI Line0 Interrupt to the lowest priority */
|
316 | NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
|
317 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
|
318 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
|
319 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
320 | NVIC_Init(&NVIC_InitStructure);
|
321 | }
|
322 |
|
323 | /****END OF FILE****/
|