历史上的今天
返回首页

历史上的今天

今天是:2024年12月04日(星期三)

正在发生

2019年12月04日 | 基于STM8的ADC读取---STM8-第四章

2019-12-04 来源:eefocus

1. 综诉


  想学会如何在STM8上使用ADC这个功能,我们先得了解单片机中ADC究竟是什么。


  ADC是模拟信号转成数值信号,单片机只能识别TTL电平,其实就是 1 或者 0 ,但是如果我们给它一个3.3V电压,单片机就无法识别,,若想使用单片机读取出来得时候,它必须将模拟量变成数字量。


2. 关于STM8S103手册的ADC简介

由官方的全英手册可知。


----------------------------------------------------------------------------------------------------------------------------------


STM8中ADC1和ADC2主要功能如下:


10位分辨率

单词和连续的转换模式

可编程的(转换频率的)预分频,fMASTER 可以被分频 2到18

可选择ADC专用外部中断(ADC_ETR)或者定时器触发信号(TRGO)来作为外部触发信号

模拟放大(对于具有VREF引角的型号)

转换结束时可产生中断

灵活的数据对齐方式

ADC输入电压范围:VSSA≤VIN≤VDDA

----------------------------------------------------------------------------------------------------------------------------------


ADC1具有以下拓展功能:


带缓冲的连续转换模式

单次和连续转换的扫描模式

具有上限和下限门槛的模拟看门狗

模拟看门狗时间发生可产生中断

----------------------------------------------------------------------------------------------------------------------------------


3. 例程


3.1 编译环境


  我的编译环境是IAR,这款软件是现在STM8的主流平台,比较推荐。不过我打算等到STCubeMX更新出比较方便的版本后再去使用Keil5,因为我在用STM32的时候就是利用Keil5,的确很方便,你们也可以学着用一下。


3.2 主芯片


  我的主芯片是STM8S系列中的103,其中STM8S的003、005、和103、105,配置一样(外设和CPU频率,FLASH),在代码相同的情况下均可进行烧写。


3.3 库文件的添加


  我们的工程可以在IAR的例程中复制,操作过程:打开STM8S_StdPeriph_Lib(这是一个官方的库文件,下载IAR STM8包的时候就携带,里面有库文件和相对应的例程),将Libraries文件复制到你工程所在的文件下,并将有关于ADC的库文件添加到你的工程列表当中。添加完成后,有可能你会看到一些C文件会有红色的小点报错,这是因为你选的芯片上没有该功能,你需要将其删掉才能不报错。如图。

添加成功后,我们需要将头文件添加进来,头文件的路径存放在 Libraries->STM8S_StdPeriph_Driver->inc中,如图。 

3.4 代码编写


  STM8SF003这款芯片能用的是5个AD采样通道,分别为为AIN2~AIN6。其一个通道AIN7,但在官方手册中我没找到有对其描述的,感兴趣的朋友可以去察看芯片的英文手册进行研究,也许会找到和我不一样的结果。


在ADC头文件中,将ADC1所有的ADC1_CHANNEL(ADC通道)都进行枚举,以方便调用。


 1 /* Enum ----------------------------------------------------------------------*/

 2 

 3 enum ADC1_CHANNEL

 4 {                                        //bit  8  7  6  5  4  3  2  1

 5   

 6     ADC1_CHANNEL2 = 0x01,                //     0  0  0  0  0  0  0  1

 7     ADC1_CHANNEL3 = 0x02,                //     0  0  0  0  0  0  1  0

 8     ADC1_CHANNEL4 = 0x04,                //     0  0  0  0  0  1  0  0

 9     ADC1_CHANNEL5 = 0x08,                //     0  0  0  0  1  0  0  0

10     ADC1_CHANNEL6 = 0x10                 //     0  0  0  1  0  0  0  0

11         

12 };  

 

在ADC.C文件中,分为了多个函数,降低他们的耦合性,也方便理解。


首先是ADC中引角的初始化,将你所选通道的引角进行初始化,没有选到的就不进行初始化。


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC_GPIO_Init

 3 * Description    : ADC GPIO Init

 4 * Input          : ADC1_CHANNEL

 5 * Output         : None

 6 * Return         : None

 7 ********************************************************************************/

 8 

 9 void MX_ADC_GPIO_Init(uint8_t ADC1_CHANNEL)

