• STM32 入门教程(江科大教材)#笔记2


    3-4按键控制LED

    1. /** LED.c**/
    2. #include "stm32f10x.h" // Device header
    3. void LED_Init(void)
    4. {
    5. /*开启时钟*/
    6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
    7. /*GPIO初始化*/
    8. GPIO_InitTypeDef GPIO_InitStructure;
    9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
    11. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    12. GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA1和PA2引脚初始化为推挽输出
    13. /*设置GPIO初始化后的默认电平*/
    14. GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2); //设置PA1和PA2引脚为高电平
    15. }
    16. /**
    17. * 函 数:LED1开启
    18. * 参 数:无
    19. * 返 回 值:无
    20. */
    21. void LED1_ON(void)
    22. {
    23. GPIO_ResetBits(GPIOA, GPIO_Pin_1); //设置PA1引脚为低电平
    24. }
    25. /**
    26. * 函 数:LED1关闭
    27. * 参 数:无
    28. * 返 回 值:无
    29. */
    30. void LED1_OFF(void)
    31. {
    32. GPIO_SetBits(GPIOA, GPIO_Pin_1); //设置PA1引脚为高电平
    33. }
    34. void LED1_Turn(void)
    35. {
    36. if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0) //获取输出寄存器的状态,如果当前引脚输出低电平
    37. {
    38. GPIO_SetBits(GPIOA, GPIO_Pin_1); //则设置PA1引脚为高电平
    39. }
    40. else //否则,即当前引脚输出高电平
    41. {
    42. GPIO_ResetBits(GPIOA, GPIO_Pin_1); //则设置PA1引脚为低电平
    43. }
    44. }
    45. /**
    46. * 函 数:LED2开启
    47. * 参 数:无
    48. * 返 回 值:无
    49. */
    50. void LED2_ON(void)
    51. {
    52. GPIO_ResetBits(GPIOA, GPIO_Pin_2); //设置PA2引脚为低电平
    53. }
    54. /**
    55. * 函 数:LED2关闭
    56. * 参 数:无
    57. * 返 回 值:无
    58. */
    59. void LED2_OFF(void)
    60. {
    61. GPIO_SetBits(GPIOA, GPIO_Pin_2); //设置PA2引脚为高电平
    62. }
    63. /**
    64. * 函 数:LED2状态翻转
    65. * 参 数:无
    66. * 返 回 值:无
    67. */
    68. void LED2_Turn(void)
    69. {
    70. if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0) //获取输出寄存器的状态,如果当前引脚输出低电平
    71. {
    72. GPIO_SetBits(GPIOA, GPIO_Pin_2); //则设置PA2引脚为高电平
    73. }
    74. else //否则,即当前引脚输出高电平
    75. {
    76. GPIO_ResetBits(GPIOA, GPIO_Pin_2); //则设置PA2引脚为低电平
    77. }
    78. }
    1. /**Key.c**/
    2. #include "stm32f10x.h" // Device header
    3. #include "Delay.h"
    4. #include "stm32f10x_gpio.h"
    5. #include "stm32f10x_rcc.h"
    6. void Key_Init(void)
    7. {
    8. /*开启时钟*/
    9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟
    10. /*GPIO初始化*/
    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); //将PB1和PB11引脚初始化为上拉输入
    16. }
    17. /**
    18. * 函 数:按键获取键码
    19. * 参 数:无
    20. * 返 回 值:按下按键的键码值,范围:0~2,返回0代表没有按键按下
    21. * 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手
    22. */
    23. uint8_t Key_GetNum(void)
    24. {
    25. uint8_t KeyNum = 0; //定义变量,默认键码值为0
    26. if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //读PB1输入寄存器的状态,如果为0,则代表按键1按下
    27. {
    28. Delay_ms(20); //延时消抖
    29. while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); //等待按键松手
    30. Delay_ms(20); //延时消抖
    31. KeyNum = 1; //置键码为1
    32. }
    33. if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0) //读PB11输入寄存器的状态,如果为0,则代表按键2按下
    34. {
    35. Delay_ms(20); //延时消抖
    36. while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0); //等待按键松手
    37. Delay_ms(20); //延时消抖
    38. KeyNum = 2; //置键码为2
    39. }
    40. return KeyNum; //返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
    41. }
    1. /**main.c**/
    2. #include "stm32f10x.h" // Device header
    3. #include "Delay.h"
    4. #include "LED.h"
    5. #include "Key.h"
    6. uint8_t KeyNum; //定义用于接收按键键码的变量
    7. int main(void)
    8. {
    9. /*模块初始化*/
    10. LED_Init(); //LED初始化
    11. Key_Init(); //按键初始化
    12. while (1)
    13. {
    14. KeyNum = Key_GetNum(); //获取按键键码
    15. if (KeyNum == 1) //按键1按下
    16. {
    17. LED1_Turn(); //LED1翻转
    18. }
    19. if (KeyNum == 2) //按键2按下
    20. {
    21. LED2_Turn(); //LED2翻转
    22. }
    23. }
    24. }

    3-5光敏传感器控制蜂鸣器

    1. /*buzzer.c*/
    2. #include "stm32f10x.h" // Device header
    3. void Buzzer_Init(void)
    4. {
    5. /*开启时钟*/
    6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟
    7. /*GPIO初始化*/
    8. GPIO_InitTypeDef GPIO_InitStructure;
    9. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    11. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    12. GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB12引脚初始化为推挽输出
    13. /*设置GPIO初始化后的默认电平*/
    14. GPIO_SetBits(GPIOB, GPIO_Pin_12); //设置PB12引脚为高电平
    15. }
    16. void Buzzer_ON(void)
    17. {
    18. GPIO_ResetBits(GPIOB, GPIO_Pin_12); //设置PB12引脚为低电平
    19. }
    20. /**
    21. * 函 数:蜂鸣器关闭
    22. * 参 数:无
    23. * 返 回 值:无
    24. */
    25. void Buzzer_OFF(void)
    26. {
    27. GPIO_SetBits(GPIOB, GPIO_Pin_12); //设置PB12引脚为高电平
    28. }
    29. void Buzzer_Turn(void)
    30. {
    31. if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_12) == 0) //获取输出寄存器的状态,如果当前引脚输出低电平
    32. {
    33. GPIO_SetBits(GPIOB, GPIO_Pin_12); //则设置PB12引脚为高电平
    34. }
    35. else //否则,即当前引脚输出高电平
    36. {
    37. GPIO_ResetBits(GPIOB, GPIO_Pin_12); //则设置PB12引脚为低电平
    38. }
    39. }
    40. /*lightsensor*/
    41. #include "stm32f10x.h" // Device header
    42. void LightSensor_Init(void)
    43. {
    44. /*开启时钟*/
    45. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟
    46. /*GPIO初始化*/
    47. GPIO_InitTypeDef GPIO_InitStructure;
    48. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    49. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    50. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    51. GPIO_Init(GPIOB, &GPIO_InitStructure); //将PB13引脚初始化为上拉输入
    52. }
    53. uint8_t LightSensor_Get(void)
    54. {
    55. return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13); //返回PB13输入寄存器的状态
    56. }
    57. /*main.c*/
    58. #include "stm32f10x.h" // Device header
    59. #include "Delay.h"
    60. #include "Buzzer.h"
    61. #include "LightSensor.h"
    62. int main(void)
    63. {
    64. /*模块初始化*/
    65. Buzzer_Init(); //蜂鸣器初始化
    66. LightSensor_Init(); //光敏传感器初始化
    67. while (1)
    68. {
    69. if (LightSensor_Get() == 1) //如果当前光敏输出1
    70. {
    71. Buzzer_ON(); //蜂鸣器开启
    72. }
    73. else //否则
    74. {
    75. Buzzer_OFF(); //蜂鸣器关闭
    76. }
    77. }
    78. }

    4-1 OLED调试工具

    OLED(Organic Light Emitting Diode):有机发光二极管

    OLED显示屏:性能优异的新型显示屏,具有功耗低、相应速度快、宽视角、轻薄柔韧等特点

    0.96寸OLED模块:小巧玲珑、占用接口少、简单易用,是电子设计中非常常见的显示屏模块

    供电:3~5.5V,通信协议:I2C/SPI,分辨率:128*64

    三种调试方式

    OLED的驱动函数

     

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

  • 相关阅读:
    pgsql_全文检索_使用空间换时间的方法支持中文搜索
    [附源码]java毕业设计-室内田径馆预约管理系统
    【C++】pow函数实现的伽马变换详解和示例
    Pr:代理工作流程
    OpenCV(三十九):积分图像
    高等教育学:课程
    PostgreSQL 查询某个属性相同内容出现的次数
    MediaCodec视频编码H264流程及参考demo
    TEINet: Towards an Efficient Architecture for Video Recognition 论文阅读
    joplin更新后找不到文章
  • 原文地址:https://blog.csdn.net/2301_79706774/article/details/139277561