gpio
点亮第一个led灯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include "stm32f10x.h" #include "Delay.h"
int main(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); while(1) { GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET); Delay_ms(1000); GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); Delay_ms(1000); } }
|
流水灯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
#include "stm32f10x.h" #include "Delay.h"
int main(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); uint16_t turn_on = 0x0001; while(1) { for(int i = 0 ; i < 8; ++i) { GPIO_Write(GPIOA, ~turn_on); Delay_ms(100); turn_on = turn_on << 1; } turn_on = 0x0001; } }
|
蜂鸣器
A15,B3,B4是JTAG的调试端口,不便于用于普通的io口
给蜂鸣器输出低电平,就会响;输出高电平就不响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
#include "stm32f10x.h" #include "Delay.h"
int main(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); while(1) { GPIO_ResetBits(GPIOA, GPIO_Pin_0); Delay_ms(100); GPIO_SetBits(GPIOA, GPIO_Pin_0); Delay_ms(100); } }
|
按键控制led灯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
#include "stm32f10x.h" #include "Delay.h"
void init_led() { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); uint16_t led_pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = led_pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_SetBits(GPIOA, led_pin); }
void init_btn() { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); uint16_t led_pin = GPIO_Pin_1 | GPIO_Pin_11; GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = led_pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct); }
uint8_t key_getNum() { uint8_t keyNum = 0; if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); Delay_ms(20); keyNum = 1; } else if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0) { Delay_ms(20); while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0); Delay_ms(20); keyNum = 2; } return keyNum; }
void led1_turn() { if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0) { GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET); } else{ GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET); } }
void led2_turn() { if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0) { GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET); } else{ GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET); } }
int main(void) { init_led(); init_btn(); uint8_t keyNum = 0; while(1) { keyNum = key_getNum(); if(keyNum == 1) { led1_turn(); } if(keyNum == 2) { led2_turn(); } } }
|
通过光敏电阻控制蜂鸣器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
#include "stm32f10x.h" #include "Delay.h"
void init_buzzer() { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); uint16_t led_pin = GPIO_Pin_12; GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = led_pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct); }
void init_lightSensor() { RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); uint16_t led_pin = GPIO_Pin_13; GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = led_pin; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct); }
void buzzer_on() { GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET); }
void buzzer_off() { GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET); }
int main(void) { init_buzzer(); init_lightSensor(); while(1) { if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) == 0) { buzzer_on(); } else { buzzer_off(); } }
}
|
中断
对射式红外传感器计次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
#include "stm32f10x.h" #include "Delay.h" #include "OLED.h"
uint32_t CountSensor = 0;
void CountSensor_Init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14); EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line14; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStruct); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct); }
void EXTI15_10_IRQHandler() { if( EXTI_GetITStatus(EXTI_Line14) == SET) { if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0) { ++CountSensor; } EXTI_ClearITPendingBit(EXTI_Line14); } }
uint32_t CountSensor_Get() { return CountSensor; }
int main(void) { CountSensor_Init(); OLED_Init(); OLED_ShowString(1,1,"count:"); while(1) { OLED_ShowNum(1,7,CountSensor_Get(),5); }
}
|
旋转编码器计次
B0和B1的相位相差90°,以此来判断正反转,判断方式如下。在代码中如中断函数内所示。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#include "stm32f10x.h" #include "Delay.h" #include "OLED.h"
uint32_t CountSensor = 0;
void Encoder_Init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line0 | EXTI_Line1; EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Init(&EXTI_InitStruct); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; NVIC_Init(&NVIC_InitStruct); }
uint16_t Encoder_Count = 0; void EXTI0_IRQHandler() { if( EXTI_GetITStatus(EXTI_Line0) == SET) {
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Encoder_Count--; }
EXTI_ClearITPendingBit(EXTI_Line0); } }
void EXTI1_IRQHandler() { if(EXTI_GetITStatus(EXTI_Line1) == SET) {
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { Encoder_Count++; }
EXTI_ClearITPendingBit(EXTI_Line1); } }
uint16_t Encoder_Get() { int16_t tmp = 0; tmp = Encoder_Count; Encoder_Count = 0; return tmp; }
int main(void) { Encoder_Init(); OLED_Init(); OLED_ShowString(1,1,"num:"); int16_t num; while(1) { num += Encoder_Get(); OLED_ShowSignedNum(1,5,num,5); }
}
|
TIM定时器
定时器定时中断
初始化流程

定时器的选择

TIM_Period 和 TIM_Prescaler 的计算
参考STM32学习笔记——TIM_Period 和 TIM_Prescaler_stm32period怎么设置?-CSDN博客
概念
TIM_TimeBaseStructure.TIM_Period 和 TIM_TimeBaseStructure.TIM_Prescaler 是STM32定时器(Timer)的两个重要参数。
- TIM_Period:这个参数代表的是定时器的自动重装载值(Auto-reload value)。当定时器的计数值达到这个值时,定时器就会产生一个中断或更新事件。这个参数可以用来控制定时器中断的间隔时间。
**例如,如果设置TIM\_Period为7199,那么定时器每计数7199次就会产生一个中断。**
- TIM_Prescaler:这个参数代表的是定时器的预分频值(Prescaler value)。它决定了定时器的时钟频率被分频的倍数。这可以用来控制定时器的分辨率和计数速度。通过调整TIM_Prescaler的值,可以实现对定时器行为的精细控制。
**例如,如果设置TIM\_Prescaler为9,那么定时器的时钟频率将被除以9,从而降低定时器的计数速度。**
这两个参数共同决定了定时器的中断间隔时间。在STM32的TIM2中,可以通过设置这两个参数来实现在特定的时间间隔产生中断的功能。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
TIM_Prescaler=7200-1;
TIM_Period=20000-1;
|
总结:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| 定时器中断时间(s) = (TIM_Prescaler + 1)* (TIM_Period +1) / 时钟频率
定时器中断时间(ms)=(TIM_Prescaler + 1)* (TIM_Period +1) * 1000 / 时钟频率
```c
#include "stm32f10x.h" #include "OLED.h" #include "Delay.h"
uint16_t num = 0;
void Time_Init() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1; TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1; TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void TIM2_IRQHandler() { if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { num++; TIM_ClearITPendingBit(TIM2, TIM_IT_Update); }
}
int main() { Time_Init(); OLED_Init();
while(1) { OLED_ShowNum(1,1,num,5); OLED_ShowNum(2,1,TIM_GetCounter(TIM2),5); } }
|
外部触发中断
TIM_ETRClockMode2Config()
最后一个参数——采样滤波器的配置

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| #include "stm32f10x.h" #include "OLED.h" #include "Delay.h"
void Timer_Init() { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = 10 - 1; TIM_TimeBaseInitStruct.TIM_Prescaler = 2 - 1; TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); TIM_ClearFlag(TIM2, TIM_FLAG_Update); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); }
uint16_t Num;
void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { Num ++; TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } }
uint16_t Timer_GetCounter(void) { return TIM_GetCounter(TIM2); }
int main(void) { OLED_Init(); Timer_Init(); OLED_ShowString(1, 1, "Num:"); OLED_ShowString(2, 1, "CNT:"); while (1) { OLED_ShowNum(1, 5, Num, 5); OLED_ShowNum(2, 5, Timer_GetCounter(), 5); } }
|
输出比较波形——输出pwm波形