搜索
bottom↓
回复: 29

STM8S103的ADC1多通道电压检测

[复制链接]

出0入0汤圆

发表于 2012-6-26 23:13:17 | 显示全部楼层 |阅读模式
用了STM8S103来检测两路电压,用定时器TIM4来控制,定时器没10ms中断一次,设计的方案是交替检测两路电压,也就是说第1个10ms中断就检测第一路电压,第2个10ms中断就检测第二路电压,第3个10ms中断就检测第一路电压,一次类推。每次电压检测都采集16次数据,以方便做平均处理。目前遇到的问题是:
1)如果只检测第一路电压(固定vs_sel为0),结果正确;
2)如果只检测第二路电压(固定vs_sel为1),结果正确;
3)如果让vs_sel从0,1,2,0,1,2...变化,在vs_sel等于0的时候检测第一路电压,在vs_sel等于1的时候检测第二路电压,结果发现第一路电压和第二路电压的检测结果都不正确。

有没有高手帮我解决一下?附上我的程序。

=================================================================
在main函数的初始对ADC频率和对齐方式进行了初始化:
ADC1->CR1 |= (ADC1_CR1_SPSEL & (0x02<<4));

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2012-6-26 23:14:13 | 显示全部楼层
在main函数的初始对ADC频率和对齐方式进行了初始化:
ADC1->CR1 |= (ADC1_CR1_SPSEL & (0x02<<4));                //fADC = 4 MHz
ADC1->CR2 |= ADC1_CR2_ALIGN;                                        //right aligment

出0入0汤圆

 楼主| 发表于 2012-6-26 23:14:35 | 显示全部楼层
TIM4中断函数:
@far @interrupt void irq_system_tim4_ovf (void)
{
          // If MAX NO OF SAMPLES are taken then voltage
                // values will not be recorded in array vs12_arr
                no_of_sample_vals = 0;
                while( no_of_sample_vals < MAX_NO_SAMPLE_VAL )       
                {                                            
                                //start ADC
                                ADC1->CR1 |= ADC1_CR1_ADON;                //ADC powered up
                                ADC1->CR1 |= ADC1_CR1_ADON;                //begin conversion       
                                //check for the EOC
                                while (!(ADC1->CSR & ADC1_CSR_EOC)){};
                                //must read LSBs first
                                if (vs_sel==0){
                                        vs12_arr[no_of_sample_vals] = ADC1->DRL;                                       
                                        vs12_arr[no_of_sample_vals] |= ADC1->DRH << 8;
                                } else if (vs_sel==1){
                                        vs5_arr[no_of_sample_vals] = ADC1->DRL;                                       
                                        vs5_arr[no_of_sample_vals] |= ADC1->DRH << 8;
                                }
                                //ADC powered down
                                ADC1->CR1 |= ~ADC1_CR1_ADON;       
               
                                no_of_sample_vals++;
                }
                // Update the time counter
                flag_10ms = 1;
                if (t_10ms==100){  /* 1 sec is completed */
                  flag_1sec = 1;
                        t_10ms = 0;
                }
                t_10ms++;
                vs_sel++;
                if (vs_sel==3) vs_sel = 0;
                // Clear the flag
    TIM4->SR1 &=~(0x01);
    return;
}

出0入0汤圆

 楼主| 发表于 2012-6-26 23:21:59 | 显示全部楼层
