当前位置:   article > 正文

51单片机之智能小车(避障、跟随、循迹)_51单片机智能小车

51单片机智能小车

目录

基本概述

硬件组成

功能

关键字

模块介绍

电机模块L9110S

循迹模块(TCRT5000传感器)

红外避障模块

测速模块 

小车 

移动小车(控制电机转动,使小车前进、后退、左转、右转 )

遥控小车( 使用蓝牙模块,通过串口发送信息控制小车移动)

调速小车(利用PWM波对电机进行调速)

循迹小车 (利用循迹模块进行黑白色的检测)

跟随小车(利用红外避障模块完成跟随行为)

避障小车(利用超声波测距完成避障行为)

测速小车,使用OLED屏显示小车速度

语音控制小车,循迹、跟随、避障三种功能切换

 

基本概述

硬件组成

电机模块L9110S、循迹模块、红外避障模块、超声波模块、测速模块、OLED屏、蓝牙模块、4G,模块、语音模块SU-03T

功能

蓝牙控制小车、WiFi控制小车、4G控制小车、小车的避障、跟随、循迹

关键字

单片机中一般都有两块存储区域,ROM和RAM,程序代码存储在ROM中,程序要用的变量存储在RAM中。而“code”的作用就是将其修饰过的变量存储在ROM中而非RAM。 在单片机中,RAM空间都比较小,是比较宝贵的,当存放在RAM中的数据过多时,会导致编译不成功。

  • exturn:使用exturn关键字修饰的全局变量或函数,作用域不再局限本文件,其他文件同样能访问到这些变量或函数,跟static关键字恰恰相反。
  • code:使用code关键字修饰的变量(一般是初始化后,值保持不变的变量)后会被存放到ROM区,从而节省RAM的空间。

模块介绍

电机模块L9110S

aa5cb1e961d8406699bf75655fa90f4b.png

L0110S模块的A、B分别控制着两个电机,如果需要控制四个电机,则需要两个L0110S模块

  • 当B-1A为高电平,B-2A为低电平时,电机反转或正转
  • 当B-1A为低电平,B-2A为高电平时,电机正转反转
  • 当B-1A为低电平,B-2A为低电平时,电机不转
  • 电机的正转和反转与跟电机的接线不同而不同,注意自己调试

循迹模块(TCRT5000传感器)

de5641f570fd4adba541c272a8063677.png

  • 当发射出的红外线没有被反射回来或被反射回来但强度不够大时,DO输出高电平,灯灭。 黑色吸收红外线,DO输出高电平,灯亮
  • 当发射出的红外线被反射回来或被反射回来且强度足够大,DO输出低电平,灯亮。 白色反射红外线,DO输出低电平,灯亮
  • 即黑色输出高电平,灯灭,白色输出低电平,灯亮

红外避障模块

6265a10e74644db7b3c133fa870458c8.png

  • 当发射出的红外线没有被反射回来或被反射回来但强度不够大时,DO输出高电平,灯灭。没有障碍物
  • 当发射出的红外线被反射回来,DO输出低电平,灯亮。有障碍物
  • 即有障碍物输出低电平,灯亮,没有障碍物输出高电平,灯灭

测速模块 

0877a6d59b6b4a61a22d38b3c0c7b352.png

  • 发射的红外线被物体遮挡时,输出高电平,发射的红外线没被物体遮挡时,输出低电平
  • 有物体高电平,没物体低电平
  • 当搭配小车测速盘,会形成下降沿(有遮挡高电平,没遮挡低电平)

小车 