10 {

11   switch(ADC1_CHANNEL)

12   {

13     case ADC1_CHANNEL2:  GPIO_Init(ADC_Opt_GPIOC_Port,ADC_channe2_Pin,GPIO_MODE_IN_PU_NO_IT);break;

14     case ADC1_CHANNEL3:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe3_Pin,GPIO_MODE_IN_PU_NO_IT);break;

15     case ADC1_CHANNEL4:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe4_Pin,GPIO_MODE_IN_PU_NO_IT);break; 

16     case ADC1_CHANNEL5:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe5_Pin,GPIO_MODE_IN_PU_NO_IT);break;

17     case ADC1_CHANNEL6:  GPIO_Init(ADC_Opt_GPIOD_Port,ADC_channe6_Pin,GPIO_MODE_IN_PU_NO_IT);break;

18   } 

19   

20 }

 

  然后是ADC1的选择通道初始化:ADC连续读取,所选的通道,二分频,外部转换触发,外部触发器不开启,数据右对齐,施密特触发,不开启。(注意:STMS8003中的串口使用了PD5和PD6,与ADC1中通道5、通道6发生冲突,故不可使用。如需使用,请将串口的TXRX引角更改换为其它的引角。)


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC1_CHANNEL_Init

 3 * Description    : ADC CHANNEL Init

 4 * Input          : ADC1_CHANNEL

 5 * Output         : None

 6 * Return         : None

 7 ********************************************************************************/

 8 

 9 void MX_ADC1_CHANNEL_Init(uint8_t ADC1_CHANNEL)

10 {

11   switch(ADC1_CHANNEL)

12   {

13     case ADC1_CHANNEL2: 

14     {

15        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_2, 

16        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

17        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL2, DISABLE);break;

18     }

19     case ADC1_CHANNEL3:

20     {

21        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_3, 

22        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

23        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL3, DISABLE);break;

24     }

25     case ADC1_CHANNEL4:

26     {

27        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_4, 

28        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

29        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL4, DISABLE);break;

30     } 

31     case ADC1_CHANNEL5:

32     {

33        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_5, 

34        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

35        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL5, DISABLE);break;

36     }

37     case ADC1_CHANNEL6:

38     {

39        ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_6, 

40        ADC1_PRESSEL_FCPU_D2, ADC1_EXTTRIG_TIM, DISABLE, 

41        ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL6, DISABLE);break;

42     }

43   } 

44 }


这里就是将所有的ADC初始化进行一个统一的一个归类。


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC1_Init

 3 * Description    : ADC Init

 4 * Input          : ADC1_CHANNEL

 5 * Output         : None

 6 * Return         : None

 7 ********************************************************************************/

 8 void MX_ADC1_Init(uint8_t ADC1_CHANNEL)

 9 {  

10   //初始化GPIO

11   MX_ADC_GPIO_Init(ADC1_CHANNEL);

12   

13   //初始化ADC1所有寄存器

14   ADC1_DeInit();

15   

16   //配置ADC1寄存器中的参数

17   MX_ADC1_CHANNEL_Init(ADC1_CHANNEL);

18   

19   //使能ADC1

20   ADC1_Cmd(ENABLE);

21   

22   //ADC1转换开始

23   ADC1_StartConversion();

24 }

 最后就是数据获取,可以选择直接获取数据,也可以获取十次数据后取平均数。


注意:


ADC获取的值是AD值,需要将其进行代入公式中才能得到电压值。


Vin = (ADC * Vref) / 1024


VCC很明显可以使用万用表先测出来,1024是因为STM8S这款的AD是10位精度。


这里测试的VCC是3.35V,VCC另外一个意思就是单片机的供给电源。


 1 /*******************************************************************************

 2 * Function Name  : MX_ADC1_Get_Data

 3 * Description    : get VCC data

 4 * Input          : None

 5 * Output         : None

 6 * Return         : fVCC

 7 ********************************************************************************/

 8 float MX_ADC1_Get_Data(void)

 9 {

10   int iADC1_Value;

11   float fVCC;

12   

13   //读取转换结果

14   iADC1_Value = ADC1_GetConversionValue();

15   fVCC = (iADC1_Value * 3.350)/1024;

16   return fVCC;

17   

18 }

