当前位置:   article > 正文

STM32 1-5

STM32 1-5

目录

STM32简介

点亮PC13LED

 GPIO

LED闪烁

LED流水灯

按键控制LED

光敏传感器控制蜂鸣器

OLED调试工具

OLED显示

EXTI外部中断

对射式红外传感器计次

旋转编码器计次


继续

STM32简介

点亮PC13LED

main.c

  1. #include "stm32f10x.h" // Device header
  2. int main(void)
  3. {
  4. //方式二:
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  6. //配置GPIOC的时钟
  7. GPIO_InitTypeDef GPIO_InitStructure;//配置结构体
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置通用推挽输出
  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;//配置13针脚
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//配置速度
  11. GPIO_Init(GPIOC, &GPIO_InitStructure);
  12. //配置端口模式
  13. GPIO_SetBits(GPIOC, GPIO_Pin_13);//将其置为高电平
  14. //GPIO_ResetBits(GPIOC, GPIO_Pin_13);//将其置为低电平
  15. //配置高低电平
  16. /*****************************************/
  17. //方式一:
  18. //PC13有一个灯,这个灯低电平才会亮
  19. //RCC ->APB2ENR = 0x00000010;//GPIO都是APB2的外设,APB2ENR是
  20. //APB2时钟使能寄存器,IOPCEN为使能位,将其设置为1,打开时钟
  21. //GPIOC ->CRH = 0x00300000;//配置PC13口模式,端口配置高寄存器
  22. //(GPIOx_CRH),配置CNF13以及MODE13,
  23. //GPIOC ->ODR = 0x00002000;//端口输出数据寄存器GPIOx_ODR,
  24. //为ODR13进行配置高低电平,0x00002000灭,0x00000000亮
  25. while(1)
  26. {
  27. }
  28. }

 GPIO

面包板两端横向是相通的,内部是纵向相通

LED闪烁

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. int main(void)
  4. {
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  6. //第一步:使用RCC开启GPIO时钟
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOA,&GPIO_InitStructure);
  12. //第二步:使用GPIO_Init()初始化GPIO
  13. //GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灯亮
  14. //GPIO_SetBits(GPIOA,GPIO_Pin_0);//灯灭
  15. //GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//灯亮
  16. //GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);//灯灭
  17. //第三步:使用输出或者输入的函数控制GPIO口
  18. while(1)
  19. {
  20. GPIO_ResetBits(GPIOA,GPIO_Pin_0);
  21. Delay_ms(100);
  22. GPIO_SetBits(GPIOA,GPIO_Pin_0);
  23. Delay_ms(100);
  24. GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);
  25. Delay_ms(500);
  26. GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);
  27. Delay_ms(500);
  28. GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);
  29. Delay_ms(500);
  30. GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);
  31. Delay_ms(500);
  32. }
  33. }
LED流水灯

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. int main(void)
  4. {
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  6. //第一步:使用RCC开启GPIO时钟
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;//初始化所有端口
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOA,&GPIO_InitStructure);
  12. //第二步:使用GPIO_Init()初始化GPIO
  13. //GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灯亮
  14. //GPIO_SetBits(GPIOA,GPIO_Pin_0);//灯灭
  15. //GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//灯亮
  16. //GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);//灯灭
  17. //第三步:使用输出或者输入的函数控制GPIO口
  18. while(1)
  19. {
  20. // GPIO_Write(GPIOA,~0x0001);
  21. // Delay_ms(500);
  22. // GPIO_Write(GPIOA,~0x0002);
  23. // Delay_ms(500);
  24. // GPIO_Write(GPIOA,~0x0004);
  25. // Delay_ms(500);
  26. // GPIO_Write(GPIOA,~0x0008);
  27. // Delay_ms(500);
  28. // GPIO_Write(GPIOA,~0x0010);
  29. // Delay_ms(500);
  30. // GPIO_Write(GPIOA,~0x0020);
  31. // Delay_ms(500);
  32. // GPIO_Write(GPIOA,~0x0040);
  33. // Delay_ms(500);
  34. // GPIO_Write(GPIOA,~0x0080);
  35. // Delay_ms(500);
  36. unsigned char i ;
  37. for( i = 0 ; i < 8 ;i++)
  38. {
  39. GPIO_Write(GPIOA,~(0x0001 << i));
  40. Delay_ms(500);
  41. }
  42. }
  43. }

