hal_sc7a20.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. #include "hal_sc7a20.h"
  2. #include "hc32_ll_gpio.h"
  3. //pb10 --sda pb15 --sck
  4. #define READ_SDA3 GPIO_ReadInputPins(GPIO_PORT_B,GPIO_PIN_10)
  5. #define IIC_SDA3(n) (n?GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_10):GPIO_ResetPins(GPIO_PORT_B, GPIO_PIN_10))
  6. #define IIC_SCL3(n) (n?GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_15):GPIO_ResetPins(GPIO_PORT_B, GPIO_PIN_15))
  7. //需要示波器调1us的时间
  8. static void delay_us(uint16_t time)
  9. {
  10. uint16_t i;
  11. for(i=time;i>0;i--)
  12. {
  13. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  14. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  15. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  16. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  17. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  18. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  19. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  20. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  21. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  22. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  23. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  24. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  25. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  26. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  27. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  28. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  29. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  30. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  31. }
  32. }
  33. void iic3_init(void)
  34. {
  35. stc_gpio_init_t pstcGpioInit1;
  36. GPIO_StructInit(&pstcGpioInit1);
  37. pstcGpioInit1.u16PinDir = PIN_DIR_OUT;
  38. pstcGpioInit1.u16PinState = PIN_STAT_RST;
  39. GPIO_Init(GPIO_PORT_B, GPIO_PIN_10,&pstcGpioInit1);
  40. GPIO_Init(GPIO_PORT_B, GPIO_PIN_15,&pstcGpioInit1);
  41. GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_10);
  42. GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_15);
  43. }
  44. void sc7a20_init(void)
  45. {
  46. iic3_init();
  47. }
  48. static void SDA_IN3(void)
  49. {
  50. stc_gpio_init_t pstcGpioInit3;//iic的引脚
  51. pstcGpioInit3.u16PinDir = PIN_DIR_IN;
  52. GPIO_Init(GPIO_PORT_B, GPIO_PIN_10,&pstcGpioInit3);
  53. }
  54. static void SDA_OUT3(void)
  55. {
  56. stc_gpio_init_t pstcGpioInit3;
  57. pstcGpioInit3.u16PinDir = PIN_DIR_OUT;
  58. pstcGpioInit3.u16PinOutputType=PIN_OUT_TYPE_NMOS;
  59. GPIO_Init(GPIO_PORT_B, GPIO_PIN_10,&pstcGpioInit3);
  60. }
  61. static void iic_start(void)
  62. {
  63. SDA_OUT3();
  64. IIC_SDA3(1);
  65. IIC_SCL3(1);
  66. delay_us(5);
  67. IIC_SDA3(0);
  68. delay_us(5);
  69. IIC_SCL3(0);
  70. }
  71. static void iic_stop(void)
  72. {
  73. SDA_OUT3();
  74. IIC_SCL3(0);
  75. IIC_SDA3(0);
  76. delay_us(5);
  77. IIC_SCL3(1);
  78. IIC_SDA3(1);
  79. delay_us(5);
  80. }
  81. static void iic_ack(void)
  82. {
  83. SDA_OUT3();
  84. IIC_SCL3(0);
  85. IIC_SDA3(0);
  86. delay_us(5);
  87. IIC_SCL3(1);
  88. delay_us(5);
  89. IIC_SCL3(0);
  90. }
  91. static void iic_nack(void)
  92. {
  93. SDA_OUT3();
  94. IIC_SCL3(0);
  95. IIC_SDA3(1);
  96. delay_us(5);
  97. IIC_SCL3(1);
  98. delay_us(5);
  99. IIC_SCL3(0);
  100. }
  101. static uint8_t iic_wait_ack(void)
  102. {
  103. uint16_t t =200;
  104. SDA_OUT3();
  105. IIC_SDA3(1);delay_us(1);
  106. IIC_SCL3(1);delay_us(1);
  107. SDA_IN3();
  108. while(READ_SDA3)
  109. {
  110. t--;
  111. if(t==0)
  112. {
  113. iic_stop();
  114. return 1;
  115. }
  116. delay_us(1);
  117. }
  118. IIC_SCL3(0);
  119. return 0;
  120. }
  121. static void iic_send_byte(uint8_t byte)
  122. {
  123. uint8_t bit_cnt;
  124. SDA_OUT3();
  125. IIC_SCL3(0);
  126. for(bit_cnt=0;bit_cnt<8;bit_cnt++)
  127. {
  128. if(byte&0x80)
  129. IIC_SDA3(1);
  130. else
  131. IIC_SDA3(0);
  132. byte<<=1;
  133. delay_us(5);
  134. IIC_SCL3(1);
  135. delay_us(5);
  136. IIC_SCL3(0);
  137. }
  138. }
  139. static uint8_t iic_recive_byte(unsigned char ack)
  140. {
  141. uint8_t retc = 0;
  142. uint8_t bit_cnt;
  143. SDA_IN3();
  144. delay_us(5);
  145. for(bit_cnt=0;bit_cnt<8;bit_cnt++)
  146. {
  147. IIC_SCL3(0);
  148. delay_us(5);
  149. IIC_SCL3(1);
  150. retc=retc<<1;
  151. if(READ_SDA3)
  152. retc++;
  153. delay_us(5);
  154. }
  155. return(retc);
  156. }
  157. static void sc7a20_write_byte(uint8_t RAddr, uint8_t WData)
  158. {
  159. iic_start();
  160. iic_send_byte(Sensor_Wr_Addr1);
  161. iic_wait_ack();
  162. iic_send_byte(RAddr);
  163. iic_wait_ack();
  164. iic_send_byte(WData);
  165. iic_wait_ack();
  166. iic_stop();
  167. }
  168. static void sc7a20_read_byte(uint8_t RAddr, uint8_t *RData)
  169. {
  170. iic_start();
  171. iic_send_byte(Sensor_Wr_Addr1);
  172. iic_wait_ack();
  173. iic_send_byte(RAddr);
  174. iic_wait_ack();
  175. iic_start();
  176. iic_send_byte(Sensor_Rd_Addr1);
  177. iic_wait_ack();
  178. *RData = iic_recive_byte(0);
  179. iic_stop();
  180. }
  181. /*SC7A20获取加速度值
  182. accd_lsb:加速度值低寄存器地址
  183. accd_msb:加速度值高寄存器地址
  184. 返回值accd_f:加速度值,单位mg */
  185. int SC7A20_Get_ACCD(uint8_t accd_lsb,uint8_t accd_msb)
  186. {
  187. uint8_t accd_l,accd_m = 0;
  188. unsigned int temp;
  189. int accd;
  190. sc7a20_read_byte(accd_lsb,&accd_l);
  191. sc7a20_read_byte(accd_msb,&accd_m);
  192. temp &= 0x0000;
  193. temp |= accd_m;
  194. temp <<= 8;
  195. temp &= 0xff00;
  196. temp |= accd_l;
  197. if(temp&0x8000)
  198. {
  199. temp >>= 4;
  200. temp |= 0xf000;
  201. }
  202. else
  203. {
  204. temp >>= 4;
  205. temp &= 0x0fff;
  206. }
  207. accd = temp*1;
  208. return accd;
  209. }
  210. uint8_t read_chip_id(void)
  211. {
  212. uint8_t chip_id;
  213. sc7a20_read_byte(0x0f,&chip_id);
  214. // printf("chip_id=0x%x\r\n",chip_id);
  215. return chip_id;
  216. }
  217. void SC7A20_BOOT(void)
  218. {
  219. uint8_t ret;
  220. sc7a20_read_byte(0x24,&ret);
  221. sc7a20_write_byte(0x24,0x80/*|ret*/); //boot
  222. }
  223. int8_t SC7A20_INT_Config(void)
  224. {
  225. uint8_t SL_Read_Reg;
  226. /*******************AOI1 IN INT1********************/
  227. SL_Read_Reg=0x08;//AOI1 LATCH
  228. sc7a20_write_byte(SL_SC7A20_CTRL_REG5, SL_Read_Reg);
  229. SL_Read_Reg=SL_SC7A20_INT_ACTIVE_HIGH_LEVEL;
  230. //interrupt happen,int pin output lower level
  231. sc7a20_write_byte(SL_SC7A20_CTRL_REG6, SL_Read_Reg);
  232. //AOI1 CONFIG
  233. SL_Read_Reg=0x00; //0x7F
  234. SL_Read_Reg=SL_Read_Reg|0x40;//閿熸枻鎷烽敓鏂ゆ嫹閿熷壙璁规嫹璇嗛敓鏂ゆ嫹妯″紡
  235. SL_Read_Reg=SL_Read_Reg|0x03;//X 閿熸枻鎷峰彥閿熸枻鎷峰綍閿燂拷 X閿熸枻鎷烽敓鏂ゆ嫹閿熸嵎鐨勬拝鎷烽敓鏂ゆ嫹鍊奸敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹鍊�
  236. SL_Read_Reg=SL_Read_Reg|0x0C;//Y 閿熸枻鎷峰彥閿熸枻鎷峰綍閿燂拷 Y閿熸枻鎷烽敓鏂ゆ嫹閿熸嵎鐨勬拝鎷烽敓鏂ゆ嫹鍊奸敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹鍊�
  237. SL_Read_Reg=SL_Read_Reg|0x30;//Z 閿熸枻鎷峰彥閿熸枻鎷峰綍閿燂拷 Z閿熸枻鎷烽敓鏂ゆ嫹閿熸嵎鐨勬拝鎷烽敓鏂ゆ嫹鍊奸敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹鍊�
  238. sc7a20_write_byte(SL_SC7A20_INT1_CFG, SL_Read_Reg);
  239. //HPF SET
  240. // GSENSOR_ReadReg(SL_SC7A20_CTRL_REG2,1, &SL_Read_Reg);
  241. SL_Read_Reg=0x00;//SL_Read_Reg|0x81;//Normal HP , HPF TO AOI1
  242. sc7a20_write_byte(SL_SC7A20_CTRL_REG2, SL_Read_Reg);
  243. //閿熷彨璁规嫹閿熸枻鎷峰€奸敓鏂ゆ嫹閿熸枻鎷�
  244. sc7a20_write_byte(SL_SC7A20_INT1_THS, SL_SC7A20_INT_THS_20PERCENT);
  245. //閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷峰€奸敓鏂ゆ嫹閿熸枻鎷锋椂閿熸垝瑙﹂敓鏂ゆ嫹閿熷彨璁规嫹
  246. sc7a20_write_byte(SL_SC7A20_INT1_DURATION, SL_SC7A20_INT_DURATION_10CLK);
  247. //AOI1 TO INT1
  248. // GSENSOR_ReadReg(SL_SC7A20_CTRL_REG3,1, &SL_Read_Reg);
  249. SL_Read_Reg=0x40;//SL_Read_Reg|0x40; //AOI1 TO INT1
  250. sc7a20_write_byte(SL_SC7A20_CTRL_REG3, SL_Read_Reg);
  251. /*******************AOI1 IN INT1********************/
  252. /*******************AOI2 IN INT2********************/
  253. sc7a20_read_byte(SL_SC7A20_CTRL_REG5,&SL_Read_Reg);
  254. SL_Read_Reg=SL_Read_Reg|0x02;//AOI2 LATCH
  255. sc7a20_write_byte(SL_SC7A20_CTRL_REG5, SL_Read_Reg);
  256. //AOI2 CONFIG
  257. SL_Read_Reg=0x00; //0xFF
  258. SL_Read_Reg=SL_Read_Reg|0xc0;//閿熸枻鎷烽敓鏂ゆ嫹閿熷壙璁规嫹璇嗛敓鏂ゆ嫹妯″紡
  259. SL_Read_Reg=SL_Read_Reg|0x03;//X 閿熸枻鎷峰彥閿熸枻鎷峰綍閿燂拷 X閿熸枻鎷烽敓鏂ゆ嫹閿熸嵎鐨勬拝鎷烽敓鏂ゆ嫹鍊奸敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹鍊�
  260. SL_Read_Reg=SL_Read_Reg|0x0C;//Y 閿熸枻鎷峰彥閿熸枻鎷峰綍閿燂拷 Y閿熸枻鎷烽敓鏂ゆ嫹閿熸嵎鐨勬拝鎷烽敓鏂ゆ嫹鍊奸敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹鍊�
  261. SL_Read_Reg=SL_Read_Reg|0x30;//Z 閿熸枻鎷峰彥閿熸枻鎷峰綍閿燂拷 Z閿熸枻鎷烽敓鏂ゆ嫹閿熸嵎鐨勬拝鎷烽敓鏂ゆ嫹鍊奸敓鏂ゆ嫹閿熸枻鎷烽敓鏂ゆ嫹鍊�
  262. sc7a20_write_byte(SL_SC7A20_INT2_CFG, SL_Read_Reg);
  263. //HPF SET
  264. sc7a20_read_byte(SL_SC7A20_CTRL_REG2,&SL_Read_Reg);
  265. // SL_Read_Reg=SL_Read_Reg&0xFD;//NO HPF TO AOI2
  266. // GSENSOR_WriteReg(SL_SC7A20_CTRL_REG2, SL_Read_Reg);
  267. //閿熷彨璁规嫹閿熸枻鎷峰€奸敓鏂ゆ嫹閿熸枻鎷�
  268. sc7a20_write_byte(SL_SC7A20_INT2_THS, SL_SC7A20_INT_THS_20PERCENT);
  269. //閿熸枻鎷烽敓鏂ゆ嫹閿熸枻鎷峰€奸敓鏂ゆ嫹閿熸枻鎷锋椂閿熸垝瑙﹂敓鏂ゆ嫹閿熷彨璁规嫹
  270. sc7a20_write_byte(SL_SC7A20_INT2_DURATION, SL_SC7A20_INT_DURATION_10CLK);
  271. //AOI2 TO INT2
  272. sc7a20_read_byte(SL_SC7A20_CTRL_REG6,&SL_Read_Reg);
  273. SL_Read_Reg=SL_Read_Reg|0x20; //AOI2 TO INT2
  274. sc7a20_write_byte(SL_SC7A20_CTRL_REG6, SL_Read_Reg);
  275. /*******************AOI2 IN INT2********************/
  276. return 1;
  277. }
  278. /*SC7A20初始化 */
  279. void SC7A20_Init(void)
  280. {
  281. if(read_chip_id() == CHIP_ID)
  282. {
  283. SC7A20_BOOT();
  284. sc7a20_write_byte(0x23,0x80|0x10/*|0x08关闭滤波*/); //读取完成再更新、4g+正常模式
  285. SC7A20_INT_Config();
  286. sc7a20_write_byte(0x20,0x77); //400Hz,正常模式xyz使能
  287. }
  288. }
  289. /*SC7A20获取xyz轴加速度值 */
  290. uint8_t SC7A20_GetInfo(int16_t *SL_SC7A20_Data_XYZ_Buf)
  291. {
  292. uint8_t SL_Read_Buf[7];
  293. sc7a20_read_byte(SL_SC7A20_STATUS_REG,&SL_Read_Buf[0]);
  294. if((SL_Read_Buf[0]&0x0f)==0x0f)
  295. {
  296. for (uint8_t i = 1; i < 7; i++)
  297. {
  298. sc7a20_read_byte(SL_SC7A20_STATUS_REG+i,&SL_Read_Buf[i]);
  299. }
  300. SL_SC7A20_Data_XYZ_Buf[0]=(int16_t)((SL_Read_Buf[2]<<8) + SL_Read_Buf[1]);
  301. SL_SC7A20_Data_XYZ_Buf[1]=(int16_t)((SL_Read_Buf[4]<<8) + SL_Read_Buf[3]);
  302. SL_SC7A20_Data_XYZ_Buf[2]=(int16_t)((SL_Read_Buf[6]<<8) + SL_Read_Buf[5]);
  303. SL_SC7A20_Data_XYZ_Buf[0] = SL_SC7A20_Data_XYZ_Buf[0]>>4;
  304. SL_SC7A20_Data_XYZ_Buf[1] = SL_SC7A20_Data_XYZ_Buf[1]>>4;
  305. SL_SC7A20_Data_XYZ_Buf[2] = SL_SC7A20_Data_XYZ_Buf[2]>>4;
  306. SL_SC7A20_Data_XYZ_Buf[0] = SL_SC7A20_Data_XYZ_Buf[0]*2;
  307. SL_SC7A20_Data_XYZ_Buf[1] = SL_SC7A20_Data_XYZ_Buf[1]*2;
  308. SL_SC7A20_Data_XYZ_Buf[2] = SL_SC7A20_Data_XYZ_Buf[2]*2;
  309. printf("x = %d; y = %d; z = %d\r\n",SL_SC7A20_Data_XYZ_Buf[0],SL_SC7A20_Data_XYZ_Buf[1],SL_SC7A20_Data_XYZ_Buf[2]);
  310. return 1;
  311. }
  312. else
  313. {
  314. return 0;
  315. }
  316. }
  317. #include "FreeRTOS.h"
  318. #include "task.h"
  319. void sc7a20_task(void *argv)
  320. {
  321. int16_t SL_SC7A20_Data_XYZ_Buf[3] = {0};
  322. SC7A20_Init();
  323. while(1)
  324. {
  325. SC7A20_GetInfo(SL_SC7A20_Data_XYZ_Buf);
  326. vTaskDelay(1000);
  327. }
  328. }