久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6571|回復(fù): 4
收起左側(cè)

智能小車學(xué)習(xí)進(jìn)修 激光引導(dǎo) 循跡 遙控原理圖與程序

[復(fù)制鏈接]
ID:218034 發(fā)表于 2017-7-8 21:25 | 顯示全部樓層 |閱讀模式
希望能得到學(xué)習(xí)與交流,大家有什么意見可以一起交流,含有我做的幾個(gè)項(xiàng)目的完整原理圖與單片機(jī)源碼.
0.png

單片機(jī)源程序如下:
  1. //******小車程序******

  2. #include"stc12c5a.h"
  3. #include <intrins.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. uchar sys_mod = 't';//'t':循跡模式, 'r':遙控模式, 'l',激光引導(dǎo)模式

  7. //*******NRF24L01******
  8. uchar idata RxBuf[16];        //接收緩存 data區(qū)滿 存入idata區(qū)
  9. uchar idata TxBuf[16];        //發(fā)送緩存
  10. //******0:系統(tǒng)模式-- ‘t’:循跡模式,‘r’:遙控模式,'l':激光模式
  11. //******1: 時(shí)間高8位
  12. //******2: 時(shí)間低8位
  13. //******3: ADC4
  14. //******4: ADC5
  15. //******5: 感光板上最小電壓值
  16. //******6: 感光板上激光打到的位置
  17. //******7: 行駛步驟高8位
  18. //******8: 行駛步驟低8位
  19. //******9: 硬幣數(shù)量
  20. //*****10: 激光模塊上步進(jìn)電機(jī)轉(zhuǎn)過的角度高8位
  21. //*****11: 激光模塊上步進(jìn)電機(jī)轉(zhuǎn)過的角度低8位
  22. //*****12: addone變量 NRF24L01每發(fā)送一次數(shù)據(jù),addone自加1,接收方判斷發(fā)送方是否離線的一個(gè)標(biāo)志
  23.                    //addone在一定時(shí)間內(nèi)都保持不變說明發(fā)送方離線
  24. //*****13:未定義

  25. #define LED P36                //led燈接P3.6
  26. #define SPK P37                //蜂鳴器接P3.7
  27. //*********** LCD ************
  28. #define RS P44
  29. #define RW P45
  30. #define LCDEN P46
  31. #define LCD_DATA P0                //P0口接LCD數(shù)據(jù)口
  32. #define LCD_BUSY P07        //lcd1602忙碌標(biāo)志位

  33. uchar idata lcd_code[10];//用來標(biāo)記lcd1602 什么時(shí)候清顯示  每個(gè)頁面都設(shè)一個(gè)code,code不想同時(shí)清顯示
  34.                        
  35. //**********                紅外探頭及行進(jìn)方式宏定義        ***************
  36. #define PROBE_L                P22                //左側(cè)紅外探頭        白色區(qū)域低電平         黑色高電平
  37. #define PROBE_M                P21                //中間紅外探頭
  38. #define PROBE_R                P20                //右側(cè)紅外探頭
  39. #define LEFT_Z                 P30          //左輪正極
  40. #define LEFT_F                 P31                //左輪負(fù)極
  41. #define RIGHT_Z         P34          //右輪正極
  42. #define RIGHT_F                P35                //右輪負(fù)極
  43. #define LEFT_GO                {        LEFT_Z = 1;LEFT_F = 0;}                //左輪向前轉(zhuǎn)                                               
  44. #define LEFT_BACK        {        LEFT_Z = 0;LEFT_F = 1;}                //左輪向后轉(zhuǎn)
  45. #define LEFT_STOP        {        LEFT_Z = 0;LEFT_F = 0;}                //左輪停止                                               
  46. #define RIGHT_GO        {        RIGHT_Z = 1;RIGHT_F = 0;}        //右輪向前轉(zhuǎn)                                               
  47. #define RIGHT_BACK        {        RIGHT_Z = 0;RIGHT_F = 1;}        //右輪向后轉(zhuǎn)
  48. #define        RIGHT_STOP        {        RIGHT_Z = 0;RIGHT_F = 0;}        //右輪停止
  49. //****************************************************************
  50. //uchar left_mod[5] = "STOP";                //左輪轉(zhuǎn)動(dòng)方式        用于在lcd上顯示
  51. //uchar right_mod[5] = "STOP";                //右輪轉(zhuǎn)動(dòng)方式        用于在lcd上顯示
  52. uchar probe_before = 's';                        //上一次探頭的狀態(tài)        's':停止        'l':左轉(zhuǎn) 'g':前進(jìn) 'r':右轉(zhuǎn)
  53. uchar step = 1;                                //第?步 0表示檢測(cè)到硬幣
  54. uchar num_coin = 0;                        //硬幣數(shù)量
  55. uchar see_coin = 0;                        //0:未檢測(cè)到硬幣          1:檢測(cè)到硬幣
  56. uchar flag_see_coin = 0;        //0:剛檢測(cè)到硬幣         1:不是剛檢測(cè)到         剛檢測(cè)到硬幣要為t1_flag_see_coin 置零
  57. uchar change_line = 1;                //進(jìn)入內(nèi)圈的步驟
  58. uchar times_probe_l = 0;        //左探頭探測(cè)到黑帶的次數(shù)
  59. uchar times_probe_r = 0;        //右探頭探測(cè)到黑帶的次數(shù)
  60. uchar change_line_mod = '?';//進(jìn)入內(nèi)圈的方式 是左轉(zhuǎn)還是右轉(zhuǎn)

  61. #define xs  8                                 //系數(shù),1表示占空比再乘以0.1,設(shè)置合適 <=8 可安全使用12V的電池

  62. //**************** ADC *********************
  63.                
  64. uchar idata adc5[49];                 //data區(qū)滿 存到idata
  65. uchar times_adc = 0;                //adc轉(zhuǎn)換完成的次數(shù)
  66. uchar num_vmin = 0;                        //電壓最小的光敏電阻的編號(hào) 0~48(橫向加1 縱向加7)
  67. uchar num_vmin_before = 24;        //激光脫離前打到的點(diǎn) 第3行 第3列為停止的點(diǎn)

  68. uint volt = 0;
  69. //***********        CD4051通道         *********
  70. #define SW_CH         P23                 //行掃描a b c        (選通行接地)
  71. #define SW_BH         P24
  72. #define SW_AH         P25
  73. #define SW_CL        P26                 //列掃描a b c        (選通列輸出電壓值給ADC)
  74. #define SW_BL        P27
  75. #define SW_AL        P32       

  76. //***************************************
  77. uint angle = 0;                //步進(jìn)電機(jī)轉(zhuǎn)過的角度

  78. //******************* 定時(shí)器變量 ***********************
  79. uint t0_flag = 0;                        //定時(shí)器0進(jìn)入中斷的次數(shù)
  80. uint t1_flag = 0;                        //定時(shí)器1進(jìn)入中斷的次數(shù)
  81. uint t1_flag_add = 0;                //為addone = addone_b 定時(shí),即為與發(fā)送端失聯(lián)時(shí)間定時(shí)
  82. uint t1_flag_time = 0;                //系統(tǒng)時(shí)間中斷次數(shù) 1000次為1s
  83. uint t1_flag_see_coin = 0;        //用于在檢測(cè)到硬幣時(shí) 停車2秒 和聲光報(bào)警功能
  84. uint t1_flag_laserout = 0;        //為激光脫離感光板定時(shí)
  85. uchar flag_laserout = 0;        //標(biāo)記是否剛脫離 0:剛脫離,1:已經(jīng)脫離  剛脫離置零t1_flag_laserout

  86. uchar t0_h;
  87. uchar t0_l;
  88. uchar t1_h;
  89. uchar t1_l;
  90. uint time_of_move = 0;        //小車移動(dòng)總時(shí)間 單位s

  91. //*****************************************延時(shí)函數(shù)***************************************
  92. void delayms(uint ms)//延時(shí)?個(gè) ms
  93. {
  94.     unsigned char a,b;
  95.         while(ms--)
  96.         {
  97.             for(b=64;b>0;b--)           // 僅作為粗略延時(shí) 中斷繁忙時(shí)差距很大
  98.                 for(a=45;a>0;a--);
  99.         }
  100. }
  101. void delayus(uint us)
  102. {
  103.         for(;us >0;us--)
  104.         {       
  105.                 _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  106.                 _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //stc12c5a不分頻 12MHz 下12個(gè)指令周期為1us
  107.         }
  108. }
  109. //**********字符串復(fù)制函數(shù)**********
  110. void string_copy(uchar *target,uchar *source)//字符串復(fù)制 target:目標(biāo) source:源
  111. {
  112.         uchar i = 0;

  113.         for(i = 0;source[i] != '\0';i++)//注意target的長度 無保護(hù)措施!
  114.         {
  115.                 target[i] = source[i];       
  116.         }
  117.         target[i] = '\0';
  118. }
  119. //**********字符串比較函數(shù)**********
  120. uchar string_cmp(uchar *target,uchar *source)//字符串比較 target:目標(biāo) source:源
  121. {
  122.         uchar revalue;
  123.         uchar i = 0;

  124.         for(i = 0;target[i] != '\0' && source[i] != '\0';i++)  //兩個(gè)都不等于'\0'才執(zhí)行 出現(xiàn)一個(gè)等于'\0'就跳出
  125.         {
  126.                 if(target[i] == source[i])
  127.                 {       
  128.                         revalue = 1;
  129.                 }
  130.                 else
  131.                 {
  132.                         revalue = 0;
  133.                         break;
  134.                 }               
  135.         }
  136.         if(revalue == 1)
  137.         {
  138.                 if(target[i] == '\0' && source[i] == '\0')
  139.                         revalue = 1;
  140.                 else
  141.                         revalue = 0;       
  142.         }
  143.         return(revalue);
  144. }
  145. //****************************************NRF24L01 IO端口定義*********************************
  146. #define          CE                   P10
  147. #define          SCK                  P11
  148. #define                MISO                  P12
  149. #define         CSN                 P16
  150. #define         MOSI                  P17
  151. //#define         IRQ                  P32        //以下程序IRQ不顯示中中斷
  152. //*****************************NRF24L01的接收和發(fā)送地址***************************************
  153. #define TX_ADR_WIDTH    5   // 5個(gè)字節(jié)的TX地址長度
  154. #define RX_ADR_WIDTH    5   // 5個(gè)字節(jié)的RX地址長度
  155. #define TX_PLOAD_WIDTH  16  // ?個(gè)字節(jié)的TX數(shù)據(jù)長度
  156. #define RX_PLOAD_WIDTH  16  // ?個(gè)字節(jié)的RX數(shù)據(jù)長度
  157. uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
  158. uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
  159. //***************************************NRF24L01寄存器指令**********************************
  160. #define READ_REG        0x00          // 讀寄存器
  161. #define WRITE_REG       0x20         // 寫寄存器
  162. #define RD_RX_PLOAD     0x61          // 讀取接收數(shù)據(jù)
  163. #define WR_TX_PLOAD     0xA0          // 寫待發(fā)數(shù)據(jù)
  164. #define FLUSH_TX        0xE1         // 沖洗發(fā)送 FIFO
  165. #define FLUSH_RX        0xE2          // 沖洗接收 FIFO
  166. #define REUSE_TX_PL     0xE3          // 定義重復(fù)裝載數(shù)據(jù)
  167. #define NOP             0xFF          // 保留
  168. //*************************************SPI(nRF24L01)寄存器地址*****************************
  169. #define CONFIG          0x00          // 配置收發(fā)狀態(tài),CRC校驗(yàn)?zāi)J揭约笆瞻l(fā)狀態(tài)響應(yīng)方式
  170. #define EN_AA           0x01          // 自動(dòng)應(yīng)答功能設(shè)置
  171. #define EN_RXADDR       0x02          // 可用信道設(shè)置
  172. #define SETUP_AW        0x03          // 收發(fā)地址寬度設(shè)置
  173. #define SETUP_RETR      0x04          // 自動(dòng)重發(fā)功能設(shè)置
  174. #define RF_CH           0x05          // 工作頻率設(shè)置
  175. #define RF_SETUP        0x06          // 發(fā)射速率、功耗功能設(shè)置
  176. #define STATUS          0x07          // 狀態(tài)寄存器
  177. #define OBSERVE_TX      0x08          // 發(fā)送監(jiān)測(cè)功能
  178. #define CD              0x09          // 地址檢測(cè)           
  179. #define RX_ADDR_P0      0x0A          // 頻道0接收數(shù)據(jù)地址
  180. #define RX_ADDR_P1      0x0B          // 頻道1接收數(shù)據(jù)地址
  181. #define RX_ADDR_P2      0x0C          // 頻道2接收數(shù)據(jù)地址
  182. #define RX_ADDR_P3      0x0D          // 頻道3接收數(shù)據(jù)地址
  183. #define RX_ADDR_P4      0x0E          // 頻道4接收數(shù)據(jù)地址
  184. #define RX_ADDR_P5      0x0F          // 頻道5接收數(shù)據(jù)地址
  185. #define TX_ADDR         0x10          // 發(fā)送地址寄存器
  186. #define RX_PW_P0        0x11          // 接收頻道0接收數(shù)據(jù)長度
  187. #define RX_PW_P1        0x12          // 接收頻道0接收數(shù)據(jù)長度
  188. #define RX_PW_P2        0x13          // 接收頻道0接收數(shù)據(jù)長度
  189. #define RX_PW_P3        0x14          // 接收頻道0接收數(shù)據(jù)長度
  190. #define RX_PW_P4        0x15          // 接收頻道0接收數(shù)據(jù)長度
  191. #define RX_PW_P5        0x16          // 接收頻道0接收數(shù)據(jù)長度
  192. #define FIFO_STATUS     0x17          // FIFO棧入棧出狀態(tài)寄存器設(shè)置

  193. uchar SPI_RW_Reg(uchar reg, uchar value);
  194. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);

  195. //****************************************狀態(tài)標(biāo)志****************************************
  196. uchar         bdata sta;
  197. sbit        RX_DR        =sta^6;
  198. sbit        TX_DS        =sta^5;
  199. sbit        MAX_RT        =sta^4;
  200. //********************************NRF24L01初始化******************************************
  201. void init_NRF24L01()
  202. {
  203.     delayus(100);
  204.         CE=0;    // 片選使能
  205.         CSN=1;   // SPI使能
  206.         SCK=0;   // SPI時(shí)鐘拉低
  207.         SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    //寫本地地址       
  208.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //寫接收端地址
  209.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                             //通道0自動(dòng)應(yīng)答         
  210.         SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);                         //允許接收地址頻道0
  211.         SPI_RW_Reg(WRITE_REG + RF_CH, 0x32);                             //設(shè)置信道工作頻率,收發(fā)必須一致
  212.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);                //設(shè)置接收數(shù)據(jù)長度
  213.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);                                    //設(shè)置發(fā)射速率為2MHZ,發(fā)射功率為最大值0dB       
  214.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x7c);                                                          //IRQ引腳不顯示中斷 掉電模式 1~16位CRC校驗(yàn)
  215. }
  216. //****************************************************************************************************
  217. //*函數(shù):uint SPI_RW(uint uchar)
  218. //*功能:NRF24L01的SPI寫時(shí)序
  219. //****************************************************************************************************
  220. uchar SPI_RW(uchar num)
  221. {
  222.         uchar bit_ctr;
  223.            for(bit_ctr=0;bit_ctr<8;bit_ctr++)  // output 8-bit
  224.            {
  225.                 MOSI = (num & 0x80);            // output 'uchar', MSB to MOSI
  226.                 num = (num << 1);               // shift next bit into MSB..
  227.                 SCK = 1;                        // Set SCK high..
  228.                 num |= MISO;                               // capture current MISO bit
  229.                 SCK = 0;                                // ..then set SCK low again
  230.            }
  231.     return(num);                                   // return read uchar
  232. }
  233. //****************************************************************************************************
  234. //函數(shù):uchar SPI_Read(uchar reg)
  235. //功能:NRF24L01的SPI時(shí)序
  236. //****************************************************************************************************
  237. uchar SPI_Read(uchar reg)
  238. {
  239.         uchar reg_val;
  240.         CSN = 0;                // CSN low, initialize SPI communication...
  241.         SPI_RW(reg);            // Select register to read from..
  242.         reg_val = SPI_RW(0);    // ..then read registervalue
  243.         CSN = 1;                // CSN high, terminate SPI communication
  244.         return(reg_val);        // return register value
  245. }
  246. //****************************************************************************************************
  247. //*功能:NRF24L01讀寫寄存器函數(shù)
  248. //****************************************************************************************************
  249. uchar SPI_RW_Reg(uchar reg, uchar value)
  250. {
  251.         uchar status;
  252.         CSN = 0;                   // CSN low, init SPI transaction
  253.         status = SPI_RW(reg);      // select register
  254.         SPI_RW(value);             // ..and write value to it..
  255.         CSN = 1;                   // CSN high again
  256.         return(status);            // return nRF24L01 status uchar
  257. }
  258. //****************************************************************************************************
  259. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
  260. {
  261.         uchar status,byte_ctr;
  262.         CSN = 0; // Set CSN low, init SPI tranaction
  263.         status = SPI_RW(reg); // Select register to write to and read status byte
  264.         for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
  265.         pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte from nRF24L01
  266.         CSN = 1; // Set CSN high again
  267.         return(status); // return nRF24L01 status byte
  268. }
  269. //*********************************************************************************************************
  270. //*函數(shù):uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  271. //*功能: 用于寫數(shù)據(jù):為寄存器地址,pBuf:為待寫入數(shù)據(jù)地址,uchars:寫入數(shù)據(jù)的個(gè)數(shù)
  272. //*********************************************************************************************************
  273. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  274. {
  275.         uchar status,uchar_ctr;
  276.        
  277.         CSN = 0;            //SPI使能      
  278.         status = SPI_RW(reg);   
  279.         for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  280.                 SPI_RW(*pBuf++);
  281.         CSN = 1;           //關(guān)閉SPI
  282.         return(status);     
  283. }
  284. //********** nrf收發(fā)程序 **********
  285. void nrf_RxTx(uchar mod_nrf,uchar *buff) //NRF24L01收發(fā)程序       
  286. {                       
  287.         static uchar mod_nrf_b;//static 地址不釋放

  288.         //******進(jìn)入發(fā)射模式******
  289.         if(mod_nrf == 't')
  290.         {
  291.                 if(mod_nrf_b != 't')
  292.                 {       
  293.                         mod_nrf_b = 't';
  294.                         CE = 0;
  295.                         SPI_RW_Reg(WRITE_REG+STATUS,0xff);         //清除中斷標(biāo)志
  296.                         SPI_RW_Reg(FLUSH_TX,0x00);                        //清除TX_FIFO寄存器
  297.                         SPI_RW_Reg(WRITE_REG + CONFIG,0x7e);//IRQ引腳不顯示中斷 上電 發(fā)射模式  1~16CRC校驗(yàn)
  298.                         CE = 1;
  299.                         delayus(130);//從CE = 0 到 CE = 1;即待機(jī)模式到收發(fā)模式,需要最大130us                  
  300.                 }
  301.                
  302.         //******發(fā)送數(shù)據(jù)******
  303.                 CE = 0;                        //StandBy I模式       
  304.                 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 裝載接收端地址
  305.                 SPI_Write_Buf(WR_TX_PLOAD,buff,TX_PLOAD_WIDTH);                          // 裝載數(shù)據(jù)
  306.                 CE = 1;                 //置高CE激發(fā)數(shù)據(jù)發(fā)送
  307.                 delayus(130);//從CE = 0 到 CE = 1;即待機(jī)模式到收發(fā)模式,需要最大130us
  308.                
  309.                 delayus(100); //給發(fā)送數(shù)據(jù)一點(diǎn)時(shí)間 發(fā)送延時(shí)可以比接收少
  310.                 sta = SPI_Read(STATUS);//讀取狀態(tài)寄存器的值
  311.                 SPI_RW_Reg(WRITE_REG+STATUS,sta);//清除對(duì)應(yīng)的中斷
  312.                                                
  313.                 if(TX_DS == 1)//發(fā)送成功再清除tx fifo寄存器
  314.                 {       
  315.                         CE = 0;                       
  316.                         SPI_RW_Reg(FLUSH_TX,0x00); //清除tx fifo寄存器        //********重要*********
  317.                         CE = 1;
  318.                 }                                                                                       
  319.         }
  320.         //******進(jìn)入接收模式******
  321.         else if(mod_nrf == 'r')//接收模式
  322.         {
  323.                 if(mod_nrf_b != 'r')
  324.                 {
  325.                         mod_nrf_b = 'r';
  326.                         CE = 0;
  327.                         SPI_RW_Reg(WRITE_REG+STATUS,0xff);        //清除中斷標(biāo)志
  328.                         SPI_RW_Reg(FLUSH_RX,0x00);                         //清除RX_FIFO寄存器
  329.                         SPI_RW_Reg(WRITE_REG + CONFIG, 0x7f);//IRQ引腳不顯示中斷 上電 接收模式   1~16CRC校驗(yàn)   
  330.                         CE = 1;
  331.                         delayus(130);//從CE = 0 到 CE = 1;即待機(jī)模式到收發(fā)模式,需要最大130us
  332.                 }               
  333.                 delayus(500); //不能少 值可調(diào) 給接收數(shù)據(jù)一點(diǎn)時(shí)間
  334.                 sta = SPI_Read(STATUS);
  335.                 SPI_RW_Reg(WRITE_REG+STATUS,sta);   
  336.                 if(RX_DR == 1)   
  337.                 {
  338.                         CE = 0;  
  339.                         SPI_Read_Buf(RD_RX_PLOAD,buff,RX_PLOAD_WIDTH);//讀取數(shù)據(jù) 存入數(shù)組
  340.                         SPI_RW_Reg(FLUSH_RX,0x00);//清除rx fifo寄存器        數(shù)據(jù)不抖動(dòng)
  341.                         CE = 1;
  342.                 }                 
  343.          }
  344. }

  345. //************* 外部中斷 *********************
  346. void int1() interrupt 2         //檢測(cè)到硬幣時(shí)發(fā)生中斷 P3.3引腳
  347. {       
  348.         while(1)//檢測(cè)到硬幣時(shí),即時(shí)沖出賽道也能重新回去       
  349.         {
  350.                 if(PROBE_L == 1 && PROBE_M == 0 && PROBE_R == 0)
  351.                 {        probe_before = 'l';break;                                        }
  352.                 else if(PROBE_L == 0 && PROBE_M ==0 && PROBE_R == 1)
  353.                 {        probe_before = 'r';break;                                        }
  354.         }
  355.         EX1 = 0; //禁止中斷 等到P33電平由0變1時(shí)再允許中斷
  356.         see_coin = 1;
  357.         num_coin++;
  358. }
  359. //********************     定時(shí)器    ***********************
  360. void timer_init()//定時(shí)器初始化
  361. {
  362. //        ET0 = 1;
  363.         ET1 = 1;
  364.         TMOD = 0x11;// 定時(shí)器0,1 :不響應(yīng)外部引線,定時(shí)器方式(為振蕩器12分頻計(jì)數(shù)) 模式1(16位計(jì)數(shù)器)
  365.         TCON = 0;
  366. //        t0_h = 0x3C;        //0x3CB0 = 65536 -50000= 15536        50ms中斷一次
  367. //        t0_l = 0xB0;
  368. //        TH0 = t0_h;
  369. //        TL0 = t0_l;

  370.         t1_h = 0xFC;
  371.         t1_l = 0x18;//0xFC18 = 64536        1000 = 65536 - 64536  1ms中斷一次
  372.         TH1 = t1_h;
  373.         TL1 = t1_l;         
  374. }
  375. /*
  376. //**********定時(shí)器0**********
  377. void timer0() interrupt 1 //定時(shí)器默認(rèn)12T 即12MHz晶振下 THi TLi 每1us加1,與c51單片機(jī)兼容
  378. {
  379.         TH0 = t0_h;        //0x3CAF = 65535 -50000= 15535        50ms中斷一次
  380.         TL0 = t0_l;
  381.         t0_flag++;

  382.         if(t0_flag == 20) //1s
  383.         {
  384.                 t0_flag = 0;
  385.                 time_of_move++;//每過一秒 小車行駛時(shí)間變量+1
  386.         }
  387. }*/
  388. //**********定時(shí)器1**********
  389. void timer1() interrupt 3        //每1ms中斷一次
  390. {
  391.         TH1 = 0xFC;
  392.         TL1 = 0x17;
  393.         t1_flag++;
  394.         t1_flag_add++;
  395.         t1_flag_time++;
  396.         t1_flag_see_coin++;
  397.         t1_flag_laserout++;

  398.         if(t1_flag_time == 1000)
  399.         {
  400.                 t1_flag_time = 0;
  401.                 time_of_move++;//每過一秒 小車行駛時(shí)間變量+1
  402.         }
  403. }
  404. //************* PWM調(diào)速相關(guān)函數(shù) ****************
  405. void pca0()//P1.3輸出
  406. {
  407.         CCAPM0 = 0x42;//8位PWM,無中斷模式
  408.         CCAP0H = CCAP0L = 0xFF;//初始占空比設(shè)為0%       
  409. }
  410. void pca1()//P1.4輸出
  411. {
  412.         CCAPM1 = 0x42;
  413.         CCAP1H = CCAP1L = 0xFF;
  414. }       
  415. void pca_start()//設(shè)置pca工作模式
  416. {
  417.         CMOD = 0x02;//2分頻(23kHz在人耳聽覺范圍之外),不允許CF中斷 允許中斷時(shí),運(yùn)行卡
  418.         CCON = 0;
  419.         CH = CL = 0;
  420.         CR = 1;//pca開始計(jì)數(shù)
  421. }
  422. void pwm(unsigned long pwm0,unsigned long pwm1)
  423. {
  424.         uint pwm0_temp,pwm1_temp;
  425.         pwm0_temp = 255 - (pwm0*xs*255/1000); //pwm0 = 0 時(shí) pwm0_temp = 255;xs:系數(shù)0~10
  426.         pwm1_temp = 255 - (pwm1*xs*255/1000);
  427.         CCAP0H = CCAP0L = pwm0_temp;
  428.         CCAP1H = CCAP1L = pwm1_temp;
  429. }
  430. //**************** LCD1602 ********************
  431. //******LCD基本函數(shù)******
  432. void busy_check()  //忙碌檢測(cè)
  433. {       
  434.         RW = 1;         //讀
  435.         RS = 0;         //指令寄存器
  436.         LCD_DATA = 0xFF;//實(shí)驗(yàn)證明讀數(shù)時(shí)要將I/O口要置1  

  437.         LCDEN = 0;
  438.         _nop_();
  439.         _nop_();
  440.         _nop_();
  441.         _nop_();
  442.         LCDEN = 1;// EN高電平讀信息 負(fù)跳變執(zhí)行指令
  443.         _nop_();
  444.         _nop_();
  445.         _nop_();
  446.         _nop_();
  447.         while(1)
  448.         {
  449.                 if(LCD_BUSY == 0)//P07 == 0跳出循環(huán)
  450.                         break;
  451.         }
  452. }
  453. void lcdwrcom(uchar command)//寫指令
  454. {       
  455.         busy_check();
  456.         RW = 0;//寫
  457.     RS = 0;//指令寄存器
  458.     LCD_DATA = command;

  459.         LCDEN = 1;//負(fù)跳變寫入指令
  460.         _nop_();
  461.         _nop_();
  462.         _nop_();
  463.         _nop_();
  464.         LCDEN = 0;
  465. }
  466. void lcdwrdata(uchar lcd_data)//寫數(shù)據(jù)        數(shù)字、字母、標(biāo)點(diǎn)符號(hào)都是數(shù)據(jù)
  467. {
  468.         busy_check();
  469.         RW = 0;//寫
  470.     RS = 1;//數(shù)據(jù)寄存器
  471.     LCD_DATA = lcd_data;

  472.         LCDEN = 1;//負(fù)跳變寫入指令
  473.         _nop_();
  474.         _nop_();
  475.         _nop_();
  476.         _nop_();
  477.         LCDEN = 0;       
  478. }
  479. void lcd_init()
  480. {       
  481.         delayms(20);//必要 lcd1602上電到電壓穩(wěn)定需要時(shí)間   
  482.         RW = 0;//寫
  483.         RS = 0;//指令寄存器
  484.     LCD_DATA = 0x38;// 0x38設(shè)置顯示模式為:16X2 顯示,5X7 點(diǎn)陣,8 位數(shù)據(jù)接口'
  485.         LCDEN = 1;
  486.         _nop_();
  487.         _nop_();
  488.         _nop_();
  489.         _nop_();
  490.         LCDEN = 0;
  491.         delayms(5);

  492.         lcdwrcom(0x0c);//打開顯示 無光標(biāo) 不閃爍
  493.         lcdwrcom(0x06);//指令3 光標(biāo)右移 屏幕所有文字移動(dòng)無效
  494.         lcdwrcom(0x01);// 清顯示,光標(biāo)復(fù)位到地址00H位置。
  495. }
  496. //****** LCD擴(kuò)展函數(shù) ******
  497. void address(uchar x,uchar y)  //定位下一步要寫數(shù)的地址
  498. {       
  499.         uchar location;
  500.         if(x == 0)
  501.             location = 0x80|y;
  502.         else
  503.                 location = 0xC0|y;

  504.          lcdwrcom(location);               
  505. }
  506. void printchar(uchar x,uchar y,uchar letter)//顯示字母、單個(gè)字符
  507. {
  508.         address(x,y);
  509.         lcdwrdata(letter);
  510. }
  511. void printword(uchar x,uchar y,uchar *word) //顯示單詞(字符數(shù)組)
  512. {
  513.         uchar i = 0;
  514.         for(i = 0;word[i] != '\0';i++)
  515.         {
  516.                 address(x,y + i);
  517.                 lcdwrdata(word[i]);       
  518.         }       
  519. }
  520. void printuint(uchar x,uchar y,uchar num_ws_max,uint num)//顯示無符號(hào)整形 0~65535 x:行 y:列 num_ws_max 變量的最大位數(shù)
  521. {
  522.         uchar i = 0;
  523.         uchar str[5] = {0x20,0x20,0x20,0x20,0x20};

  524.         if(num >= 10000)
  525.         {
  526.                 str[0] = num/10000 + '0';
  527.                 str[1] = num%10000/1000 + '0';
  528.                 str[2] = num%1000/100 + '0';
  529.                 str[3] = num%100/10 + '0';
  530.                 str[4] = num%10 + '0';
  531.         //        str[5] = '\0';         //手動(dòng)加字符串結(jié)束標(biāo)志
  532.         }
  533.         else if(num >= 1000)
  534.         {
  535.                 str[0] = num/1000 + '0';
  536.                 str[1] = num%1000/100 + '0';
  537.                 str[2] = num%100/10 + '0';
  538.                 str[3] = num%10 + '0';
  539.                 str[4] ='\0';
  540.         }
  541.         else if(num >= 100)
  542.         {       
  543.                 str[0] = num/100 + '0';
  544.                 str[1] = num%100/10 + '0';
  545.                 str[2] = num%10 + '0';
  546.                 str[3] = '\0';
  547.         }
  548.         else if(num >=10)
  549.         {       
  550.                 str[0] = num/10 + '0';
  551.                 str[1] = num%10 + '0';
  552.                 str[2] = '\0';
  553.         }
  554.         else if(num >= 0)
  555.         {
  556.                 str[0] = num + '0';
  557.                 str[1] = '\0';
  558.         }
  559.          
  560.         for(i = 0;i <= 5;i++)        //uint類型 最大值65535 為5位數(shù)
  561.         {
  562.                 if(str[i] != '\0' && i < num_ws_max)
  563.                 {
  564.                         address(x,y + i);
  565.                         lcdwrdata(str[i]);
  566.                 }
  567.                 else if(str[i] == '\0' && i < num_ws_max)
  568.                 {
  569.                         address(x,y+i);
  570.                         lcdwrdata(' ');//空格                                  // 實(shí)現(xiàn)功能:在此變量的位數(shù)范圍內(nèi),把沒數(shù)字的位存0x20(空白)
  571.                                                                                                  //例如:最大有3位:999 當(dāng)變?yōu)?9時(shí),存為9+'0' 9+'0' 0x20
  572.                 }                                       
  573.         }       
  574. }
  575. /*
  576. void printvolt(uchar x,uchar y,uint v) //將一個(gè)3位數(shù)除以100 保留兩位小數(shù) 可用來顯示電壓 0.00~5.00V
  577. {                                                                          
  578.         uchar str[4] = "0";
  579.         uchar i = 0;

  580.         str[0] = v/100 + '0';
  581.         str[1] = '.';
  582.         str[2] = v%100/10 + '0';
  583.         str[3] = v%10 + '0';

  584.         printword(x,y,str);
  585.        
  586. }*/
  587. //***************        ADC           ******************
  588. void adc_init()        //adc初始化       
  589. {       
  590.         EADC = 1;  //允許ADC中斷
  591.         SW_CH = SW_BH = SW_AH = 0;
  592.         SW_CL = SW_BL = SW_AL = 0;
  593.         ADC_CONTR = 0x8D;//使用P1.5口 540個(gè)時(shí)鐘周期轉(zhuǎn)換一次
  594. //        ADC_CONTR = 0xCD;//使用P1.5口 180個(gè)時(shí)鐘周期轉(zhuǎn)換一次
  595.         P1ASF = 0x20;//P1口 P1.5作為模擬功能A/D使用       
  596. }
  597. void adc() interrupt 5
  598. {
  599.         unsigned long int volt_temp; //涉及到*500的計(jì)算 所以定義出無符號(hào)長整形
  600.         uchar i = 0;
  601. //        ADC_CONTR = 0xC5;// A/D轉(zhuǎn)換完成 ADC_FLAG軟件置零        停止轉(zhuǎn)換
  602.         ADC_CONTR = 0x85;

  603.         adc5[times_adc] = ADC_RES;

  604.         volt_temp = ADC_RES;
  605.         volt = volt_temp*500/255; //volt_temp 設(shè)為無符號(hào)長整形 先乘再除保證精度。將0~5的數(shù)拉長為0~500,提高精度。

  606.         if(times_adc < 48 )
  607.         {         
  608.                 times_adc++; //0~48
  609.                 SW_CH = 4&(times_adc/7); //按位與  接通cd4051正確的行
  610.                 SW_BH = 2&(times_adc/7);
  611.                 SW_AH = 1&(times_adc/7);

  612.                 SW_CL = 4&(times_adc%7); //接通cd4051正確的列
  613.                 SW_BL = 2&(times_adc%7);
  614.                 SW_AL = 1&(times_adc%7);
  615.         }
  616.         else  //找出最小值,當(dāng)最小值小于某個(gè)值說明激光打在adc_min這個(gè)區(qū)域
  617.         {         
  618.                 times_adc = 0;
  619.                 SW_CH = SW_BH = SW_AH = 0;
  620.                 SW_CL = SW_BL = SW_AL = 0;        //為下一次掃描cd4051做準(zhǔn)備                 

  621.            //*****        判斷最小值        ******
  622.                 num_vmin = 0;
  623.                 for(i = 0;i < 49;i++)
  624.                 {
  625.                         if(adc5[i] <= adc5[num_vmin])
  626.                                 num_vmin = i;
  627.                 }        
  628.         }       
  629. //   ADC_CONTR = 0xCD;//開始轉(zhuǎn)換
  630.    ADC_CONTR = 0x8D;          
  631. }

  632. void move(uchar g_b_l,uchar g_b_r,uchar pwm0,uchar pwm1)         
  633. //g_b_l: 'g'左輪前進(jìn) 'b' 左輪后退 ;g_b_r:'g':右輪前進(jìn) 'b'右輪后退  pwm_left:左輪占空比  pwm_right:右輪占空比
  634. {
  635.         if(g_b_l == 'g')
  636.         {       
  637.                 LEFT_GO;
  638. /*                left_mod[0] = 'G';        //數(shù)組只能在初始化時(shí)整體賦值 在這里left[] = "GO  "是行不通的
  639.                 left_mod[1] = 'O';
  640.                 left_mod[2] = 0x20;        //空值 打空格也行
  641.                 left_mod[3] = ' ';        //空格
  642.                 left_mod[4] = '\0';        */       
  643.         }
  644.         else if(g_b_l == 'b')
  645.         {       
  646.                 LEFT_BACK;
  647. /*                left_mod[0] = 'B';
  648.                 left_mod[1] = 'A';
  649.                 left_mod[2] = 'C';
  650.                 left_mod[3] = 'K';
  651.                 left_mod[4] = '\0';        */
  652.         }
  653.         else if(g_b_l == 's')
  654.         {
  655.                 LEFT_STOP;
  656. /*                left_mod[0] = 'S';
  657.                 left_mod[1] = 'T';
  658.                 left_mod[2] = 'O';
  659.                 left_mod[3] = 'P';
  660.                 left_mod[4] = '\0';        */       
  661.         }

  662.         if(g_b_r == 'g')
  663.         {
  664.                 RIGHT_GO;
  665. /*                right_mod[0] = 'G';
  666.                 right_mod[1] = 'O';
  667.                 right_mod[2] = 0x20; //空值
  668.                 right_mod[3] = 0x20; //空值
  669.                 right_mod[4] = '\0';        */
  670.         }
  671.         else if(g_b_r == 'b')
  672.         {       
  673.                 RIGHT_BACK;
  674. /*                right_mod[0] = 'B';
  675.                 right_mod[1] = 'A';
  676.                 right_mod[2] = 'C';
  677.                 right_mod[3] = 'K';
  678.                 right_mod[4] = '\0';*/       
  679.         }
  680.         else if(g_b_r == 's')
  681.         {
  682.                 RIGHT_STOP;
  683. /*                right_mod[0] = 'S';
  684.                 right_mod[1] = 'T';
  685.                 right_mod[2] = 'O';
  686.                 right_mod[3] = 'P';
  687.                 right_mod[4] = '\0';   */
  688.         }
  689.         if(pwm0 >= 0 && pwm0 <= 100 && pwm1 >= 0 && pwm1 <= 100)       
  690.         {
  691.                 pwm(pwm0,pwm1);
  692.         }
  693.         else   //值不在0 ~100 的范圍
  694.         {
  695.                 pwm(0,0);
  696.         }       
  697. }
  698. void track(uchar pwm0,uchar pwm1)//循跡函數(shù)
  699. {
  700.         if(PROBE_L == 0 && PROBE_M ==0 && PROBE_R == 0)           //處理上一步探頭狀態(tài) 避免沖出跑道
  701.         {
  702.                 if(probe_before == 'l')  //上一步左轉(zhuǎn)
  703.                 {       
  704.                         move('b','g',86,86);//左輪?馬力向后轉(zhuǎn)         右輪?馬力向前轉(zhuǎn) 即左轉(zhuǎn)       
  705.                 }
  706.                 else if(probe_before == 'g')        //上一步前進(jìn)
  707.                 {
  708.                         move('g','g',pwm0,pwm1);//左右輪分別以pwm0 pwm1 馬力前進(jìn)
  709.                 //        move('b','g',pwm0,pwm1);//左輪pwm0馬力向后轉(zhuǎn)   右輪pwm1馬力向前轉(zhuǎn) 即左轉(zhuǎn)
  710.                         //繼續(xù)前進(jìn)的話容易出現(xiàn)失誤,跑出賽道。選擇左轉(zhuǎn),右轉(zhuǎn)均可
  711.                 }  
  712.                 else if(probe_before == 'r')        //上一步右轉(zhuǎn)
  713.                 {
  714.                         move('g','b',86,86);//左輪?馬力向前轉(zhuǎn)   右輪?馬力向后轉(zhuǎn) 即右轉(zhuǎn)       
  715.                 }       
  716.         }
  717.         else if(PROBE_L == 0 && PROBE_M == 1 && PROBE_R == 0) //中部探頭在黑帶處 前進(jìn)
  718.         {
  719.                 probe_before = 'g';//前進(jìn)標(biāo)志
  720.                 move('g','g',pwm0,pwm1);//前進(jìn)
  721.         }
  722.         else if(PROBE_L == 1 && PROBE_M == 1 && PROBE_R == 0)
  723.         {
  724.                 if(change_line_mod == '?')
  725.                 {
  726.                         times_probe_l++;
  727.                 }

  728.                 probe_before = 'l'; //左轉(zhuǎn)標(biāo)志
  729.                 move('b','g',85,85);//左轉(zhuǎn)
  730.         }
  731.         else if(PROBE_L == 1 && PROBE_M ==0 && PROBE_R == 0)
  732.         {
  733.                    if(change_line_mod == '?')
  734.                 {
  735.                         times_probe_l++;
  736.                 }

  737.                 probe_before = 'l'; //左轉(zhuǎn)標(biāo)志
  738.                 move('b','g',86,86);//左轉(zhuǎn)       
  739.         }
  740.         else if(PROBE_L == 0 && PROBE_M == 1 && PROBE_R == 1)
  741.         {
  742.                 if(change_line_mod == '?') //未定值時(shí)
  743.                 {
  744.                         times_probe_r++;
  745.                 }

  746.                 probe_before = 'r';//右轉(zhuǎn)標(biāo)志
  747.                 move('g','b',85,85);//右轉(zhuǎn)
  748.         }
  749.         else if(PROBE_L == 0 && PROBE_M ==0 && PROBE_R == 1)
  750.         {
  751.                 if(change_line_mod == '?') //未定值時(shí)
  752.                 {
  753.                         times_probe_r++;
  754.                 }               

  755.                 probe_before = 'r';//右轉(zhuǎn)標(biāo)志
  756.                 move('g','b',86,86);//右轉(zhuǎn)
  757.         }
  758.         else if(PROBE_L == 1 && PROBE_M == 1 && PROBE_R == 1)  //賽道中 111表示橫著的黑帶,標(biāo)志著下一個(gè)步驟
  759.         {       
  760.                 while(1)
  761.                 {       
  762.                         move('g','g',pwm0,pwm1);//前進(jìn)
  763.                         if(PROBE_L == 0 || PROBE_M == 0 || PROBE_R == 0)
  764.                         {
  765.                            if(step < 255) //防止溢出變?yōu)?
  766.                                         step++;
  767.                                 break;
  768.                         }               
  769.                 }       
  770.         }
  771. /*        else if(PROBE_L == 1 && PROBE_M ==0 && PROBE_R == 1) //賽道上不出現(xiàn)這個(gè)情況
  772.         {

  773.         }
  774. */
  775.         if(change_line_mod == '?')        //為change_line_mod的定值
  776.         {
  777.                 if(times_probe_l == 15 || times_probe_r == 15) //任意一個(gè)探測(cè)到黑帶數(shù)達(dá)到15 開始確定change_line_mod的值
  778.                 {
  779.                         if(times_probe_l > times_probe_r)
  780.                                 change_line_mod = 'l'; //左轉(zhuǎn)進(jìn)入內(nèi)圈
  781.                         else
  782.                                 change_line_mod = 'r'; //右轉(zhuǎn)進(jìn)入內(nèi)圈
  783.                 }
  784.         }
  785. }
  786. void track_all(uchar pwm_l,uchar pwm_r)
  787. {       
  788.         if(angle < 720)
  789.         {       
  790. /*                if(P33 == 1 && EX1 == 0 && flag_see_coin == 0)
  791.                         EX1 = 1;*/
  792.           if(see_coin == 1 && P33 == 1) //檢測(cè)到硬幣 且探頭脫離硬幣 防止多次檢測(cè)同一個(gè)硬幣
  793.                 {
  794.                         move('s','s',0,0);//停車
  795.                         if(flag_see_coin == 0) //剛檢測(cè)到硬幣時(shí) 置零t1_flag_see_coin 開始計(jì)時(shí)
  796.                         {
  797.                                 flag_see_coin = 1;                //已經(jīng)檢測(cè)到硬幣
  798.                                 t1_flag_see_coin = 0;         //置零t1_flag_see_coin 開始計(jì)時(shí)
  799.                         }
  800.                         if(t1_flag_see_coin < 500)
  801.                         {        LED = 1;        SPK = 1;        }
  802.                         else if(t1_flag_see_coin < 1000)
  803.                         {        LED = 0;        SPK = 0;        }
  804.                         else if(t1_flag_see_coin < 1500)
  805.                         {        LED = 1;        SPK = 1;        }
  806.                         else if(t1_flag_see_coin < 2000)
  807.                         {        LED = 0;        SPK = 0;        }
  808.                         else
  809.                         {       
  810.                                 EX1 = 1;
  811.                                 see_coin = 0; //回去執(zhí)行檢測(cè)到硬幣之前的else語句
  812.                                 flag_see_coin = 0;
  813.                         }       
  814.                 }
  815.                 else if(step == 0)
  816.                 {
  817.                         if(PROBE_L == 1 && PROBE_M == 1 && PROBE_R == 1)
  818.                         {
  819.                                 move('g','g',83,83);
  820.                                 while(1)
  821.                                 {       
  822.                                         if(PROBE_L == 0 || PROBE_M == 0 || PROBE_R == 0)
  823.                                         {
  824.                                                 step = 1;
  825.                                                 break;
  826.                                         }
  827.                                 }
  828.                         }
  829.                 }
  830.                 else if(step == 1)
  831.                 {       
  832.                         track(pwm_l,pwm_r);
  833.                 }
  834.                 else if(step  == 2)
  835.                 {       
  836.                         track(pwm_l + 5,pwm_r + 5);        //加速行駛
  837.                 }
  838.                 else if( step == 3)
  839.                 {
  840.                          track(pwm_l,pwm_r);       
  841.                 }
  842.                 else if(step == 4)        //進(jìn)入內(nèi)圈 聲光提示
  843.                 {       
  844.                         if(change_line == 1)//第1步 駛出橫黑帶
  845.                         {
  846.                                 LED = SPK = 1;
  847.                                 move('g','g',pwm_l,pwm_r);
  848.                                 if(PROBE_L == 0 || PROBE_M == 0 || PROBE_R == 0)
  849.                                         change_line = 2;
  850.                         }
  851.                         else if(change_line == 2)//第2步 讓與轉(zhuǎn)向方式相異的邊探頭探測(cè)到黑帶
  852.                         {
  853.                                 LED = SPK = 0;
  854.                                 if(change_line_mod == 'l') //左轉(zhuǎn) 探頭狀態(tài)001 (讓右探頭探測(cè)黑帶,再進(jìn)入下一步)
  855.                                 {
  856.                                         move('b','g',86,86);
  857.                                         if(PROBE_L == 0 && PROBE_M == 0 && PROBE_R == 1)
  858.                                         change_line = 3;
  859.                                 }
  860.                                 else if(change_line_mod == 'r')        //右轉(zhuǎn) 探頭狀態(tài)100
  861.                                 {
  862.                                         move('g','b',86,86);
  863.                                         if(PROBE_L == 1 && PROBE_M == 0 && PROBE_R == 0)
  864.                                         change_line = 3;       
  865.                                 }                                        
  866.                         }
  867.                         else if(change_line == 3) //第3步 轉(zhuǎn)向前進(jìn)交替
  868.                         {
  869.                                  if(change_line_mod == 'l')        //左轉(zhuǎn)前進(jìn)交替
  870.                                 {
  871.                                         LED = SPK = 1;
  872.                                         move('b','g',86,86);
  873.                                         delayms(10);
  874.                
  875.                                         LED = SPK = 0;
  876.                                         move('g','g',pwm_l + 15,pwm_r + 15);
  877.                                         delayms(5);
  878.                                         if(PROBE_L == 1 || PROBE_M == 1)
  879.                                         {
  880.                                                 LED = SPK = 0;
  881.                                                 change_line = 0;
  882.                                                 step = 5;
  883.                                         }
  884.                                 }
  885.                                 else if(change_line_mod == 'r')        //右轉(zhuǎn)前進(jìn)交替
  886.                                 {
  887.                                         LED = SPK = 1;
  888.                                         move('g','b',86,86);
  889.                                         delayms(10);
  890.                
  891.                                         LED = SPK = 0;
  892.                                         move('g','g',pwm_l + 15,pwm_r + 15);
  893.                                         delayms(5);
  894.                                         if(PROBE_L == 1 || PROBE_M == 1)
  895.                                         {
  896.                                                 LED = SPK = 0;
  897.                                                 change_line = 0;
  898.                                                 step = 5;
  899.                                         }       
  900.                                 }
  901.                         }               
  902.                 }
  903.                 else
  904.                 {
  905.                         track(pwm_l,pwm_r);       
  906.                 }
  907.         }
  908.         else if(angle >= 720)
  909.         {
  910.                 move('s','s',0,0);
  911.         }       
  912. }

  913. void laser_guide(uchar pwm) //激光引導(dǎo)模式
  914. {
  915.         uchar x;
  916.         uchar y;
  917.        
  918.         if(adc5[num_vmin] < 210)// 確保有激光打到光敏電阻上才執(zhí)行
  919.         {
  920.                 flag_laserout = 0;
  921.                 x = num_vmin/7;        //對(duì)7取整得到行數(shù)
  922.                 y = num_vmin%7;        //對(duì)7取余得到列數(shù)

  923.                 num_vmin_before = num_vmin;
  924.                 if(x >= 2  && x <= 4 && y <= 2)       
  925.                 {
  926.                         move('g','g',pwm - 5,pwm - 5);//前進(jìn)        轉(zhuǎn)彎比直走費(fèi)勁
  927.                 }
  928.                 else if(x >= 2  && x <= 4 && y >= 4)
  929.                 {
  930.                          move('b','b',pwm - 5,pwm - 5);//后退
  931.                 }
  932.                 else if(x >= 5)
  933.                 {       
  934.                         move('b','g',pwm,pwm);//左轉(zhuǎn)  轉(zhuǎn)彎比直走費(fèi)勁
  935.                 }
  936.                 else if(x <= 2)       
  937.                 {
  938.                         move('g','b',pwm,pwm);//右轉(zhuǎn)
  939.                 }
  940.                 else
  941.                 {
  942.                         move('s','s',0,0);//停止
  943.                 }                       
  944.         }
  945.         else  //激光脫離 保持原行駛狀態(tài)一段時(shí)間,希望能重新感應(yīng)到
  946.         {
  947.                 x = num_vmin_before/7;        //對(duì)7取整 得到行數(shù)
  948.                 y = num_vmin_before%7;        //對(duì)7取余 得到列數(shù)

  949.                 if(flag_laserout == 0)        //剛脫離感光板
  950.                 {
  951.                         flag_laserout = 1;
  952.                         t1_flag_laserout = 0;        //置零 每1ms加1
  953.                 }

  954.                 if(t1_flag_laserout < 300 )         //?ms
  955.                 {
  956.                         if(x >= 2  && x <= 4 && y <= 2)       
  957.                         {
  958.                                 move('g','g',pwm - 5,pwm - 5);//前進(jìn)
  959.                         }
  960.                         else if(x >= 2  && x <= 4 && y >= 4)
  961.                         {
  962.                                  move('b','b',pwm - 5,pwm - 5);//后退
  963.                         }
  964.                         else if(x >= 5)
  965.                         {       
  966.                                 move('b','g',pwm,pwm);//左轉(zhuǎn)
  967.                         }
  968.                         else if(x <= 2)       
  969.                         {
  970.                                 move('g','b',pwm,pwm);//右轉(zhuǎn)
  971.                         }
  972.                         else
  973.                         {
  974.                         move('s','s',0,0);//停止
  975.                         }               
  976.                 }
  977.                 else
  978.                 {
  979.                         move('s','s',0,0);
  980.                         num_vmin_before = 24;       
  981.                 }
  982.                
  983.         }
  984. }
  985. //************ 判斷NRF24L01是否聯(lián)機(jī) ************
  986. uchar isonline(uint time)         //返回0:離線、超時(shí) ,返回1:在線或未超時(shí)
  987. {
  988.         static uchar addone;
  989.         static uchar addone_b;
  990.         static uchar flag_add;
  991.         uchar revalue;

  992.         addone = RxBuf[12];
  993.         if(addone == addone_b) //值不變 發(fā)送方可能離線        當(dāng)值保持不變的時(shí)間超過參數(shù)time,則視發(fā)送方為離線
  994.         {
  995.                 if(flag_add == 0)
  996.                 {
  997.                         flag_add = 1;
  998.                         t1_flag_add = 0;//t1_flag_add 置0;t1_flag_add在定時(shí)器1中斷函數(shù)中 每1ms自加1
  999.                 }
  1000.                 if(t1_flag_add < time)//未超時(shí)
  1001.                 {
  1002.                         revalue = 1;
  1003.                 }
  1004.                 else if(t1_flag_add >= time)//超時(shí)
  1005.                 {
  1006.                         t1_flag_add = time;
  1007.                         revalue = 0;                //超時(shí) 發(fā)送端離線
  1008.                 }
  1009.         }
  1010.         else if(addone != addone_b)
  1011.         {
  1012.                 addone_b = addone;
  1013.                 flag_add = 0;
  1014.                 revalue = 1;//值在變 發(fā)送端在線 未失聯(lián)
  1015.         }
  1016.         return(revalue);//返回1:在線 , 0:離線       
  1017. }
  1018. void rc_ol(uchar pwm_ctrl_l,uchar pwm_ctrl_r) //rc 遙控 模式 發(fā)送方在線
  1019. {
  1020.         uchar mod_ctrl_l;
  1021.         uchar mod_ctrl_ls;        //用于顯示+ -
  1022.         uchar mod_ctrl_r;
  1023.         uchar mod_ctrl_rs;        //用于顯示+ -
  1024.         uint pwm_ctrl_temp;        //防止數(shù)據(jù)溢出

  1025.         if(pwm_ctrl_l >= 129 && pwm_ctrl_l <= 255)//129~255  差值126
  1026.         {
  1027.                 mod_ctrl_l = 'g';
  1028.                 mod_ctrl_ls = '+';//前進(jìn)
  1029.                 pwm_ctrl_temp = pwm_ctrl_l;
  1030.                 pwm_ctrl_l = (pwm_ctrl_temp - 129)*100/126;//將129~255轉(zhuǎn)換成0~100
  1031.         }
  1032.         else if(pwm_ctrl_l >= 0 && pwm_ctrl_l <= 126)
  1033.         {
  1034.                 mod_ctrl_l = 'b';
  1035.                 mod_ctrl_ls = '-';
  1036.                 pwm_ctrl_temp = pwm_ctrl_l;
  1037.                 pwm_ctrl_l = 100 - (pwm_ctrl_temp*100/126);        //將0~126轉(zhuǎn)換為100~0
  1038.         }
  1039.         else  //包括等于 127,128 其他
  1040.         {
  1041.                 mod_ctrl_l = 's';
  1042.                 mod_ctrl_ls = ' ';
  1043.                 pwm_ctrl_l = 0;
  1044.         }
  1045.         if(pwm_ctrl_r >= 129 && pwm_ctrl_r <= 255)//129~255  差值126
  1046.         {
  1047.                 mod_ctrl_r = 'g';//前進(jìn)
  1048.                 mod_ctrl_rs = '+';
  1049.                 pwm_ctrl_temp = pwm_ctrl_r;
  1050.                 pwm_ctrl_r = (pwm_ctrl_temp - 129)*100/126;//將129~255轉(zhuǎn)換成0~100
  1051.         }
  1052.         else if(pwm_ctrl_r >= 0 && pwm_ctrl_r <= 126)
  1053.         {
  1054.                 mod_ctrl_r = 'b';
  1055.                 mod_ctrl_rs = '-';
  1056.                 pwm_ctrl_temp = pwm_ctrl_r;
  1057.                 pwm_ctrl_r = 100 - (pwm_ctrl_temp*100/126);        //將0~126轉(zhuǎn)換為100~0
  1058.         }
  1059.         else  //包括等于 127,128 其他
  1060.         {
  1061.                 mod_ctrl_r = 's';
  1062.                 mod_ctrl_rs = ' ';
  1063.                 pwm_ctrl_r = 0;
  1064.         }

  1065.         move(mod_ctrl_l,mod_ctrl_r,pwm_ctrl_l,pwm_ctrl_r);
  1066.         if(string_cmp(lcd_code,"rc_ol") != 1)
  1067.         {
  1068.                 lcdwrcom(0x01);//清顯示
  1069.                 string_copy(lcd_code,"rc_ol");
  1070.         }
  1071.         printword(0,0,"MODE:RC");
  1072.         printword(0,8,"TIME:");
  1073.         printuint(0,13,3,time_of_move);
  1074.         printword(1,0,"L:");
  1075.         printchar(1,2,mod_ctrl_ls);
  1076.         printuint(1,3,3,pwm_ctrl_l);
  1077.         printword(1,8,"R:");               
  1078.         printchar(1,10,mod_ctrl_rs);
  1079.         printuint(1,11,3,pwm_ctrl_r);
  1080.        
  1081. }
  1082. //******************** 主函數(shù) ***********************
  1083. void main()
  1084. {
  1085.         uchar addone_tx = 0;
  1086.         uchar pwm_ctrl_l;
  1087.         uchar pwm_ctrl_r;
  1088.         uint pwm_rx = 0;
  1089.         uint pwm_laser = 0;
  1090. ……………………

  1091. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
小車.zip (107.05 KB, 下載次數(shù): 57)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:220062 發(fā)表于 2018-5-17 19:02 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:79544 發(fā)表于 2019-8-30 09:08 | 顯示全部樓層
很好的資料,感謝分享,學(xué)習(xí)啦!!!!!!!!
回復(fù)

使用道具 舉報(bào)

ID:890359 發(fā)表于 2021-3-10 15:07 | 顯示全部樓層
用的是什么傳感器啊
回復(fù)

使用道具 舉報(bào)

ID:576302 發(fā)表于 2021-4-8 11:02 | 顯示全部樓層
同問,用的是什么傳感器
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 99精品视频在线观看免费播放 | 一区二区三区在线免费观看 | 欧美在线色 | 日韩在线中文字幕 | 国产精品综合久久 | 国产美女久久久 | 国产超碰人人爽人人做人人爱 | 性做久久久久久免费观看欧美 | 欧美精品三区 | 欧美久久不卡 | 在线观看成人精品 | 亚洲乱码一区二区三区在线观看 | 欧美日韩一区二区三区四区五区 | 日韩精品在线一区 | 国产午夜精品久久久久免费视高清 | 午夜欧美| 九九精品久久久 | 精久久久久 | 奇米四色影视 | 九色av| 农村黄性色生活片 | 国产综合精品一区二区三区 | 国产精品久久久久久婷婷天堂 | 看片国产| 欧美日韩亚洲视频 | 久久精品亚洲精品国产欧美 | 爱操影视 | 福利视频大全 | 精品国产乱码久久久 | 久久精品国产亚洲夜色av网站 | 日本一本视频 | 欧美日韩看片 | 久久久久国产成人精品亚洲午夜 | www.久久| 久久亚洲视频网 | 蜜桃臀av一区二区三区 | 中文字幕视频在线 | 欧美高清一区 | 久久最新网址 | 欧美精品一区二区在线观看 | 国产永久免费 |