ADCSetup.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*--------------------------------------------------------------------------------------
  2. * @file ADCSetup.c
  3. * @author ZhangJing
  4. * @version base on stm32f0x
  5. * @date 2015.09.11
  6. * @brief 芯片内部ADC驱动
  7. ---------------------------------------------------------------------------------------*/
  8. #include "stm32f10x_gpio.h"
  9. #include "stm32f10x_adc.h"
  10. #include "stm32f10x_dma.h"
  11. #include "TypeDefine.h"
  12. #include "ADCSetup.h"
  13. __IO uint32_t ADC_ConvertedValue[2];//内部ADC转换数组
  14. uint16_t batteryVolt[7]={ 0xffff , 0xffff , 0xffff , 0xffff , 0xffff, 0xffff , 0xffff };//电池电压采集数组
  15. uint16_t batteryAverage = 0xffff;//电池电压平均值
  16. uint8_t batteryCounts = 0;//采集次数累计
  17. uint8_t ADC_Voit_Done=0; //电压AD采集完成标志
  18. /***************************************************************************************
  19. * Function: DriverADCInit
  20. * Object: Configures ADC GPIO.
  21. * 输入: 无
  22. * 输出: 无
  23. * 备注: PB0
  24. ***************************************************************************************/
  25. void AdcDmaInit(void)
  26. {
  27. DMA_InitTypeDef DMA_InitStructure;
  28. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* use for adc model */
  29. /* DMA1 channel1 configuration ----------------------------------------------*/
  30. DMA_DeInit(DMA1_Channel1);
  31. DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  32. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
  33. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  34. DMA_InitStructure.DMA_BufferSize = 1;
  35. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  36. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  37. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  38. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  39. DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  40. DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  41. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  42. DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  43. /* Enable DMA1 channel1 */
  44. DMA_Cmd(DMA1_Channel1, ENABLE);
  45. }
  46. /******************************************
  47. * 功能:ADC1初始化,使用PC04引脚采集
  48. ******************************************/
  49. void DriverADCInit(void)
  50. {
  51. ADC_InitTypeDef ADC_InitStructure;
  52. GPIO_InitTypeDef GPIO_InitStructure;
  53. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
  54. /* Configure PC.04 (ADC Channel12) as analog input -------------------------*/
  55. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  56. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  57. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  58. GPIO_Init(GPIOC, &GPIO_InitStructure);
  59. /* ADC1 configuration ------------------------------------------------------*/
  60. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;/*ADC工作在独立模式*/
  61. ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  62. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  63. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;/*软件触发*/
  64. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  65. ADC_InitStructure.ADC_NbrOfChannel = 1;/*单通道*/
  66. ADC_Init(ADC1, &ADC_InitStructure);
  67. /* ADC1 regular channel12 configuration */
  68. ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);
  69. AdcDmaInit();/*DMA配置*/
  70. /* Enable ADC1 DMA */
  71. ADC_DMACmd(ADC1, ENABLE);
  72. /* Enable ADC1 */
  73. ADC_Cmd(ADC1, ENABLE);
  74. /* Enable ADC1 reset calibration register */
  75. ADC_ResetCalibration(ADC1);
  76. /* Check the end of ADC1 reset calibration register */
  77. while(ADC_GetResetCalibrationStatus(ADC1));
  78. /*开始校准*/
  79. ADC_StartCalibration(ADC1);
  80. /* 等待校准结束*/
  81. while(ADC_GetCalibrationStatus(ADC1));
  82. ADC_SoftwareStartConvCmd(ADC1, ENABLE);/*开启转换*/
  83. }
  84. /********************************************************************************************************
  85. * Function: BatteryVoltADCGet
  86. * Object: 电池电压采集
  87. * 输入: 无
  88. * 输出: 无
  89. * 备注: 1、只要TaskSchedulerFlag.sensorPWBatteryFlag标志位置位或 motorWorkState == MOTOR_WORK_OFF才会采集一次电池电压值
  90. * 2、uint32_t tempADC1 = 0;临时变量读取AD数值
  91. * 3、uint16_t tempVolt = 0;临时变量计算采集电压
  92. * 4、通过均值算法得出稳定电压值,每采集7次值,前2次值丢弃,比较一下,取平均值
  93. * 5、realTimeData.batteryVolt = (uint8_t)( 100 - ( ( 45 - batteryAverage ) * 100 / 15 ) );//电池电压 4.5 - 3.0 = 1.5*10
  94. ********************************************************************************************************/
  95. void BatteryVoltADCGet( void )
  96. {
  97. uint32_t tempADC1 = 0;
  98. uint16_t tempVolt = 0;
  99. uint8_t i,j;
  100. if ( TaskSchedulerFlag.sensorPWBatteryFlag == TASK_FLAG_SET )
  101. {
  102. //conment by wulianwei
  103. /**if(( TaskSchedulerFlag.zigbeeXmitFlag != TASK_FLAG_CLEAR )&&(RunToLorawawn_flag != TASK_FLAG_CLEAR)&&(EngineeringModeValue.networkState == ENGINEERINGMODE_ON))//如果在采集的时候恰巧碰到数据发送,则此时不采集等待下一个周期再采电池电压
  104. {
  105. TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压关闭
  106. TaskSchedulerTimer.batteryVoltTimer = TEN_SECOND_TIMER;
  107. }
  108. else */ if (motorWorkState != MOTOR_WORK_OFF )
  109. {
  110. TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压关闭
  111. TaskSchedulerTimer.batteryVoltTimer = TEN_SECOND_TIMER;
  112. }
  113. else
  114. {
  115. //ADC 采集的值在DMA 中赋值
  116. ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);
  117. ADC_SoftwareStartConvCmd(ADC2, ENABLE); //启动转换
  118. while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC )); //等待转换完成
  119. tempADC1=ADC_GetConversionValue(ADC2); //获取转换结果*ADC_ConvertedValue*
  120. //tempADC1 = ADC_ConvertedValue[0] & 0x0fff;
  121. tempADC1 = tempADC1 * 2515 / 4096;
  122. batteryVolt[batteryCounts] = (uint16_t)( tempADC1 * 6 ); //6这个数值是从分压电路得到
  123. batteryCounts++;
  124. if( batteryCounts >= 7 )//每采集7次值,前2次值丢弃,比较一下,取平均值
  125. {
  126. batteryCounts = 0;
  127. for( i = 2; i < 7; i++ )
  128. {
  129. tempVolt = batteryVolt[i];
  130. for( j = 2; j < 8 - i; j++ )
  131. {
  132. if( batteryVolt[j] > batteryVolt[j + 1] )
  133. {
  134. tempVolt = batteryVolt[j];
  135. batteryVolt[j] = batteryVolt[j + 1];
  136. batteryVolt[j + 1] = tempVolt;
  137. }
  138. }
  139. }
  140. tempVolt = ( batteryVolt[3] + batteryVolt[4] + batteryVolt[5] ) / 3;//去掉最高最低值,其余3个值做平均值
  141. /*if( ( tempVolt % 100 ) > 70 )//如果余数>70mv采集值就向上加100mV
  142. {
  143. tempVolt /= 100;//x.x V,舍去后两位
  144. tempVolt += 1;
  145. }
  146. else
  147. {
  148. tempVolt /= 100;//x.x V,舍去后两位
  149. }*/
  150. if( tempVolt <= 4900 )//如果平均值大于45则说明采集值有很大误差,则重新采集7次 20170519修改电压《=4.9v都为正常的电压
  151. {
  152. batteryAverage = tempVolt;
  153. if( batteryAverage > 4500 )//如果采集值>4.5V则默认为4.5V,电压范围为3.0~4.5V
  154. {
  155. batteryAverage = 4500;
  156. }
  157. else if( batteryAverage < 3000 )
  158. {
  159. batteryAverage = 3000;
  160. }
  161. realTimeData.batteryVolt = (uint8_t)( 100 - ( ( 4500 - batteryAverage ) * 100 / 1500 ) );//电池电压 4.5 - 3.0 = 1.5*10
  162. TaskSchedulerFlag.sensorPWBatteryFlag = TASK_FLAG_CLEAR;//传感器电源-电压关闭
  163. ADC_Voit_Done=1;//电压采集并运算完毕
  164. }
  165. }
  166. }
  167. }
  168. }