user_adc.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /*
  2. * uer_adc.c
  3. *
  4. * Created on: 2025年7月13日
  5. * Author: 罗成
  6. */
  7. #include <math.h>
  8. #include "user_adc.h"
  9. #include "user_charge.h"
  10. #include "my_math.h"
  11. #include "tools.h"
  12. static uint8_t tmpIdx = 0;
  13. static uint16_t tmpValue[ADC_COUNT * ADC_BUFFER_SIZE] = {0}; //温度
  14. static int16_t Calibrattion_Val = 0;
  15. static adc_data_s adc_data = {
  16. .left_ntc = 0,
  17. .right_ntc = 0,
  18. #if TEMPE_OWNER == 1
  19. .tmp_chip = 0.0f,
  20. #endif
  21. };
  22. static adc_upload_func adc_upload = NULL;
  23. //static bool set_rand_seek = false;
  24. static void upload_adc_value(bool tmp_stat);
  25. /*******************************************************************************
  26. * @函数名称 ADC_Function_Init
  27. * @函数说明 ADC初始化
  28. * @输入参数 无
  29. * @输出参数 无
  30. * @返回参数 无
  31. *******************************************************************************/
  32. static void ADC_Function_Init(void)
  33. {
  34. ADC_InitTypeDef ADC_InitStructure={0};
  35. GPIO_InitTypeDef GPIO_InitStructure={0};
  36. NVIC_InitTypeDef NVIC_InitStructure;
  37. ADC_GPIO_RCC_ENABLE;
  38. ADC_RCC_ENABLE;
  39. RCC_ADCCLKConfig(RCC_PCLK2_Div8);
  40. GPIO_InitStructure.GPIO_Pin = LEFT_NTC_PIN;
  41. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  42. GPIO_Init(LEFT_NTC_GPIO, &GPIO_InitStructure);
  43. GPIO_InitStructure.GPIO_Pin = RIGHT_NTC_PIN;
  44. GPIO_Init(RIGHT_NTC_GPIO, &GPIO_InitStructure);
  45. ADC_DeInit(ADC_CHANNEL);
  46. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  47. ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  48. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  49. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  50. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  51. #if TEMPE_OWNER == 1
  52. ADC_InitStructure.ADC_NbrOfChannel = 3;
  53. #else
  54. ADC_InitStructure.ADC_NbrOfChannel = 2;
  55. #endif
  56. ADC_Init(ADC_CHANNEL, &ADC_InitStructure);
  57. // Configure channel sequence
  58. ADC_RegularChannelConfig(ADC_CHANNEL, LEFT_NTC_CHANNEL, 1, ADC_SampleTime_239Cycles5);
  59. ADC_RegularChannelConfig(ADC_CHANNEL, RIGHT_NTC_CHANNEL, 2, ADC_SampleTime_239Cycles5);
  60. // Enable DMA for ADC
  61. ADC_DMACmd(ADC_CHANNEL, ENABLE);
  62. // Enable ADC
  63. ADC_Cmd(ADC_CHANNEL, ENABLE);
  64. ADC_ResetCalibration(ADC_CHANNEL);
  65. while(ADC_GetResetCalibrationStatus(ADC_CHANNEL));
  66. ADC_StartCalibration(ADC_CHANNEL);
  67. while(ADC_GetCalibrationStatus(ADC_CHANNEL));
  68. Calibrattion_Val = Get_CalibrationValue(ADC_CHANNEL);
  69. PRINT("Calibrattion_Val=%d\n", Calibrattion_Val);
  70. #if TEMPE_OWNER == 1
  71. ADC_TempSensorVrefintCmd(ENABLE);
  72. #endif
  73. }
  74. /*********************************************************************
  75. * @fn DMA_Tx_Init
  76. *
  77. * @brief Initializes the DMAy Channelx configuration.
  78. *
  79. * @param DMA_CHx - x can be 1 to 7.
  80. * ppadr - Peripheral base address.
  81. * memadr - Memory base address.
  82. * bufsize - DMA channel buffer size.
  83. *
  84. * @return none
  85. */
  86. static void ADC_DMA_Init(void)
  87. {
  88. DMA_InitTypeDef DMA_InitStructure = {0};
  89. NVIC_InitTypeDef NVIC_InitStructure;
  90. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  91. // Configure DMA interrupt
  92. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  93. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  94. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  95. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  96. NVIC_Init(&NVIC_InitStructure);
  97. DMA_DeInit(DMA1_Channel1);
  98. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->RDATAR;
  99. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tmpValue;
  100. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  101. DMA_InitStructure.DMA_BufferSize = ADC_COUNT * ADC_BUFFER_SIZE; // For two channels
  102. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  103. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  104. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  105. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  106. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // Continuous mode
  107. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  108. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  109. DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  110. DMA_Cmd(DMA1_Channel1, ENABLE);
  111. // Enable DMA interrupt
  112. DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
  113. }
  114. /*********************************************************************
  115. * @fn Get_ConversionVal
  116. *
  117. * @brief Get Conversion Value.
  118. *
  119. * @param val - Sampling value
  120. *
  121. * @return val+Calibrattion_Val - Conversion Value.
  122. */
  123. uint16_t Get_ConversionVal(int16_t val)
  124. {
  125. if((val + Calibrattion_Val) < 0)
  126. {
  127. return 0;
  128. }
  129. else if((Calibrattion_Val + val) > 4095 || val == 4095)
  130. {
  131. return 4095;
  132. }
  133. return (val + Calibrattion_Val);
  134. }
  135. const float Rp = 100000.0; //10K
  136. const float T2 = (273.15 + 25.0);;//T2
  137. const float Bx = 3950.0;//B
  138. const float Ka = 273.15;
  139. float Get_Temp(float Rt)
  140. {
  141. float temp;
  142. //like this R=5000, T2=273.15+25,B=3470, RT=5000*EXP(3470*(1/T1-1/(273.15+25)),
  143. temp = Rt/Rp;
  144. temp = log(temp);//ln(Rt/Rp)
  145. temp/=Bx;//ln(Rt/Rp)/B
  146. temp+=(1/T2);
  147. temp = 1/(temp);
  148. temp-=Ka;
  149. return temp;
  150. }
  151. /*******************************************************************************
  152. * @函数名称 temperature_task
  153. * @函数说明 温度任务
  154. * @输入参数 无
  155. * @输出参数 无
  156. * @返回参数 无
  157. *******************************************************************************/
  158. static void temperature_task(void)
  159. {
  160. #if TEMPE_OWNER == 1
  161. uint32_t tempe_temp = 0;
  162. #endif
  163. uint32_t leftadcvalue = tmpValue[0];
  164. uint32_t rightadcvalue = tmpValue[1];
  165. for(int i = 2; i < ADC_COUNT * ADC_BUFFER_SIZE; i+=2)
  166. {
  167. leftadcvalue += tmpValue[i];
  168. rightadcvalue += tmpValue[i+1];
  169. leftadcvalue /= 2;
  170. rightadcvalue /= 2;
  171. }
  172. float lefttemp = (float)(Get_ConversionVal(leftadcvalue) * ADC_VDDA / 4096);
  173. float righttemp = (float)(Get_ConversionVal(rightadcvalue) * ADC_VDDA / 4096);
  174. float left_r = (lefttemp * 100000.0f) / (5000.0f - lefttemp);
  175. float right_r = (righttemp * 100000.0f) / (5000.0f - righttemp);
  176. // PRINT("left=%d,%.02f,%.02f,right=%d,%.02f,%.02f\n", leftadcvalue, lefttemp, left_r / 1000, rightadcvalue ,righttemp, right_r / 1000);
  177. adc_data.left_ntc = Get_Temp(left_r) * 100;
  178. adc_data.right_ntc = Get_Temp(right_r) * 100;
  179. #if TEMPE_OWNER == 1
  180. tempe_temp = Get_ConversionVal(tmpValue[2]) * ADC_VDDA / 4096;
  181. adc_data.tmp_chip =((float)tempe_temp - TEMPE_V_25) / TEMPE_AVG_SLOPE +25.0;
  182. #endif
  183. upload_adc_value(true);
  184. }
  185. /*******************************************************************************
  186. * @函数名称 upload_adc_value
  187. * @函数说明 上报温度值
  188. * @输入参数 无
  189. * @输出参数 无
  190. * @返回参数 无
  191. *******************************************************************************/
  192. static void upload_adc_value(bool tmp_stat)
  193. {
  194. // PRINT("temperature left=%d.%d, right=%d.%d\n", adc_data.left_ntc / 100 , adc_data.left_ntc % 100,
  195. // adc_data.right_ntc / 100, adc_data.right_ntc % 100);
  196. if(adc_upload != NULL)
  197. {
  198. adc_upload(adc_data, tmp_stat);
  199. }
  200. }
  201. /*******************************************************************************
  202. * @函数名称 adc_task_start
  203. * @函数说明 ADC任务启动
  204. * @输入参数 无
  205. * @输出参数 无
  206. * @返回参数 无
  207. *******************************************************************************/
  208. void adc_task_start(void)
  209. {
  210. bStatus_t stat = tmos_start_reload_task(user_charge_task_id, (1 << ADC_QUEUE_TIME), MS1_TO_SYSTEM_TIME(TEMP_INTERVAL));
  211. ADC_SoftwareStartConvCmd(ADC_CHANNEL, ENABLE);
  212. }
  213. /*******************************************************************************
  214. * @函数名称 adc_task_process_event
  215. * @函数说明 task的event处理回调函数,需要在注册task时候,传进去
  216. * @输入参数 task_id:任务ID
  217. events:事件
  218. * @输出参数 无
  219. * @返回参数 无
  220. *******************************************************************************/
  221. uint16_t adc_task_process_event(uint8_t task_id, uint16_t events)
  222. {
  223. //event 处理
  224. if(events & (1 << ADC_QUEUE_TIME))
  225. {
  226. // PRINT("ADC_QUEUE_JEOC execute\r\n");
  227. DMA_SetCurrDataCounter(DMA1_Channel1, ADC_COUNT * ADC_BUFFER_SIZE);
  228. DMA_Cmd(DMA1_Channel1, ENABLE);
  229. ADC_SoftwareStartConvCmd(ADC_CHANNEL, ENABLE);
  230. return (events ^ (1 << ADC_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  231. }
  232. if(events & (1 << ADC_QUEUE_DMA))
  233. {
  234. // PRINT("ADC_QUEUE_JEOC execute\r\n");
  235. temperature_task();
  236. return (events ^ (1 << ADC_QUEUE_DMA)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  237. }
  238. return 0;
  239. }
  240. /*******************************************************************************
  241. * @函数名称 adc_init
  242. * @函数说明 ADC初始化
  243. * @输入参数 无
  244. * @输出参数 无
  245. * @返回参数 无
  246. *******************************************************************************/
  247. void adc_init(void)
  248. {
  249. ADC_Function_Init();
  250. ADC_DMA_Init();
  251. }
  252. /*******************************************************************************
  253. * @函数名称 set_adc_upload_func
  254. * @函数说明 设置adc结果上报回调函数指针
  255. * @输入参数 func:函数直针
  256. * @输出参数 无
  257. * @返回参数 无
  258. *******************************************************************************/
  259. void set_adc_upload_func(adc_upload_func func)
  260. {
  261. adc_upload = func;
  262. }
  263. /*******************************************************************************
  264. * @函数名称 vUser_adc_dma_finish
  265. * @函数说明 ADC DMA中断
  266. * @输入参数 无
  267. * @输出参数 无
  268. * @返回参数 无
  269. *******************************************************************************/
  270. void vUser_adc_dma_finish(void)
  271. {
  272. DMA_Cmd(DMA1_Channel1, DISABLE);
  273. ADC_SoftwareStartConvCmd(ADC_CHANNEL, DISABLE);
  274. bStatus_t stat = tmos_start_task(user_charge_task_id, (1 << ADC_QUEUE_DMA), MS1_TO_SYSTEM_TIME(1));
  275. }