蜂鸣器

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. int main(void)
  4. {
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  6. //第一步:使用RCC开启GPIO时钟
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//初始化12端口
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOB,&GPIO_InitStructure);
  12. //第二步:使用GPIO_Init()初始化GPIO
  13. //GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灯亮
  14. //GPIO_SetBits(GPIOA,GPIO_Pin_0);//灯灭
  15. //GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//灯亮
  16. //GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);//灯灭
  17. //第三步:使用输出或者输入的函数控制GPIO口
  18. while(1)
  19. {
  20. GPIO_ResetBits(GPIOB,GPIO_Pin_12);
  21. Delay_ms(100);
  22. GPIO_SetBits(GPIOB,GPIO_Pin_12);
  23. Delay_ms(100);
  24. GPIO_ResetBits(GPIOB,GPIO_Pin_12);
  25. Delay_ms(100);
  26. GPIO_SetBits(GPIOB,GPIO_Pin_12);
  27. Delay_ms(700);
  28. }
  29. }

 

按键控制LED

key.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. /**
  4. * @brief 初始化位于PB1以及PB11按键
  5. * @param 无
  6. * @retval 无
  7. */
  8. void Key_Init(void)//配置按键
  9. {
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  11. GPIO_InitTypeDef GPIO_InitStructure;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//需要读取按键,设置上拉输入
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//输出速度,输入不影响
  15. GPIO_Init(GPIOB,&GPIO_InitStructure);
  16. }
  17. /**
  18. * @brief 获取所按下的键值
  19. * @param 无
  20. * @retval KeyNum 按下的键值
  21. */
  22. uint8_t Key_GetNum(void)
  23. {
  24. uint8_t KeyNum = 0;
  25. if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
  26. {
  27. Delay_ms(20);
  28. while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
  29. //此时处于一直按下的状态
  30. Delay_ms(20);
  31. KeyNum = 1;
  32. }
  33. if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
  34. {
  35. Delay_ms(20);
  36. while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
  37. //此时处于一直按下的状态
  38. Delay_ms(20);
  39. KeyNum = 2;
  40. }
  41. return KeyNum;
  42. }

