• 51单片机控制电动机正反转,PWM调速,记录转动圈数。


    今天的实验需要用到的材料有:51单片机最小系统,4X4的矩阵键盘,DC直流6V-12V带编码器电机,L298N模块,一个led小灯。下面把产品截图展示一下:

    单片机就不展示了,都一样,下面是接线图:

    下面是电机的脉冲信号接法:4个脉冲1圈,图中单片机处接到51单片机的P3.2口,外部中断0

    接下来就是我组装完了的一张图片了。

    下面介绍一下程序的大体流程:按A键正转,按B键反转,0停止,1到9设置脉冲的高电平占用的百分比,10%到90%,也就是1最慢,9最快了。还能再快,没有写,到100%就是最快了,不管什么情况下,转够十圈都会停止转动。

    下面就是整个程序,有注释,程序测试没有问题,特此记录:

    1. #include
    2. sbit IN1=P3^5; //接L298N 7
    3. sbit IN2=P3^6; //接L298N 6
    4. sbit EN1=P3^7; //接L298N 5
    5. sbit LED=P2^7; //接一个小led灯检测信号用
    6. #define uc unsigned char
    7. #define uint unsigned int
    8. uint dat_H[2]; // 定时器初值的高位取值数组
    9. uint dat_L[2]; // 定时器初值的低位取值数组
    10. uint num=1000; // 定时器的定时时间(高电平时间为0.1毫秒)
    11. uc flag=0; //记录按键是否被按下的标志
    12. uc count=0; //用来记录电机转的圈数,4个数为1圈
    13. //电动机停止函数
    14. void motor_stop()
    15. {
    16. IN1=1;
    17. IN2=1;
    18. EN1=1;
    19. EA=0;
    20. }
    21. //电动机正转函数
    22. void motor_zheng()
    23. {
    24. IN1=1;
    25. IN2=0;
    26. EA = 1;
    27. }
    28. //电动机反转函数
    29. void motor_fan()
    30. {
    31. IN1=0;
    32. IN2=1;
    33. EA = 1;
    34. }
    35. //数据初始化
    36. void dat_init()
    37. {
    38. dat_H[0]=(65536-(10000-num))/256;
    39. dat_L[0]=(65536-(10000-num))%256;
    40. dat_H[1]=(65536-num)/256;
    41. dat_L[1]=(65536-num)%256;
    42. }
    43. void key()
    44. {
    45. uc temp=0, temp1=0, temp2=0;
    46. P0 = 0x0F;
    47. if(P0 != 0x0F && flag == 0)
    48. {
    49. flag=1;
    50. }
    51. if(P0 != 0x0F && flag == 1)
    52. {
    53. flag=0; //
    54. temp1 = P0;
    55. }
    56. P0 = 0xF0;
    57. if(P0 != 0xF0 && flag == 0)
    58. {
    59. flag = 1;//temp2 = P0;
    60. }
    61. if(P0 != 0xF0 && flag == 1)
    62. {
    63. flag = 0;//
    64. temp2 = P0;
    65. }
    66. temp = temp1 + temp2;
    67. //按键1按下 修改num值达到修改定时器定时时间的目的
    68. if(temp == 0xEE)
    69. {
    70. num = 1000;
    71. }
    72. //按键2按下
    73. if(temp == 0xDE)
    74. {
    75. num = 2000;
    76. }
    77. //按键3按下
    78. if(temp == 0xBE)
    79. {
    80. num = 3000;
    81. }
    82. //按键A按下
    83. if(temp == 0x7E)
    84. {
    85. motor_zheng(); // 电机正转
    86. }
    87. //按键4按下
    88. if(temp == 0xED)
    89. {
    90. num = 4000;
    91. }
    92. //按键5按下
    93. if(temp == 0xDD)
    94. {
    95. num = 5000;
    96. }
    97. //按键6按下
    98. if(temp == 0xBD)
    99. {
    100. num = 6000;
    101. }
    102. //按键B按下
    103. if(temp == 0x7D)
    104. {
    105. motor_fan(); // 电机反转
    106. }
    107. //按键7按下
    108. if(temp == 0xEB)
    109. {
    110. num = 7000;
    111. }
    112. //按键8按下
    113. if(temp == 0xDB)
    114. {
    115. num = 8000;
    116. }
    117. //按键9按下
    118. if(temp == 0xBB)
    119. {
    120. num = 9000;
    121. }
    122. //按键C按下
    123. // if(temp == 0x7B)
    124. // {
    125. //
    126. // }
    127. //按键*按下
    128. // if(temp == 0xE7)
    129. // {
    130. //
    131. // }
    132. //按键0按下
    133. if(temp == 0xD7)
    134. {
    135. motor_stop(); //停止转动
    136. }
    137. //按键#按下
    138. // if(temp == 0xB7)
    139. // {
    140. //
    141. // }
    142. //
    143. // //按键D按下
    144. // if(temp == 0x77)
    145. // {
    146. //
    147. // }
    148. LED=0;
    149. dat_init(); // 所有按键都检测完了就要重新设置一下初值,好叫按键更改的num值起效
    150. }
    151. //定时器初始化
    152. void time_init()
    153. {
    154. TMOD=0x01;
    155. TH0=dat_H[0];
    156. TL0=dat_L[0];
    157. ET0=1;
    158. EA=1;
    159. TR0=1;
    160. IN1=1;
    161. IN2=0;
    162. EN1=0;
    163. LED=0; //P2的7口接了一个led小灯检测信号有没有用的。
    164. //下面是外部中断初始化
    165. IT0=1; // 外部中断设置成1,边沿触发方式
    166. EX0=1; // 使用INT0的中断
    167. }
    168. // 主函数
    169. int main()
    170. {
    171. time_init(); //初始化定时器
    172. while(1)
    173. {
    174. key(); // 检测按键
    175. }
    176. return 0;
    177. }
    178. // 定时器中断入口函数
    179. void zd() interrupt 1
    180. {
    181. EN1=~EN1; // 电动机转动使能,每次取反, 得1时转动,得0时停止
    182. if(EN1==0) // 如果是停止转动时,就设置初值为(65536-(10000-num))num为定时时间1000为1毫秒
    183. {
    184. TH0=dat_H[0];
    185. TL0=dat_L[0];
    186. }
    187. if(EN1==1) // 如果是转动时,就设置初值为(65536-num),num为定时时间1000为1毫秒
    188. {
    189. TH0=dat_H[1];
    190. TL0=dat_L[1];
    191. }
    192. }
    193. // 外部中断入口函数
    194. void wbzd() interrupt 0
    195. {
    196. count++;
    197. if(count == 40) //记录电机转10圈的时候就停止转动,点亮led灯,圈数置0.
    198. {
    199. LED=1;
    200. count=0;
    201. motor_stop();
    202. }
    203. }

  • 相关阅读:
    RISC-V Optimization Guide(笔记)
    工程力学部分知识点
    JAVA在线电子病历编辑器源码 B/S架构
    一些测试知识
    非零基础自学Java (老师:韩顺平) 第2章 Java概述 2.18 Java代码规范 && 2.19 DOS命令
    ARMv8函数传参中的bug!
    python--利用os模块读取指定目录下所有文件名
    Springboot项目 导出生成jar包
    vue页面嵌入飞书网页组件,用于在类似ERP,OA等系统中展示在线文档
    SpringBoot + 自定义注解 + AOP 高级玩法打造通用开关
  • 原文地址:https://blog.csdn.net/xingyuncao520025/article/details/133378488