IB_Reader.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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 uint8_t oil_type = 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. memset(rom_id, 0, sizeof(rom_id));
  122. Ackbit = OneWire_Init(); //总线初始化时序
  123. if(0 == Ackbit){
  124. OneWire_SenByte(IB_SKIP_ROM);
  125. OneWire_SenByte(IB_READ_MEMORY);
  126. OneWire_SenByte(0x00);
  127. OneWire_SenByte(0x00);
  128. for(i=0; i<2;i++){
  129. rom_id[i]=OneWire_ReceiveByte(); //第一个字节为低位
  130. }
  131. //油品两个字节互为补码
  132. if((0 == (rom_id[0]&rom_id[1])) && (0xFF == (rom_id[0]|rom_id[1]))){
  133. oil_type = rom_id[0];
  134. ib_readerror_count = 0;
  135. }else{
  136. if(((0xFF == rom_id[0]) && (0xFF == rom_id[1])) || ((0x00 == rom_id[0]) && (0x00 == rom_id[1])))
  137. {
  138. //断开
  139. oil_type = OIL_TYPE_NULL;
  140. ib_readerror_count = 0;
  141. }else{
  142. //通信错误 或有干扰
  143. ib_readerror_count++;
  144. if(ib_readerror_count >= 3){
  145. ib_readerror_count = 3;
  146. oil_type = OIL_TYPE_NULL;
  147. }
  148. }
  149. }
  150. }else{
  151. //通信错误 无ACK
  152. ib_readerror_count++;
  153. if(ib_readerror_count >= 2){
  154. ib_readerror_count = 3;
  155. oil_type = OIL_TYPE_NULL;
  156. }
  157. }
  158. return 0;
  159. }
  160. void IB_Print(void)
  161. {
  162. IBread_ROMID();
  163. 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]);
  164. }
  165. void IBRead_OilType(void)
  166. {
  167. IBread_Memory();
  168. }
  169. uint8_t IBGet_OilType(void)
  170. {
  171. return oil_type;
  172. }