LED.c

  1. #include "stm32f10x.h" // Device header
  2. /**
  3. * @brief 打开GPIO时钟,并进行初始化
  4. * @param 无
  5. * @retval 无
  6. */
  7. void LED_Init(void)
  8. {
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  10. //第一步:使用RCC开启GPIO时钟
  11. GPIO_InitTypeDef GPIO_InitStructure;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(GPIOA,&GPIO_InitStructure);
  16. //第二步:使用GPIO_Init()初始化GPIO
  17. // GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
  18. }
  19. /**
  20. * @brief 将位于PA1端口电平置零
  21. * @param 无
  22. * @retval 无
  23. */
  24. void LED1_On(void)
  25. {
  26. GPIO_ResetBits(GPIOA,GPIO_Pin_1);
  27. }
  28. /**
  29. * @brief 将位于PA1端口电平置一
  30. * @param 无
  31. * @retval 无
  32. */
  33. void LED1_Off(void)
  34. {
  35. GPIO_SetBits(GPIOA,GPIO_Pin_1);
  36. }
  37. /**
  38. * @brief 查看PA1端口电平并将其翻转
  39. * @param 无
  40. * @retval 无
  41. */
  42. void LED1_Turn(void)
  43. {
  44. if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 0)//查看当前端口输出
  45. {
  46. GPIO_SetBits(GPIOA,GPIO_Pin_1);//将其置一
  47. }
  48. else
  49. {
  50. GPIO_ResetBits(GPIOA,GPIO_Pin_1);//将其置零
  51. }
  52. }
  53. /**
  54. * @brief 将位于PA2端口电平置零
  55. * @param 无
  56. * @retval 无
  57. */
  58. void LED2_On(void)
  59. {
  60. GPIO_ResetBits(GPIOA,GPIO_Pin_2);
  61. }
  62. /**
  63. * @brief 将位于PA1端口电平置一
  64. * @param 无
  65. * @retval 无
  66. */
  67. void LED2_Off(void)
  68. {
  69. GPIO_SetBits(GPIOA,GPIO_Pin_2);
  70. }
  71. /**
  72. * @brief 查看PA2端口电平并将其翻转
  73. * @param 无
  74. * @retval 无
  75. */
  76. void LED2_Turn(void)
  77. {
  78. if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) == 0)//查看当前端口输出
  79. {
  80. GPIO_SetBits(GPIOA,GPIO_Pin_2);//将其置一
  81. }
  82. else
  83. {
  84. GPIO_ResetBits(GPIOA,GPIO_Pin_2);//将其置零
  85. }
  86. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "LED.h"
  4. #include "Key.h"
  5. uint8_t KeyNum;
  6. int main(void)
  7. {
  8. LED_Init();
  9. Key_Init();
  10. while(1)
  11. {
  12. KeyNum = Key_GetNum();//获取键值
  13. if(KeyNum == 1)//如果键1按下,则翻转LED1电平
  14. {
  15. LED1_Turn();
  16. }
  17. if(KeyNum == 2)//如果键2按下,则翻转LED1电平
  18. {
  19. LED2_Turn();
  20. }
  21. }
  22. }
光敏传感器控制蜂鸣器

LightSensor.c

  1. #include "stm32f10x.h" // Device header
  2. /**
  3. * @brief 初始化端口在PB^13光敏传感器
  4. * @param 无
  5. * @retval 无
  6. */
  7. void LightSensor_Init(void)
  8. {
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  10. //第一步:使用RCC开启GPIO时钟
  11. GPIO_InitTypeDef GPIO_InitStructure;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(GPIOB,&GPIO_InitStructure);
  16. //第二步:使用GPIO_Init()初始化GPIO
  17. }
  18. /**
  19. * @brief 获得当前光敏传感器输入电平
  20. * @param 无
  21. * @retval 返回周围光线情况
  22. */
  23. uint8_t LightSensor_Get(void)
  24. {
  25. return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);
  26. //周围暗的时候输入1;亮的时候输入0
  27. //周围暗的时候输出0;亮的时候输出1
  28. }

Buzzer.c

  1. #include "stm32f10x.h" // Device header
  2. /**
  3. * @brief 打开GPIO时钟,并进行初始化
  4. * @param 无
  5. * @retval 无
  6. */
  7. void Buzzer_Init(void)
  8. {
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  10. //第一步:使用RCC开启GPIO时钟
  11. GPIO_InitTypeDef GPIO_InitStructure;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  14. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15. GPIO_Init(GPIOB,&GPIO_InitStructure);
  16. //第二步:使用GPIO_Init()初始化GPIO
  17. GPIO_SetBits(GPIOB,GPIO_Pin_12);
  18. }
  19. /**
  20. * @brief 将位于PB12端口电平置零
  21. * @param 无
  22. * @retval 无
  23. */
  24. void Buzzer_On(void)
  25. {
  26. GPIO_ResetBits(GPIOB,GPIO_Pin_12);
  27. }
  28. /**
  29. * @brief 将位于PB12端口电平置一
  30. * @param 无
  31. * @retval 无
  32. */
  33. void Buzzer_Off(void)
  34. {
  35. GPIO_SetBits(GPIOB,GPIO_Pin_12);
  36. }
  37. /**
  38. * @brief 查看PB12端口电平并将其翻转
  39. * @param 无
  40. * @retval 无
  41. */
  42. void Buzzer_Turn(void)
  43. {
  44. if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12) == 0)//查看当前端口输出
  45. {
  46. GPIO_SetBits(GPIOB,GPIO_Pin_12);//将其置一
  47. }
  48. else
  49. {
  50. GPIO_ResetBits(GPIOB,GPIO_Pin_12);//将其置零
  51. }
  52. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "Buzzer.h"
  4. #include "LightSensor.h"
  5. int main(void)
  6. {
  7. Buzzer_Init();
  8. LightSensor_Init();
  9. while(1)
  10. {
  11. if(LightSensor_Get() == 1)//比较暗的时候
  12. {
  13. Buzzer_On();
  14. }
  15. else{
  16. Buzzer_Off();
  17. }
  18. }
  19. }

