bsp_adc.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*********************************************************************
  2. * INCLUDES
  3. */
  4. #include "bsp_adc.h"
  5. #include "system.h"
  6. #include "exception.h"
  7. /*********************************************************************
  8. * DEFINITIONS
  9. */
  10. #define CHANNEL_MAX 8
  11. #define PIN_NOT_USED 0xFF
  12. #define CHANNEL_NOT_USED 0xFF
  13. #define WAIT_TIME_VALUE 3 // 等待超时最大值
  14. /*********************************************************************
  15. * STRUCTION
  16. */
  17. typedef struct {
  18. uint32_t pin;
  19. uint32_t channel;
  20. }adc_config_t;
  21. /*********************************************************************
  22. * LOCAL VARIABLES
  23. */
  24. static adc_config_t m_adc_config[CHANNEL_MAX] = {{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED}};
  25. static nrf_saadc_channel_config_t channelConfig[CHANNEL_MAX];
  26. static nrf_saadc_value_t s_bufferPool[CHANNEL_MAX] = {0};
  27. static volatile bool adc_SampleOk = true; // adc采集完成标志
  28. //定义SAADC采样数据缓存
  29. //定义SAADC采样缓存数组大小
  30. //只有采样结果存满该缓存之后,才会产生SAADC采样完成事件
  31. static uint32_t sample_in_buffer = 0;
  32. /*********************************************************************
  33. * LOCAL FUNCTIONS
  34. */
  35. /**
  36. @brief ADC中断处理回调函数
  37. @param 无
  38. @return 无
  39. */
  40. static void adcCallbackFunc(nrf_drv_saadc_evt_t const *pEvent)
  41. {
  42. ret_code_t err_code;
  43. if(pEvent->type == NRF_DRV_SAADC_EVT_DONE) // 采样完成,采集时填充顺序为,通道编号小的先填充。
  44. {
  45. //设置好缓存,为下一次采样做准备
  46. err_code=nrf_drv_saadc_buffer_convert(pEvent->data.done.p_buffer,sample_in_buffer);
  47. if(err_code == NRF_SUCCESS)
  48. {
  49. adc_SampleOk = true;
  50. }
  51. }
  52. }
  53. static void bsp_adc_init_process(void)
  54. {
  55. if(Except_TxError(EXCEPT_ADC_INIT,"bsp_adc_init_error\r\n") == 0)
  56. {
  57. Process_Stop(bsp_adc_init_process);
  58. }
  59. }
  60. /**
  61. @brief 初始化ADC
  62. @param 无
  63. @return 无
  64. */
  65. static void ADC_Init(void)
  66. {
  67. int ret = 0;
  68. ret_code_t errCode;
  69. nrf_drv_saadc_config_t p_config = NRFX_SAADC_DEFAULT_CONFIG;
  70. p_config.interrupt_priority = ADC_IRQ_PRIORITY;
  71. // ADC初始化
  72. errCode = nrf_drv_saadc_init(&p_config, adcCallbackFunc);//优先级设置为3,比定时器中断要高,不然回调会在定时器中断结束后触发。
  73. if(errCode != NRF_SUCCESS)ret = -1;
  74. // ADC通道配置
  75. for(int i=0;i<CHANNEL_MAX;i++)
  76. {
  77. if(m_adc_config[i].pin != PIN_NOT_USED && m_adc_config[i].channel != CHANNEL_NOT_USED)
  78. {
  79. //设置ADC引脚为浮空
  80. nrf_gpio_cfg_input(m_adc_config[i].pin,NRF_GPIO_PIN_NOPULL);
  81. // 单端输入
  82. channelConfig[m_adc_config[i].channel].resistor_p = NRF_SAADC_RESISTOR_DISABLED;
  83. channelConfig[m_adc_config[i].channel].resistor_n = NRF_SAADC_RESISTOR_DISABLED;
  84. channelConfig[m_adc_config[i].channel].gain = NRF_SAADC_GAIN1_6;
  85. channelConfig[m_adc_config[i].channel].reference = NRF_SAADC_REFERENCE_INTERNAL;
  86. channelConfig[m_adc_config[i].channel].acq_time = NRF_SAADC_ACQTIME_10US;
  87. channelConfig[m_adc_config[i].channel].mode = NRF_SAADC_MODE_SINGLE_ENDED;
  88. channelConfig[m_adc_config[i].channel].burst = NRF_SAADC_BURST_DISABLED;
  89. channelConfig[m_adc_config[i].channel].pin_p = (nrf_saadc_input_t)(m_adc_config[i].channel + 1);
  90. channelConfig[m_adc_config[i].channel].pin_n = NRF_SAADC_INPUT_DISABLED;
  91. // ADC通道初始化
  92. errCode = nrf_drv_saadc_channel_init(m_adc_config[i].channel, &channelConfig[m_adc_config[i].channel]);
  93. if(errCode != NRF_SUCCESS)ret = -1;
  94. sample_in_buffer++;
  95. }
  96. }
  97. if(sample_in_buffer > 0)
  98. {
  99. // 缓冲配置
  100. errCode = nrf_drv_saadc_buffer_convert(s_bufferPool, sample_in_buffer);
  101. if(errCode != NRF_SUCCESS)ret = -1;
  102. }
  103. if(ret == -1)
  104. {
  105. Process_Start(0,"bsp_adc_init_process",bsp_adc_init_process);
  106. }
  107. }
  108. static void cb_adcWakeup(uint32_t t)
  109. {
  110. ADC_Enable();
  111. }
  112. static void cb_adcSleep(uint32_t t)
  113. {
  114. ADC_Disable();
  115. }
  116. /*********************************************************************
  117. * PUBLIC FUNCTIONS
  118. */
  119. /**
  120. @brief 初始化ADC引脚和通道
  121. @param pin -[in] 需要初始化的adc引脚
  122. @param channel -[in] 需要初始化的adc通道
  123. @return 错误代码
  124. */
  125. uint32_t ADC_SetPinChannel(uint32_t pin, uint32_t channel)
  126. {
  127. for(int i=0;i<CHANNEL_MAX;i++)
  128. {
  129. if(m_adc_config[i].pin == pin)return ADC_ERR_INIT_PIN;
  130. if(m_adc_config[i].channel == channel)return ADC_ERR_INIT_CHANNEL;
  131. if(PIN_NOT_USED != pin && m_adc_config[i].pin == PIN_NOT_USED)
  132. {
  133. m_adc_config[i].pin = pin;
  134. m_adc_config[i].channel = channel;
  135. return ADC_OP_SUCCESS;
  136. }
  137. }
  138. return ADC_ERR_INIT_CONGESTION;
  139. }
  140. /**
  141. @brief 移除已初始化ADC引脚和通道
  142. @param pin -[in] 需要移除的adc引脚
  143. @param channel -[in] 需要移除的adc通道
  144. @return 错误代码
  145. */
  146. uint32_t ADC_RemovePinChannel(uint32_t pin, uint32_t channel)
  147. {
  148. for(int i=0;i<CHANNEL_MAX;i++)
  149. {
  150. if(m_adc_config[i].pin == pin && m_adc_config[i].channel == channel)
  151. {
  152. m_adc_config[i].pin = PIN_NOT_USED;
  153. m_adc_config[i].channel = CHANNEL_NOT_USED;
  154. return ADC_OP_SUCCESS;
  155. }
  156. }
  157. return ADC_ERR_REMOVE_PIN_CHANNEL;
  158. }
  159. /**
  160. @brief ADC初始化
  161. @param 无
  162. @return 无
  163. */
  164. void ADC_Initialize(void)
  165. {
  166. ADC_SetPinChannel(PIN_ADC_BAT_IN, PIN_ADC_BAT_CHANNEL);
  167. ADC_SetPinChannel(PIN_ADC_CHARGMEASURE, PIN_ADC_CHARGMEASURE_CHANNEL);
  168. ADC_Init();
  169. Wakeup_Regist(cb_adcWakeup);
  170. Sleep_Regist(cb_adcSleep);
  171. }
  172. /**
  173. @brief ADC读取
  174. @param channel -[in] 需要读取的通道
  175. @param p_adc_value -[out] 返回读取的通道值
  176. @return 错误代码
  177. */
  178. uint32_t ADC_Read(uint32_t channel, int16_t *p_adc_value)
  179. {
  180. uint32_t errCode;
  181. uint32_t wait_time_out = WAIT_TIME_VALUE;
  182. uint8_t adc_sort[CHANNEL_MAX] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  183. uint8_t sort_index = 0;
  184. int i;
  185. adc_SampleOk = false;
  186. //没有配置通道返回失败
  187. if(sample_in_buffer == 0)return ADC_ERR_READ_NO_CHANNEL;
  188. errCode = nrf_drv_saadc_sample();
  189. if(errCode != NRF_SUCCESS)return ADC_ERR_READ_FAIL;
  190. //等待采集
  191. while(!adc_SampleOk)
  192. {
  193. if(wait_time_out--){
  194. nrf_pwr_mgmt_run();
  195. }
  196. else{
  197. return ADC_ERR_READ_TIMEOUT;
  198. }
  199. }
  200. //预先排序,采集时填充顺序为,通道编号小的先填充。
  201. for(i=0;i<CHANNEL_MAX;i++)
  202. {
  203. if(channelConfig[i].pin_p != NRF_SAADC_INPUT_DISABLED){
  204. adc_sort[sort_index] = i;
  205. sort_index++;
  206. }
  207. }
  208. //获取数据
  209. for(i=0;i<sample_in_buffer;i++)
  210. {
  211. if(adc_sort[i] == channel)
  212. {
  213. *p_adc_value = s_bufferPool[i];
  214. }
  215. }
  216. return ADC_OP_SUCCESS;
  217. }
  218. /**
  219. @brief 开启ADC,与初始化没有区别,为了与Disable成对出现
  220. @param 无
  221. @return 无
  222. */
  223. void ADC_Enable(void)
  224. {
  225. ADC_Init();
  226. }
  227. /**
  228. @brief 禁用ADC
  229. @param 无
  230. @return 无
  231. */
  232. void ADC_Disable(void)
  233. {
  234. nrf_drv_saadc_uninit();
  235. sample_in_buffer = 0;
  236. }