找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6737|回复: 9
收起左侧

STM32两轮自平衡小车资料

[复制链接]
ID:95059 发表于 2017-3-18 11:47 | 显示全部楼层 |阅读模式
stm32单片机做的两轮自平衡小车资料,带完整的源码。还附带很多pdf教程 如pid控制和滤波的资料.
QQ截图20170317114629.jpg
全部资料打包下载:
两轮自平衡小车资料.rar (8.27 MB, 下载次数: 195)
回复

使用道具 举报

ID:1 发表于 2017-3-18 21:26 | 显示全部楼层
iic部分源码:
  1. #include "ofme_iic.h"

  2. ////////////////////////////////////////////////////////////////////////////////
  3. // ofme_iic.c
  4. // v2012.12.20
  5. // Copyright(C) ofourme@163.com
  6. // All rights reserved
  7. ////////////////////////////////////////////////////////////////////////////////
  8. // iic 主机模拟程序 for F/S mode
  9. // 不可重入
  10. // 所有的函数结束后都是占有scl总线的,故不会有别的主机与之竞争(除非与别的主...
  11. // 机处于完全同步),但别的主机也可能在程序运行期间加入竞争。
  12. ////////////////////////////////////////////////////////////////////////////////
  13. // 详见《I2C总线规范(周立功翻译版)》
  14. // 传输格式:P8~P10
  15. // 同步与仲裁:P10~P11
  16. // 时序要求:P27~P28
  17. // tag: 同步发生于主机活跃的所有时间
  18. //      仲裁发生于主机发送数据的情况,包括ACK位
  19. ////////////////////////////////////////////////////////////////////////////////
  20. // 全局变量,用于保存IIC_TIME_OUT等错误信息。通过iic_error_check()获取。
  21. static int _IIC_ERROR_CODE = IIC_OK;
  22. ////////////////////////////////////////////////////////////////////////////////
  23. #ifndef F_SCL
  24.     #err "F_SCL not defined."
  25. #elif (F_SCL==100)
  26. ////////////////////////////////////////////////////////////////////////////////
  27. // (重复)起始条件的保持时间。在这个周期后,产生第一个时间脉冲...
  28. //  4.0us<t_hd_sta or 0.6us<t_hd_sta
  29. #define T_HD_STA (4)
  30. // SCL时钟的低电平周期 4.7us<t or 1.3us<t
  31. // SDA should hold at least 300ns while SCL is falling
  32. #define T_LOW1  (1)
  33. #define T_LOW2  (4)
  34. #define T_LOW   (T_LOW1+T_LOW2)
  35. // SCL时钟的高电平周期 4.0us<t or 0.6us<t
  36. #define T_HIGH  (4)
  37. // 重复起始条件的建立时间 4.7us<t or 0.6us<t
  38. #define T_SU_STA (5)
  39. // 数据保持时间:
  40. // IIC总线器件:0<t<3.45us or 0<t<0.9us
  41. // 兼容CUBS的主机:5.0us<t<NULL or NULL<t<NULL
  42. // SDA should hold at least 300ns while SCL is falling
  43. #define T_HD_DAT (1)
  44. // 数据建立时间:250ns<t or 100ns<t
  45. #define T_SU_DAT (1)
  46. // 停止条件的建立时间:4.0us<t or 0.6us<t
  47. #define T_SU_STO (4)
  48. // 停止和启动条件之间的总线空闲时间 4.7us<t_buf or 1.3us<t_buf
  49. #define T_BUF   (5)
  50. ////////////////////////////////////////////////////////////////////////////////
  51. #elif (F_SCL==400)
  52. ////////////////////////////////////////////////////////////////////////////////
  53. #define T_HD_STA    (1)
  54. #define T_LOW1      (1)
  55. #define T_LOW2      (1)
  56. #define T_LOW       (T_LOW1+T_LOW2)
  57. #define T_HIGH      (1)
  58. #define T_SU_STA    (1)
  59. #define T_HD_DAT    (0)
  60. #define T_SU_DAT    (1)
  61. #define T_SU_STO    (1)
  62. #define T_BUF       (2)
  63. ////////////////////////////////////////////////////////////////////////////////
  64. #else
  65. #err "F_SCL value error."
  66. #endif
  67. ////////////////////////////////////////////////////////////////////////////////
  68. // 提供给iic的延时函数,单位为1微秒。
  69. #ifndef iic_delay
  70.     #err "iic_delay() not defined."
  71. #endif
  72. ////////////////////////////////////////////////////////////////////////////////
  73. // 主机释放SCL总线,而且等待外部主机、设备释放SCL总线。用于SCL同步。
  74. /* "IIC SCL SYNCHRONIZE." 不属于异常错误,故大写表示。*/
  75. #define IIC_SCL_RELEASE(t) \
  76. {\
  77.     SCL_H();\
  78.         t = 0;\
  79.         while(SCL==0)\
  80.         {\
  81.                 t++;\
  82.                 if(t==IIC_RAISING_COUNT) IIC_DEBUG("IIC SCL SYNCHRONIZE.\r\n");\
  83.                 if(t>=IIC_TIME_OUT_COUNT)\
  84.                 {\
  85.                         _IIC_ERROR_CODE = IIC_TIME_OUT;\
  86.                         IIC_DEBUG("iic scl synchronize time out.\r\n");\
  87.                         break;\
  88.                 }\
  89.         }\
  90. }
  91. ////////////////////////////////////////////////////////////////////////////////
  92. // 保持时间T的高电平。但是如果总线电平被外部拉低,则提前退出。用于SCL同步。
  93. #define IIC_SCL_HOLD(T, t) \
  94. {\
  95.     for(t=0; t<T; t++)\
  96.     {\
  97.         iic_delay(1);\
  98.         if(SCL==0) break;\
  99.     }\
  100. }
  101. ////////////////////////////////////////////////////////////////////////////////
  102. void iic_init(void)
  103. {
  104.         hw_iic_init(); // 外部函数。配置端口为开漏输出。
  105. //        _IIC_ERROR_CODE = IIC_OK;        // 延后到iic_start()里面设置。
  106.         SCL_H();                // 释放端口
  107.         SDA_H();
  108. }
  109. ////////////////////////////////////////////////////////////////////////////////
  110. // iic_start()函数在总线忙碌的情况下返回失败值
  111. int iic_start(void)
  112. {
  113. // 其它主机可能处于<1>start、<2>restart、<3>stop、<4>读写SDA且SDA为高电平。
  114. // 有可能独占总线或与别的主机同步占有总线,这是我们希望的最好结果。
  115. // 但iic协议是否有可能导致不同步地占有总线?
  116. //
  117. // 程序实际上应该检查总线在T_BUF期间是否被占用,保证起始标志时序不被打断,...
  118. // 但使用软件查询方式无法确切认定在延时期间总线电平没有被外部主机拉低,...
  119. // 本程序的缺陷有可能导致不同步地占有总线!!!
  120. // 只能寄希望于程序在后面的多主机竞争中失败退出而避免错误了。


  121.         _IIC_ERROR_CODE = IIC_OK;

  122.     SCL_H();
  123.     SDA_H();
  124.     iic_delay(T_BUF+T_BUF_ALT);        // 保证SCL与SDA线的高电平维持时间

  125.     if( SCL==0 )            // SCL总线忙
  126.         {
  127.         return IIC_SCL_BUSY;
  128.         }
  129.     if( SDA==0 )            // SDA总线忙
  130.         {
  131.                 return IIC_SDA_BUSY;
  132.         }
  133.        
  134.     SDA_L();
  135.     iic_delay(T_HD_STA);
  136.     SCL_L();    // get the SCL & SDA bus

  137.     return IIC_OK;
  138. }

  139. ////////////////////////////////////////////////////////////////////////////////
  140. // 在传输完数据后可立即调用iic_restart(),与iic_start()类似。
  141. void iic_restart(void)
  142. {
  143.         int t;
  144. // scl==0
  145.     SDA_H();
  146.     iic_delay(T_LOW);
  147.     IIC_SCL_RELEASE(t);
  148.     iic_delay(T_SU_STA);
  149.     SDA_L();
  150.     iic_delay(T_HD_STA);
  151.     SCL_L();    // get the SCL & SDA bus
  152. }
  153. ////////////////////////////////////////////////////////////////////////////////
  154. void iic_stop(void)
  155. {
  156. // scl==0
  157.     SDA_L();
  158.     iic_delay(T_LOW);
  159.         SCL_H();        // release SCL, ignore pulling down by other device.
  160.     iic_delay(T_SU_STO);
  161.     SDA_H();    // release SDA
  162. }

  163. ////////////////////////////////////////////////////////////////////////////////
  164. // 主机接收数据发送ack, 比较响应位进行多主机仲裁,由于ack为低电平,故实际不仲裁
  165. void iic_ack(void)
  166. {
  167.     int t;

  168. // scl==0
  169.     SDA_L();    // ack
  170.     iic_delay(T_LOW);
  171.     IIC_SCL_RELEASE(t);         // SCL SYNCHRONIZE
  172.     IIC_SCL_HOLD(T_HIGH, t);   // SCL SYNCHRONIZE
  173.     SCL_L();    // get the SCL bus
  174. }

  175. ////////////////////////////////////////////////////////////////////////////////
  176. // 主机接收数据发送nack, 比较响应位进行多主机仲裁
  177. int iic_nack(void)
  178. {
  179.     int t;

  180. // scl==0
  181.     SDA_H();  // nack
  182.     iic_delay(T_LOW);
  183.     IIC_SCL_RELEASE(t);         // SCL SYNCHRONIZE
  184.     if(SDA==0)
  185.     {   // scl & sda had been released before.
  186.                 IIC_DEBUG("iic_nack() arbitrate failed.\r\n");
  187.                 // 应该不用再发送时钟直到nack周期结束?
  188.         return IIC_AARB_FAIL;
  189.     }
  190.     IIC_SCL_HOLD(T_HIGH, t);         // SCL SYNCHRONIZE
  191.     SCL_L();    // get the SCL bus

  192.     return IIC_OK;
  193. }
  194. ////////////////////////////////////////////////////////////////////////////////
  195. // 主机发送数据完等待从机响应ack or nack,不进行多主机仲裁
  196. int iic_wait_ack(void)
  197. {
  198.     int t, data;

  199. // scl==0
  200.     SDA_H();            // release SDA
  201.     iic_delay(T_LOW);   // wait for SDA to be change
  202.     IIC_SCL_RELEASE(t);        // SCL SYNCHRONIZE
  203.         data = SDA;
  204.     IIC_SCL_HOLD(T_HIGH, t);  // SCL SYNCHRONIZE
  205.     SCL_L();    // get the SCL bus

  206.     if(data) return IIC_NACK;
  207.     else     return IIC_ACK;
  208. }
  209. ////////////////////////////////////////////////////////////////////////////////
  210. // 主机读取数据,不比较数据位进行多主机仲裁
  211. u8 iic_read(void)
  212. {
  213.     u8 d;
  214.     int i, t;

  215. // sda==0, scl==0;
  216.     SDA_H(); // release SDA, wait for SDA to be change
  217.     for(i=0, d=0; i<8; i++)
  218.     {
  219.         iic_delay(T_LOW);
  220.         IIC_SCL_RELEASE(t);          // SCL SYNCHRONIZE
  221. //      read_bit();
  222.         d<<=1;
  223.         if(SDA) d++;
  224. // 理论上read函数和write函数在这里收发字节的第1位时,应不断检测SCL高电平期间,...
  225. // SDA的电平有无变化以识别restart()或stop()标志,但同时还要检测SCL有无被外部拉低...
  226. // 在不使用中断而采用纯粹查询手段的情况下,实现起来有困难,故不做判断。
  227.         IIC_SCL_HOLD(T_HIGH, t);    // SCL SYNCHRONIZE
  228.         SCL_L();    // get the SCL bus
  229.     }

  230.     return d;
  231. }

  232. ////////////////////////////////////////////////////////////////////////////////
  233. // 主机发送数据,比较数据位进行多主机仲裁
  234. // 主机在发送数据的第一位且第一位为1时,其它主机可能在SCL高电平期间发送...
  235. // restart()或是stop()标志,也即电平0->1或是1->0,理论上程序应该检测这种...
  236. // 情况的发生,并停止发送数据而发送一样的restart或是stop标志(见P11)。
  237. // 为简化程序,一旦遇到这种情况既转化为IIC_ARB_FAIL处理。
  238. int iic_write(u8 data)
  239. {
  240.     int i, t, err = IIC_OK;

  241. // sda==0, scl==0;
  242.     for(i=0; i<8; i++, data<<=1)
  243.     {
  244.         iic_delay(T_LOW1);

  245. //                send_bit();
  246.                if(data&0x80)
  247.                    SDA_H();
  248.                else
  249.                    SDA_L();
  250. //
  251.             iic_delay(T_LOW2);
  252.                IIC_SCL_RELEASE(t);          // SCL SYNCHRONIZE
  253.                if( data&0x80 && (SDA==0) )//仲裁失败
  254.                {   // scl & sda had been released before.
  255.                         // 理论上仲裁失败就由其它主机接管控制器,程序可以停止产生SCL...
  256.                         // 在这里我们应该可以直接返回 IIC_DARB_FAIL
  257.             // return IIC_DARB_FAIL;
  258.                         // 但我选择发送0xff直到字节结束
  259.                         err = IIC_DARB_FAIL;
  260.                         data = 0xFF;
  261.         }
  262.         IIC_SCL_HOLD(T_HIGH, t);    // SCL SYNCHRONIZE
  263.         SCL_L();    // get the SCL bus
  264.     }

  265.     return err;
  266. }

  267. ////////////////////////////////////////////////////////////////////////////////
  268. #if 0
  269. int iic_dev_read(u8 dev, u8 addr, u8* data)
  270. {
  271. // 注意将IIC_DEBUG()放iic_stop()后面,以免影响总线时序。

  272.     int i;

  273.     i = iic_start();  // select the device and set address
  274.     if( i != IIC_OK ) goto err_bus_busy;
  275.     i = iic_write(dev);
  276.     if( i != IIC_OK ) goto err_arb_fail;
  277.     i = iic_wait_ack();
  278.     if( i != IIC_ACK) goto err_dev_fail;
  279.     i = iic_write(addr);
  280.     if( i != IIC_OK ) goto err_arb_fail;
  281.     i = iic_wait_ack();
  282.     if( i != IIC_ACK) goto err_tar_fail;

  283.     iic_restart();
  284.     i = iic_write(dev|1);  // start read
  285.     if( i != IIC_OK ) goto err_arb_fail;
  286.     i = iic_wait_ack();
  287.     if( i != IIC_ACK) goto err_dev_fail;
  288.     *data = iic_read();
  289.     i = iic_nack();// write nack to tell the slave stop transfer data.
  290.     if( i != IIC_OK ) goto err_arb_fail;

  291. //end:
  292.     iic_stop();
  293. //        IIC_DEBUG("R: IIC READ DONE.\r\n");
  294.         if(_IIC_ERROR_CODE & IIC_TIME_OUT)
  295.         {
  296.                 IIC_DEBUG("r: iic time out.\r\n");
  297.                 return _IIC_ERROR_CODE;
  298.         }
  299.     return IIC_OK;
  300. err_bus_busy:
  301.         if(i == IIC_SCL_BUSY)
  302.                 IIC_DEBUG("r: iic scl bus busy.\r\n");
  303.         else
  304.                 IIC_DEBUG("r: iic sda bus busy.\r\n");
  305.         return i | _IIC_ERROR_CODE;
  306. err_arb_fail:
  307. //  总线仲裁失败可能是由于硬件错误或是多主机竞争。如果是硬件错误,应继续产生...
  308. //  时钟到字节传输结束,然后释放总线?不管怎样,都不应该再调用iic_stop();
  309.         SDA_H();
  310.         SCL_H();
  311.         IIC_DEBUG("r: iic bus arbitrate failed.\r\n");
  312.         return i | _IIC_ERROR_CODE;        // IIC_ARB_FAIL
  313. err_dev_fail:
  314.         iic_stop();
  315.         IIC_DEBUG("r: iic device not respond.\r\n");
  316.         return IIC_DEVICE_FAIL | _IIC_ERROR_CODE;
  317. err_tar_fail:
  318.         iic_stop();
  319.         IIC_DEBUG("r: device target not respond.\r\n");
  320.         return IIC_TARGET_FAIL | _IIC_ERROR_CODE;
  321. }
  322. #else
  323. int iic_dev_read(u8 dev, u8 addr, u8* data)
  324. {
  325.         return iic_dev_gets(dev, addr, data, 1);
  326. }

  327. #endif
  328. ////////////////////////////////////////////////////////////////////////////////

  329. int iic_dev_gets(u8 dev, u8 addr, u8* data, u16 n)
  330. {
  331.     int i;

  332.     i = iic_start();  // select the device and set address
  333.     if( i != IIC_OK ) goto err_bus_busy;
  334.     i = iic_write(dev);
  335.     if( i != IIC_OK ) goto err_arb_fail;
  336.     i = iic_wait_ack();
  337.     if( i != IIC_ACK) goto err_dev_fail;
  338.     i = iic_write(addr);
  339.     if( i != IIC_OK ) goto err_arb_fail;
  340.     i = iic_wait_ack();
  341.     if( i != IIC_ACK) goto err_tar_fail;

  342.     iic_restart();
  343.     i = iic_write(dev|1);  // start read
  344.     if( i != IIC_OK ) goto err_arb_fail;
  345.     i = iic_wait_ack();
  346.     if( i != IIC_ACK) goto err_dev_fail;
  347.         if(n<1) n=1;
  348.         while(--n)
  349.     {
  350.                 *data++ = iic_read();
  351.                 iic_ack();
  352.         }
  353.         *data = iic_read();
  354.     i = iic_nack();// write nack to tell the slave stop transfer data.
  355.     if( i != IIC_OK ) goto err_arb_fail;

  356. //end:
  357.     iic_stop();
  358. //        IIC_DEBUG("R: IIC READ DONE.\r\n");
  359.         if(_IIC_ERROR_CODE & IIC_TIME_OUT)
  360.         {
  361.                 IIC_DEBUG("r: iic time out.\r\n");
  362.                 return _IIC_ERROR_CODE;
  363.         }
  364.     return IIC_OK;
  365. err_bus_busy:
  366.         if(i == IIC_SCL_BUSY)
  367.                 IIC_DEBUG("r: iic scl bus busy.\r\n");
  368.         else
  369.                 IIC_DEBUG("r: iic sda bus busy.\r\n");
  370.         return i | _IIC_ERROR_CODE;
  371. err_arb_fail:
  372. //  总线仲裁失败可能是由于硬件错误或是多主机竞争。如果是硬件错误,应继续产生...
  373. //  时钟到字节传输结束,然后释放总线?不管怎样,都不应该再调用iic_stop();
  374.         SDA_H();
  375.         SCL_H();
  376.         IIC_DEBUG("r: iic bus arbitrate failed.\r\n");
  377.         return i | _IIC_ERROR_CODE;        // IIC_ARB_FAIL
  378. err_dev_fail:
  379.         iic_stop();
  380.         IIC_DEBUG("r: iic device not respond.\r\n");
  381.         return IIC_DEVICE_FAIL | _IIC_ERROR_CODE;
  382. err_tar_fail:
  383.         iic_stop();
  384.         IIC_DEBUG("r: device target not respond.\r\n");
  385.         return IIC_TARGET_FAIL | _IIC_ERROR_CODE;
  386. }


  387. ////////////////////////////////////////////////////////////////////////////////
  388. #if 0
  389. int iic_dev_write(u8 dev, u8 addr, u8 data)
  390. {
  391. // 注意将IIC_DEBUG()放iic_stop()后面,以免影响总线时序。

  392.     int i;

  393.     i = iic_start();
  394.     if( i != IIC_OK ) goto err_bus_busy;
  395.     i = iic_write(dev);
  396.     if( i != IIC_OK ) goto err_arb_fail;
  397.     i = iic_wait_ack();
  398.     if( i != IIC_ACK) goto err_dev_fail;
  399.     i = iic_write(addr);
  400.     if( i != IIC_OK ) goto err_arb_fail;
  401.     i = iic_wait_ack();
  402.     if( i != IIC_ACK) goto err_tar_fail;
  403.     i = iic_write(data);
  404.     if( i != IIC_OK ) goto err_arb_fail;
  405. // 如果返回IIC_NACK,则不能再继续往从机写数据。本函数只写一字节的数据,故忽略。
  406.     i = iic_wait_ack();
  407. //end:
  408.     iic_stop();
  409. //        IIC_DEBUG("W: IIC WRITE DONE.\r\n");
  410.         if( i != IIC_ACK)
  411.                 IIC_DEBUG("w: IIC DEVICE NO ACK.\r\n");
  412.         if(_IIC_ERROR_CODE & IIC_TIME_OUT)
  413.         {
  414.                 IIC_DEBUG("w: iic time out.\r\n");
  415.                 return _IIC_ERROR_CODE;
  416.         }
  417.     return IIC_OK;
  418. err_bus_busy:
  419.         if(i == IIC_SCL_BUSY)
  420.                 IIC_DEBUG("w: iic scl bus busy.\r\n");
  421.         else
  422.                 IIC_DEBUG("w: iic sda bus busy.\r\n");
  423.         return i | _IIC_ERROR_CODE;
  424. err_arb_fail:
  425. //  总线仲裁失败可能是由于硬件错误或是多主机竞争。如果是硬件错误,应继续产生...
  426. //  时钟到字节传输结束,然后释放总线?不管怎样,都不应该再调用iic_stop();
  427.         SDA_H();
  428.         SCL_H();
  429.         IIC_DEBUG("w: iic bus arbitrate failed.\r\n");
  430.         return i | _IIC_ERROR_CODE;        // IIC_ARB_FAIL
  431. err_dev_fail:
  432.         iic_stop();
  433.         IIC_DEBUG("w: iic device not respond.\r\n");
  434.         return IIC_DEVICE_FAIL | _IIC_ERROR_CODE;
  435. err_tar_fail:
  436.         iic_stop();
  437.         IIC_DEBUG("w: device target not respond.\r\n");
  438.         return IIC_TARGET_FAIL | _IIC_ERROR_CODE;
  439. }

  440. #else

  441. int iic_dev_write(u8 dev, u8 addr, u8 data)
  442. {
  443.         u8 buf = data;
  444.         return iic_dev_puts(dev, addr, &buf, 1);
  445. }

  446. #endif

  447. ////////////////////////////////////////////////////////////////////////////////

  448. int iic_dev_puts(u8 dev, u8 addr, u8* data, u16 n)
  449. {
  450. // 注意将IIC_DEBUG()放iic_stop()后面,以免影响总线时序。

  451.     int i;

  452.     i = iic_start();
  453.     if( i != IIC_OK ) goto err_bus_busy;
  454.     i = iic_write(dev);
  455.     if( i != IIC_OK ) goto err_arb_fail;
  456.     i = iic_wait_ack();
  457.     if( i != IIC_ACK) goto err_dev_fail;
  458.     i = iic_write(addr);
  459.     if( i != IIC_OK ) goto err_arb_fail;
  460.     i = iic_wait_ack();
  461.     if( i != IIC_ACK) goto err_tar_fail;

  462.         if(n<1) n=1;
  463.         while(--n)
  464.         {
  465.                 i = iic_write(*data++);
  466.             if( i != IIC_OK ) goto err_arb_fail;
  467.             i = iic_wait_ack();
  468.                 if( i != IIC_ACK) goto err_tar_fail;        //could not write data.
  469.         }
  470.         i = iic_write(*data);
  471.            if( i != IIC_OK ) goto err_arb_fail;
  472.            iic_wait_ack();        // 最后一个字节,忽略ack。


  473. //end:
  474.     iic_stop();
  475. //        IIC_DEBUG("W: IIC WRITE DONE.\r\n");

  476.         if(_IIC_ERROR_CODE & IIC_TIME_OUT)
  477.         {
  478.                 IIC_DEBUG("w: iic time out.\r\n");
  479.                 return _IIC_ERROR_CODE;
  480.         }
  481.     return IIC_OK;
  482. err_bus_busy:
  483.         if(i == IIC_SCL_BUSY)
  484.                 IIC_DEBUG("w: iic scl bus busy.\r\n");
  485.         else
  486.                 IIC_DEBUG("w: iic sda bus busy.\r\n");
  487.         return i | _IIC_ERROR_CODE;
  488. err_arb_fail:
  489. //  总线仲裁失败可能是由于硬件错误或是多主机竞争。如果是硬件错误,应继续产生...
  490. //  时钟到字节传输结束,然后释放总线?不管怎样,都不应该再调用iic_stop();
  491.         SDA_H();
  492.         SCL_H();
  493.         IIC_DEBUG("w: iic bus arbitrate failed.\r\n");
  494.         return i | _IIC_ERROR_CODE;        // IIC_ARB_FAIL
  495. err_dev_fail:
  496.         iic_stop();
  497.         IIC_DEBUG("w: iic device not respond.\r\n");
  498.         return IIC_DEVICE_FAIL | _IIC_ERROR_CODE;
  499. err_tar_fail:
  500.         iic_stop();
  501.         IIC_DEBUG("w: device target not respond.\r\n");
  502.         return IIC_TARGET_FAIL | _IIC_ERROR_CODE;
  503. }

  504. ////////////////////////////////////////////////////////////////////////////////
