IB_Reader.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "IB_Reader.h"
  2. #include "gpio.h"
  3. #include "string.h"
  4. #define IB_READ_ROM (0x33)
  5. #define IB_MATCH_ROM (0x55)
  6. #define IB_SEARCH_ROM (0xF0)
  7. #define IB_SKIP_ROM (0xCC)
  8. #define IB_WRITE_SCRATCHPAD (0x0F)
  9. #define IB_READ_SCRATCHPAD (0xAA)
  10. #define IB_COPY_SCRATCHPAD (0x55)
  11. #define IB_READ_MEMORY (0xF0)
  12. static uint8_t rom_id[8]={0};
  13. static uint16_t g_oilType = OIL_TYPE_NULL;
  14. static uint8_t ib_readerror_count = 0;
  15. /**
  16. * @brief 初始化
  17. * @param 无
  18. * @retval ACK应答位
  19. **/
  20. uint8_t OneWire_Init()
  21. {
  22. uint8_t Ackbit = 0;
  23. IBTX_WIRE_HIGH; //先将总线拉高
  24. IBTX_WIRE_LOW; //然后将总线拉低
  25. udelay(480);
  26. IBTX_WIRE_HIGH; //释放总线
  27. udelay(70); //Delay 70 us
  28. Ackbit=IBRX_WIRE_BIT; //读取应答位
  29. udelay(410); //Delay 500 us
  30. return Ackbit;
  31. }
  32. /**
  33. * @brief 发送一位
  34. * @param Bit
  35. * @retval 无
  36. **/
  37. void OneWire_Senbit(uint8_t Bit)
  38. {
  39. IBTX_WIRE_LOW; //拉低
  40. udelay(5); //Delay 10 us(考虑到调用函数需要时间,实际i可以适当取的更大)
  41. //发送一位
  42. if(0 == Bit){
  43. IBTX_WIRE_LOW;
  44. }else{
  45. IBTX_WIRE_HIGH;
  46. }
  47. //讲解:从发送0和发送1俩个不同的时序可以看出,如果我们在10us的时候将Bit放在DQ上,如果是0
  48. // 则DQ一直会被拉低,如果是1,主机也会将DQ拉高,最后等50us后将数据发送即可
  49. udelay(50); //Delay 50 us
  50. IBTX_WIRE_HIGH; //拉高,便于下次发送
  51. udelay(5); //Delay 50 us
  52. }
  53. /**
  54. * @brief 接受一位
  55. * @param 无
  56. * @retval Bit
  57. **/
  58. uint8_t OneWire_ReceiveBit()
  59. {
  60. uint8_t Bit;
  61. IBTX_WIRE_LOW;
  62. udelay(3); //Delay 5 us
  63. IBTX_WIRE_HIGH;
  64. udelay(5); //Delay 5 us
  65. //解释:读取数据需要在15us内进行(贴近15us的时候),如果是0,DQ会在5us后被从机拉低,
  66. // 如果是1, DQ会在5us后被从机拉高
  67. Bit=IBRX_WIRE_BIT; //进行数据接受
  68. udelay(50); //Delay 50 us
  69. return Bit;
  70. }
  71. /**
  72. * @brief 发送一个字节
  73. * @param Byte
  74. * @retval 无
  75. **/
  76. void OneWire_SenByte(uint8_t Byte)
  77. {
  78. uint8_t i;
  79. for(i=0;i<8;i++)
  80. {
  81. OneWire_Senbit(Byte&(0x01<<i));//低位在前
  82. }
  83. }
  84. /**
  85. * @brief 接受一个字节
  86. * @param 无
  87. * @retval Byte
  88. **/
  89. uint8_t OneWire_ReceiveByte()
  90. {
  91. uint8_t i;
  92. uint8_t Byte=0x00;
  93. for(i=0;i<8;i++)
  94. {
  95. if(OneWire_ReceiveBit()){Byte|=(0x01<<i);} //低位在前
  96. }
  97. return Byte;
  98. }
  99. uint8_t IBread_OilType(void)
  100. {
  101. return 0;
  102. }
  103. uint8_t IBread_ROMID(void)
  104. {
  105. uint8_t Ackbit = 1;
  106. uint8_t i=0;
  107. Ackbit = OneWire_Init(); //总线初始化时序
  108. if(0 == Ackbit){
  109. //printf("IBread_ROMID recv ack \r\n");
  110. OneWire_SenByte(IB_READ_ROM); //发送读ROMID指令
  111. for(i=0; i<8;i++){
  112. rom_id[i]=OneWire_ReceiveByte(); //第一个字节为低位
  113. }
  114. }
  115. return 0;
  116. }
  117. uint8_t IBread_Memory(void)
  118. {
  119. uint8_t Ackbit = 1;
  120. uint8_t i=0;
  121. uint16_t oil_type = 0;
  122. uint16_t _type = 0;
  123. memset(rom_id, 0, sizeof(rom_id));
  124. Ackbit = OneWire_Init(); //总线初始化时序
  125. if(0 == Ackbit){
  126. OneWire_SenByte(IB_SKIP_ROM);
  127. OneWire_SenByte(IB_READ_MEMORY);
  128. OneWire_SenByte(0x00);
  129. OneWire_SenByte(0x00);
  130. for(i=0; i<4;i++){
  131. rom_id[i]=OneWire_ReceiveByte(); //第一个字节为低位
  132. }
  133. oil_type = (rom_id[0]<<8)|rom_id[1];
  134. _type = (rom_id[2]<<8)|rom_id[3];
  135. //油品类型 是按位取反关系
  136. if((0 == (oil_type&_type)) && (0xFFFF == (oil_type|_type))){
  137. //oil_type = rom_id[0];
  138. g_oilType = oil_type;
  139. ib_readerror_count = 0;
  140. }else{
  141. if(((0xFFFF == oil_type) && (0xFFFF == _type)) || ((0x00 == oil_type) && (0x00 == _type)))
  142. {
  143. //断开
  144. g_oilType = OIL_TYPE_NULL;
  145. ib_readerror_count = 0;
  146. }else{
  147. //通信错误 或有干扰
  148. ib_readerror_count++;
  149. if(ib_readerror_count >= 3){
  150. ib_readerror_count = 3;
  151. g_oilType = OIL_TYPE_NULL;
  152. }
  153. }
  154. }
  155. }else{
  156. //通信错误 无ACK
  157. ib_readerror_count++;
  158. if(ib_readerror_count >= 2){
  159. ib_readerror_count = 3;
  160. g_oilType = OIL_TYPE_NULL;
  161. }
  162. }
  163. return 0;
  164. }
  165. void IB_Print(void)
  166. {
  167. IBread_ROMID();
  168. printf("memory:[%x][%x][%x][%x][%x][%x][%x][%x] \r\n", rom_id[0],rom_id[1],rom_id[2],rom_id[3],rom_id[4],rom_id[5],rom_id[6],rom_id[7]);
  169. }
  170. void IBRead_OilType(void)
  171. {
  172. IBread_Memory();
  173. }
  174. uint16_t IBGet_OilType(void)
  175. {
  176. return g_oilType;
  177. }