OLED调试工具

OLED显示

OLED.c

  1. #include "stm32f10x.h"
  2. #include "OLED_Font.h"
  3. /*引脚配置*/
  4. #define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))
  5. #define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))
  6. /*引脚初始化*/
  7. void OLED_I2C_Init(void)
  8. {
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  10. GPIO_InitTypeDef GPIO_InitStructure;
  11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  12. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  13. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  14. GPIO_Init(GPIOB, &GPIO_InitStructure);
  15. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  16. GPIO_Init(GPIOB, &GPIO_InitStructure);
  17. OLED_W_SCL(1);
  18. OLED_W_SDA(1);
  19. }
  20. /**
  21. * @brief I2C开始
  22. * @param 无
  23. * @retval 无
  24. */
  25. void OLED_I2C_Start(void)
  26. {
  27. OLED_W_SDA(1);
  28. OLED_W_SCL(1);
  29. OLED_W_SDA(0);
  30. OLED_W_SCL(0);
  31. }
  32. /**
  33. * @brief I2C停止
  34. * @param 无
  35. * @retval 无
  36. */
  37. void OLED_I2C_Stop(void)
  38. {
  39. OLED_W_SDA(0);
  40. OLED_W_SCL(1);
  41. OLED_W_SDA(1);
  42. }
  43. /**
  44. * @brief I2C发送一个字节
  45. * @param Byte 要发送的一个字节
  46. * @retval 无
  47. */
  48. void OLED_I2C_SendByte(uint8_t Byte)
  49. {
  50. uint8_t i;
  51. for (i = 0; i < 8; i++)
  52. {
  53. OLED_W_SDA(Byte & (0x80 >> i));
  54. OLED_W_SCL(1);
  55. OLED_W_SCL(0);
  56. }
  57. OLED_W_SCL(1); //额外的一个时钟,不处理应答信号
  58. OLED_W_SCL(0);
  59. }
  60. /**
  61. * @brief OLED写命令
  62. * @param Command 要写入的命令
  63. * @retval 无
  64. */
  65. void OLED_WriteCommand(uint8_t Command)
  66. {
  67. OLED_I2C_Start();
  68. OLED_I2C_SendByte(0x78); //从机地址
  69. OLED_I2C_SendByte(0x00); //写命令
  70. OLED_I2C_SendByte(Command);
  71. OLED_I2C_Stop();
  72. }
  73. /**
  74. * @brief OLED写数据
  75. * @param Data 要写入的数据
  76. * @retval 无
  77. */
  78. void OLED_WriteData(uint8_t Data)
  79. {
  80. OLED_I2C_Start();
  81. OLED_I2C_SendByte(0x78); //从机地址
  82. OLED_I2C_SendByte(0x40); //写数据
  83. OLED_I2C_SendByte(Data);
  84. OLED_I2C_Stop();
  85. }
  86. /**
  87. * @brief OLED设置光标位置
  88. * @param Y 以左上角为原点,向下方向的坐标,范围:0~7
  89. * @param X 以左上角为原点,向右方向的坐标,范围:0~127
  90. * @retval 无
  91. */
  92. void OLED_SetCursor(uint8_t Y, uint8_t X)
  93. {
  94. OLED_WriteCommand(0xB0 | Y); //设置Y位置
  95. OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); //设置X位置高4位
  96. OLED_WriteCommand(0x00 | (X & 0x0F)); //设置X位置低4位
  97. }
  98. /**
  99. * @brief OLED清屏
  100. * @param 无
  101. * @retval 无
  102. */
  103. void OLED_Clear(void)
  104. {
  105. uint8_t i, j;
  106. for (j = 0; j < 8; j++)
  107. {
  108. OLED_SetCursor(j, 0);
  109. for(i = 0; i < 128; i++)
  110. {
  111. OLED_WriteData(0x00);
  112. }
  113. }
  114. }
  115. /**
  116. * @brief OLED显示一个字符
  117. * @param Line 行位置,范围:1~4
  118. * @param Column 列位置,范围:1~16
  119. * @param Char 要显示的一个字符,范围:ASCII可见字符
  120. * @retval 无
  121. */
  122. void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
  123. {
  124. uint8_t i;
  125. OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); //设置光标位置在上半部分
  126. for (i = 0; i < 8; i++)
  127. {
  128. OLED_WriteData(OLED_F8x16[Char - ' '][i]); //显示上半部分内容
  129. }
  130. OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); //设置光标位置在下半部分
  131. for (i = 0; i < 8; i++)
  132. {
  133. OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]); //显示下半部分内容
  134. }
  135. }
  136. /**
  137. * @brief OLED显示字符串
  138. * @param Line 起始行位置,范围:1~4
  139. * @param Column 起始列位置,范围:1~16
  140. * @param String 要显示的字符串,范围:ASCII可见字符
  141. * @retval 无
  142. */
  143. void OLED_ShowString(uint8_t Line, uint8_t Column, char *String)
  144. {
  145. uint8_t i;
  146. for (i = 0; String[i] != '\0'; i++)
  147. {
  148. OLED_ShowChar(Line, Column + i, String[i]);
  149. }
  150. }
  151. /**
  152. * @brief OLED次方函数
  153. * @retval 返回值等于X的Y次方
  154. */
  155. uint32_t OLED_Pow(uint32_t X, uint32_t Y)
  156. {
  157. uint32_t Result = 1;
  158. while (Y--)
  159. {
  160. Result *= X;
  161. }
  162. return Result;
  163. }
  164. /**
  165. * @brief OLED显示数字(十进制,正数)
  166. * @param Line 起始行位置,范围:1~4
  167. * @param Column 起始列位置,范围:1~16
  168. * @param Number 要显示的数字,范围:0~4294967295
  169. * @param Length 要显示数字的长度,范围:1~10
  170. * @retval 无
  171. */
  172. void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
  173. {
  174. uint8_t i;
  175. for (i = 0; i < Length; i++)
  176. {
  177. OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
  178. }
  179. }
  180. /**
  181. * @brief OLED显示数字(十进制,带符号数)
  182. * @param Line 起始行位置,范围:1~4
  183. * @param Column 起始列位置,范围:1~16
  184. * @param Number 要显示的数字,范围:-2147483648~2147483647
  185. * @param Length 要显示数字的长度,范围:1~10
  186. * @retval 无
  187. */
  188. void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
  189. {
  190. uint8_t i;
  191. uint32_t Number1;
  192. if (Number >= 0)
  193. {
  194. OLED_ShowChar(Line, Column, '+');
  195. Number1 = Number;
  196. }
  197. else
  198. {
  199. OLED_ShowChar(Line, Column, '-');
  200. Number1 = -Number;
  201. }
  202. for (i = 0; i < Length; i++)
  203. {
  204. OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
  205. }
  206. }
  207. /**
  208. * @brief OLED显示数字(十六进制,正数)
  209. * @param Line 起始行位置,范围:1~4
  210. * @param Column 起始列位置,范围:1~16
  211. * @param Number 要显示的数字,范围:0~0xFFFFFFFF
  212. * @param Length 要显示数字的长度,范围:1~8
  213. * @retval 无
  214. */
  215. void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
  216. {
  217. uint8_t i, SingleNumber;
  218. for (i = 0; i < Length; i++)
  219. {
  220. SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
  221. if (SingleNumber < 10)
  222. {
  223. OLED_ShowChar(Line, Column + i, SingleNumber + '0');
  224. }
  225. else
  226. {
  227. OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
  228. }
  229. }
  230. }
  231. /**
  232. * @brief OLED显示数字(二进制,正数)
  233. * @param Line 起始行位置,范围:1~4
  234. * @param Column 起始列位置,范围:1~16
  235. * @param Number 要显示的数字,范围:0~1111 1111 1111 1111
  236. * @param Length 要显示数字的长度,范围:1~16
  237. * @retval 无
  238. */
  239. void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
  240. {
  241. uint8_t i;
  242. for (i = 0; i < Length; i++)
  243. {
  244. OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
  245. }
  246. }
  247. /**
  248. * @brief OLED初始化
  249. * @param 无
  250. * @retval 无
  251. */
  252. void OLED_Init(void)
  253. {
  254. uint32_t i, j;
  255. for (i = 0; i < 1000; i++) //上电延时
  256. {
  257. for (j = 0; j < 1000; j++);
  258. }
  259. OLED_I2C_Init(); //端口初始化
  260. OLED_WriteCommand(0xAE); //关闭显示
  261. OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率
  262. OLED_WriteCommand(0x80);
  263. OLED_WriteCommand(0xA8); //设置多路复用率
  264. OLED_WriteCommand(0x3F);
  265. OLED_WriteCommand(0xD3); //设置显示偏移
  266. OLED_WriteCommand(0x00);
  267. OLED_WriteCommand(0x40); //设置显示开始行
  268. OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置
  269. OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置
  270. OLED_WriteCommand(0xDA); //设置COM引脚硬件配置
  271. OLED_WriteCommand(0x12);
  272. OLED_WriteCommand(0x81); //设置对比度控制
  273. OLED_WriteCommand(0xCF);
  274. OLED_WriteCommand(0xD9); //设置预充电周期
  275. OLED_WriteCommand(0xF1);
  276. OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别
  277. OLED_WriteCommand(0x30);
  278. OLED_WriteCommand(0xA4); //设置整个显示打开/关闭
  279. OLED_WriteCommand(0xA6); //设置正常/倒转显示
  280. OLED_WriteCommand(0x8D); //设置充电泵
  281. OLED_WriteCommand(0x14);
  282. OLED_WriteCommand(0xAF); //开启显示
  283. OLED_Clear(); //OLED清屏
  284. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. uint8_t KeyNum;
  5. int main(void)
  6. {
  7. OLED_Init();
  8. OLED_ShowChar(1,1,'A');
  9. OLED_ShowString(1,3,"Hello,world!");
  10. OLED_ShowNum(2,1,30,2);
  11. OLED_ShowSignedNum(2,4,300,3);
  12. OLED_ShowSignedNum(2,9,-300,3);
  13. OLED_ShowHexNum(3,1,0xAA55,4);
  14. OLED_ShowBinNum(4,1,0xAA55,16);
  15. OLED_Clear();
  16. while(1)
  17. {
  18. }
  19. }

EXTI外部中断

对射式红外传感器计次

Encoder.c

  1. #include "stm32f10x.h" // Device header
  2. uint16_t CountSensor_Count;
  3. /**
  4. * 函 数:计数传感器初始化
  5. * 参 数:无
  6. * 返 回 值:无
  7. */
  8. void CountSensor_Init(void)//初始化
  9. {
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  11. //开启GPIOB时钟
  12. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  13. //开启AFIO时钟
  14. //EXTI与NVIC不需要开启时钟
  15. //GPIO配置
  16. GPIO_InitTypeDef GPIO_InitStructure;//外部中断一般选择浮空,上拉或者下拉
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入模式
  18. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
  19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  20. GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB外设
  21. //AFIO配置
  22. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
  23. //EXTI配置
  24. EXTI_InitTypeDef EXTI_InitStructure;
  25. EXTI_InitStructure.EXTI_Line = EXTI_Line14;//选择中断源位置
  26. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  27. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择事件还是中断
  28. //EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发(离开后触发+1)
  29. //EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发
  30. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升下降都触发
  31. EXTI_Init(&EXTI_InitStructure);//初始化EXTI
  32. //NVIC配置
  33. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组(两位抢占,两位相应)
  34. NVIC_InitTypeDef NVIC_InitStructure;
  35. NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//选择芯片对应通道
  36. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断通道
  37. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//0-3
  38. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//0-3
  39. NVIC_Init(&NVIC_InitStructure);
  40. }
  41. /**
  42. * 函 数:获取计数传感器的计数值
  43. * 参 数:无
  44. * 返 回 值:计数值,范围:0~65535
  45. */
  46. uint16_t CountSensor_Get(void)
  47. {
  48. return CountSensor_Count;
  49. }
  50. /**
  51. * 函 数:EXTI15_10外部中断函数
  52. * 参 数:无
  53. * 返 回 值:无
  54. * 注意事项:此函数为中断函数,无需调用,中断触发后自动执行
  55. * 函数名为预留的指定名称,可以从启动文件复制
  56. * 请确保函数名正确,不能有任何差异,否则中断函数将不能进入
  57. */
  58. void EXTI15_10_IRQHandler(void)//中断函数
  59. {
  60. if(EXTI_GetITStatus(EXTI_Line14) == SET)//判断是否是来自14号端口的中断
  61. {
  62. if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) == 1 || GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) == 0)
  63. //上升沿若设置为0,则离开加一
  64. //下降沿若设置为1,则挡住加一
  65. //若上升下降都触发若设置为 0|1,则挡住加一,离开也加一
  66. //这里的判断是为了防止数据跳跃幅度大
  67. //传感器输出高电平灭,输出低电平亮
  68. //传感器输入高电平亮,输入低电平灭
  69. {
  70. CountSensor_Count++;
  71. }
  72. EXTI_ClearITPendingBit(EXTI_Line14);//完成中断后清除中断标志位
  73. }
  74. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "CountSensor.h"
  5. uint8_t KeyNum;
  6. int main(void)
  7. {
  8. OLED_Init();
  9. CountSensor_Init();
  10. OLED_ShowString(1,1,"Count:");
  11. while(1)
  12. {
  13. OLED_ShowNum(1,7,CountSensor_Get(),5);
  14. }
  15. }