在main函数的while(1)循环里面根据vs_sel的值选择了ADC通道(CH_VS12和CH_VS5):
while (1){
          if (vs_sel==0){
                        ADC1->CSR |= (ADC1_CSR_CH & CH_VS12);       
                } else if (vs_sel==1){
                        ADC1->CSR |= (ADC1_CSR_CH & CH_VS5);
                }

出0入0汤圆

 楼主| 发表于 2012-6-27 10:09:21 | 显示全部楼层
求帮助。

出0入0汤圆

 楼主| 发表于 2012-6-27 12:05:24 | 显示全部楼层
解决了,通道选择错误。

出0入0汤圆

发表于 2012-8-2 21:34:37 | 显示全部楼层
怎么stm8 的这么少啊,顶起。

出0入0汤圆

 楼主| 发表于 2012-8-3 10:03:20 | 显示全部楼层
ZL88 发表于 2012-8-2 21:34
怎么stm8 的这么少啊,顶起。

同感。不知道8位机,便宜的,大家都在用什么?或者呢,可能是因为8位简单,问题很少。

出0入0汤圆

发表于 2012-12-3 11:30:22 | 显示全部楼层
oulutek 发表于 2012-6-26 23:21
在main函数的while(1)循环里面根据vs_sel的值选择了ADC通道(CH_VS12和CH_VS5):
while (1){
          if (vs_s ...

问下楼主,我用了6路AD,为什么只能读到最后一路的值?求帮助;谢谢

出0入0汤圆

 楼主| 发表于 2012-12-4 09:55:57 | 显示全部楼层
先选择通道再读取啊。

出0入0汤圆

发表于 2012-12-4 13:59:13 | 显示全部楼层
学习了,mark

出0入0汤圆

发表于 2013-3-5 20:16:59 | 显示全部楼层
楼主你有没有用过连续扫描方式啊,为什么出来的数值总是变化呢

出0入0汤圆

发表于 2013-10-8 15:46:36 | 显示全部楼层
oulutek 发表于 2012-6-26 23:14
TIM4中断函数:
@far @interrupt void irq_system_tim4_ovf (void)
{

  STM8S103F的TIM4中断函数这样子写的... ,我这样写行不?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-2-13 13:57:20 | 显示全部楼层
lwg998 发表于 2013-3-5 20:16
楼主你有没有用过连续扫描方式啊,为什么出来的数值总是变化呢

你的连续扫描模式调试通没?

出0入0汤圆

发表于 2014-5-4 11:55:00 | 显示全部楼层
误差极大

出0入0汤圆

发表于 2014-5-4 12:13:47 | 显示全部楼层
连续扫描一直没用好,但是stm8s003确实便宜

出0入0汤圆

发表于 2014-8-22 10:28:00 | 显示全部楼层
楼主,还在吗?我现在也在用STM8S103F2P,我用了AIN4,用单次读,发现读到值没有变化,一直是379

出0入0汤圆

发表于 2014-8-22 11:46:13 | 显示全部楼层
第一次在论坛回帖,赞一个

出0入0汤圆

发表于 2014-10-7 19:40:11 | 显示全部楼层
zcan 发表于 2014-8-22 11:46
第一次在论坛回帖,赞一个

你的中级就是这样水出来的吗?

出0入0汤圆

发表于 2014-10-7 23:36:11 | 显示全部楼层
STM8的资料就是少啊

出0入0汤圆

发表于 2014-10-8 09:38:12 | 显示全部楼层
小手冰凉 发表于 2014-10-7 19:40
你的中级就是这样水出来的吗?

出0入0汤圆

发表于 2014-10-8 15:27:29 来自手机 | 显示全部楼层
淘宝上有这种单片机做的五位电压表卖,精度还可以,不知有没有人开源

出0入0汤圆

发表于 2014-12-29 21:56:12 | 显示全部楼层
多通道一直调不出来

出0入0汤圆

发表于 2014-12-29 22:06:50 | 显示全部楼层

楼主你好,不止问题解决了没有,我的处理方法不用中断,MCU采用STM8S103FP6,我的使用方法是,每隔20ms调用一次
,可随意切换通道
  1. /***************************************************************
  2. *函数名 :ADC_GPIO_Init
  3. *描述   :ADC通道初始化
  4. *输入   :NULL
  5. *输出   :NULL
  6. *备注   :
  7. ****************************************************************/
  8. //配置对应的ADC通道为开漏输入方式
  9. //根据需要配置相应的AIN口,如果不需要,请删除相应IO配置使能
  10. //PC4 -- AIN2
  11. //PD2 -- AIN3
  12. //PD3 -- AIN4
  13. //PD5 -- AIN5
  14. //PD6 -- AIN6
  15. void Init_ADC(void)
  16. {
  17.         ADC1_DeInit();
  18.         ADC1->TDRH = 0x00;
  19.         ADC1->TDRL = ( 1<< ADC1_SCHMITTTRIG_CHANNEL2 );
  20.         ADC1->CSR = 0x07;
  21.         ADC1->CR2 = ( ADC1_ALIGN_RIGHT );//右对齐
  22.         ADC1->CR3 = 0x00;
  23.         ADC1->CR1 = ( ADC1_PRESSEL_FCPU_D4 | ADC1_CR1_ADON ); //4分频,唤醒电源

  24. }

  25. /***************************************************************
  26. *函数名 :Get_Val_To_ADC
  27. *描述   :ADC取样
  28. *输入   :psc:分频系数; ADC1_CHANNEL_X:通道
  29. *输出   :RetADCVal
  30. *备注   :
  31. ****************************************************************/

  32. //ADC_Psc取值范围:0~7(对应:2, 3, 4, 6, 8, 10, 12, 18分频)
  33. //ADC1_CHANNEL_X取值范围:2~6
  34. uint16_t Get_Val_To_ADC( uint8_t ADC1_CHANNEL_X )
  35. {
  36.         uint16_t MaxADCVal = 0;    //取样最大值
  37.         uint16_t MinADCVal = 1023;   //取样最小值
  38.         uint16_t TmpADCVal = 0;    //取样中间值
  39.         uint16_t RetADCVal = 0;    //取样最终返回值
  40.         uint8_t Index = 0;
  41.         //转换通道 `
  42.         ADC1->CSR = ADC1_CHANNEL_X;//转换通道

  43.         for( Index = 0; Index < 10; Index ++ )
  44.         {
  45.                 ADC1->CR1 |= ADC1_CR1_ADON;
  46.                 while( !(ADC1->CSR & ADC1_IT_EOC));
  47.                 ADC1->CSR &= (uint8_t)(~ADC1_FLAG_EOC);
  48.                 //提取10次的后6次,减去最大值与最小值后取平均值
  49.                 if ( Index >= 4)
  50.                 {
  51.                         TmpADCVal = ADC1_GetConversionValue();
  52. //                          TmpADCVal = ADC1->DRL;
  53. //                        TmpADCVal |= (ADC1->DRH<<8);
  54.                         RetADCVal += TmpADCVal;
  55.                         if ( MaxADCVal < TmpADCVal )
  56.                         {
  57.                                 MaxADCVal = TmpADCVal;
  58.                         }
  59.                         if ( MinADCVal > TmpADCVal )
  60.                         {
  61.                                 MinADCVal = TmpADCVal;
  62.                         }
  63.                 }
  64.         }

  65.         RetADCVal -= MinADCVal;
  66.         RetADCVal -= MaxADCVal;
  67.         RetADCVal = RetADCVal/4;
  68.         return RetADCVal;
  69. }
复制代码

出0入4汤圆

发表于 2014-12-30 13:25:18 | 显示全部楼层
qq开始学单片机 发表于 2014-12-29 22:06
楼主你好,不止问题解决了没有,我的处理方法不用中断,MCU采用STM8S103FP6,我的使用方法是,每隔20ms调 ...

你好,不知有没有库函数版本的?

这个stm8s的ad这块一直都不太理解,尤其是参考电压,资料上说的含糊

出0入0汤圆

发表于 2014-12-30 15:57:20 | 显示全部楼层
huarana 发表于 2014-12-30 13:25
你好,不知有没有库函数版本的?

这个stm8s的ad这块一直都不太理解,尤其是参考电压,资料上说的含糊 ...

你可以论坛搜索“风驰”

出0入4汤圆

发表于 2015-1-8 08:19:15 | 显示全部楼层
qq开始学单片机 发表于 2014-12-30 15:57
你可以论坛搜索“风驰”

嗯,一直在看风驰的例程资料。但是里面没看到有配置参考电压的代码 = =

出0入0汤圆

发表于 2015-1-13 19:40:21 | 显示全部楼层
qq开始学单片机 发表于 2014-12-29 22:06
楼主你好,不止问题解决了没有,我的处理方法不用中断,MCU采用STM8S103FP6,我的使用方法是,每隔20ms调 ...

赞一下你的这种方法,我等读取ADC的神器~

出0入0汤圆

发表于 2020-9-7 09:18:24 | 显示全部楼层
2是什么状态?检测哪个通道?

出0入0汤圆

发表于 2020-9-7 09:19:08 | 显示全部楼层
61行与65行是否写反了?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-3 19:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表