19 

20 

21 /*******************************************************************************

22 * Function Name  : MX_ADC1_Get_Average_Data

23 * Description    : Get VCC ten times average data. 

24 * Input          : None

25 * Output         : None

26 * Return         : fAverage_VCC

27 ********************************************************************************/

28 float MX_ADC1_Get_Average_Data(void)

29 {

30   int i;

31   float fAverage_VCC = 0.0;

32   

33   for(i=0;i<10;i++)

34   {

35    fAverage_VCC += MX_ADC1_Get_Data();

36   }

37   fAverage_VCC /= 10;

38   

39   return fAverage_VCC;

40   

41 }

将上面需要用到的函数在主函数中调用打印即可。


4. 实验结果


 调试仪器:可调式电源,可通过旋钮控制电压的输出大小。


 当没有输出电压时,打印的值为0V.

 当可调式电源输出的电压值为3.3V,串口助手上打印的也是3.3V。

当可调式电源输出的电压值为24V,串口助手上打印的也是24V。


注意:请不要将24V电源直接通入单片机中,我是自己设置了一条电路进行测试的。ADC的最大输入电压是3.3V,为了安全起见,请不要超过该值。


注意:请不要将24V电源直接通入单片机中,我是自己设置了一条电路进行测试的。ADC的最大输入电压是3.3V,为了安全起见,请不要超过该值。


注意:请不要将24V电源直接通入单片机中,我是自己设置了一条电路进行测试的。ADC的最大输入电压是3.3V,为了安全起见,请不要超过该值。

5. 结尾


对STM8的ADC的说明和引用到这里结束,感谢各位看官的点击。

推荐阅读

史海拾趣

Aristo-Craft/ L M P Inc公司的发展小趣事

品质是公司的生命线。Aristo-Craft/L M P Inc一直注重品质管理,从原材料采购到生产过程的每一个环节都进行严格把控。公司建立了完善的质量管理体系,并通过了多项国际质量认证。同时,公司还注重品牌建设,通过广告宣传、参加行业活动等方式提高品牌知名度和美誉度。

Elpress AB公司的发展小趣事

在追求经济效益的同时,Elpress AB也注重可持续发展和环境保护。公司积极采用环保材料和绿色生产工艺,降低生产过程中的能耗和排放。同时,Elpress AB还积极参与环保公益活动,推动电子行业的绿色发展。这些举措不仅体现了Elpress AB的社会责任感,也为公司的长期发展奠定了坚实的基础。

CMOSIS公司的发展小趣事

随着CMOS图像传感器在智能手机、安防监控、汽车等领域的广泛应用,CMOSIS公司看到了巨大的市场潜力。公司加大了市场拓展力度,不仅在国内市场取得了显著成绩,还积极开拓海外市场。同时,公司注重品牌建设,通过提升产品质量、加强售后服务等方式,树立了良好的企业形象和口碑。

强盛电子(AEC)公司的发展小趣事

面对国内市场的饱和,AEC决定实施国际化战略,拓展海外市场。公司首先在欧洲设立了研发中心,随后在北美和亚洲等地建立了销售网络和生产基地。通过不断优化产品结构和提升服务质量,AEC逐渐在国际市场上树立起了良好的品牌形象,成为一家具有全球影响力的电子企业。

Freeport Resources Enterprises Corp公司的发展小趣事

在21世纪初,Freeport Resources作为一家历史悠久的矿业公司,开始意识到电子材料市场的巨大潜力。公司决定利用其丰富的矿产资源和勘探经验,转向对电子级金属材料的探索与开发。通过深入研究和市场调研,Freeport Resources成功定位了高纯度铜、钴等金属在半导体、电路板等电子领域的应用,并逐步建立了从矿产开采到电子材料加工的完整产业链。这一转型不仅为公司带来了新的增长点,也使其在电子行业中崭露头角。

