找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3095|回复: 4
收起左侧

单片机+nRF905公交车自动报站系统设计 附程序+电路图

[复制链接]
ID:602704 发表于 2019-8-28 10:22 | 显示全部楼层 |阅读模式
大家好:

        今天我基于STC89C52单片机制作了一个公交车自动报站系统的设计。


1, 实物照片
1AD31D2D5346378E21B0802DF602CD9C.png

2报站;接收模块原理图及PCB
51hei截图_20190828101331.png 51hei截图_20190828101355.png 51hei截图_20190828101414.png 51hei截图_20190828101433.png


3,发送信号整机程序

  1. #include <reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. uchar SUM = 0;
  5. #define BYTE_BIT0 0x01
  6. #define BYTE_BIT1 0x02
  7. #define BYTE_BIT2 0x04
  8. #define BYTE_BIT3 0x08
  9. #define BYTE_BIT4 0x10
  10. #define BYTE_BIT5 0x20
  11. #define BYTE_BIT6 0x40
  12. #define BYTE_BIT7 0x80
  13. ////////////SPI指令
  14. #define WC  0x00
  15. #define RC  0x10
  16. #define WTP  0x20
  17. #define RTP  0x21
  18. #define WTA  0x22
  19. #define RTA  0x23
  20. #define RRP  0x24
  21. bdata unsigned  char DATA_BUF;
  22. #define DATA7 ((DATA_BUF&BYTE_BIT7) != 0)
  23. #define DATA0   ((DATA_BUF&BYTE_BIT0) != 0)
  24. sbit flag =DATA_BUF^7;
  25. sbit flag1 =DATA_BUF^0;
  26. #define TxRxBuf_Len 1
  27. unsigned char TxRxBuf[TxRxBuf_Len]=
  28. {
  29. 0x29
  30. };
  31. //配置口定义//
  32. sbit TXEN=P2^4;
  33. sbit TRX_CE=P2^3;
  34. sbit PWR=P2^5;
  35. sbit MISO=P2^1;
  36. sbit MOSI=P2^6;
  37. sbit SCK=P2^0;
  38. sbit CSN=P2^7;
  39. /////////////////////////////////////////////////////
  40. sbit AM=P2^2;
  41. sbit DR=P1^3;
  42. ///////////////////////////////////////////////////////
  43. sbit led1=P2^2;
  44. sbit led0=P2^3;
  45. sbit led2=P2^1;
  46. sbit led3=P2^0;
  47. ///////////////////////////////////////////////////////
  48. sbit KEY0=P1^0;
  49. sbit KEY1=P1^1;
  50. uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};         //0~~9段码
  51. //RF寄存器配置//
  52. unsigned char idata RFConf[11]=
  53. {
  54.   0x00,                             //配置命令//
  55.   0x4c,                             //CH_NO,配置频段在423MHZ
  56.   0x0c,                             //输出功率为10db,不重发,节电为正常模式
  57.   0x44,                             //地址宽度设置,为4字节
  58.   0x04,0x04,                        //接收发送有效数据长度为32字节
  59.   0xCC,0xCC,0xCC,0xCC,              //接收地址
  60.   0x58,                              //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振
  61. };
  62. bit lcdbit;
  63. code TxAddress[4]={0xcc,0xcc,0xcc,0xcc};
  64. ///////////延时/////////////////
  65. static void Delay(uchar n)
  66. {
  67. uint i;
  68. while(n--)
  69. for(i=0;i<80;i++);
  70. }
  71. void SpiWrite(unsigned char send)
  72. {
  73. unsigned char i;
  74. DATA_BUF=send;
  75. for (i=0;i<8;i++)
  76. {
  77.   if (DATA7) //总是发送最高位
  78.   {
  79.    MOSI=1;
  80.   }
  81.   else
  82.   {
  83.    MOSI=0;
  84.   }
  85.   SCK=1;
  86.   DATA_BUF=DATA_BUF<<1;
  87.   SCK=0;
  88. }
  89. }
  90. ////////////////初始化nRF905///////////////////
  91. void nRF905Init(void)
  92. {
  93.     CSN=1;      // Spi  disable
  94. SCK=0;      // Spi clock line init low
  95. DR=0;      // Init DR for input
  96. AM=0;      // Init AM for input
  97. // CD=0;      // Init CD for input
  98. PWR=1;     // nRF905 power on
  99. TRX_CE=0;     // Set nRF905 in standby mode
  100. TXEN=0;     // set radio in Rx mode
  101. }
  102. ////////初始化寄存器
  103. void Config905(void)
  104. {
  105. uchar i;
  106. CSN=0;      // Spi enable for write a spi command
  107. //SpiWrite(WC);    // Write config command写放配置命令
  108. for (i=0;i<11;i++) // Write configration words  写放配置字
  109. {
  110.     SpiWrite(RFConf[i]);
  111. }
  112. CSN=1;     // Disable Spi
  113. }
  114. /////////////发送数据
  115. void TxPacket(uchar *TxRxBuf)
  116. {
  117. uchar i;
  118. //Config905();
  119. CSN=0;
  120. SpiWrite(WTP);    // Write payload command
  121.     SpiWrite(TxRxBuf[0]);  // Write 32 bytes Tx data
  122. CSN=1;
  123. Delay(1);      // Spi disable
  124. CSN=0;      // Spi enable for write a spi command
  125. SpiWrite(WTA);    // Write address command
  126. for (i=0;i<4;i++)   // Write 4 bytes address
  127. {
  128. SpiWrite(TxAddress[i]);
  129. }
  130. CSN=1;      // Spi disable
  131. TRX_CE=1;     // Set TRX_CE high,start Tx data transmission
  132. Delay(1);     // while (DR!=1);
  133. TRX_CE=0;     // Set TRX_CE low
  134. }
  135. ////////////////////////////////////////////////////
  136. void SetTxMode(void)
  137. {
  138. TRX_CE=0;
  139. TXEN=1;
  140. Delay(1);      // delay for mode change(>=650us)
  141. }
  142. void main(void)
  143. {  
  144.   uchar i;
  145.   nRF905Init();
  146.   Config905();
  147.    while(1)
  148.     {
  149. if(KEY0==0)      //有键按下
  150.   {
  151.       Delay(20);
  152.       if(KEY0 == 0)
  153.       {
  154.    while(!KEY0);      //等待按键松开  RED
  155.       SUM++;
  156.       if(SUM == 5) SUM = 1;
  157.       if(SUM == 1)
  158.       {
  159.     TxRxBuf[0]=0x11;
  160.         for(i=0;i<2;i++)
  161.          {
  162.          SetTxMode();// Set nRF905 in Tx mode
  163.       TxPacket(TxRxBuf);// Send data by nRF905
  164.          }
  165.        }
  166.       else if(SUM == 2)
  167.       {
  168.      TxRxBuf[0]=0x12;
  169.         for(i=0;i<2;i++)
  170.          {
  171.          SetTxMode();// Set nRF905 in Tx mode
  172.       TxPacket(TxRxBuf);// Send data by nRF905
  173.          }
  174.        }
  175.       else if(SUM == 3)
  176.       {
  177.      TxRxBuf[0]=0x13;
  178.         for(i=0;i<2;i++)
  179.          {
  180.          SetTxMode();// Set nRF905 in Tx mode
  181.       TxPacket(TxRxBuf);// Send data by nRF905
  182.          }
  183.        }
  184.       else if(SUM == 4)
  185.       {
  186.      TxRxBuf[0]=0x14;
  187.         for(i=0;i<2;i++)
  188.          {
  189.          SetTxMode();// Set nRF905 in Tx mode
  190.       TxPacket(TxRxBuf);// Send data by nRF905
  191.          }
  192.        }
  193.      }
  194.    }
  195. }
  196. }



  197. 4,接受信号整机程序

  198. #include <regx52.h>
  199. #define uchar unsigned char
  200. #define uint unsigned int

  201. /*------------LCD12864相关声明-----------------------------*/
  202. #define com_byte 0
  203. #define dat_byte 1
  204. sbit cs =P0^0;
  205. sbit sid=P0^1;
  206. sbit sck=P0^2;
  207. uchar lcdPosX, lcdPosY;       //X,Y坐标
  208. uchar halfScr, halfLineCnt, basicBlock;   //半屏,半屏行数,N*8块
  209. uchar code TAB1[]={"20  年  月  上行"};//第一行初始化.
  210. uchar code TAB2[]={"  :  :      ℃"};
  211. uchar code TAB3[]={"0123456789: "};
  212. /**************************************************************/
  213. //===============================================
  214. void delay_Ms (uchar ms)
  215. {
  216. uchar i;
  217. while (--ms)
  218. {
  219.   for (i = 0; i < 125; i++);
  220. }
  221. }
  222. /**************************************************************
  223. 函数名称:void w_12864byte(uchar byte)
  224. 函数功能: 写字节
  225. **************************************************************/
  226. void w_12864byte(uchar byte)
  227. {
  228. uchar i;
  229. for(i=0;i<8;i++)
  230. {
  231. sck=0;
  232. byte<<=1;
  233. sid=CY;
  234. sck=1;
  235. }
  236. }
  237. /**************************************************************
  238. 函数名称:uchar r_12864byte(void)
  239. 函数功能: 读字节
  240. ***************************************************************/
  241. uchar r_12864byte(void)
  242. {
  243. uchar i,temp1,temp2;
  244. temp1 = 0;
  245. temp2 = 0;
  246. for(i=0;i<8;i++)
  247. {
  248. temp1=temp1<<1;
  249. sck = 0;
  250. sck = 1;
  251. sck = 0;
  252. if(sid) temp1++;
  253. }
  254. for(i=0;i<8;i++)
  255. {
  256. temp2=temp2<<1;
  257. sck = 0;
  258. sck = 1;
  259. sck = 0;
  260. if(sid) temp2++;
  261. }
  262. return ((0xf0&temp1)+(0x0f&temp2));
  263. }
  264. /**************************************************************
  265. 函数名称:void c_12864busy( void )
  266. 函数功能: 检测忙函数
  267. **************************************************************/
  268. void c_12864busy( void )
  269. {
  270. do
  271. w_12864byte(0xfc); //11111,RW(1),RS(0),0
  272. while(0x80&r_12864byte());
  273. }
  274. /**************************************************************
  275. 函数名称:void w_12864(bit dat_byte_com_byte,uchar byt)
  276. 函数功能: 写入函数
  277. ***************************************************************/
  278. void w_12864(bit dat_byte_com_byte,uchar byt)
  279. {
  280. uchar temp;
  281. if(dat_byte_com_byte==0) //为零,写入指令
  282. temp=0xf8; //11111,RS(0),RW(0),0
  283. else //否则,写入数据
  284. temp=0xfa; //11111,RS(1),RW(0),0
  285. cs=1;
  286. c_12864busy();
  287. w_12864byte(temp);
  288. w_12864byte(byt&0xf0); //写入高四位
  289. w_12864byte(byt<<4); //写入低四位
  290. cs=0;
  291. }
  292. void lcdClear (void)
  293. {
  294. w_12864(com_byte,0x01);
  295. }
  296. void wrPosition (void)
  297. {
  298. w_12864(com_byte,0x34);
  299. w_12864(com_byte,lcdPosY);
  300. w_12864(com_byte,lcdPosX);
  301. w_12864(com_byte,0x30);
  302. }
  303. //===============================================
  304. void displayPhoto (uchar *bmp, uchar bmpCls)
  305. {
  306. lcdPosX = 0x80;
  307. halfScr = 2;

  308. for (;halfScr != 0; halfScr--)
  309. {
  310.   lcdPosY = 0x80;
  311.   halfLineCnt = 32;
  312.   
  313.   for (;halfLineCnt != 0; halfLineCnt--)
  314.   {
  315.    basicBlock = 16;
  316.    wrPosition ();
  317.    
  318.    for (; basicBlock != 0; basicBlock--)
  319.    {
  320.     if (bmpCls == 0)
  321.     {
  322.      w_12864(dat_byte, *bmp++);
  323.     }
  324.     else if (bmpCls == 1)
  325.     {
  326.      w_12864(dat_byte,0x00);
  327.     }
  328.    }
  329.    lcdPosY++;
  330.   }
  331.   lcdPosX = 0x88;
  332. }
  333. w_12864(com_byte,0x36);
  334. w_12864(com_byte,0x30);
  335. }
  336. //字符反白显示
  337. //输入参数:CX=要反白字符的行(0-3)
  338. //CY=要反白字符的列(0-7)
  339. //width=要反白字符的长度(1-16)
  340. //===============================================
  341. void convertChar (uchar CX, CY, width)
  342. {
  343. displayPhoto(0,1);
  344. lcdPosY = 0x80;
  345. if (CX == 0)
  346. {
  347.   CX = 0x80;
  348.   halfLineCnt = 16;
  349. }
  350. else if (CX == 1)
  351. {
  352.   CX = 0x80;
  353.   halfLineCnt = 32;
  354. }
  355. else if (CX == 2)
  356. {
  357.   CX = 0x88;
  358.   halfLineCnt = 16;
  359. }
  360. else if (CX == 3)
  361. {
  362.   CX = 0x88;
  363.   halfLineCnt = 32;
  364. }
  365. lcdPosX = CX + CY;

  366.     for (; halfLineCnt != 0; halfLineCnt--)
  367. {
  368.   basicBlock = width;
  369.   wrPosition();

  370.   for (;basicBlock != 0; basicBlock--)
  371.   {
  372.    if (halfLineCnt > 16)
  373.    {
  374.     w_12864(dat_byte,0x00);
  375.    }
  376.    else
  377.    {
  378.     w_12864(dat_byte,0xff);
  379.    }
  380.   }
  381.   lcdPosY++;
  382. }
  383. w_12864(com_byte,0x36);
  384. w_12864(com_byte,0x30);
  385. }
  386. void dispString(uchar X,uchar Y,uchar speed, uchar *msg)
  387. {
  388. if (X == 0)
  389. {
  390.   X = 0x80;
  391. }
  392. else if (X == 1)
  393. {
  394.   X = 0x90;
  395. }
  396. else if (X == 2)
  397. {
  398.   X = 0x88;
  399. }
  400. else if (X == 3)
  401. {
  402.   X = 0x98;
  403. }
  404. Y = X + Y;
  405. w_12864(com_byte,Y);
  406. while (*msg)
  407. {
  408.   w_12864(dat_byte,*msg++);
  409.   delay_Ms(speed);
  410. }
  411. }
  412. //=============================================================
  413. /**************************************************************
  414. 函数名称:void init_12864(void)
  415. 函数功能:初始化12864
  416. ***************************************************************/
  417. void init_12864(void)
  418. {
  419. uint i;
  420. w_12864(com_byte,0x30); //基本指令功能.
  421. w_12864(com_byte,0x0c); //显示打开,关光标,反白关.
  422. w_12864(com_byte,0x01); //清屏指令.
  423. w_12864(com_byte,0x06); //AC自动加一
  424. w_12864(com_byte,0x80);
  425. for(i=0;i<16;i++)
  426. w_12864(dat_byte,TAB1[i]);   
  427. w_12864(com_byte,0x90);
  428. for(i=0;i<16;i++)
  429. w_12864(dat_byte,TAB2[i]);
  430. dispString(2,0,1,"欢迎乘学院路公交");
  431. dispString(3,0,1,"志华站=>财经学院");
  432. }


  433. 5,时钟程序

  434. #ifndef _CLOCK_H_
  435. #define _CLOCK_H_
  436. #include <regx52.h>

  437. //#define PortDisplayData P0  //定义数码管数据和位选择输出口
  438. //#define PortDisplayBit P1

  439. unsigned char ucClockStatu;  //时钟状态
  440. #define RUNING 0x00
  441. #define MODIFY_YEA 0x01
  442. #define MODIFY_MON 0x02
  443. #define MODIFY_DAY 0x03
  444. #define MODIFY_HOU 0x04
  445. #define MODIFY_MIN 0x05
  446. #define MODIFY_SEC 0x06

  447. //定义跟DS1302相关的数据
  448. sbit SCLK = P3^4;  //实时时钟端口定义
  449. sbit SDAT = P3^6;
  450. sbit SRST = P3^7;
  451. //定义跟键盘有关的端口
  452. sbit FUNTION_KEY = P1^6;
  453. sbit INCREASE_KEY = P1^7;
  454. sbit DECREASE_KEY = P1^5;
  455. sbit WENXING_KEY    =P1^4;
  456. sbit PLAY_KEY     = P1^3;
  457. sbit UP_DOWN__KEY   = P1^2;//上下行切换键
  458. #define W_OP 0x00  //定义写操作
  459. #define R_OP 0x01  //定义读操作
  460. #define SEC 0x80  //秒寄存器地址
  461. #define MIN 0x82  //分寄存器地址
  462. #define HOU 0x84  //小时寄存器地址
  463. #define WEK 0x8a  //星期寄存器地址
  464. #define DAY 0x86  //日寄存器地址
  465. #define MON 0x88  //月寄存器地址
  466. #define YER 0x8c  //年寄存器地址
  467. #define CHARGER 0x90 //充电控制寄存器地址
  468. //充电控制寄存器结构:TCS为控制位,当它的值为1010时开启充电功能,其它值都禁止充电,芯片上电时禁止充电.
  469. //DS为二极管选择位,选择串在VCC1和VCC2之间的二极管个数,当值为01时选择一个二极管,为10时选择两个二极管,其它值为禁止充电.
  470. //RS为电阻选择寄存器,选择串在VCC1和VCC2之间的电阻值,当值为00时不选择任何电阻,而且禁止充电,01时为2K,10时为4K,11时为8K
  471. //_____________________________
  472. //|TCS|TCS|TCS|TCS|DS|DS|RS|RS|
  473. //|___|___|___|___|__|__|__|__|
  474. #define WPR 0x8e  //写保护寄存器地址
  475. #define DISABLE 0x80  //开启写保护
  476. #define ENABLE  0x00  //关闭写保护

  477. unsigned char OldSecond;
  478. unsigned char OldMinute;
  479. unsigned char OldHour;
  480. unsigned char NewSecond;
  481. unsigned char NewMinute;
  482. unsigned char NewHour;
  483. unsigned char TempSecond;
  484. unsigned char TempMinute;
  485. unsigned char TempHour;
  486. unsigned char OldDay;
  487. unsigned char OldMonth;
  488. unsigned char OldYear;
  489. unsigned char NewDay;
  490. unsigned char NewMonth;
  491. unsigned char NewYear;
  492. unsigned char TempDay;
  493. unsigned char TempMonth;
  494. unsigned char TempYear;
  495. unsigned int uiTimerHalfSecond;
  496. unsigned char ucTimerKeyChange;
  497. unsigned char ucTimerDelay;
  498. bit bFlagFlshTime;
  499. #endif
复制代码

6,以上就是我做的公交车自动报站系统,站点名字可以更改  如果解决了你的问题 请帮我评论 赞一个 谢谢了
0.png
全部资料51hei下载地址:
公交无线自动报站【增加温度显示,增加日期,上下行功能,模拟4站】_2017.10.19.rar (8.56 MB, 下载次数: 139)
回复

使用道具 举报

ID:602704 发表于 2019-8-28 10:26 | 显示全部楼层
由于刚刚接触这么强大的51hei电子网,所以帖子发的不是很好,也不是很详细 实物照片没插入进去 具体看压缩包
回复

使用道具 举报

ID:680125 发表于 2020-1-4 11:41 来自手机 | 显示全部楼层
很好
回复

使用道具 举报

ID:695076 发表于 2020-4-21 22:04 | 显示全部楼层
十分感谢楼主,给了我很大的借鉴,我想在上面再加一个测速电路和断电数据保护
回复

使用道具 举报

ID:425494 发表于 2021-3-19 10:51 | 显示全部楼层
很好的参考,谢谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表