移动小车(控制电机转动,使小车前进、后退、左转、右转 

  1. #include "reg52.h"
  2. #include <intrins.h>
  3. sbit left_con1A = P1^1;
  4. sbit left_con2A = P1^2;
  5. sbit right_con1A = P1^3;
  6. sbit right_con2A = P1^4;
  7. void Delay2000ms() //@11.0592MHz
  8. {
  9. unsigned char i, j, k;
  10. _nop_();
  11. i = 15;
  12. j = 2;
  13. k = 235;
  14. do
  15. {
  16. do
  17. {
  18. while (--k);
  19. } while (--j);
  20. } while (--i);
  21. }
  22. //两个电机反转,前进
  23. void goForward()
  24. {
  25. left_con1A = 1;
  26. left_con2A = 0;
  27. right_con1A = 1;
  28. right_con2A = 0;
  29. }
  30. //两个电机正转,后退
  31. void goBack()
  32. {
  33. left_con1A = 0;
  34. left_con2A = 1;
  35. right_con1A = 0;
  36. right_con2A = 1;
  37. }
  38. //两个电机不转,停止
  39. void goStop()
  40. {
  41. left_con1A = 0;
  42. left_con2A = 0;
  43. right_con1A = 0;
  44. right_con2A = 0;
  45. }
  46. //左电机不转,右电机反转,左转
  47. void goLeft()
  48. {
  49. left_con1A = 0;
  50. left_con2A = 0;
  51. right_con1A = 1;
  52. right_con2A = 0;
  53. }
  54. //左电机反转,右电机不转,右转
  55. void goRight()
  56. {
  57. left_con1A = 1;
  58. left_con2A = 0;
  59. right_con1A = 0;
  60. right_con2A = 0;
  61. }
  62. void main()
  63. {
  64. while(1){
  65. goForward();
  66. Delay2000ms();
  67. goBack();
  68. Delay2000ms();
  69. goLeft();
  70. Delay2000ms();
  71. goRight();
  72. Delay2000ms();
  73. goStop();
  74. Delay2000ms();
  75. }
  76. }

遥控小车( 使用蓝牙模块,通过串口发送信息控制小车移动)

  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #include <string.h>
  4. sfr AUXR = 0x8E;
  5. sbit left_con1A = P1^1;
  6. sbit left_con2A = P1^2;
  7. sbit right_con1A = P1^3;
  8. sbit right_con2A = P1^4;
  9. sbit led1 = P3^7;
  10. char mybuf[24] ;
  11. void Delay1000ms() //@11.0592MHz
  12. {
  13. unsigned char i, j, k;
  14. _nop_();
  15. i = 8;
  16. j = 1;
  17. k = 243;
  18. do
  19. {
  20. do
  21. {
  22. while (--k);
  23. } while (--j);
  24. } while (--i);
  25. }
  26. void uartInit()
  27. {
  28. AUXR = 0x01;
  29. PCON &= 0x7F; //配置波特率正常
  30. SCON = 0x50; //配置串口选择工作方式1,允许串口接收数据
  31. //配置定时器1为8位自动重装模式
  32. TMOD &= 0x0F;
  33. TMOD |= 0x20;
  34. //给定时器1,9600波特率初值
  35. TH1 = 0xFD; //定时器1初值
  36. TL1 = 0xFD; //定时器1重装值
  37. ET1 = 0; //不允许定时器1产生中断
  38. TR1 = 1; //开启定时器1
  39. EA = 1; //开启总中断
  40. ES = 1; //开启串口中断
  41. }
  42. void sendByte(char mydata)
  43. {
  44. SBUF = mydata; //向串口发送一帧信息
  45. while(!TI); //等待硬件置位
  46. TI = 0; //TI软件清0
  47. }
  48. void sendString(char *str)
  49. {
  50. while(*str != '\0'){
  51. sendByte(*str);
  52. str++;
  53. }
  54. }
  55. //两个电机反转,前进
  56. void goForward()
  57. {
  58. left_con1A = 1;
  59. left_con2A = 0;
  60. right_con1A = 1;
  61. right_con2A = 0;
  62. }
  63. //两个电机正转,后退
  64. void goBack()
  65. {
  66. left_con1A = 0;
  67. left_con2A = 1;
  68. right_con1A = 0;
  69. right_con2A = 1;
  70. }
  71. //两个电机不转,停止
  72. void goStop()
  73. {
  74. left_con1A = 0;
  75. left_con2A = 0;
  76. right_con1A = 0;
  77. right_con2A = 0;
  78. }
  79. //左电机不转,右电机反转,左转
  80. void goLeft()
  81. {
  82. left_con1A = 0;
  83. left_con2A = 0;
  84. right_con1A = 1;
  85. right_con2A = 0;
  86. }
  87. //左电机反转,右电机不转,右转
  88. void goRight()
  89. {
  90. left_con1A = 1;
  91. left_con2A = 0;
  92. right_con1A = 0;
  93. right_con2A = 0;
  94. }
  95. void main()
  96. {
  97. uartInit();
  98. while(1){
  99. sendString("jiangxiaoya\r\n"); //发送心跳包,确保串口通信没有中断
  100. Delay1000ms();
  101. }
  102. }
  103. void myUart() interrupt 4
  104. {
  105. static int i = 0;
  106. char tmp;
  107. //接收数据后,RI硬件置位产生的中断
  108. if(RI){
  109. RI = 0; //RI软件清0
  110. //获取从pc端接收到的数据
  111. tmp = SBUF;
  112. if(tmp == 'f' || tmp == 'b' || tmp == 'l' || tmp == 'r' || tmp == 's'){
  113. i = 0;
  114. }
  115. mybuf[i] = tmp;
  116. i++;
  117. //forward
  118. if(mybuf[0] == 'f' && mybuf[1] == 'o'){
  119. goForward();
  120. memset(mybuf,'\0',24);
  121. }
  122. //forward
  123. if(mybuf[0] == 'b' && mybuf[1] == 'a'){
  124. goBack();
  125. memset(mybuf,'\0',24);
  126. }
  127. //left
  128. if(mybuf[0] == 'l' && mybuf[1] == 'e'){
  129. goLeft();
  130. memset(mybuf,'\0',24);
  131. }
  132. //right
  133. if(mybuf[0] == 'r' && mybuf[1] == 'i'){
  134. goRight();
  135. memset(mybuf,'\0',24);
  136. }
  137. //stop
  138. if(mybuf[0] == 's' && mybuf[1] == 't'){
  139. goStop();
  140. memset(mybuf,'\0',24);
  141. }
  142. if(i == 24){
  143. i = 0;
  144. }
  145. }
  146. //发送数据后,TI硬件置位产生的中断
  147. if(TI);
  148. }

调速小车(利用PWM波对电机进行调速)

  • 利用定时器0软件模拟PWM波控制小车左轮速度,定时器1软件模拟PWM波控制小车右轮速度,通过控制轮子的速度来达到前进、停止、左转、右转
  • 在20ms的过程中,部分时间让电机正转,剩下时间让电机停止不动就能改变电机获得的功率,从而改变电机速度。
  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #include <string.h>
  4. sfr AUXR = 0x8E;
  5. sbit left_con1A = P1^1;
  6. sbit left_con2A = P1^2;
  7. sbit right_con1A = P1^3;
  8. sbit right_con2A = P1^4;
  9. sbit led1 = P3^7;
  10. char mybuf[24] ;
  11. char leftSpeed;
  12. char rightSpeed;
  13. int cntLeft = 0;
  14. int cntRight = 0;
  15. void Delay1000ms() //@11.0592MHz
  16. {
  17. unsigned char i, j, k;
  18. _nop_();
  19. i = 8;
  20. j = 1;
  21. k = 243;
  22. do
  23. {
  24. do
  25. {
  26. while (--k);
  27. } while (--j);
  28. } while (--i);
  29. }
  30. //左电机反转
  31. void goLeftForward()
  32. {
  33. left_con1A = 1;
  34. left_con2A = 0;
  35. }
  36. //左电机不转
  37. void goLeftStop()
  38. {
  39. left_con1A = 0;
  40. left_con2A = 0;
  41. }
  42. //右电机反转
  43. void goRightForward()
  44. {
  45. right_con1A = 1;
  46. right_con2A = 0;
  47. }
  48. //右电机不转
  49. void goRightStop()
  50. {
  51. right_con1A = 0;
  52. right_con2A = 0;
  53. }
  54. //前进
  55. void goForward()
  56. {
  57. leftSpeed = 18;
  58. rightSpeed = 20;
  59. }
  60. //停止
  61. void goStop()
  62. {
  63. leftSpeed = 0;
  64. rightSpeed = 0;
  65. }
  66. //左转
  67. void goLeft()
  68. {
  69. leftSpeed = 10;
  70. rightSpeed = 20;
  71. }
  72. //右转
  73. void goRight()
  74. {
  75. leftSpeed = 20;
  76. rightSpeed = 10;
  77. }
  78. void Timer0Init(void) //1毫秒@11.0592MHz
  79. {
  80. AUXR &= 0x7F; //定时器时钟12T模式
  81. TMOD &= 0xF0; //设置定时器模式
  82. TMOD |= 0x01; //设置定时器模式
  83. //定时器初值为1ms
  84. TL0 = 0x66;
  85. TH0 = 0xFC;
  86. TF0 = 0; //清除TF0标志
  87. TR0 = 1; //定时器0开始计时
  88. ET0 = 1;
  89. EA = 1;
  90. }
  91. void Timer1Init(void) //1毫秒@11.0592MHz
  92. {
  93. AUXR |= 0x40; //定时器时钟1T模式
  94. TMOD &= 0x0F; //设置定时器模式
  95. TMOD |= 0x10; //设置定时器模式
  96. //定时器初值为1ms
  97. TL1 = 0xCD;
  98. TH1 = 0xD4;
  99. TF1 = 0; //清除TF1标志
  100. TR1 = 1; //定时器1开始计时
  101. ET1 = 1;
  102. EA = 1;
  103. }
  104. void main()
  105. {
  106. Timer0Init();
  107. Timer1Init();
  108. while(1){
  109. Delay1000ms();
  110. goForward();
  111. Delay1000ms();
  112. goLeft();
  113. Delay1000ms();
  114. goRight();
  115. }
  116. }
  117. //定时器0的中断函数
  118. void Time0Handler() interrupt 1
  119. {
  120. cntLeft++;
  121. TL0 = 0x66;
  122. TH0 = 0xFC;
  123. if(cntLeft < leftSpeed)
  124. {
  125. goLeftForward();
  126. }else{
  127. goLeftStop();
  128. }
  129. if(cntLeft == 20){
  130. cntLeft = 0;
  131. }
  132. }
  133. void Time1Handler() interrupt 3
  134. {
  135. cntRight++;
  136. TL1 = 0x66;
  137. TH1 = 0xFC;
  138. if(cntRight < rightSpeed)
  139. {
  140. goRightForward();
  141. }else{
  142. goRightStop();
  143. }
  144. if(cntRight == 20){
  145. cntRight = 0;
  146. }
  147. }

循迹小车 (利用循迹模块进行黑白色的检测)

  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #include <string.h>
  4. sfr AUXR = 0x8E;
  5. sbit left_con1A = P1^1;
  6. sbit left_con2A = P1^2;
  7. sbit right_con1A = P1^3;
  8. sbit right_con2A = P1^4;
  9. sbit tracingLeft = P1^5;
  10. sbit tracingRight = P1^6;
  11. char leftSpeed;
  12. char rightSpeed;
  13. int cntLeft = 0;
  14. int cntRight = 0;
  15. //左电机反转
  16. void goLeftForward()
  17. {
  18. left_con1A = 1;
  19. left_con2A = 0;
  20. }
  21. //左电机不转
  22. void goLeftStop()
  23. {
  24. left_con1A = 0;
  25. left_con2A = 0;
  26. }
  27. //右电机反转
  28. void goRightForward()
  29. {
  30. right_con1A = 1;
  31. right_con2A = 0;
  32. }
  33. //右电机不转
  34. void goRightStop()
  35. {
  36. right_con1A = 0;
  37. right_con2A = 0;
  38. }
  39. //前进
  40. void goForward()
  41. {
  42. leftSpeed = 17;
  43. rightSpeed = 20;
  44. }
  45. //停止
  46. void goStop()
  47. {
  48. leftSpeed = 0;
  49. rightSpeed = 0;
  50. }
  51. //左转
  52. void goLeft()
  53. {
  54. leftSpeed = 5;
  55. rightSpeed = 20;
  56. }
  57. //右转
  58. void goRight()
  59. {
  60. leftSpeed = 20;
  61. rightSpeed = 5;
  62. }
  63. void Timer0Init(void) //1毫秒@11.0592MHz
  64. {
  65. AUXR &= 0x7F; //定时器时钟12T模式
  66. TMOD &= 0xF0; //设置定时器模式
  67. TMOD |= 0x01; //设置定时器模式
  68. //定时器初值为1ms
  69. TL0 = 0x66;
  70. TH0 = 0xFC;
  71. TF0 = 0; //清除TF0标志
  72. TR0 = 1; //定时器0开始计时
  73. ET0 = 1;
  74. EA = 1;
  75. }
  76. void Timer1Init(void) //1毫秒@11.0592MHz
  77. {
  78. AUXR |= 0x40; //定时器时钟1T模式
  79. TMOD &= 0x0F; //设置定时器模式
  80. TMOD |= 0x10; //设置定时器模式
  81. //定时器初值为1ms
  82. TL1 = 0xCD;
  83. TH1 = 0xD4;
  84. TF1 = 0; //清除TF1标志
  85. TR1 = 1; //定时器1开始计时
  86. ET1 = 1;
  87. EA = 1;
  88. }
  89. void tracingMode()
  90. {
  91. if(tracingLeft == 0 && tracingRight == 0){ //
  92. goForward();
  93. }
  94. if(tracingLeft == 0 && tracingRight == 1){
  95. goRight();
  96. }
  97. if(tracingLeft == 1 && tracingRight == 0){
  98. goLeft();
  99. }
  100. if(tracingLeft == 1 && tracingRight == 1){
  101. goStop();
  102. }
  103. }
  104. void main()
  105. {
  106. Timer0Init();
  107. Timer1Init();
  108. while(1){
  109. tracingMode();
  110. }
  111. }
  112. //定时器0的中断函数
  113. void Time0Handler() interrupt 1
  114. {
  115. cntLeft++;
  116. TL0 = 0x66;
  117. TH0 = 0xFC;
  118. if(cntLeft < leftSpeed)
  119. {
  120. goLeftForward();
  121. }else{
  122. goLeftStop();
  123. }
  124. if(cntLeft == 20){
  125. cntLeft = 0;
  126. }
  127. }
  128. void Time1Handler() interrupt 3
  129. {
  130. cntRight++;
  131. TL1 = 0x66;
  132. TH1 = 0xFC;
  133. if(cntRight < rightSpeed)
  134. {
  135. goRightForward();
  136. }else{
  137. goRightStop();
  138. }
  139. if(cntRight == 20){
  140. cntRight = 0;
  141. }
  142. }

跟随小车(利用红外避障模块完成跟随行为)

  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #include <string.h>
  4. sfr AUXR = 0x8E;
  5. sbit left_con1A = P1^1;
  6. sbit left_con2A = P1^2;
  7. sbit right_con1A = P1^3;
  8. sbit right_con2A = P1^4;
  9. sbit followLeft = P2^1;
  10. sbit followRight = P2^2;
  11. char leftSpeed;
  12. char rightSpeed;
  13. int cntLeft = 0;
  14. int cntRight = 0;
  15. //左电机反转
  16. void goLeftForward()
  17. {
  18. left_con1A = 1;
  19. left_con2A = 0;
  20. }
  21. //左电机不转
  22. void goLeftStop()
  23. {
  24. left_con1A = 0;
  25. left_con2A = 0;
  26. }
  27. //右电机反转
  28. void goRightForward()
  29. {
  30. right_con1A = 1;
  31. right_con2A = 0;
  32. }
  33. //右电机不转
  34. void goRightStop()
  35. {
  36. right_con1A = 0;
  37. right_con2A = 0;
  38. }
  39. //前进
  40. void goForward()
  41. {
  42. leftSpeed = 17;
  43. rightSpeed = 20;
  44. }
  45. //停止
  46. void goStop()
  47. {
  48. leftSpeed = 0;
  49. rightSpeed = 0;
  50. }
  51. //左转
  52. void goLeft()
  53. {
  54. leftSpeed = 8;
  55. rightSpeed = 20;
  56. }
  57. //右转
  58. void goRight()
  59. {
  60. leftSpeed = 20;
  61. rightSpeed = 10;
  62. }
  63. void Timer0Init(void) //1毫秒@11.0592MHz
  64. {
  65. AUXR &= 0x7F; //定时器时钟12T模式
  66. TMOD &= 0xF0; //设置定时器模式
  67. TMOD |= 0x01; //设置定时器模式
  68. //定时器初值为1ms
  69. TL0 = 0x66;
  70. TH0 = 0xFC;
  71. TF0 = 0; //清除TF0标志
  72. TR0 = 1; //定时器0开始计时
  73. ET0 = 1;
  74. EA = 1;
  75. }
  76. void Timer1Init(void) //1毫秒@11.0592MHz
  77. {
  78. AUXR |= 0x40; //定时器时钟1T模式
  79. TMOD &= 0x0F; //设置定时器模式
  80. TMOD |= 0x10; //设置定时器模式
  81. //定时器初值为1ms
  82. TL1 = 0xCD;
  83. TH1 = 0xD4;
  84. TF1 = 0; //清除TF1标志
  85. TR1 = 1; //定时器1开始计时
  86. ET1 = 1;
  87. EA = 1;
  88. }
  89. void followMode()
  90. {
  91. if(followLeft == 0 && followRight == 0){ //
  92. goForward();
  93. }
  94. if(followLeft == 0 && followRight == 1){
  95. goRight();
  96. }
  97. if(followLeft == 1 && followRight == 0){
  98. goLeft();
  99. }
  100. if(followLeft == 1 && followRight == 1){
  101. goStop();
  102. }
  103. }
  104. void main()
  105. {
  106. Timer0Init();
  107. Timer1Init();
  108. while(1){
  109. followMode();
  110. }
  111. }
  112. //定时器0的中断函数
  113. void Time0Handler() interrupt 1
  114. {
  115. cntLeft++;
  116. TL0 = 0x66;
  117. TH0 = 0xFC;
  118. if(cntLeft < leftSpeed)
  119. {
  120. goLeftForward();
  121. }else{
  122. goLeftStop();
  123. }
  124. if(cntLeft == 20){
  125. cntLeft = 0;
  126. }
  127. }
  128. void Time1Handler() interrupt 3
  129. {
  130. cntRight++;
  131. TL1 = 0x66;
  132. TH1 = 0xFC;
  133. if(cntRight < rightSpeed)
  134. {
  135. goRightForward();
  136. }else{
  137. goRightStop();
  138. }
  139. if(cntRight == 20){
  140. cntRight = 0;
  141. }
  142. }

避障小车(利用超声波测距完成避障行为)

  • 利用定时器0软件模拟PWM波控制sg90舵机转动方向
  • 利用定时器1和超声波不断测量前方距离
  1. #include "reg52.h"
  2. #include <intrins.h>
  3. sbit left_con1A = P1^1;
  4. sbit left_con2A = P1^2;
  5. sbit right_con1A = P1^3;
  6. sbit right_con2A = P1^4;
  7. sbit Trig = P2^3;
  8. sbit Echo = P2^4;
  9. sbit sg90 = P2^5;
  10. int angle;
  11. int angleBack;
  12. int cnt = 0;
  13. void Delay100ms() //@11.0592MHz
  14. {
  15. unsigned char i, j;
  16. i = 180;
  17. j = 73;
  18. do
  19. {
  20. while (--j);
  21. } while (--i);
  22. }
  23. void Delay300ms() //@11.0592MHz
  24. {
  25. unsigned char i, j, k;
  26. _nop_();
  27. i = 3;
  28. j = 26;
  29. k = 223;
  30. do
  31. {
  32. do
  33. {
  34. while (--k);
  35. } while (--j);
  36. } while (--i);
  37. }
  38. void Delay500ms() //@11.0592MHz
  39. {
  40. unsigned char i, j, k;
  41. _nop_();
  42. i = 4;
  43. j = 129;
  44. k = 119;
  45. do
  46. {
  47. do
  48. {
  49. while (--k);
  50. } while (--j);
  51. } while (--i);
  52. }
  53. void Delay10us() //@11.0592MHz
  54. {
  55. unsigned char i;
  56. i = 2;
  57. while (--i);
  58. }
  59. //两个电机反转,前进
  60. void goForward()
  61. {
  62. left_con1A = 1;
  63. left_con2A = 0;
  64. right_con1A = 1;
  65. right_con2A = 0;
  66. }
  67. //两个电机正转,后退
  68. void goBack()
  69. {
  70. left_con1A = 0;
  71. left_con2A = 1;
  72. right_con1A = 0;
  73. right_con2A = 1;
  74. }
  75. //两个电机不转,停止
  76. void goStop()
  77. {
  78. left_con1A = 0;
  79. left_con2A = 0;
  80. right_con1A = 0;
  81. right_con2A = 0;
  82. }
  83. //左电机不转,右电机反转,左转
  84. void goLeft()
  85. {
  86. left_con1A = 0;
  87. left_con2A = 0;
  88. right_con1A = 1;
  89. right_con2A = 0;
  90. }
  91. //左电机反转,右电机不转,右转
  92. void goRight()
  93. {
  94. left_con1A = 1;
  95. left_con2A = 0;
  96. right_con1A = 0;
  97. right_con2A = 0;
  98. }
  99. void timer0Init()
  100. {
  101. //设置定时器0为16为计时模式
  102. TMOD &=0xF0;
  103. TMOD |=0x01;
  104. //设置定时器0定时时间为0.5ms
  105. TH0 = 0xFE;
  106. TL0 = 0x33;
  107. TR0 = 1; //定时器0开始计时
  108. TF0 = 0; //不执行定时器0爆表时导致的中断
  109. ET0 = 1; //定时器0中断开关
  110. EA = 1; //总中断开关
  111. }
  112. void timer1Init()
  113. {
  114. //设置定时器1为16为计时模式
  115. TMOD &= 0x0F;
  116. TMOD |= 0x10;
  117. TH1 = 0x00;
  118. TL1 = 0x00;
  119. }
  120. void ultrasonicStart()
  121. {
  122. Trig = 0;
  123. Trig = 1;
  124. Delay10us();
  125. Trig = 0;
  126. }
  127. double getDistance()
  128. {
  129. double time = 0;
  130. //定时器1清0
  131. TH1 = 0x00;
  132. TL1 = 0x00;
  133. ultrasonicStart();
  134. while(Echo == 0); //当Echo引脚从低电平跳到高电平时开启定时器1
  135. TR1 = 1;
  136. while(Echo == 1); //当Echo引脚从高电平跳到低电平时关闭定时器1
  137. TR1 = 0;
  138. time = (TH1*256 + TL1) * 1.085; //微秒
  139. return (time * 0.017);
  140. }
  141. void sg90Left()
  142. {
  143. angle = 5; //180°
  144. if(angleBack != angle){
  145. cnt = 0;
  146. }
  147. angleBack = angle;
  148. Delay100ms();
  149. }
  150. void sg90Middle()
  151. {
  152. angle = 3; //90°
  153. if(angleBack != angle){
  154. cnt = 0;
  155. }
  156. angleBack = angle;
  157. Delay100ms();
  158. }
  159. void sg90Right()
  160. {
  161. angle = 1; //0°
  162. if(angleBack != angle){
  163. cnt = 0;
  164. }
  165. angleBack = angle;
  166. Delay100ms();
  167. }
  168. void main()
  169. {
  170. double leftDistance;
  171. double rightDistance;
  172. double middleDistance;
  173. timer0Init();
  174. timer1Init();
  175. sg90Middle();
  176. Delay500ms();
  177. while(1){
  178. sg90Middle();
  179. Delay300ms();
  180. middleDistance = getDistance();
  181. if(middleDistance > 35){
  182. goForward();
  183. }else{
  184. goStop();
  185. sg90Left();
  186. Delay300ms();
  187. leftDistance = getDistance();
  188. sg90Middle();
  189. Delay300ms();
  190. sg90Right();
  191. Delay300ms();
  192. rightDistance = getDistance();
  193. if(leftDistance < 15 && rightDistance < 15){
  194. goBack();
  195. Delay500ms();
  196. goStop();
  197. }else{
  198. if(leftDistance > rightDistance){
  199. goLeft();
  200. Delay500ms();
  201. goStop();
  202. }
  203. if(rightDistance > leftDistance){
  204. goRight();
  205. Delay500ms();
  206. goStop();
  207. }
  208. }
  209. }
  210. }
  211. }
  212. //定时器0的中断函数
  213. void Time0Handler() interrupt 1
  214. {
  215. TH0 = 0xFE;
  216. TL0 = 0x33;
  217. cnt++;
  218. //控制占空比
  219. if(cnt < angle){
  220. sg90 = 1;
  221. }else{
  222. sg90 = 0;
  223. }
  224. if(cnt == 40){ //每个周期为20ms
  225. cnt = 0;
  226. sg90 = 1;
  227. }
  228. }

测速小车,使用OLED屏显示小车速度

  • 轮子走一圈,经过一个周长,C = 2x3.14x半径= 3.14 x 直径(6.5cm),对应的转速码盘也转了一圈
  • 码盘有20个格子,每经过一个格子,会遮挡(高电平)和不遮挡(低电平),即产生下降沿,一个下降沿就是走了 3.14 * 6.5 cm /20 = 1.0205CM
  • 定时器可以设计成一秒,统计下降沿,一个下降沿就是1cm,假设一秒有80脉冲,那么就是80cm/s
  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. sfr AUXR = 0x8E;
  6. sbit left_con1A = P1^1;
  7. sbit left_con2A = P1^2;
  8. sbit right_con1A = P1^3;
  9. sbit right_con2A = P1^4;
  10. sbit Tachometer = P3^2; //测速模块产生下降沿,让外部中断0产生中断
  11. sbit scl = P2^6;
  12. sbit sda = P2^7;
  13. char mybuf[24];
  14. int signal;
  15. unsigned int cnt;
  16. unsigned int speedCnt = 0;
  17. unsigned int speed;
  18. char speedMsg[24];
  19. void Delay5us() //@11.0592MHz
  20. {
  21. }
  22. //两个电机反转,前进
  23. void goForward()
  24. {
  25. left_con1A = 1;
  26. left_con2A = 0;
  27. right_con1A = 1;
  28. right_con2A = 0;
  29. }
  30. //两个电机正转,后退
  31. void goBack()
  32. {
  33. left_con1A = 0;
  34. left_con2A = 1;
  35. right_con1A = 0;
  36. right_con2A = 1;
  37. }
  38. //两个电机不转,停止
  39. void goStop()
  40. {
  41. left_con1A = 0;
  42. left_con2A = 0;
  43. right_con1A = 0;
  44. right_con2A = 0;
  45. }
  46. //左电机不转,右电机反转,左转
  47. void goLeft()
  48. {
  49. left_con1A = 0;
  50. left_con2A = 0;
  51. right_con1A = 1;
  52. right_con2A = 0;
  53. }
  54. //左电机反转,右电机不转,右转
  55. void goRight()
  56. {
  57. left_con1A = 1;
  58. left_con2A = 0;
  59. right_con1A = 0;
  60. right_con2A = 0;
  61. }
  62. //串口初始化
  63. void uartInit()
  64. {
  65. AUXR = 0x01;
  66. PCON &= 0x7F; //配置波特率正常
  67. SCON = 0x50; //配置串口选择工作方式1,允许串口接收数据
  68. //配置定时器1为8位自动重装模式
  69. TMOD &= 0x0F;
  70. TMOD |= 0x20;
  71. //给定时器1,9600波特率初值
  72. TH1 = 0xFD; //定时器1初值
  73. TL1 = 0xFD; //定时器1重装值
  74. ET1 = 0; //不允许定时器1产生中断
  75. TR1 = 1; //开启定时器1
  76. EA = 1; //开启总中断
  77. ES = 1; //开启串口中断
  78. }
  79. //定时器0初始化,初值为1ms
  80. void Time0Init()
  81. {
  82. TMOD &=0xF0;
  83. TMOD |=0x01;
  84. //1ms
  85. TL0 = 0x66;
  86. TH0 = 0xFC;
  87. TR0 = 1;
  88. ET0 = 1;
  89. EA =1;
  90. }
  91. //外部中断0初始化
  92. void int0Init()
  93. {
  94. EX0 = 1;
  95. EA = 1;
  96. IT0 = 1; //下降沿触发外部中断0
  97. }
  98. //IIC起始信号
  99. void IIC_start()
  100. {
  101. sda = 0;
  102. scl = 1;
  103. sda = 1;
  104. Delay5us();
  105. sda = 0;
  106. Delay5us();
  107. scl = 0;
  108. }
  109. //IIC终止信号
  110. void IIC_stop()
  111. {
  112. scl = 0;
  113. sda = 0;
  114. scl = 1;
  115. Delay5us();
  116. sda = 1;
  117. Delay5us();
  118. sda = 0;
  119. }
  120. //IIC的ACK应答信号
  121. char IIC_ack()
  122. {
  123. char flag;
  124. scl = 0;
  125. sda = 1; //在时钟脉冲9期间释放数据线
  126. Delay5us(); //延时5微秒后,为读取sda数据做准备
  127. scl = 1;
  128. Delay5us();
  129. flag = sda; //读取数据线,0为应答
  130. Delay5us();
  131. scl = 0;
  132. Delay5us();
  133. return flag;
  134. }
  135. //IIC发送一个字节
  136. void IIC_sendByte(char myData)
  137. {
  138. int i;
  139. for ( i = 0; i < 8; i++){
  140. //发生数据翻转,选择即将发送的是0还是1
  141. scl = 0;
  142. sda = myData & 0x80; //获取需要发送字节的最高位到SDA
  143. Delay5us(); //数据建立时间
  144. //开始发送数据
  145. scl = 1;
  146. Delay5us(); //数据发送时间
  147. scl = 0; //发送完毕拉低,等待下1bit数据的传输
  148. Delay5us();
  149. myData = myData << 1;
  150. }
  151. }
  152. //OLED写入一条指令
  153. void oledWriteCmd(char writeCmd)
  154. {
  155. IIC_start();
  156. IIC_sendByte(0x78); //选择一个OLED屏,写模式
  157. IIC_ack();
  158. IIC_sendByte(0x00); //写入命令,D/C位为0
  159. IIC_ack();
  160. IIC_sendByte(writeCmd);
  161. IIC_ack();
  162. IIC_stop();
  163. }
  164. //OLED写入一个数据
  165. void oledWriteData(char writeData)
  166. {
  167. IIC_start();
  168. IIC_sendByte(0x78); //选择一个OLED屏,写模式
  169. IIC_ack();
  170. IIC_sendByte(0x40); //写入命令,D/C位为0
  171. IIC_ack();
  172. IIC_sendByte(writeData);
  173. IIC_ack();
  174. IIC_stop();
  175. }
  176. //OLCD初始化
  177. void oledInit()
  178. {
  179. oledWriteCmd(0xAE);
  180. oledWriteCmd(0x00);
  181. oledWriteCmd(0x10);
  182. oledWriteCmd(0x40);
  183. oledWriteCmd(0xB0);
  184. oledWriteCmd(0x81);
  185. oledWriteCmd(0xFF);
  186. oledWriteCmd(0xA1);
  187. oledWriteCmd(0xA6);
  188. oledWriteCmd(0xA8);
  189. oledWriteCmd(0x3F);
  190. oledWriteCmd(0xC8);
  191. oledWriteCmd(0xD3);
  192. oledWriteCmd(0x00);
  193. oledWriteCmd(0xD5);
  194. oledWriteCmd(0x80);
  195. oledWriteCmd(0xD8);
  196. oledWriteCmd(0x05);
  197. oledWriteCmd(0xD9);
  198. oledWriteCmd(0xF1);
  199. oledWriteCmd(0xDA);
  200. oledWriteCmd(0x12);
  201. oledWriteCmd(0xDB);
  202. oledWriteCmd(0x30);
  203. oledWriteCmd(0x8D);
  204. oledWriteCmd(0x14);
  205. oledWriteCmd(0xAF);
  206. }
  207. void olceClean()
  208. {
  209. int i,j;
  210. for(i=0;i<8;i++){
  211. oledWriteCmd(0xB0 + i); //选择PAGE
  212. //选择PAGE的第0列开始显示
  213. oledWriteCmd(0x00);
  214. oledWriteCmd(0x10);
  215. for(j = 0;j < 128; j++){
  216. oledWriteData(0); //写入字符0
  217. }
  218. }
  219. }
  220. //OLED的字符构造点阵
  221. const unsigned char code oledFont[]=
  222. {
  223. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
  224. 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  225. 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  226. 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  227. 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  228. 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  229. 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  230. 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  231. 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  232. 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  233. 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  234. 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  235. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  236. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  237. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  238. 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  239. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  240. 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  241. 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  242. 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  243. 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  244. 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  245. 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  246. 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  247. 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  248. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  249. 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  250. 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
  251. 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  252. 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  253. 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  254. 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  255. 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  256. 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  257. 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  258. 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  259. 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  260. 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  261. 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  262. 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  263. 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  264. 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  265. 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  266. 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  267. 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  268. 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  269. 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  270. 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  271. 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  272. 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  273. 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  274. 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  275. 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  276. 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  277. 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  278. 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  279. 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  280. 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  281. 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  282. 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  283. 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  284. 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  285. 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  286. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  287. 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  288. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  289. 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  290. 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  291. 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  292. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  293. 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  294. 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  295. 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  296. 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  297. 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  298. 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  299. 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  300. 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  301. 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  302. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  303. 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  304. 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  305. 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  306. 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  307. 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  308. 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  309. 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  310. 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  311. 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  312. 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  313. 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  314. 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  315. 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  316. 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  317. 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
  318. };
  319. //OLED显示一个字符
  320. void oledShowByte(char rows,char columns,char oledByte)
  321. {
  322. unsigned int i;
  323. //显示字符的上半部分
  324. oledWriteCmd(0xb0+(rows*2-2)); //选择行
  325. //选择列
  326. oledWriteCmd(0x00+(columns&0x0f));
  327. oledWriteCmd(0x10+(columns>>4));
  328. //显示数据
  329. for(i=((oledByte-32)*16);i<((oledByte-32)*16+8);i++){
  330. oledWriteData(oledFont[i]);
  331. }
  332. //显示字符的上半部分
  333. oledWriteCmd(0xb0+(rows*2-1)); //选择行
  334. //选择列
  335. oledWriteCmd(0x00+(columns&0x0f));
  336. oledWriteCmd(0x10+(columns>>4));
  337. //显示数据
  338. for(i=((oledByte-32)*16+8);i<((oledByte-32)*16+8+8);i++){
  339. oledWriteData(oledFont[i]);
  340. }
  341. }
  342. //OLED显示一个字符串
  343. void oledShowString(char rows,char columns,char *str)
  344. {
  345. while(*str != '\0'){
  346. oledShowByte(rows,columns,*str);
  347. str++;
  348. columns += 8;
  349. }
  350. }
  351. void main()
  352. {
  353. uartInit();
  354. Time0Init();
  355. int0Init();
  356. oledInit();
  357. olceClean(); //清屏函数
  358. oledWriteCmd(0x20); //设置内存
  359. oledWriteCmd(0x02); //选择页寻址模式
  360. while(1){
  361. if(signal == 1){
  362. sprintf(speedMsg,"speed:%dcm/s ",speed);
  363. olceClean();
  364. oledShowString(2,5,speedMsg);
  365. signal = 0;
  366. }
  367. }
  368. }
  369. //定时器0产生的中断的处理函数
  370. void Time0Handle() interrupt 1
  371. {
  372. cnt++;
  373. TL0 = 0x66;
  374. TH0 = 0xFC;
  375. //每过一秒统计一次产生了多少次下降沿,让main函数向串口发送当前小车速度
  376. if(cnt == 1000){
  377. cnt = 0;
  378. signal = 1;
  379. speed = speedCnt;
  380. speedCnt = 0;
  381. }
  382. }
  383. //外部中断0产生的中断的处理函数
  384. void int0Handle() interrupt 0
  385. {
  386. speedCnt++; //每产生一个下降沿让标志位+1
  387. }
  388. //串口产生的中断的处理函数
  389. void myUart() interrupt 4
  390. {
  391. static int i = 0;
  392. char tmp;
  393. //接收数据后,RI硬件置位产生的中断
  394. if(RI){
  395. RI = 0; //RI软件清0
  396. //获取从pc端接收到的数据
  397. tmp = SBUF;
  398. if(tmp == 'f' || tmp == 'b' || tmp == 'l' || tmp == 'r' || tmp == 's'){
  399. i = 0;
  400. }
  401. mybuf[i] = tmp;
  402. i++;
  403. //forward
  404. if(mybuf[0] == 'f' && mybuf[1] == 'o'){
  405. goForward();
  406. memset(mybuf,'\0',24);
  407. }
  408. //forward
  409. if(mybuf[0] == 'b' && mybuf[1] == 'a'){
  410. goBack();
  411. memset(mybuf,'\0',24);
  412. }
  413. //left
  414. if(mybuf[0] == 'l' && mybuf[1] == 'e'){
  415. goLeft();
  416. memset(mybuf,'\0',24);
  417. }
  418. //right
  419. if(mybuf[0] == 'r' && mybuf[1] == 'i'){
  420. goRight();
  421. memset(mybuf,'\0',24);
  422. }
  423. //stop
  424. if(mybuf[0] == 's' && mybuf[1] == 't'){
  425. goStop();
  426. memset(mybuf,'\0',24);
  427. }
  428. if(i == 24){
  429. i = 0;
  430. }
  431. }
  432. //发送数据后,TI硬件置位产生的中断
  433. if(TI);
  434. }

语音控制小车,循迹、跟随、避障三种功能切换

  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #define BZ 1
  4. #define XJ 2
  5. #define GS 3
  6. sfr AUXR = 0x8E;
  7. //sg90
  8. sbit sg90 = P2^5;
  9. //ultrasonic
  10. sbit Trig = P2^3;
  11. sbit Echo = P2^4;
  12. //oled
  13. sbit scl = P2^6;
  14. sbit sda = P2^7;
  15. //car
  16. sbit left_con1A = P1^1;
  17. sbit left_con2A = P1^2;
  18. sbit right_con1A = P1^3;
  19. sbit right_con2A = P1^4;
  20. //循迹
  21. sbit tracingLeft = P1^5;
  22. sbit tracingRight = P1^6;
  23. //跟随
  24. sbit followLeft = P2^1;
  25. sbit followRight = P2^2;
  26. //su-03t
  27. sbit A25 = P0^1;
  28. sbit A26 = P0^2;
  29. sbit A27 = P0^3;
  30. int angle;
  31. int angleBack;
  32. int cnt = 0;
  33. double leftDistance;
  34. double rightDistance;
  35. double middleDistance;
  36. //OLED的字符构造点阵
  37. const unsigned char code oledFont[]=
  38. {
  39. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0
  40. 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
  41. 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2
  42. 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3
  43. 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4
  44. 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5
  45. 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6
  46. 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7
  47. 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8
  48. 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9
  49. 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10
  50. 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11
  51. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12
  52. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13
  53. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14
  54. 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15
  55. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16
  56. 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17
  57. 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18
  58. 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19
  59. 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20
  60. 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21
  61. 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22
  62. 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23
  63. 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24
  64. 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25
  65. 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26
  66. 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27
  67. 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28
  68. 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29
  69. 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30
  70. 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31
  71. 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32
  72. 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33
  73. 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34
  74. 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35
  75. 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36
  76. 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37
  77. 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38
  78. 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39
  79. 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40
  80. 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41
  81. 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42
  82. 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43
  83. 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44
  84. 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45
  85. 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46
  86. 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47
  87. 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48
  88. 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49
  89. 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50
  90. 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51
  91. 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52
  92. 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53
  93. 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54
  94. 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55
  95. 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56
  96. 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57
  97. 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58
  98. 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59
  99. 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60
  100. 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61
  101. 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62
  102. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63
  103. 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64
  104. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65
  105. 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66
  106. 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67
  107. 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68
  108. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69
  109. 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70
  110. 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71
  111. 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72
  112. 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73
  113. 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74
  114. 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75
  115. 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76
  116. 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77
  117. 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78
  118. 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79
  119. 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80
  120. 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81
  121. 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82
  122. 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83
  123. 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84
  124. 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85
  125. 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86
  126. 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87
  127. 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88
  128. 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89
  129. 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90
  130. 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91
  131. 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92
  132. 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93
  133. 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
  134. };
  135. void Delay5us() //@11.0592MHz
  136. {
  137. }
  138. void Delay10us() //@11.0592MHz
  139. {
  140. unsigned char i;
  141. i = 2;
  142. while (--i);
  143. }
  144. void Delay100ms() //@11.0592MHz
  145. {
  146. unsigned char i, j;
  147. i = 180;
  148. j = 73;
  149. do
  150. {
  151. while (--j);
  152. } while (--i);
  153. }
  154. void Delay300ms() //@11.0592MHz
  155. {
  156. unsigned char i, j, k;
  157. _nop_();
  158. i = 3;
  159. j = 26;
  160. k = 223;
  161. do
  162. {
  163. do
  164. {
  165. while (--k);
  166. } while (--j);
  167. } while (--i);
  168. }
  169. void Delay500ms() //@11.0592MHz
  170. {
  171. unsigned char i, j, k;
  172. _nop_();
  173. i = 4;
  174. j = 129;
  175. k = 119;
  176. do
  177. {
  178. do
  179. {
  180. while (--k);
  181. } while (--j);
  182. } while (--i);
  183. }
  184. //sg90
  185. void timer0Init()
  186. {
  187. //设置定时器0为16为计时模式
  188. TMOD &=0xF0;
  189. TMOD |=0x01;
  190. //设置定时器0定时时间为0.5ms
  191. TH0 = 0xFE;
  192. TL0 = 0x33;
  193. TR0 = 1; //定时器0开始计时
  194. TF0 = 0; //不执行定时器0爆表时导致的中断
  195. ET0 = 1; //定时器0中断开关
  196. EA = 1; //总中断开关
  197. }
  198. void sg90Left()
  199. {
  200. angle = 5; //180°
  201. if(angleBack != angle){
  202. cnt = 0;
  203. }
  204. angleBack = angle;
  205. Delay100ms();
  206. }
  207. void sg90Middle()
  208. {
  209. angle = 3; //90°
  210. if(angleBack != angle){
  211. cnt = 0;
  212. }
  213. angleBack = angle;
  214. Delay100ms();
  215. }
  216. void sg90Right()
  217. {
  218. angle = 1; //0°
  219. if(angleBack != angle){
  220. cnt = 0;
  221. }
  222. angleBack = angle;
  223. Delay100ms();
  224. }
  225. //ultrasonic
  226. void timer1Init()
  227. {
  228. //设置定时器1为16为计时模式
  229. TMOD &= 0x0F;
  230. TMOD |= 0x10;
  231. TH1 = 0x00;
  232. TL1 = 0x00;
  233. }
  234. void ultrasonicStart()
  235. {
  236. Trig = 0;
  237. Trig = 1;
  238. Delay10us();
  239. Trig = 0;
  240. }
  241. double getDistance()
  242. {
  243. double time = 0;
  244. //定时器1清0
  245. TH1 = 0x00;
  246. TL1 = 0x00;
  247. ultrasonicStart();
  248. while(Echo == 0); //当Echo引脚从低电平跳到高电平时开启定时器1
  249. TR1 = 1;
  250. while(Echo == 1); //当Echo引脚从高电平跳到低电平时关闭定时器1
  251. TR1 = 0;
  252. time = (TH1*256 + TL1) * 1.085; //微秒
  253. return (time * 0.017);
  254. }
  255. //oled
  256. //IIC起始信号
  257. void IIC_start()
  258. {
  259. sda = 0;
  260. scl = 1;
  261. sda = 1;
  262. Delay5us();
  263. sda = 0;
  264. Delay5us();
  265. scl = 0;
  266. }
  267. //IIC终止信号
  268. void IIC_stop()
  269. {
  270. scl = 0;
  271. sda = 0;
  272. scl = 1;
  273. Delay5us();
  274. sda = 1;
  275. Delay5us();
  276. sda = 0;
  277. }
  278. //IIC的ACK应答信号
  279. char IIC_ack()
  280. {
  281. char flag;
  282. scl = 0;
  283. sda = 1; //在时钟脉冲9期间释放数据线
  284. Delay5us(); //延时5微秒后,为读取sda数据做准备
  285. scl = 1;
  286. Delay5us();
  287. flag = sda; //读取数据线,0为应答
  288. Delay5us();
  289. scl = 0;
  290. Delay5us();
  291. return flag;
  292. }
  293. //IIC发送一个字节
  294. void IIC_sendByte(char myData)
  295. {
  296. int i;
  297. for ( i = 0; i < 8; i++){
  298. //发生数据翻转,选择即将发送的是0还是1
  299. scl = 0;
  300. sda = myData & 0x80; //获取需要发送字节的最高位到SDA
  301. Delay5us(); //数据建立时间
  302. //开始发送数据
  303. scl = 1;
  304. Delay5us(); //数据发送时间
  305. scl = 0; //发送完毕拉低,等待下1bit数据的传输
  306. Delay5us();
  307. myData = myData << 1;
  308. }
  309. }
  310. //OLED写入一条指令
  311. void oledWriteCmd(char writeCmd)
  312. {
  313. IIC_start();
  314. IIC_sendByte(0x78); //选择一个OLED屏,写模式
  315. IIC_ack();
  316. IIC_sendByte(0x00); //写入命令,D/C位为0
  317. IIC_ack();
  318. IIC_sendByte(writeCmd);
  319. IIC_ack();
  320. IIC_stop();
  321. }
  322. //OLED写入一个数据
  323. void oledWriteData(char writeData)
  324. {
  325. IIC_start();
  326. IIC_sendByte(0x78); //选择一个OLED屏,写模式
  327. IIC_ack();
  328. IIC_sendByte(0x40); //写入命令,D/C位为0
  329. IIC_ack();
  330. IIC_sendByte(writeData);
  331. IIC_ack();
  332. IIC_stop();
  333. }
  334. //OLCD初始化
  335. void oledInit()
  336. {
  337. oledWriteCmd(0xAE);
  338. oledWriteCmd(0x00);
  339. oledWriteCmd(0x10);
  340. oledWriteCmd(0x40);
  341. oledWriteCmd(0xB0);
  342. oledWriteCmd(0x81);
  343. oledWriteCmd(0xFF);
  344. oledWriteCmd(0xA1);
  345. oledWriteCmd(0xA6);
  346. oledWriteCmd(0xA8);
  347. oledWriteCmd(0x3F);
  348. oledWriteCmd(0xC8);
  349. oledWriteCmd(0xD3);
  350. oledWriteCmd(0x00);
  351. oledWriteCmd(0xD5);
  352. oledWriteCmd(0x80);
  353. oledWriteCmd(0xD8);
  354. oledWriteCmd(0x05);
  355. oledWriteCmd(0xD9);
  356. oledWriteCmd(0xF1);
  357. oledWriteCmd(0xDA);
  358. oledWriteCmd(0x12);
  359. oledWriteCmd(0xDB);
  360. oledWriteCmd(0x30);
  361. oledWriteCmd(0x8D);
  362. oledWriteCmd(0x14);
  363. oledWriteCmd(0xAF);
  364. }
  365. //OLED清屏函数
  366. void olceClean()
  367. {
  368. int i,j;
  369. for(i=0;i<8;i++){
  370. oledWriteCmd(0xB0 + i); //选择PAGE
  371. //选择PAGE的第0列开始显示
  372. oledWriteCmd(0x00);
  373. oledWriteCmd(0x10);
  374. for(j = 0;j < 128; j++){
  375. oledWriteData(0); //写入字符0
  376. }
  377. }
  378. }
  379. //OLED显示一个字符
  380. void oledShowByte(char rows,char columns,char oledByte)
  381. {
  382. unsigned int i;
  383. //显示字符的上半部分
  384. oledWriteCmd(0xb0+(rows*2-2)); //选择行
  385. //选择列
  386. oledWriteCmd(0x00+(columns&0x0f));
  387. oledWriteCmd(0x10+(columns>>4));
  388. //显示数据
  389. for(i=((oledByte-32)*16);i<((oledByte-32)*16+8);i++){
  390. oledWriteData(oledFont[i]);
  391. }
  392. //显示字符的上半部分
  393. oledWriteCmd(0xb0+(rows*2-1)); //选择行
  394. //选择列
  395. oledWriteCmd(0x00+(columns&0x0f));
  396. oledWriteCmd(0x10+(columns>>4));
  397. //显示数据
  398. for(i=((oledByte-32)*16+8);i<((oledByte-32)*16+8+8);i++){
  399. oledWriteData(oledFont[i]);
  400. }
  401. }
  402. //OLED显示一个字符串
  403. void oledShowString(char rows,char columns,char *str)
  404. {
  405. while(*str != '\0'){
  406. oledShowByte(rows,columns,*str);
  407. str++;
  408. columns += 8;
  409. }
  410. }
  411. //car
  412. //两个电机反转,前进
  413. void goForward()
  414. {
  415. left_con1A = 1;
  416. left_con2A = 0;
  417. right_con1A = 1;
  418. right_con2A = 0;
  419. }
  420. //两个电机正转,后退
  421. void goBack()
  422. {
  423. left_con1A = 0;
  424. left_con2A = 1;
  425. right_con1A = 0;
  426. right_con2A = 1;
  427. }
  428. //两个电机不转,停止
  429. void goStop()
  430. {
  431. left_con1A = 0;
  432. left_con2A = 0;
  433. right_con1A = 0;
  434. right_con2A = 0;
  435. }
  436. //左电机不转,右电机反转,左转
  437. void goLeft()
  438. {
  439. left_con1A = 0;
  440. left_con2A = 0;
  441. right_con1A = 1;
  442. right_con2A = 0;
  443. }
  444. //左电机反转,右电机不转,右转
  445. void goRight()
  446. {
  447. left_con1A = 1;
  448. left_con2A = 0;
  449. right_con1A = 0;
  450. right_con2A = 0;
  451. }
  452. //循迹模式
  453. void tracingMode()
  454. {
  455. if(tracingLeft == 0 && tracingRight == 0){
  456. goForward();
  457. }
  458. if(tracingLeft == 0 && tracingRight == 1){
  459. goRight();
  460. }
  461. if(tracingLeft == 1 && tracingRight == 0){
  462. goLeft();
  463. }
  464. if(tracingLeft == 1 && tracingRight == 1){
  465. goStop();
  466. }
  467. }
  468. //跟随模式
  469. void followMode()
  470. {
  471. if(followLeft == 0 && followRight == 0){ //
  472. goForward();
  473. }
  474. if(followLeft == 0 && followRight == 1){
  475. goRight();
  476. }
  477. if(followLeft == 1 && followRight == 0){
  478. goLeft();
  479. }
  480. if(followLeft == 1 && followRight == 1){
  481. goStop();
  482. }
  483. }
  484. //避障模式
  485. void avoidMode()
  486. {
  487. sg90Middle();
  488. Delay300ms();
  489. middleDistance = getDistance();
  490. if(middleDistance > 35){
  491. goForward();
  492. }else{
  493. goStop();
  494. sg90Left();
  495. Delay300ms();
  496. leftDistance = getDistance();
  497. sg90Middle();
  498. Delay300ms();
  499. sg90Right();
  500. Delay300ms();
  501. rightDistance = getDistance();
  502. if(leftDistance < 15 && rightDistance < 15){
  503. goBack();
  504. Delay500ms();
  505. goStop();
  506. }else{
  507. if(leftDistance > rightDistance){
  508. goLeft();
  509. Delay500ms();
  510. goStop();
  511. }
  512. if(rightDistance > leftDistance){
  513. goRight();
  514. Delay500ms();
  515. goStop();
  516. }
  517. }
  518. }
  519. }
  520. void main()
  521. {
  522. int mark = 0;
  523. timer0Init();
  524. timer1Init();
  525. sg90Middle();
  526. Delay500ms();
  527. oledInit();
  528. olceClean();
  529. oledShowString(2,5,"haozige");
  530. while(1){
  531. if(A25 == 0 && A26 == 1 && A27 == 1){
  532. if(mark != GS){
  533. olceClean();
  534. oledShowString(2,5,"genshuai");
  535. }
  536. mark = GS;
  537. followMode();
  538. }
  539. if(A25 == 1 && A26 == 0 && A27 == 1){
  540. if(mark != BZ){
  541. olceClean();
  542. oledShowString(2,5,"bizhang");
  543. }
  544. mark = BZ;
  545. avoidMode();
  546. }
  547. if(A25 == 1 && A26 == 1 && A27 == 0){
  548. if(mark != XJ){
  549. olceClean();
  550. oledShowString(2,5,"xunji");
  551. }
  552. mark = XJ;
  553. tracingMode();
  554. }
  555. }
  556. }
  557. //定时器0的中断函数
  558. void Time0Handler() interrupt 1
  559. {
  560. TH0 = 0xFE;
  561. TL0 = 0x33;
  562. cnt++;
  563. //控制占空比
  564. if(cnt < angle){
  565. sg90 = 1;
  566. }else{
  567. sg90 = 0;
  568. }
  569. if(cnt == 40){ //每个周期为20ms
  570. cnt = 0;
  571. sg90 = 1;
  572. }
  573. }

 

 

 

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

闽ICP备14008679号