adc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("AutoChips Software") are
  4. * protected under relevant copyright laws. The information contained herein is
  5. * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
  6. * the prior written permission of AutoChips inc. and/or its licensors, any
  7. * reproduction, modification, use or disclosure of AutoChips Software, and
  8. * information contained herein, in whole or in part, shall be strictly
  9. * prohibited.
  10. *
  11. * AutoChips Inc. (C) 2016. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
  15. * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  16. * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
  17. * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  19. * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
  20. * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  21. * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
  22. * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  23. * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  24. * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
  25. * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
  26. * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  27. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
  28. * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
  29. * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
  30. * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  31. * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
  32. */
  33. /**********<Incldue>**********/
  34. #include "adc.h"
  35. #include "timer.h"
  36. #include "math.h"
  37. #include "uart.h"
  38. #include "string.h"
  39. /*********<Variable>********/
  40. uint8_t g_dmaFinish = 0;//DMA传输完成
  41. uint8_t g_halfDmaFinish = 0; //DMA传输半完成
  42. uint8_t g_dmaTransError = 0; //DMA传输错误
  43. uint16_t __align(2) g_ADCValueBuffer[ADC_SAMPLE_CHANNEL*ADC_FILTER_NUM] = {0};
  44. uint32_t g_timer0Cnt = 0;
  45. //uint32_t g_averageSampleValue = 0;
  46. static uint8_t printfBuff[64];
  47. static uint16_t printfLen = 0;
  48. static float t_bias = 0.0;
  49. static float p_bias = 0.0;
  50. /**
  51. * ADC_DMACallback
  52. *
  53. * @param[in] wpara:dmaChannelStatus
  54. * lpara:0
  55. * @return 0
  56. *
  57. * @brief ADC DMA中断回调函数。
  58. */
  59. void ADC_DMACallback(void *device, uint32_t wpara, uint32_t lpara)
  60. {
  61. /*
  62. wparam为DMA通道状态,状态含义可参考CHANNELx_STATUS寄存器,
  63. CHANNELx_STATUS[2] 传输错误
  64. CHANNELx_STATUS[1] 半传输完成(相对设置的transferNum,如果半传输中断有使能,transferNum设为6,则DATA_TRANS_NUM为3时产生中断,进入回调)
  65. CHANNELx_STATUS[0] 传输完成
  66. */
  67. if ((wpara & 0x01) == 0x1)
  68. {
  69. g_dmaFinish = 1;
  70. }
  71. if ((wpara & 0x02) == 0x2)
  72. {
  73. g_halfDmaFinish = 1;
  74. }
  75. if ((wpara & 0x04) == 0x4)
  76. {
  77. g_dmaTransError = 1;
  78. }
  79. }
  80. /**
  81. * ADC_DMAInit
  82. *
  83. * @param[in] void
  84. * @return void
  85. *
  86. * @brief ADC DMA初始化,配置DMA相关参数。
  87. */
  88. void ADC_DMAInit(void)
  89. {
  90. DMA_ConfigType tmpDMAConfig;
  91. memset(&tmpDMAConfig, 0x00, sizeof(DMA_ConfigType));
  92. tmpDMAConfig.channelEn = ENABLE; ///<使能DMAx通道
  93. tmpDMAConfig.finishInterruptEn = ENABLE; ///<使能DMA传输完成中断
  94. tmpDMAConfig.halfFinishInterruptEn = DISABLE; ///<去能DMA半传输完成中断
  95. tmpDMAConfig.errorInterruptEn = ENABLE; ///<使能DMA传输错误中断
  96. tmpDMAConfig.channelPriority = DMA_PRIORITY_VERY_HIGH;///<设置DMA通道优先级,0~3 :优先级由低到高
  97. tmpDMAConfig.circular = ENABLE; ///<使能循环模式,如果只想工作一次,设为0即可。
  98. tmpDMAConfig.direction = DMA_READ_FROM_PERIPH; ///<0: 从外设读取,1:从存储器读取
  99. tmpDMAConfig.MEM2MEM = DISABLE; ///<0:在非存储器与存储器之间传输,1:在存储器与存储器之间传输
  100. tmpDMAConfig.memByteMode = DMA_MEM_BYTE_MODE_1TIME; ///<MEM字分割传输数,0:32-bit,1:16-bit[15:0]; 2:16-bit[23:16][7:0];3:8-bit。详情可参考AC781X芯片手册 表20-2 可编程数据宽度&数据对齐
  101. tmpDMAConfig.memIncrement = ENABLE; ///<1:MEM地址增加
  102. tmpDMAConfig.periphIncrement = DISABLE; ///<0:外设地址固定
  103. tmpDMAConfig.memSize = DMA_MEM_SIZE_16BIT; ///<0:8-bit,1:16-bit,2:32-bit
  104. tmpDMAConfig.periphSize = DMA_PERIPH_SIZE_16BIT; ///<0:8-bit,1:16-bit,2:32-bit
  105. tmpDMAConfig.transferNum = ADC_SAMPLE_CHANNEL*ADC_FILTER_NUM; ///<DMA通道传输长度
  106. tmpDMAConfig.periphSelect = DMA_PEPIRH_ADC0; //外设选择
  107. tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC0->RDR)); ///<Move ADC DR to memory
  108. tmpDMAConfig.memStartAddr = (uint32_t)g_ADCValueBuffer; //设置DMA开始地址
  109. tmpDMAConfig.memEndAddr = (uint32_t)g_ADCValueBuffer+sizeof(g_ADCValueBuffer);//设置DMA结束地址
  110. tmpDMAConfig.callBack = ADC_DMACallback; ///<设置DMA中断回调
  111. DMA_Init(DMA0_CHANNEL2, &tmpDMAConfig); ///<ADC 使用DMA1通道,每个模块对应的DMA通道,可参考 AC781X芯片手册 表20-1 DMA请求列表
  112. NVIC_SetPriority(DMA0_CHANNEL2_IRQn, 3);
  113. NVIC_ClearPendingIRQ(DMA0_CHANNEL2_IRQn);
  114. NVIC_EnableIRQ(DMA0_CHANNEL2_IRQn); ///<使能DMA1中断请求
  115. }
  116. /**
  117. * CTU_Config
  118. *
  119. * @param[in] void
  120. * @return void
  121. *
  122. * @brief 配置CTU模块,Timer0触发ADC规则组采样。
  123. */
  124. void CTU_Config(void)
  125. {
  126. CTU_ConfigType ctuConfig;
  127. memset(&ctuConfig, 0x00, sizeof(ctuConfig));
  128. ctuConfig.uart0RxFilterEn = DISABLE; //去能UART0_RX滤波
  129. ctuConfig.rtcCaptureEn = DISABLE; //去能RTC捕获
  130. ctuConfig.acmpCaptureEn = DISABLE; //去能ACMP捕获
  131. ctuConfig.uart0RxCaptureEn = DISABLE; //去能UART0_RX捕获
  132. ctuConfig.uartTxModulateEn = DISABLE; //去能UART0_TX调制
  133. ctuConfig.clkPsc = CTU_CLK_PRESCALER_1; //分频
  134. ctuConfig.adcRegularTriggerSource = CTU_TRIGGER_ADC_TIMER_CH0_OVERFLOW; //Timer0触发ADC规则组采样。
  135. ctuConfig.delay0Time = 0; //触发延迟
  136. // ctuConfig.adcInjectTriggerSource = CTU_TRIGGER_ADC_PWM0_INIT; //
  137. // ctuConfig.delay1Time = 0;
  138. // ctuConfig.pwdt0In3Source = CTU_PWDT_IN3_SOURCE_UART0_RX;
  139. // ctuConfig.pwdt1In3Source = CTU_PWDT_IN3_SOURCE_UART0_RX;
  140. CTU_Init(&ctuConfig);
  141. }
  142. /**
  143. * ADC_init
  144. *
  145. * @param[in] void
  146. * @return void
  147. *
  148. * @brief 初始化ADC,配置ADC参数。
  149. */
  150. void ADC_init()
  151. {
  152. ADC_ConfigType tempAdcConfig;
  153. ADC_ConfigType* adcConfig;
  154. adcConfig = &tempAdcConfig;
  155. //配置PINMUX
  156. //GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2);///<ADC_IN8 Analog function enable
  157. adcConfig->scanModeEn = ENABLE; //扫描模式
  158. adcConfig->continousModeEn = DISABLE; //连续模式
  159. adcConfig->regularDiscontinousModeEn = DISABLE; //1:打开规则组间断转换模式
  160. adcConfig->injectDiscontinousModeEn = DISABLE; //1:打开注入组间断转换模式
  161. adcConfig->injectAutoModeEn = DISABLE; //1:自动注入模式
  162. adcConfig->intervalModeEn = DISABLE; //1:注入组为间隔转换模式
  163. adcConfig->regularDiscontinousNum = 0; //
  164. adcConfig->EOCInterruptEn = DISABLE; //EOC中断去能
  165. adcConfig->IEOCInterruptEn = DISABLE; //IEOC中断去能
  166. adcConfig->interruptEn = DISABLE; //去能中断
  167. adcConfig->regularDMAEn = ENABLE; //使能ADC DMA
  168. adcConfig->regularTriggerMode = ADC_TRIGGER_EXTERNAL;//ADC触发源,外部触发
  169. //adcConfig->injectTriggerMode = ADC_TRIGGER_INTERNAL; //ADC触发源,内部触发
  170. adcConfig->regularSequenceLength = ADC_SAMPLE_CHANNEL; //规则组长度设为1
  171. //adcConfig->injectSequenceLength = 0; //注入组长度设为0
  172. adcConfig->dataAlign = ADC_DATA_ALIGN_RIGHT; //右对齐
  173. adcConfig->powerMode = ADC_POWER_ON; //上电
  174. adcConfig->clkPsc = ADC_CLK_PRESCALER_1; ///<Set ADC Clk = 24M/2/(0+1)
  175. ADC_Init(ADC0, adcConfig); ///<ADC works Mode Config
  176. /*
  177. ADC转换率计算公式:
  178. 转换时间= 采样时间+转换时间+同步时间
  179. 转换时间= (SPT+12)/ADC模块时钟频率+5/APB时钟频率
  180. 备注:
  181. 1.同步时间为5个APB CLK。
  182. 2.ADC时钟频率 = APB时钟频率 /(分频系数+1)
  183. */
  184. ADC_SetRegularGroupChannel(ADC0, ADC_CH_0, ADC_SPT_CLK_7, 0); //set ADC_CH_7 为第1个采样序列 NTC 温度采集
  185. ADC_SetRegularGroupChannel(ADC0, ADC_CH_7, ADC_SPT_CLK_7, 1); //set ADC_CH_7 为第2个采样序列 压力传感器
  186. //ADC_SetRegularGroupChannel(ADC0, ADC_CH_7, ADC_SPT_CLK_7, 1); //set ADC_CH_7 为第2个采样序列 线性hall 1
  187. //ADC_SetRegularGroupChannel(ADC0, ADC_CH_8, ADC_SPT_CLK_7, 2); ///set ADC_CH_8 为第3个采样序列 线性hall 2
  188. //ADC_SetRegularGroupChannel(ADC0, ADC_CH_BANDGAP, ADC_SPT_CLK_7, 2); ///set ADC_CH_BANDGAP 为第3个采样序列
  189. //ADC_SetRegularGroupChannel(ADC0, ADC_CH_TSENSOR, ADC_SPT_CLK_7, 3); ///set ADC_CH_TSENSOR 为第4个采样序列
  190. ADC_DMAInit(); //ADC DMA初始化
  191. }
  192. void ADCSample_UpdateBias(float temp_bias, float press_bias)
  193. {
  194. t_bias = temp_bias;
  195. p_bias = press_bias;
  196. }
  197. float getTemperature(void)
  198. {
  199. uint32_t NtcAdc = 0;
  200. uint8_t i;
  201. float Rt = 0; //NTC 电阻
  202. float R = 50000; //50K 固定阻值电阻
  203. float T0 = 273.15+25; //转换为开尔文温度
  204. float B=3950; //B值
  205. float Ka=273.15; //K值
  206. float Vr=0; //电压值
  207. float temp = 0;
  208. for(i=0; i<ADC_FILTER_NUM; i++){
  209. NtcAdc += g_ADCValueBuffer[ADC_SAMPLE_CHANNEL*i];
  210. }
  211. NtcAdc = NtcAdc/ADC_FILTER_NUM;
  212. Vr = (float)(3.3*NtcAdc/4096);
  213. Rt = (3.3-Vr)*50000/Vr;
  214. temp=1/(1/T0+log(Rt/R)/B)-Ka+0.5; //计算温度
  215. return (temp+t_bias);
  216. }
  217. float getPressure(void)
  218. {
  219. uint32_t Adc = 0;
  220. uint8_t i;
  221. float v;
  222. for(i=0; i<ADC_FILTER_NUM; i++){
  223. Adc += g_ADCValueBuffer[ADC_SAMPLE_CHANNEL*i+1];
  224. }
  225. Adc = Adc/ADC_FILTER_NUM;
  226. v = 3.3*Adc/4096;
  227. return (((v-0.5)*350/2.0 - 100) + p_bias);
  228. }
  229. void printTempPress(void)
  230. {
  231. printfLen = snprintf((char*)printfBuff, 64, "ADC temp: %f, Press:%f \r\n", getTemperature(),getPressure());
  232. rs485_TransmitData(printfBuff, printfLen);
  233. }
  234. void getHallValue(uint16_t* pHall_1, uint16_t* pHall_2)
  235. {
  236. int16_t hall1_ADC = 0;
  237. int16_t hall2_ADC = 0;
  238. int8_t i;
  239. for(i=0; i<ADC_FILTER_NUM; i++){
  240. hall1_ADC += g_ADCValueBuffer[3*i+1];
  241. hall2_ADC += g_ADCValueBuffer[3*i+2];
  242. }
  243. *pHall_1 = hall1_ADC/ADC_FILTER_NUM;
  244. *pHall_2 = hall2_ADC/ADC_FILTER_NUM;
  245. }
  246. int16_t getHalldiff(void)
  247. {
  248. int16_t hall1_ADC = 0;
  249. int16_t hall2_ADC = 0;
  250. int8_t i;
  251. for(i=0; i<ADC_FILTER_NUM; i++){
  252. hall1_ADC += g_ADCValueBuffer[3*i+1];
  253. hall2_ADC += g_ADCValueBuffer[3*i+2];
  254. }
  255. hall1_ADC = hall1_ADC/ADC_FILTER_NUM;
  256. hall2_ADC = hall2_ADC/ADC_FILTER_NUM;
  257. return (hall1_ADC - hall2_ADC);
  258. }
  259. void printADCValue(void)
  260. {
  261. uint8_t index;
  262. printf("\r\n adc sample data is:");
  263. for (index = 0; index<ADC_SAMPLE_CHANNEL*ADC_FILTER_NUM; index++)
  264. {
  265. printf(" 0x%x",g_ADCValueBuffer[index]);
  266. }
  267. printf(", g_timer0Cnt:%d \r\n", g_timer0Cnt);
  268. }
  269. float getBatteryVoltage(void)
  270. {
  271. uint16_t sum = 0;
  272. uint8_t i;
  273. for(i=0; i<ADC_FILTER_NUM; i++){
  274. sum += g_ADCValueBuffer[2*i];
  275. }
  276. sum = sum/ADC_FILTER_NUM;
  277. return ((6.6*sum)/4096);
  278. }
  279. float getMotorCurrent(void)
  280. {
  281. uint16_t sum = 0;
  282. uint8_t i;
  283. for(i=0; i<ADC_FILTER_NUM; i++){
  284. sum += g_ADCValueBuffer[2*i+1];
  285. }
  286. sum = sum/ADC_FILTER_NUM;
  287. return ((3.3*sum)/4096);
  288. }
  289. /**
  290. * ADC_SampleTimerTrigerRegular
  291. *
  292. * @param[in] void
  293. * @return void
  294. *
  295. * @brief Timer定时触发规则组ADC_CHANNEL0单次采样。
  296. */
  297. void ADCSample_Init(void)
  298. {
  299. CTU_Config();
  300. ADC_init();
  301. Timer0_Init();
  302. }
  303. /**********<End>*********/