[STM8] 分享stm8s003单片机的ADC转换,附加冒泡算法(减少误差)

[复制链接]
 楼主| wailian1265k 发表于 2021-6-22 23:13 | 显示全部楼层 |阅读模式

1.先上脚位图,不要问我为什么是stm8f103,stm8f103和stm8s003只有内存的不同。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE1Mzg5Ng==,size_16,color_FFFFFF,t_70.jpg


 楼主| wailian1265k 发表于 2021-6-22 23:14 | 显示全部楼层
2.上代码,选用PC4(AIN2)为ADC转换引脚,只提供函数,自己选择调用,不追求精度的话可以不要冒泡排序。(划重点:这个单片机是10位的分辩率,所以不要问我为什么公式是实际电压值(voltage) = adc值*参考电压(3.25V)/1024(10位分辨率))
 楼主| wailian1265k 发表于 2021-6-22 23:15 | 显示全部楼层
  1. /**************************************************************************
  2. * 函数名:ADC_conf
  3. * 描述  :ADC模块初始化
  4. * 输入  :无
  5. *
  6. * 输出  :无
  7. * 返回  :无
  8. * 调用  :外部调用
  9. *************************************************************************/
  10. void ADC_conf(u8 chn)
  11. {
  12.     GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_NO_IT);
  13.         ADC1_DeInit();//ADC1_CONVERSIONMODE_CONTINUOUS
  14.         ADC1_Init(ADC1_CONVERSIONMODE_SINGLE,      //单次转换
  15.                   ADC1_CHANNEL_2,                  //通道   
  16.                   ADC1_PRESSEL_FCPU_D4,            //预定标器选择 分频器  fMASTER 可以被分频 2 到 18
  17.                   ADC1_EXTTRIG_TIM,                //从内部的TIM1 TRGO事件转换
  18.                   DISABLE,                         //是否使能该触发方式
  19.                   ADC1_ALIGN_RIGHT,                //对齐方式(可以左右对齐)
  20.                   ADC1_SCHMITTTRIG_CHANNEL2,       //指定触发通道   
  21.                   ENABLE);                         //是否使能指定触发通道
  22.         ADC1_Cmd(ENABLE);      
  23.    
  24. }
  25. /****************************************************************************
  26. * 名    称:
  27. * 功    能:对数据进行冒泡排序
  28. * 入口参数:   
  29. * 出口参数:
  30. * 说    明:
  31. * 调用方法:
  32. ****************************************************************************/
  33. void DataFilter(u16 *data_in,u8 data_len)
  34. {
  35.         u16 temp;
  36.         u8 i,j;
  37.         for(i = 0; i < data_len; i++)
  38.         {
  39.                 for(j = i+1; j <data_len; j++)
  40.                 {
  41.                         if(data_in[i] < data_in[j])
  42.                         {
  43.                                 temp = data_in[j];
  44.                                 data_in[j] = data_in[i];
  45.                                 data_in[i] = temp;
  46.                         }
  47.                 }
  48.         }
  49. }
  50. /**************************************************************************
  51. * 函数名:ADC_GetConversionValue
  52. * 描述  :获取ADC转换结果
  53. * 输入  :无
  54. *
  55. * 输出  :无
  56. * 返回  :无
  57. * 调用  :内部调用
  58. *************************************************************************/
  59. uint16_t ADC_GetConversionValue(void)
  60. {
  61.   uint16_t value,temph;        
  62.   uint8_t templ;      
  63.   
  64.   ADC1_StartConversion();
  65.   // 定义templ存储低8位数据  temph存储高8位数据  
  66.   while(!(ADC1->CSR & 0x80));     //等待转换完成
  67.   templ = ADC1->DRL;
  68.   temph = ADC1->DRH;              //读取ADC转换  在左对齐和右对齐模式下 读取数据的顺序不同  参考STM8寄存器.PDFP371         
  69.   
  70.   value = (templ | (temph << 8));   //注意是10位的转换精度 value、temph应为unsigned int 变量
  71.   return  value;
  72. }
  73. /****************************************************************************
  74. * 名    称:
  75. * 功    能:取冒泡排序的10个数组中的中间4个数组,减少误差。
  76. * 入口参数:   
  77. * 出口参数:
  78. * 说    明:
  79. * 调用方法:  call in 10ms
  80. ****************************************************************************/
  81. void ReadInputVoltege(void)
  82. {
  83.   u8 i;
  84.   u16 temp[READ_ADC_LEN];
  85.    
  86.     for(i = 0; i < READ_ADC_LEN-1; i ++)
  87.     {
  88.       adc_input_voltage[i] = adc_input_voltage[i+1];
  89.       temp[i] = adc_input_voltage[i];
  90.     }
  91.     adc_input_voltage[READ_ADC_LEN-1] = ADC_GetConversionValue();
  92.     temp[READ_ADC_LEN-1]  = adc_input_voltage[READ_ADC_LEN-1];
  93.       
  94.     //0-8
  95.     DataFilter(&temp[0],READ_ADC_LEN);
  96.    
  97.     ReadInputAdc = temp[3]+temp[4]+temp[5]+temp[6];
  98.     ReadInputAdc >>= 2;        //    /4
  99.    
  100. }
  101. /****************************************************************************
  102. * 名    称:获取实际电压函数
  103. * 功    能:计算公式:实际电压值(voltage) = adc值*参考电压(3.25V)/1024(10位分辨率)
  104. * 入口参数:   
  105. * 出口参数:
  106. * 说    明:
  107. * 调用方法:  
  108. ****************************************************************************/
  109. void DisVoltage(void)
  110. {
  111.    u16 voltage;
  112.       
  113.       voltage =  (ReadInputAdc *325)/1024   ;// 配合一下硬件分压,没有分压值
  114.       voltage =  voltage/100;
  115. }
ldxepthnn 发表于 2021-6-29 16:15 | 显示全部楼层
不错的方法,谢谢,学习一下。
elephant00 发表于 2021-6-30 16:22 | 显示全部楼层
不错的方法,顶一下
菜鸟的第一步 发表于 2021-6-30 16:50 | 显示全部楼层
我当时用STM32F103使用ADC采样也采用的冒泡算法,对数据去杂很好用
张教官 发表于 2021-8-12 07:53 | 显示全部楼层
ReadInputAdc >>= 2; 是什么意思, ReadInputAdc 这个是库函数吗?如果不是,请问是什么类型的变量。
hhhxj 发表于 2021-10-11 15:36 | 显示全部楼层
本帖最后由 hhhxj 于 2021-10-11 15:37 编辑
张教官 发表于 2021-8-12 07:53
ReadInputAdc >>= 2; 是什么意思, ReadInputAdc 这个是库函数吗?如果不是,请问是什么类型的变量。 ...

    ReadInputAdc = temp[3]+temp[4]+temp[5]+temp[6];

    ReadInputAdc >>= 2;        //    /4   他算了4个数的和  不得除以4取平均值吗?   他是去掉两个小的数,2个大的数  剩下的求和  取平均
小叶三千 发表于 2021-10-12 08:47 | 显示全部楼层
感谢分享,很有用的ADC减小误差的算法,以后也采用冒泡算法试一试
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

413

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部