刚开始学单片机,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% |