复制代码
回复

使用道具 举报

ID:1 发表于 2017-3-18 21:26 | 显示全部楼层
红外遥控部分:
  1. #include "ofme_ir_nec.h"
  2. #include "ofme_time.h"

  3. #define NEC_HEAD_PLUSE_MAX                (9000+900)
  4. #define NEC_HEAD_PLUSE_MIN                (9000-630)
  5. #define NEC_HEAD_SPACE_MAX                (4500+450)
  6. #define NEC_HEAD_SPACE_MIN                (4500-315)
  7. #define NEC_HEAD_MAX                        (NEC_HEAD_PLUSE_MAX+NEC_HEAD_SPACE_MAX)
  8. #define NEC_HEAD_MIN                        (NEC_HEAD_PLUSE_MIN+NEC_HEAD_SPACE_MIN)
  9. #define NEC_DATA_PLUSE_MAX                (560+56)
  10. #define NEC_DATA_PLUSE_MIN                (560-56)
  11. #define NEC_LOG0_SPACE_MAX                (560+56)
  12. #define NEC_LOG0_SPACE_MIN                (560-56)
  13. #define NEC_LOG0_MAX                        (NEC_DATA_PLUSE_MAX+NEC_LOG0_SPACE_MAX)
  14. #define NEC_LOG0_MIN                        (NEC_DATA_PLUSE_MIN+NEC_LOG0_SPACE_MIN)
  15. #define NEC_LOG1_SPACE_MAX                (1680+168)
  16. #define NEC_LOG1_SPACE_MIN                (1680-168)
  17. #define NEC_LOG1_MAX                        (NEC_DATA_PLUSE_MAX+NEC_LOG1_SPACE_MAX)
  18. #define NEC_LOG1_MIN                        (NEC_DATA_PLUSE_MIN+NEC_LOG1_SPACE_MIN)
  19. #define NEC_REPEAT_PLUSE_MAX        (9000+630)
  20. #define NEC_REPEAT_PLUSE_MIN        (9000-900)
  21. #define NEC_REPEAT_SPACE_MAX        (2500+175)
  22. #define NEC_REPEAT_SPACE_MIN        (2500-250)
  23. #define NEC_REPEAT_DELAY_MAX        (97940+9794+NEC_DATA_PLUSE_MAX)
  24. #define NEC_REPEAT_DELAY_MIN        (97940-9794+NEC_DATA_PLUSE_MIN)
  25. #define NEC_REPEAT_MAX                        (NEC_REPEAT_PLUSE_MAX+NEC_REPEAT_SPACE_MAX)
  26. #define NEC_REPEAT_MIN                        (NEC_REPEAT_PLUSE_MIN+NEC_REPEAT_SPACE_MIN)

  27. #define IR_INT_CLR()                        EXTI->PR = 1<<1

  28. #define IR_NEC_DEBUG

  29. // 接收到的数值
  30. u32 ir_data;
  31. // <0: ir_data无效; 0:ir_data有效,但已经被处理过;>0: 连发次数;当>0,外部程序可以进行-1操作表示读取数据
  32. int        ir_repeat = -1;
  33. // 0: OK; >0: error count; 外部程序可读取此数值了解有无干扰信号或用于debug
  34. int ir_err_cnt = 0;

  35. void hw_ir_init(void)
  36. {

  37. //初始化红外接收引脚的设置
  38. //开启中断,并映射
  39.         RCC->APB2ENR|=1<<4;       //PC时钟使能                  
  40.         GPIOC->CRL&=0XFFFFFF0F;
  41.         GPIOC->CRL|=0X00000080;        //PC1输入         
  42.         GPIOC->ODR|=1<<1;                //PC.1上拉      
  43.         Ex_NVIC_Config(GPIO_C,1,FTIR);//将line1映射到PC.1,下降沿触发.
  44.         MY_NVIC_Init(2,1,EXTI1_IRQChannel,2);

  45. }
  46. // 一体化红外接收头只能通过38kHz左右的载波(抗干扰&节能),并转化为TTL低电平
  47. // 下降沿中断
  48. void EXTI1_IRQHandler(void)
  49. //void ir_nec_receive(void)
  50. {
  51. //        step(<=-1:表示重复帧结束; 0:表示数据帧的开头;32:表示连续帧之间的间隔;>=33:表示重复帧的开头)
  52.         static int step=-1;
  53.         static int time1=0;
  54.         int        time2;
  55.         int interval;

  56.         time2 = hw_time_get();
  57.         interval = hw_interval_get(time1,time2);
  58.         time1 = time2;

  59.         if(interval>NEC_REPEAT_DELAY_MAX)//连发码之间的最大间隔
  60.         {
  61.                 step = -1;
  62.                 goto err;
  63.         }
  64.         else if(interval>NEC_HEAD_MAX)
  65.         {
  66.                 goto err;
  67.         }
  68.         else if(interval>NEC_HEAD_MIN)
  69.         {
  70.                 ir_repeat=-1; // 表示ir_data无效
  71.                 ir_data = 0;
  72.                 step = 0;
  73. #ifdef IR_NEC_DEBUG
  74.                 putchar('[');
  75. #endif
  76.                 IR_INT_CLR();
  77.                 return;
  78.         }
  79.         else if(interval>NEC_REPEAT_MAX)
  80.         {
  81.                 goto err;
  82.         }
  83.         else if(interval>NEC_REPEAT_MIN)
  84.         {
  85.                 if(step != 33) goto err;
  86.                 step = 32;
  87.                 ir_repeat++;
  88. #ifdef IR_NEC_DEBUG
  89.                 putchar('-');
  90.                 putchar('R');
  91.                 printf("-%d*%d.", (ir_data>>16)&0x0FF, ir_repeat);
  92. #endif
  93.                 IR_INT_CLR();
  94.                 return;
  95.         }
  96.         else if(interval>NEC_LOG1_MAX)
  97.         {
  98.                 goto err;
  99.         }
  100.         else if(interval>NEC_LOG1_MIN)
  101.         {
  102.                 goto decode;
  103.         }
  104.         else if(interval>NEC_LOG0_MAX)
  105.         {
  106.                 goto err;
  107.         }
  108.         else if(interval>NEC_LOG0_MIN)
  109.         {
  110.                 goto decode;
  111.         }
  112.         else
  113.         {
  114.                 goto err;
  115.         }

  116. // 只有长度为0或1的脉冲才能执行到这里
  117. decode:
  118.         if(step<0 || step>=32) goto err;
  119.         ir_data>>= 1;
  120.         if(interval>NEC_LOG1_MIN)
  121.         {
  122.                 ir_data |= 0x80000000UL;
  123.         }
  124.         step++;
  125.         if(step==32)
  126.         {
  127.                 ir_repeat = 1;
  128. #ifdef IR_NEC_DEBUG
  129.                 putchar(']');
  130.                 printf("-%d*%d.", (ir_data>>16)&0x0FF, ir_repeat);
  131. #endif
  132.         }
  133.         IR_INT_CLR();
  134.         return;

  135. err:
  136. #ifdef IR_NEC_DEBUG
  137.         putchar('\r');
  138.         putchar('\n');
  139. #endif
  140.         if(step == 32)
  141.         {
  142.                 step = 33;
  143. #ifdef IR_NEC_DEBUG
  144.                 putchar('R');
  145. #endif
  146.         }
  147.         else if(step>=0) // 数据接收出错
  148.         {
  149.                 ir_err_cnt++;
  150.                 step = -1;
  151. #ifdef IR_NEC_DEBUG
  152.                 putchar('E');
  153. #endif
  154.         }
  155.         else
  156.         {
  157. #ifdef IR_NEC_DEBUG
  158.                 putchar('S');
  159. #endif
  160.         }

  161.         IR_INT_CLR();
  162.         return;
  163. }
复制代码


回复

使用道具 举报

ID:146110 发表于 2017-4-30 17:03 | 显示全部楼层
两轮的人玩的不多呀
回复

使用道具 举报

ID:95059 发表于 2017-8-13 21:22 | 显示全部楼层
tam1974 发表于 2017-4-30 17:03
两轮的人玩的不多呀

难度比较大,所以玩得人少
回复

使用道具 举报

ID:134810 发表于 2017-9-27 15:54 来自手机 | 显示全部楼层
是这样的
回复

使用道具 举报

ID:313772 发表于 2018-4-22 15:46 | 显示全部楼层
适合初学者  做嘛
回复

使用道具 举报

ID:363726 发表于 2018-7-18 08:31 | 显示全部楼层
学习
回复

使用道具 举报

ID:243161 发表于 2018-8-4 14:26 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:87766 发表于 2018-9-7 11:02 | 显示全部楼层
谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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