1 | #include "temp.h"
|
---|
2 | #include "cmsis_os.h"
|
---|
3 | #include "log_and_debug.h"
|
---|
4 | #include <stdio.h>
|
---|
5 |
|
---|
6 | #define F_CODE_DS18S20 0x10
|
---|
7 | #define F_CODE_DS18B20 0x28
|
---|
8 |
|
---|
9 | void vSensorTempTask(void *param);
|
---|
10 |
|
---|
11 | struct {
|
---|
12 | TaskHandle_t handler;
|
---|
13 | uint16_t value;
|
---|
14 | }timer_struct = {0};
|
---|
15 |
|
---|
16 | sensor_temp_typeDef Sensor_Temperature;
|
---|
17 |
|
---|
18 | TaskHandle_t Sensor_tempHandler;
|
---|
19 | GPIO_InitTypeDef GPIO_Sensor_Temp = {0};
|
---|
20 |
|
---|
21 | void temp_sensor_init(void)
|
---|
22 | {
|
---|
23 | __HAL_RCC_TIM7_CLK_ENABLE();
|
---|
24 |
|
---|
25 | TIM7->SR = 0;
|
---|
26 | TIM7->PSC = 83;
|
---|
27 | TIM7->ARR = 1;
|
---|
28 | TIM7->DIER |= TIM_DIER_UIE;
|
---|
29 |
|
---|
30 | NVIC_SetPriority(TIM7_IRQn, 5);
|
---|
31 |
|
---|
32 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET);
|
---|
33 | GPIO_Sensor_Temp.Pin = TEMP_Pin;
|
---|
34 | GPIO_Sensor_Temp.Pull = GPIO_NOPULL;
|
---|
35 | GPIO_Sensor_Temp.Mode = GPIO_MODE_OUTPUT_OD;
|
---|
36 | GPIO_Sensor_Temp.Speed = GPIO_SPEED_FREQ_HIGH;
|
---|
37 | HAL_GPIO_Init(TEMP_GPIO_Port, &GPIO_Sensor_Temp);
|
---|
38 |
|
---|
39 | xTaskCreate(vSensorTempTask, "SensorTempTask", 256, NULL, osPriorityNormal, &Sensor_tempHandler); // priority: above normal
|
---|
40 | }
|
---|
41 |
|
---|
42 | void _delay_us(uint16_t delay)
|
---|
43 | {
|
---|
44 | timer_struct.handler = xTaskGetCurrentTaskHandle();
|
---|
45 | timer_struct.value = delay;
|
---|
46 | ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
---|
47 | }
|
---|
48 |
|
---|
49 | void _Sensor_transmit(uint8_t *data, uint8_t size)
|
---|
50 | {
|
---|
51 | uint8_t byte = 0;
|
---|
52 | for(uint8_t i = 0; i < size; i++){
|
---|
53 | byte = data[i];
|
---|
54 | for(uint8_t q = 0; q < 8; q++){
|
---|
55 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_RESET);
|
---|
56 | _delay_us(2);
|
---|
57 | if(byte & 0x01) HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET);
|
---|
58 | _delay_us(58);
|
---|
59 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET);
|
---|
60 | _delay_us(2);
|
---|
61 | byte >>= 1;
|
---|
62 | }
|
---|
63 | }
|
---|
64 | }
|
---|
65 |
|
---|
66 | void _Sensor_receive(uint8_t* pData, uint8_t size)
|
---|
67 | {
|
---|
68 | uint8_t byte = 0;
|
---|
69 | for(uint8_t i = 0; i < size; i++){
|
---|
70 | for(uint8_t q = 0; q < 8; q++){
|
---|
71 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_RESET);
|
---|
72 | _delay_us(2);
|
---|
73 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET);
|
---|
74 | _delay_us(10);
|
---|
75 | byte |= (HAL_GPIO_ReadPin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin) << 7);
|
---|
76 | if(q != 7)byte >>= 1;
|
---|
77 | _delay_us(60);
|
---|
78 | }
|
---|
79 | pData[i] = byte;
|
---|
80 | byte = 0;
|
---|
81 | }
|
---|
82 | }
|
---|
83 |
|
---|
84 | _Bool _Sensor_reset(void)
|
---|
85 | {
|
---|
86 | _Bool fl = 0;
|
---|
87 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_RESET);
|
---|
88 | _delay_us(480);
|
---|
89 | HAL_GPIO_WritePin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin, GPIO_PIN_SET);
|
---|
90 | _delay_us(65);
|
---|
91 | fl = !HAL_GPIO_ReadPin(TEMP_GPIO_Port, GPIO_Sensor_Temp.Pin);
|
---|
92 | _delay_us(410);
|
---|
93 | return fl;
|
---|
94 | }
|
---|
95 |
|
---|
96 | unsigned char iButtonCRC(uint8_t *code, uint8_t num)
|
---|
97 | {
|
---|
98 | unsigned char j, i, Data, tmp, crc = 0;
|
---|
99 | for (j = 0; j < num; j++){
|
---|
100 | Data = code[j];
|
---|
101 | for (i = 0; i < 8; i++){
|
---|
102 | tmp = 1 & (Data ^ crc);
|
---|
103 | crc >>= 1;
|
---|
104 | Data >>= 1;
|
---|
105 | if (0 != tmp ) crc ^= 0x8c;
|
---|
106 | }
|
---|
107 | }
|
---|
108 | return crc;
|
---|
109 | }
|
---|
110 |
|
---|
111 | void IRQ_Timer_1us(void)
|
---|
112 | {
|
---|
113 | BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
---|
114 |
|
---|
115 | if(timer_struct.handler != NULL){
|
---|
116 | if(timer_struct.value != 0) timer_struct.value--;
|
---|
117 | else {
|
---|
118 | vTaskNotifyGiveFromISR(timer_struct.handler, &xHigherPriorityTaskWoken);
|
---|
119 | timer_struct.handler = NULL;
|
---|
120 | }
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | void _Timer_1us_Start(void)
|
---|
125 | {
|
---|
126 | TIM7->SR = 0;
|
---|
127 | TIM7->CNT = 0;
|
---|
128 | TIM7->CR1 |= TIM_CR1_CEN;
|
---|
129 | NVIC_ClearPendingIRQ(TIM7_IRQn);
|
---|
130 | NVIC_EnableIRQ(TIM7_IRQn);
|
---|
131 | }
|
---|
132 |
|
---|
133 | void _Timer_1us_Stop(void)
|
---|
134 | {
|
---|
135 | TIM7->CR1 &= ~TIM_CR1_CEN;
|
---|
136 | NVIC_DisableIRQ(TIM7_IRQn);
|
---|
137 | }
|
---|
138 |
|
---|
139 | void vSensorTempTask(void *param)
|
---|
140 | {
|
---|
141 | osDelay(15000); // æäåì ñîçäàíèå ïðîöåññîâ, äëÿ ïðàâèëüíûé çàäåðæåê òàéìåðà
|
---|
142 |
|
---|
143 | enum {
|
---|
144 | STATE_RESET,
|
---|
145 | STATE_READ_ROM,
|
---|
146 | STATE_SKIP_ROM,
|
---|
147 | STATE_TEMP_CONVERT,
|
---|
148 | STATE_READ_TEMP
|
---|
149 | }Sensor_State = STATE_RESET;
|
---|
150 |
|
---|
151 | struct {
|
---|
152 | _Bool wait_convert: 1;
|
---|
153 | _Bool rom_OK: 1;
|
---|
154 | }SensorFlags;
|
---|
155 |
|
---|
156 | char sBuffer[64] = {0};
|
---|
157 | uint8_t ROM[8] = {0}, sBuffCnt = 0, Sensor_Buffer[16] = {0};
|
---|
158 | uint8_t DS_family_code = 0;
|
---|
159 |
|
---|
160 | for(;;){
|
---|
161 | switch(Sensor_State){
|
---|
162 | case STATE_RESET: // ðåñåò
|
---|
163 | _Timer_1us_Start();
|
---|
164 | Sensor_Temperature.presence = _Sensor_reset();
|
---|
165 | if(Sensor_Temperature.presence){
|
---|
166 | if(!SensorFlags.rom_OK)Sensor_State = STATE_READ_ROM;
|
---|
167 | else Sensor_State = STATE_SKIP_ROM;
|
---|
168 | }
|
---|
169 | else {
|
---|
170 | _Timer_1us_Stop();
|
---|
171 | SensorFlags.rom_OK = 0;
|
---|
172 | SensorFlags.wait_convert = 0;
|
---|
173 | osDelay(30000); // æäåì 30 ñåêóíä è ïðîâåðÿåì ïðèñóòñòâèå äàèò÷èêà
|
---|
174 | }
|
---|
175 | break;
|
---|
176 | case STATE_READ_ROM:
|
---|
177 | Sensor_Buffer[0] = 0x33;
|
---|
178 | _Sensor_transmit(Sensor_Buffer, 1);
|
---|
179 | _Sensor_receive(ROM, 8);
|
---|
180 | if(ROM[7] == iButtonCRC(ROM, 7)){
|
---|
181 | DS_family_code = ROM[0]; // çàïîìèíàåì êàêîé äàò÷èê óñòàíîâëåí
|
---|
182 | for(uint16_t i = 1; i < 7; i++)sBuffCnt += sprintf(&sBuffer[sBuffCnt], "%02X", ROM[i]);
|
---|
183 | __debug(DEBUG_TEMP, "DS1820: Family code: %02X, serial number: %s\r\n", DS_family_code, sBuffer);
|
---|
184 | SensorFlags.rom_OK = 1;
|
---|
185 | }
|
---|
186 | else {
|
---|
187 | _Timer_1us_Stop();
|
---|
188 | __debug(DEBUG_TEMP, "DS1820: ROM error CRC.\r\n");
|
---|
189 | osDelay(10000);
|
---|
190 | }
|
---|
191 | Sensor_State = STATE_RESET;
|
---|
192 | break;
|
---|
193 | case STATE_SKIP_ROM: // ïðîïóñê ROM êîäà
|
---|
194 | Sensor_Buffer[0] = 0xCC;
|
---|
195 | _Sensor_transmit(Sensor_Buffer, 1);
|
---|
196 | if(!SensorFlags.wait_convert)Sensor_State = STATE_TEMP_CONVERT;
|
---|
197 | else Sensor_State = STATE_READ_TEMP;
|
---|
198 | break;
|
---|
199 | case STATE_TEMP_CONVERT: // Êîíâåðòàöèÿ òåìïåðàòóðû
|
---|
200 | Sensor_Buffer[0] = 0x44;
|
---|
201 | _Sensor_transmit(Sensor_Buffer, 1); // Convert T
|
---|
202 | _Timer_1us_Stop();
|
---|
203 | SensorFlags.wait_convert = 1;
|
---|
204 | Sensor_State = STATE_RESET;
|
---|
205 | osDelay(1000);
|
---|
206 | break;
|
---|
207 | case STATE_READ_TEMP: // ×òåíèå òåìïåðàòóðû
|
---|
208 | Sensor_Buffer[0] = 0xBE;
|
---|
209 | _Sensor_transmit(Sensor_Buffer, 1); // Read Scratchpad
|
---|
210 | _Sensor_receive(Sensor_Buffer, 9);
|
---|
211 | _Timer_1us_Stop();
|
---|
212 | if (Sensor_Buffer[8] == (uint8_t)iButtonCRC(Sensor_Buffer, 8)){
|
---|
213 | switch(DS_family_code){
|
---|
214 | case F_CODE_DS18S20:
|
---|
215 | Sensor_Temperature.sign = Sensor_Buffer[1];
|
---|
216 | if((Sensor_Buffer[0] & 0x01) == 0x01) Sensor_Temperature.share = 5;
|
---|
217 | else Sensor_Temperature.share = 0;
|
---|
218 | if(Sensor_Temperature.sign)Sensor_Temperature.info = ((Sensor_Buffer[0] ^ 0xFF) + 1) >> 1; // îòðèöàòåëüíàÿ
|
---|
219 | else Sensor_Temperature.info = Sensor_Buffer[0] >> 1;
|
---|
220 | break;
|
---|
221 | case F_CODE_DS18B20:
|
---|
222 | if((Sensor_Buffer[0] & 0x0F) == 0x08) Sensor_Temperature.share = 5;
|
---|
223 | else Sensor_Temperature.share = 0;
|
---|
224 | Sensor_Temperature.sign = Sensor_Buffer[1] >> 3;
|
---|
225 | Sensor_Temperature.info = Sensor_Buffer[0] >> 4;
|
---|
226 | Sensor_Temperature.info |= (Sensor_Buffer[1] << 4);
|
---|
227 | if(Sensor_Temperature.sign) Sensor_Temperature.info ^= 0xFF;
|
---|
228 | Sensor_Temperature.info &= ~0x80;
|
---|
229 | break;
|
---|
230 | }
|
---|
231 | __debug(DEBUG_TEMP, "DS1820: Temperature %c%d.%d C\r\n", Sensor_Temperature.sign ? '-' : ' ', Sensor_Temperature.info, Sensor_Temperature.share);
|
---|
232 | osDelay(60000);
|
---|
233 | }
|
---|
234 | else {
|
---|
235 | __debug(DEBUG_TEMP, "DS1820: Temperature CRC error.\r\n");
|
---|
236 | osDelay(1000);
|
---|
237 | }
|
---|
238 | Sensor_State = STATE_RESET;
|
---|
239 | SensorFlags.wait_convert = 0;
|
---|
240 | break;
|
---|
241 | }
|
---|
242 | }
|
---|
243 | }
|
---|