MyLibs 1.0
Расширенные библиотеки для STM32
Loading...
Searching...
No Matches
general_gpio.c
Go to the documentation of this file.
1/**
2**************************************************************************
3* @file general_gpio.c
4* @brief Модуль для инициализации портов и работы с ними.
5**************************************************************************
6* @details
7Реализация функций для работы с GPIO:
8 - Включение тактирования портов
9 - Инициализация светодиодов и кнопок
10 - Управление светодиодами: включение, выключение, моргание, плавное затухание
11 - Чтение состояния кнопок с фильтром от дребезга
12***************************************************************************/
13#include "general_gpio.h"
14
15//-------------------------------------------------------------------
16//------------------------GPIO INIT FUNCTIONS------------------------
17
18
19/**
20 * @brief Включить тактирование порта GPIO
21 */
22HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
23{
24 if(check_null_ptr_1(GPIOx))
25 return HAL_ERROR;
26
27 HAL_StatusTypeDef status = HAL_OK;
28 // choose port for enable clock
29 if (GPIOx==GPIOA)
30 __HAL_RCC_GPIOA_CLK_ENABLE();
31 else if (GPIOx==GPIOB)
32 __HAL_RCC_GPIOB_CLK_ENABLE();
33#ifdef GPIOC
34 else if (GPIOx==GPIOC)
35 __HAL_RCC_GPIOC_CLK_ENABLE();
36#endif
37#ifdef GPIOD
38 else if (GPIOx==GPIOD)
39 __HAL_RCC_GPIOD_CLK_ENABLE();
40#endif
41#ifdef GPIOE
42 else if (GPIOx==GPIOE)
43 __HAL_RCC_GPIOE_CLK_ENABLE();
44#endif
45#ifdef GPIOF
46 else if (GPIOx==GPIOF)
47 __HAL_RCC_GPIOF_CLK_ENABLE();
48#endif
49#ifdef GPIOH
50 else if (GPIOx==GPIOF)
51 __HAL_RCC_GPIOH_CLK_ENABLE();
52#endif
53 else
54 status = HAL_ERROR;
55
56 return status;
57}
58
59//------------------------GPIO INIT FUNCTIONS------------------------
60//-------------------------------------------------------------------
61
62
63//-------------------------------------------------------------------
64//------------------------GPIO LED FUNCTIONS-------------------------
65
66/**
67 * @brief Инициализировать светодиод (структуру светодиода)
68 * @param led Указатель на структуру светодиода
69 * @param GPIOx Указатель на структуру порта для светодиода
70 * @param GPIO_PIN_X Пин для светодиода
71 * @param LED_ActiveLevel Состояния пина, при котором светодиод будет включен
72 */
73HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_ActiveLevel)
74{
75 if(check_null_ptr_3(led, GPIOx, GPIO_PIN_X))
76 return HAL_ERROR;
77
78 led->LED_Port = GPIOx;
79 led->LED_Pin = GPIO_PIN_X;
80 led->LED_ActiveLvl = LED_ActiveLevel;
81
82 GPIO_LED_Off(led);
83 return HAL_OK;
84}
85
86/**
87 * @brief Включить светодиод
88 * @param led Указатель на структуру светодиода
89 * @return HAL Status
90 */
91HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led)
92{
93 if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
94 return HAL_ERROR;
95
96 led->state = LED_IS_ON;
97 HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
98
99
100 return HAL_OK;
101}
102/**
103 * @brief Выключить светодиод
104 * @param led Указатель на структуру светодиода
105 * @return HAL Status
106 */
107HAL_StatusTypeDef GPIO_LED_Off(GPIO_LEDTypeDef *led)
108{
109 if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
110 return HAL_ERROR;
111
112 led->state = LED_IS_OFF;
113 HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
114
115
116
117 return HAL_OK;
118}
119/**
120 * @brief Выставить светодиод по переменной
121 * @param led Указатель на структуру светодиода
122 * @param led_state Состояние светодиода
123 * @return HAL Status
124 */
125HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state)
126{
127 if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
128 return HAL_ERROR;
129
130 if(led_state)
131 {
132 return GPIO_LED_On(led);
133 }
134 else
135 {
136 return GPIO_LED_Off(led);
137 }
138}
139/**
140 * @brief Активировать моргание светодиодом
141 * @param led Указатель на структуру светодиода
142 * @param period Период плавного моргания светодиода
143 * @return HAL Status
144 * @details Функция ставит режим моргания, который после управляется в @ref GPIO_LED_Dynamic_Handle
145 */
146HAL_StatusTypeDef GPIO_LED_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period)
147{
148 if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
149 return HAL_ERROR;
150
151 led->state = LED_IS_BLINKING;
152 led->LED_Period = period;
153
154 return HAL_OK;
155}
156
157/**
158 * @brief Активировать моргание светодиодом
159 * @param led Указатель на структуру светодиода
160 * @param period Период плавного моргания светодиода
161 * @return HAL Status
162 * @details Функция ставит режим моргания, который после управляется в @ref GPIO_LED_Dynamic_Handle
163 */
164HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period)
165{
166 if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
167 return HAL_ERROR;
168
169 led->state = LED_IS_FADING;
170 led->LED_Period = period;
171
172
173 return HAL_OK;
174}
175
176//uint8_t LED_PWM_FADING_DUTYS[LED_PWM_TICKS] = {0 1 2 3 4 5 6 7 8 9 10 11 12 }
177/**
178 * @brief Управление динамическими режимами свечения светодиода
179 * @param Указатель на структуру светодиода
180 * @details Функция моргает/плавно моргает светодиодом в неблокирующем режиме
181 * Т.е. функцию надо вызывать постоянно, чтобы она мониторила тики
182 * и в нужный момент переключала светодиод
183 */
185{
186 if(check_null_ptr_3(led, led->LED_Port, led->LED_Pin))
187 return;
188
189 /* Режим моргания светодиода */
190 if(led->state == LED_IS_BLINKING)
191 {
192 uint32_t tickcurrent = local_time();
193 /* Ожидание истечения периода моргания */
194 if((tickcurrent - led->tickprev) > led->LED_Period)
195 {
196 /* Моргание */
197 HAL_GPIO_TogglePin(led->LED_Port, led->LED_Pin);
198
199 led->tickprev = tickcurrent;
200 }
201 }
202 /* Режим плавного моргания светодиода */
203 else if(led->state == LED_IS_FADING)
204 {
205 static unsigned direction = 0;
206 static int duty = 0;
207 uint32_t tickcurrent = local_time();
208 /* Ожидание момента изменения яркости */
209 /* Период ШИМ 20 мс, поэтому менять яроксть надо 40 раз за период (туда обратно) */
210 if((tickcurrent - led->tickprev) > led->LED_Period/(LED_PWM_TICKS*2))
211 {
212 /* Формирование разтухания */
213 if(direction == 0)
214 {
215 if(++duty >= LED_PWM_TICKS)
216 {
217 direction = 1;
218 duty = LED_PWM_TICKS;
219 }
220 }
221 /* Формирование затухания */
222 else
223 {
224 if(--duty <= 0)
225 {
226 direction = 0;
227 duty = 0;
228 }
229 }
230 led->tickprev = tickcurrent;
231 }
232 /* Формирование ШИМ для изменения яркости */
233 int duty_crt = (duty*duty/LED_PWM_TICKS);
234 if(tickcurrent%LED_PWM_TICKS < duty_crt)
235 {
236 HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, led->LED_ActiveLvl);
237 }
238 else
239 {
240 HAL_GPIO_WritePin(led->LED_Port, led->LED_Pin, !led->LED_ActiveLvl);
241 }
242 }
243}
244//------------------------GPIO LED FUNCTIONS-------------------------
245//-------------------------------------------------------------------
246
247//-------------------------------------------------------------------
248//------------------------GPIO SW FUNCTIONS-------------------------
249
250/**
251* @brief Инициализировать кнопку (структуру кнопки)
252 * @param sw Указатель на структуру кнопки
253 * @param GPIOx Указатель на структуру порта для кнопки
254 * @param GPIO_PIN_X Пин для кнопки
255 * @param SW_ActiveLevel Состояния пина, когда кнопка нажата
256 * @return HAL Status
257 */
258HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_ActiveLevel)
259{
260 if(check_null_ptr_3(sw, GPIOx, GPIO_PIN_X))
261 return HAL_ERROR;
262
263 sw->Sw_Port = GPIOx;
264 sw->Sw_Pin = GPIO_PIN_X;
265 sw->Sw_ActiveLvl = SW_ActiveLevel;
266 return HAL_OK;
267}
268
269/**
270 * @brief Считать состоянии кнопки
271 * @param sw Указатель на структуру кнопки
272 * @return 1 - если кнопка нажата,
273 * 0 - если отжата,
274 * -1 - если ошибка
275 * @details Функция включает в себя неблокирующую проверку на дребезг
276 * Т.е. функцию надо вызывать постоянно, чтобы она мониторила состояние кнопки
277 */
279{
280 if(check_null_ptr_3(sw, sw->Sw_Port, sw->Sw_Pin))
281 return -1;
282
283 if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
284 {
285 sw->Sw_PrevState = 1;
286
287
288 if(sw->Sw_FilterDelay) // если включена защита от дребезга
289 {
290 if(sw->tickprev == 0)
291 sw->tickprev = local_time();
292
293 if((local_time() - sw->tickprev) >= sw->Sw_FilterDelay)
294 {
295 if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
296 {
297 return 1;
298 }
299 else
300 {
301 sw->tickprev = 0;
302 return 0;
303 }
304 }
305 }
306 else // если нет защиты от дребезга
307 {
308 if(HAL_GPIO_ReadPin(sw->Sw_Port, sw->Sw_Pin) == sw->Sw_ActiveLvl)
309 {
310 return 1;
311 }
312 else
313 {
314 sw->tickprev = 0;
315 return 0;
316 }
317 }
318 }
319 else
320 {
321 sw->Sw_PrevState = 0;
322 }
323 return 0;
324}
325//------------------------GPIO SW FUNCTIONS-------------------------
326//-------------------------------------------------------------------
Заголовочный файл для модуля инициализации портов и работы с ними.
#define check_null_ptr_1(p1)
Проверить один указатель на NULL.
Definition mylibs_defs.h:38
#define check_null_ptr_3(p1, p2, p3)
Проверить три указателя на NULL.
Definition mylibs_defs.h:44
#define LED_PWM_TICKS
Количество тиков в периоде ШИМ
#define local_time()
Локальное время
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
Включить тактирование порта GPIO.
HAL_StatusTypeDef GPIO_LED_On(GPIO_LEDTypeDef *led)
Включить светодиод
HAL_StatusTypeDef GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period)
Активировать моргание светодиодом
HAL_StatusTypeDef GPIO_LED_Off(GPIO_LEDTypeDef *led)
Выключить светодиод
HAL_StatusTypeDef GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t LED_ActiveLevel)
Инициализировать светодиод (структуру светодиода)
void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led)
Управление динамическими режимами свечения светодиода
HAL_StatusTypeDef GPIO_LED_Set(GPIO_LEDTypeDef *led, uint8_t led_state)
Выставить светодиод по переменной
HAL_StatusTypeDef GPIO_LED_Blink_Start(GPIO_LEDTypeDef *led, uint32_t period)
Активировать моргание светодиодом
@ LED_IS_BLINKING
Моргание светодиодом
@ LED_IS_OFF
Светодиод выключен
@ LED_IS_FADING
Плавное моргание светодиодом
@ LED_IS_ON
Светодиод включен
int GPIO_Read_Switch(GPIO_SwitchTypeDef *sw)
Считать состоянии кнопки
HAL_StatusTypeDef GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, uint8_t SW_ActiveLevel)
Инициализировать кнопку (структуру кнопки)
Структура светодиода
uint32_t LED_Pin
GPIO пин ножки светодиода
uint32_t LED_Period
Период моргания светодиода
GPIO_TypeDef * LED_Port
GPIO порт ножки светодиода
uint8_t LED_ActiveLvl
Активный уровень ножки (при котором светодиод горит)
GPIO_LEDStateTypeDef state
Текущий режим работы светодиода
Структура кнопки
uint32_t Sw_PrevState
Предыдущее состояние кнопки
uint32_t Sw_FilterDelay
Фильтр от дребезга (в мс)
uint8_t Sw_ActiveLvl
Активный уровень ножки (при котором кнопка нажата)
uint32_t Sw_Pin
GPIO пин ножки кнопки
GPIO_TypeDef * Sw_Port
GPIO порт ножки кнопки