GE Power Electronics Inc公司的发展小趣事
合理设计电路布局和布线,避免信号干扰和串扰。同时,采用适当的保护电路,如过压保护、过流保护等。

问答坊 | AI 解惑

工程勾通,友好交流、扩大共识,相互借鉴

有归属、没宗派,有尊重、没辈分,有针对、没争竞,有奉献、没名利 相互尊重、友好交流、扩大共识,倡导不同文化间增进了解、相互借鉴 电子工程师,结构工程师,软件工程师,硬件工程师,FPGA研发。另有数码产品,影音视听产品,手机,微型硬盘播放机,R ...…

查看全部问答>

阿牛哥系列故事大嘴歪评世界杯

阿牛哥冒着七月的艳阳酷暑,晚上听完国际广播电台的新闻,西瓜荔枝,要看世界杯球赛了。晚上的这场要看,凌晨的那场要听。电视电脑收音机都需要,就是不能影响白天的工作。先说说世界杯比赛,不能在家里看,太影响家人.去哥们马六家看;啤酒不喝 ...…

查看全部问答>

PC104设备在纯DOS下跑程序的问题,虚拟软驱引导的纯DOS和实际安装的DOS有区别不?

如题。 现在程序跑在虚拟软驱引导的纯DOS里面,2000里面用bc31写的程序在2000下跑很流畅,但是到DOS下却非常卡。 想在DOS里面再编译,链接模式选small能通过,但是程序一跑就死,选large能通过,一跑连画面都没有,选其他linker都不成功。何解? ...…

查看全部问答>

wince 是否支持"微软雅黑"字体?

wince 是否支持\"微软雅黑\"字体? 看到linux下显示的字体比较漂亮,font文件下看到msyh.ttf,也就是雅黑字体了,EVC下显示的字效果比较一般,要是wince支持msyh.ttf的话,应该怎样添加呢? …

查看全部问答>

紧急求救!!用c开发手机或PDA需要看什么方面的书籍资料!!谢谢各位拉

本人用vc写过应用程序,用c写过mp3的程式,但是c++不太好,在vc里面基本用的都是c,现在想转做手机或pda方面,请教需要看哪些书啊?我看些资料,一般都是在用WinCE或在Linux下开发,哪个发展更好些?不知道这方面薪水待遇怎么样?敢请各位不啬赐教 ...…

查看全部问答>

晶振问题

请各位帮忙分析一下: 晶振工作不正常,第一次不起振,然后用烙铁点了一下,工作正常了一会,然后又不振了,再用烙铁点一下,又能正常工作,挂上仿真器,只能正常工作一会,如此反复。。。 请大家帮忙分析下。先谢了…

查看全部问答>

MSP430FG461X系列的20位地址指针在C语言中如何实现?

我把一个20位的地址0x10000,赋值给一个指针变量时,总是提示超出了0~0xFFFF的范围。 在汇编中这是可以做到的,因为MSP430X提供了MOVA等带A的指令,且工作寄存器都是20位的,可以用于20位的地址传输。就是不知道C语言中怎么实现。 不知是不是有 ...…

查看全部问答>

请教定时器中断的问题(一直都查不到资料,麻烦高手指点)

问题1:一般在主函数中装定时器初值,有必要吗?我好像试了,不装也能正常运行。 问题2:如果在定时器1中关闭了定时器0,用TR0=1再次打开定时器0时,需要重新装定时器0的初值吗?还是TR0=1直接就进入定时器0的中断函数从头开始执行。我试过两次不 ...…

查看全部问答>

一般不会这样做pcduino 可以连GY-86(MPU6050, HMC5883L, MS561101BA)ic吗?

一般不会这样做pcduino 可以连GY-86(MPU6050, HMC5883L, MS561101BA)ic吗?…

查看全部问答>

ADS8332疑问之二:这是哪儿带来的干扰

使用C2000的SPI驱动ADS8332,过去曾成功过,是不同的PCB。然而再次搞它时,却问题多多。 现象:采样转换的通道,采样(转换)时,输入端悬空或稍大的旁路电阻(>10K,再小没试),就有有1V左右的电压。而未采样的通道,采样通道未采样时,没有这个 ...…

查看全部问答>