当前位置:   article > 正文

STC12C5A60S2单片机制作的智能小车_工训赛小车stc代码

工训赛小车stc代码

1

1.材料清单

材料数量

电机

2
万向轮1
轮胎2
循迹模块2
超声波、舵机1
STC12C5A60S2学习板或者最小系统1
L298N1
12V可充电锂电池1

1.2图片

                                                          

2.L298N电机驱动(重点)

2.1L298N原理

如上图所示: 输出A和输出B接到电机。12V供电接到锂电池正极,5V接到单片机正极,GND单片机和锂电池共用。拔掉通道A使能和通道B使能,各接到单片机P1^3P1^4口(具有PCA的单片机最好,不是的话用定时器弄个PWM也行,接法不变),IN1IN2为一组( IN1 = P0^1;             //左电机正转,IN2 = P0^2;  //左电机反转),接到单片机P2对应OutA(输出A); IN3IN4为一组(IN3 = P0^4;     //右电机正转 ,IN4 = P0^3;             //右电机反转),对应OutB(输出B)。

正反转逻辑(0为低电平,1为高电平)

IN1IN2IN3IN4电机
1001向前
0110向后
0001左转
1000向后
1111停止
0000停止

PWM,STC12的I/O口P13和P14,PWM_Set(x,y),x=y=110可以驱动小车前进。

2.2例子代码:

.PWM.C

  1. #include "pwm.h"
  2. /**********************************
  3. *函数名称:PCA_Init(void)
  4. *输入 :无
  5. *输出 :无
  6. *调用说明:外部调用
  7. *函数说明:PWM模块初始化
  8. ***********************************/
  9. void PCA_Init(void)
  10. {
  11. CCON = 0; //PCA初始化
  12. CMOD = 0x00; //空闲时不计数,不产生中断,时钟源为Sysclk/12,PWM频率大约为4KHz
  13. CL = 0x00; //PCA低8位清零
  14. CH = 0x00; //PCA高8位清零
  15. CCAPM0 = 0x42; //8位PWM模式,无中断
  16. CCAP0H = 0xc0; //PWM0占空比(调节此处值调节PWM占空比)
  17. CCAP0L = 0xc0; //PWM0占空比(调节此处值调节PWM占空比)
  18. CCAPM1 = 0x42; //8位PWM模式,无中断
  19. CCAP1H = 0x40; //PWM1占空比(调节此处值调节PWM占空比)
  20. CCAP1L = 0x40; //PWM1占空比(调节此处值调节PWM占空比)
  21. CR = 1; //启动PCA计数器
  22. }
  23. /**********************************
  24. *函数名称:PWM_Set(unsigned char x,unsigned char y)
  25. *输入 :占空比输入1 unsigned char x(0-255),占空比输入unsigned char y(0-255)
  26. *输出 :无
  27. *调用说明:外部调用
  28. *函数说明:占空比设置
  29. ***********************************/
  30. void PWM_Set(unsigned char x,unsigned char y)
  31. {
  32. x = ~x;
  33. y = ~y;
  34. CCAP0H = y; //设置比较值
  35. CCAP0L = y;
  36. CCAP1H = x; //设置比较值
  37. CCAP1L = x;
  38. }

motor.c

  1. #include "motor.h"
  2. //智能小车前进
  3. void SmartCarForward()
  4. {
  5. LeftMotorGo; //左电机正转
  6. RightMotorGo; //右电机正转
  7. }
  8. //智能小车后退
  9. void SmartCarBack()
  10. {
  11. LeftMotorBack; //左电机反转
  12. RightMotorBack; //右电机反转
  13. }
  14. //智能小车左转
  15. void SmartCarLeft()
  16. {
  17. LeftMotorBack; //左电机反转
  18. RightMotorGo; //右电机正转
  19. }
  20. //智能小车右转
  21. void SmartCarRight()
  22. {
  23. LeftMotorGo; //左电机正转
  24. RightMotorBack; //右电机反转
  25. }
  26. //智能小车停车
  27. void SmartCarStops()
  28. {
  29. LeftMotorStop; //左电机停转
  30. RightMotorStop; //右电机停转
  31. }

motor.h头文件

  1. #ifndef _MOTOR_H
  2. #define _MOTOR_H
  3. #include "config.h"
  4. //具体逻辑查看如下真值表
  5. //ENA IN1 IN2 直流电机状态
  6. //0 x x 停止
  7. //1 0 0 制动
  8. //1 0 1 正转
  9. //1 1 0 反转
  10. //1 1 1 制动
  11. #define LeftMotorStop IN1 = 0, IN2 = 0//左电机停止
  12. #define RightMotorStop IN3 = 0, IN4 = 0//右电机停止
  13. #define LeftMotorGo IN1 = 1, IN2 = 0//左电机正传
  14. #define LeftMotorBack IN1 = 0, IN2 =1//左电机反转
  15. #define RightMotorGo IN3 = 1, IN4 = 0//右电机正传
  16. #define RightMotorBack IN3 = 0, IN4 = 1//右电机反转
  17. //---------------------------------------------
  18. //L298N双H桥直流驱动硬件接口定义
  19. //---------------------------------------------
  20. sbit IN1 = P0^1; //左电机正转
  21. sbit IN2 = P0^2; //左电机反转
  22. sbit IN3 = P0^4; //右电机正转
  23. sbit IN4 = P0^3; //右电机反转
  24. sbit ENA = P1^3; //左使能
  25. sbit ENB = P1^4; //右使能
  26. void SmartCarForward(); //智能小车前进
  27. void SmartCarBack(); //智能小车后退
  28. void SmartCarLeft(); //智能小车左转
  29. void SmartCarRight(); //智能小车右转
  30. void SmartCarStops(); //智能小车停车
  31. #endif

3.舵机

3.1舵机的接法

信号线(黄色)、正极(红色)、负极(棕色)

信号线连接到P3^4,用定时器0,0.1ms中断一次,0.1*6(中断次数)=1ms(指向右边);0.1*15(中断次数)=1.5ms(舵机指向中间);0.1*20(中断次数)=2ms(舵机指向左边)

180度舵机控制参数
角度脉冲周期脉冲高电平时间占空比
020ms0.5ms2.50%
4520ms1ms5.00%
9020ms1.5ms7.50%
14520ms2ms10.00%
18020ms2.5ms12.50%

3.2例子代码:

  1. unsigned char duoji_count=0;
  2. unsigned char zhuanjiao = 11;
  3. /*******************************************************************************
  4. * 函 数 名 :Delayms
  5. * 函数功能 :实现 ms级的延时
  6. * 输 入 :ms
  7. * 输 出 :无
  8. *******************************************************************************/
  9. void Delayms(unsigned int ms)
  10. {
  11. unsigned int i,j;
  12. for(i=0;i<ms;i++)
  13. for(j=0;j<114;j++);
  14. }
  15. /*******************************************************************************
  16. * 函 数 名 :Timer0Init
  17. * 函数功能 :定时器0初始化
  18. * 输 入 :无
  19. * 输 出 :无
  20. *******************************************************************************/
  21. void Timer0Init()
  22. {
  23. TMOD|=0x01; //设置定时器0工作方式为1
  24. TH0=164;//100us,0.1ms
  25. TL0=164;
  26. ET0=1; //开启定时器0中断
  27. TR0=1; //开启定时器
  28. EA=1; //打开总中断
  29. }
  30. /*******************************************************************************
  31. * 函 数 名 :Timer0Int
  32. * 函数功能 :定时器0中断函数 , 每隔TIME_MS ms进入
  33. * 输 入 :无
  34. * 输 出 :无
  35. *******************************************************************************/
  36. void Timer0Int() interrupt 1
  37. {
  38. TH0=164;
  39. TL0=164;
  40. duoji_count++;
  41. if(duoji_count <= zhuanjiao)
  42. {
  43. DUOJI_IO = 0;
  44. }
  45. else
  46. {
  47. DUOJI_IO = 1;
  48. }
  49. if(duoji_count >= 200)//20ms
  50. {
  51. duoji_count = 0;
  52. }
  53. }
  54. void DuojiMid()
  55. {
  56. zhuanjiao = 11;//指向中间
  57. Delayms(1000);//延时1s
  58. }
  59. void DuojiRight()
  60. {
  61. zhuanjiao = 6;//右边
  62. Delayms(1000);//延时1s
  63. }
  64. void DuojiLeft()
  65. {
  66. zhuanjiao = 18; //左边
  67. Delayms(1000);//延时1s
  68. }

4.超声波

4.1超声波接线:

超声波和舵机是接在一起的,一般网上买都有连接材料,超声波可以随便连接I/O口,我这里接的是EchoPin = P3^6;//超声波模块Echo    接收端;TrigPin = P3^5;//超声波模块Trig    控制端。

4.2例子代码:

下面是不用PCA作为电机PWM,PCA可以在CSDN上找小途或者其它文章,STC12C5A60S2独立PWM

PCA最高255,可以当作两个8位计数器来用,注意头文件,要有RCAP2H、RCAP2L、TH2、TR2和TL2,建议用reg52.h作为头文件。

  1. #include "UltrasonicCtrol.h"
  2. #include "interface.h"
  3. volatile unsigned char status = 0;//程序当前状态,0,空闲 1 发送触发信号,2 等待信号返回,3
  4. unsigned int dis_count = 0;//脉宽长计时
  5. volatile unsigned int distance_cm = 0;//当前距离
  6. unsigned char t2_full_count = 0;//计数器计满次数计数
  7. static unsigned int tick_5ms = 0;//5ms计数器
  8. void UltraSoundInit()
  9. {
  10. Trig = 0;
  11. TH2 = RCAP2H = 0;
  12. TL2 = RCAP2L = 0;
  13. TR2 = 0;//关闭定时器
  14. ET2=1; //允许T0中断
  15. EX1=0; //关闭外部中断1
  16. IT1=1; //由高电平变低电平,触发外部中断
  17. PX1 = 1;//优先级较高
  18. }
  19. //中断的方式读取距离值 每5ms执行一次
  20. void GetDistance()
  21. {
  22. if(status == 1)
  23. {
  24. //发送触发信号
  25. Trig = 1;
  26. status = 1;
  27. TH2 = 0;
  28. TL2 = 0;
  29. TR2 = 1;//打开定时器
  30. while(TL2 < 42);//延时超过10us
  31. status = 2;
  32. Trig = 0;
  33. TH2 = 0;
  34. TL2 = 0;
  35. TR2 = 0;
  36. while(Echo == 0);//等待回向信号起始位置
  37. EX1 = 1;//打开外部中断
  38. TR2 = 1;
  39. status = 3;//开始计算距离
  40. }
  41. if(status == 4)//成功接收到数据
  42. {
  43. distance_cm = (unsigned int)(((long)(dis_count) * 34)/8000);//声速340m/s
  44. status = 0;//准备下次发送
  45. }
  46. if(status == 5)//接收数据失败
  47. {
  48. status = 0;//准备下次发送
  49. }
  50. }
  51. //开始获取距离,每100ms执行一次
  52. void StartGetDistance()
  53. {
  54. status = 1;
  55. }
  56. void Distance()
  57. {
  58. tick_5ms++;
  59. if(tick_5ms >= 20)
  60. {
  61. tick_5ms = 0;
  62. // StartGetDistance();
  63. GetDistanceDelay();
  64. }
  65. //GetDistance();
  66. }
  67. //延时的方式读取距离值
  68. void GetDistanceDelay()
  69. {
  70. //发送触发信号
  71. Trig = 1;
  72. status = 1;
  73. TH2 = 0;
  74. TL2 = 0;
  75. TR2 = 1;//打开定时器
  76. while(TL2 < 42);//延时超过10us
  77. status = 2;
  78. Trig = 0;
  79. TH2 = 0;
  80. TL2 = 0;
  81. TR2 = 0;
  82. while(Echo == 0);//等待回向信号起始位置
  83. // EX1 = 1;//打开外部中断
  84. TR2 = 1;
  85. while(Echo == 1)//开始计算长度
  86. {
  87. if(status == 5)
  88. {
  89. status = 0;
  90. //distance_cm = 0;//失败后就后退
  91. return;//本次失败
  92. }
  93. }
  94. dis_count = TH2*256 + TL2;
  95. TR2 = 0;
  96. distance_cm = (unsigned int)(((long)(dis_count) * 34)/8000);//声速340m/s
  97. status = 0;//准备下次发送
  98. }
  99. /*******************************************************************************
  100. * 函 数 名 :
  101. * 函数功能 :外部中断1服务函数
  102. * 输 入 :无
  103. * 输 出 :无
  104. *******************************************************************************/
  105. void Exint1Int() interrupt 2 // 外部中断是2
  106. {
  107. if(status == 3)
  108. {
  109. dis_count = TH2*256 + TL2;
  110. EX1=0; //关闭外部中断
  111. TR2 = 0;
  112. status = 4;
  113. }
  114. }
  115. /*******************************************************************************
  116. * 函 数 名 :Timer0Int
  117. * 函数功能 :定时器0中断服务函数
  118. * 输 入 :无
  119. * 输 出 :无
  120. *******************************************************************************/
  121. void Timer2Int() interrupt 5 // 定时器0中断是1
  122. {
  123. TF2 = 0;
  124. EX1=0;
  125. status = 5;//超时
  126. }

下面是用定时器的

  1. #include "ultrasonic.h"
  2. static void Delay15us() //@11.0592MHz
  3. {
  4. unsigned char i;
  5. _nop_();
  6. _nop_();
  7. i = 38;
  8. while (--i);
  9. }
  10. /*超声波触发*/
  11. void TrigUltrasonic()
  12. {
  13. TrigPin = 0;
  14. _nop_();
  15. _nop_();
  16. _nop_();
  17. _nop_();
  18. _nop_();
  19. TrigPin = 1; //超声波模块Trig 控制端
  20. Delay15us();
  21. TrigPin = 0; //超声波模块Trig 控制端
  22. }
  23. /*====================================
  24. 函数名 :GetDistance
  25. 参数 :无
  26. 返回值 :获取距离单位毫米
  27. 描述 :超声波测距
  28. 通过发射信号到收到回响信号的时间测试距离
  29. 单片机晶振11.0592Mhz
  30. 注意测距周期为60ms以上
  31. ====================================*/
  32. unsigned int GetDistance()
  33. {
  34. double Time=0; //用于存放定时器时间值
  35. TH1=0; //清空定时器
  36. TL1=0;
  37. TrigUltrasonic(); //超声波触发
  38. while(EchoPin == 0); //判断回响信号是否为低电平
  39. TR1 = 1; //启动定时器1
  40. while(EchoPin == 1); //等待收到回响信号
  41. TR1 = 0; //关闭定时器1
  42. Time = (TH1*256 + TL1) * 1.085; //微秒
  43. return(Time * 0.017);//返回距离
  44. }

先交作业。

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

闽ICP备14008679号