打印
[STM8]

STM8 ADC多通道扫描(C++版本)

[复制链接]
2863|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
noeyes277|  楼主 | 2015-4-24 00:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
刚开始学单片机,STM8在IAR环境下能用C++,对我来说实在是太好了,我是那种没对象不会编程的银,我可以把功能都封装起来,以后需要优化时再脱离库函数。
这两天总结了一下STM8 ADC的用法,手头的103F6支持5路ADC,两路被UART占用了,这里列出我的三路扫描的方法,与各位初学者共同探讨:

// 头文件:

/*
   ADC
*/

#ifndef  _ADC1_H
#define  _ADC1_H

#include "stm8s_conf.h"

#define ADC1_EOC_IRQ                    0x16

class __near cADC1
{
  public:
    cADC1(int);
    uint16_t                    read_ADC_value(ADC1_Channel_TypeDef);
    void                        NextConversion();
    void                        StartConversion();
  private:
    uint16_t                    m_channel2_value,m_channel3_value,m_channel4_value;
    ADC1_Channel_TypeDef        m_current_channel;              
};

cADC1           __near Adc1(0);
#endif

// 源程序 Adc1.cpp

#include "Adc1.h"

/* ADC1 通道扫描方式, 开通了三个通道 */

cADC1 __near *Adc1_instance;  

cADC1::cADC1(int id)
{
  Adc1_instance = this;      // 中断要引用这个实例
  // 对于stm8s003 103F3,有ANI2~6
  // ADC1_CHANNEL_2:
    GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_FL_NO_IT);
  // ADC1_CHANNEL_3:
    GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_IN_PU_NO_IT);
  // ADC1_CHANNEL_4:
    GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_IN_PU_NO_IT);
  // ADC1_CHANNEL_5:  // UART1_TX
  // GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_IN_FL_NO_IT);
  // ADC1_CHANNEL_6:  // UART1_RX
  // GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);

  m_current_channel =  ADC1_CHANNEL_2;
  ADC1_Init(ADC1_CONVERSIONMODE_SINGLE , m_current_channel, ADC1_PRESSEL_FCPU_D8,\
    ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT,ADC1_SCHMITTTRIG_ALL,ENABLE);
  ADC1_ScanModeCmd(ENABLE);             // 扫描模式
  ADC1_DataBufferCmd(ENABLE);           // 使用数据缓冲区寄存器
  ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE); // 转换结束中断
  StartConversion();                    // 执行第一次转换
}

uint16_t cADC1::read_ADC_value(ADC1_Channel_TypeDef Ani)
{
  switch (Ani)
  {
   case ADC1_CHANNEL_2:  return m_channel2_value;
   case ADC1_CHANNEL_3:  return m_channel3_value;
   case ADC1_CHANNEL_4:  return m_channel4_value;
   default: return 0;
  }
}


void cADC1::StartConversion()
{
  if (ADC1_CHANNEL_2 == m_current_channel)      // 启动通道
  {
    ADC1_Cmd(ENABLE);                           // 中断使能
    ADC1_StartConversion();
  }
}

void cADC1::NextConversion()
{
  switch (m_current_channel)
  {
    case ADC1_CHANNEL_2:
      m_channel2_value = ADC1_GetBufferValue(0x02); // 读取ADC结果,保存在成员变量中
      m_current_channel = ADC1_CHANNEL_3;           // 切换到下一个通道
      ADC1_ConversionConfig(ADC1_CONVERSIONMODE_SINGLE, m_current_channel, ADC1_ALIGN_RIGHT);
      break;

    case ADC1_CHANNEL_3:
      m_channel3_value = ADC1_GetBufferValue(0x03); // 读取ADC结果,保存在成员变量中
      m_current_channel = ADC1_CHANNEL_4;           // 切换到下一个通道
      ADC1_ConversionConfig(ADC1_CONVERSIONMODE_SINGLE, m_current_channel, ADC1_ALIGN_RIGHT);
      break;

    case ADC1_CHANNEL_4:
      m_channel4_value = ADC1_GetBufferValue(0x04); // 读取ADC结果,保存在成员变量中
      m_current_channel = ADC1_CHANNEL_2;           // 切换到下一个通道
      ADC1_ConversionConfig(ADC1_CONVERSIONMODE_SINGLE, m_current_channel, ADC1_ALIGN_RIGHT);
                                                   
      ADC1_Cmd(DISABLE);                            // 停止,由StartConversion启动下一次的扫描
      break;
                                                     //  可以扩展到通道5、6
    default:
      break;
  }
}

INTERRUPT_HANDLER(ADC1_EOC_IRQHandler, ADC1_EOC_IRQ)
{
  ADC1_ClearITPendingBit(ADC1_IT_EOC);
  Adc1_instance->NextConversion();
}

只需要定时调用Adc1.StartConversion(),就可以通过 Adc1.read_ADC_value(ADC1_CHANNEL_x)读取相应通道的ADC值。

void cMANAGER::Run()
{
  int value;
//  Led_yellow.Flash();
  value = Adc1.read_ADC_value(ADC1_CHANNEL_2);
  double voltage = value * 3.3/ 1023;
  double radio = (double)value / 1023 * 100;
  cUART1::printf("value = %d %d %d %fV %f% \r\n",
    Adc1.read_ADC_value(ADC1_CHANNEL_3),
    Adc1.read_ADC_value(ADC1_CHANNEL_4),
    (int)value, voltage, radio);
}
三路采样输出的结果:
22:55:29.677 value = 550 658 413 1.3322V 40.3714%
22:55:30.180 value = 550 658 414 1.3354V 40.4692%
22:55:30.683 value = 550 658 414 1.3354V 40.4692%
22:55:31.186 value = 551 657 413 1.3322V 40.3714%
22:55:31.690 value = 550 657 413 1.3322V 40.3714%
22:55:32.192 value = 550 657 413 1.3322V 40.3714%
22:55:32.695 value = 550 657 414 1.3354V 40.4692%
22:55:33.198 value = 550 658 414 1.3354V 40.4692%
22:55:33.701 value = 551 658 414 1.3354V 40.4692%
22:55:34.206 value = 550 658 413 1.3322V 40.3714%
22:55:34.707 value = 550 657 414 1.3354V 40.4692%
22:55:35.210 value = 550 657 413 1.3322V 40.3714%
22:55:35.713 value = 550 657 413 1.3322V 40.3714%
22:55:36.216 value = 550 657 413 1.3322V 40.3714%
22:55:36.719 value = 550 658 413 1.3322V 40.3714%
22:55:37.220 value = 550 658 414 1.3354V 40.4692%
22:55:37.720 value = 550 657 414 1.3354V 40.4692%
22:55:38.228 value = 550 657 413 1.3322V 40.3714%
22:55:38.731 value = 550 657 413 1.3322V 40.3714%
22:55:39.234 value = 550 658 413 1.3322V 40.3714%
沙发
周董| | 2015-4-24 07:05 | 只看该作者
恩恩 要是能把解释说明说的再详细点就好了啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

17

帖子

1

粉丝