旋转编码器计次

Encoder.c

  1. #include "stm32f10x.h" // Device header
  2. int16_t Encoder_Count;
  3. /**
  4. * 函 数:旋转编码器初始化
  5. * 参 数:无
  6. * 返 回 值:无
  7. */
  8. void Encoder_Init(void)
  9. {
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  11. //开启GPIOB时钟
  12. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  13. //开启AFIO时钟
  14. //EXTI与NVIC不需要开启时钟
  15. //GPIO配置
  16. GPIO_InitTypeDef GPIO_InitStructure;//外部中断一般选择浮空,上拉或者下拉
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入模式
  18. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
  19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  20. GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB外设
  21. //AFIO配置
  22. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);//配置PB^1端口
  23. GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);//配置PB^0端口
  24. //EXTI配置
  25. EXTI_InitTypeDef EXTI_InitStructure;
  26. EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1;//选择中断源位置
  27. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  28. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//选择事件还是中断
  29. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  30. //EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发
  31. //EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升下降都触发
  32. EXTI_Init(&EXTI_InitStructure);//初始化EXTI
  33. //NVIC配置
  34. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组(两位抢占,两位相应)
  35. NVIC_InitTypeDef NVIC_InitStructure;
  36. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//选择芯片端口0对应通道
  37. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断通道
  38. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//0-3
  39. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//0-3
  40. NVIC_Init(&NVIC_InitStructure);
  41. NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;//选择芯片端口1对应通道
  42. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断通道
  43. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//0-3
  44. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//0-3
  45. NVIC_Init(&NVIC_InitStructure);
  46. }
  47. /**
  48. * 函 数:EXTI0外部中断函数
  49. * 参 数:无
  50. * 返 回 值:无
  51. * 注意事项:此函数为中断函数,无需调用,中断触发后自动执行
  52. * 函数名为预留的指定名称,可以从启动文件复制
  53. * 请确保函数名正确,不能有任何差异,否则中断函数将不能进入
  54. */
  55. void EXTI0_IRQHandler(void)//端口0触发中断(左旋)
  56. {
  57. if(EXTI_GetITStatus(EXTI_Line0) == SET)//检查EXTI是否被置位SET,如果置位则进行中断程序
  58. {
  59. if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)//进行判断另一个引脚
  60. {
  61. Encoder_Count--;
  62. }
  63. EXTI_ClearITPendingBit(EXTI_Line0);//清除标志位
  64. }
  65. }
  66. /**
  67. * 函 数:EXTI1外部中断函数
  68. * 参 数:无
  69. * 返 回 值:无
  70. * 注意事项:此函数为中断函数,无需调用,中断触发后自动执行
  71. * 函数名为预留的指定名称,可以从启动文件复制
  72. * 请确保函数名正确,不能有任何差异,否则中断函数将不能进入
  73. */
  74. void EXTI1_IRQHandler(void)//端口1触发中断(右旋)
  75. {
  76. if(EXTI_GetITStatus(EXTI_Line1) == SET)//检查EXTI是否被置位SET,如果置位则进行中断程序
  77. {
  78. if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0)//进行判断另一个引脚
  79. {
  80. Encoder_Count++;
  81. }
  82. EXTI_ClearITPendingBit(EXTI_Line1);//清除标志位
  83. }
  84. }
  85. /**
  86. * 函 数:旋转编码器获取增量值
  87. * 参 数:无
  88. * 返 回 值:自上此调用此函数后,旋转编码器的增量值
  89. */
  90. int16_t EncoderCount_Get(void)
  91. {
  92. int16_t Tmp;
  93. /*使用Tmp变量作为中继,目的是返回Encoder_Count后将其清零*/
  94. /*在这里,也可以直接返回Encoder_Count
  95. 但这样就不是获取增量值的操作方法了
  96. 也可以实现功能,只是思路不一样*/
  97. Tmp = Encoder_Count;
  98. Encoder_Count = 0;
  99. return Tmp;
  100. }

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "Encoder.h"
  5. int16_t Num;
  6. int main(void)
  7. {
  8. OLED_Init();
  9. Encoder_Init();
  10. OLED_ShowString(1,1,"Num:");
  11. while(1)
  12. {
  13. Num += EncoderCount_Get();//这里的函数得到的是对当前数进行操作(加或减)的增量值
  14. OLED_ShowSignedNum(1,5,Num,5);//这里要显示有符号数
  15. }
  16. }

注意:中断函数中,最好不要执行耗时过长的代码;最好不要在中断函数和主函数中调用相同的函数或操作同一个硬件,尤其的硬件相关函数。尽量操作变量或者标志位,当中断返回时,再对变量进行显示和操作。减少代码间的耦合性,让各部分代码相互独立。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/46262
推荐阅读
相关标签
  

闽ICP备14008679号