单片机ad与pwm问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单片机ad与pwm问题相关的知识,希望对你有一定的参考价值。
1.我想让电位器从0度转到5度时输出占空比是10%,
2.转到80度的时候输出占空比是90%。
3.电位器两瑞端加5V电压,标准时5度时电位器输出端电压0.5V,80度时输出4.5V,供AD采集。
4.但每只电位器5度和80度电压都有差异,用单片机怎么保证输出占空比一致性。
2,为什么要AD转换?
单片机(以及其他处理器)只能处理数字信号,当单片机想要获取电路上某一点的电压值时,就得用到AD转换了,如果你直接把单片机的引脚接到电路这个点上,单片机只知道这个点的电压是低电平还是高电平,又怎么能得到他的电压值呢?例如数字式的万用表,它测量电压时,先有一个AD转换电路,把电压值转换成一个数值,然后把这个值送个单片机(当然万用表里的用的处理芯片不是单片机),单片机经过计算处理后,再把这电压值显示到显示到屏幕上。
不过现在有一些比较强的单片机,其内部已经集成了AD转换器,不需要你再外接AD转换芯片。
3,8位16位的ad转换芯片是什么意思?
8位,16位就代表了AD转换芯片的转换分辨率,数字越大,分辨率越高,同时也反映了它的精度,数字越大,精度相对也越高。8位算是最低了,有些单片机里集成的AD转换器一般是10位的。12位和16位的芯片价格就比较贵了。
4,分辨率?
举个简单的例子,8位芯片只能转换最小到0.01V的电压,而12位的芯片却能转换最小到0.001V的电压,如果一个电压为3.359V,8位芯片转出来后的数值是3.35V,12位芯片转换出来后是3.359V,精度比8位就高一个档次了。(注:这里数值不是正确的数值,举例用,切勿实际使用)
5,采样?
采样是AD转换的速度性能指标,通俗的说就是每秒里能采样多少次,采样次数越高芯片性能越好。如果对采样不理解,也可以用另一种方式理解,就是一个AD转换芯把电压值转换成数字值这个过程所需要的时间,时间越短越好。
6,精度?
精度是AD芯片的一个重要参数,表示采集到的数据和真实值之间的相差的程度。例如单片机转换出来的结果是0.3V,而实际可能是0.31V,这样就相差了0.01V。这种误差是不可避免无法消除的。这和在第3点中提到的位数有关,位数越高,这样的误差越小。
7,这些知识点在“数字电路基础”一书中有详细解释,说明你数字电路没学好,自己好好加油了。 参考技术A 既然涉及AD采样和PWM调光,为了简化电路,减少外围元件,如果你采用STC系列的单片机,建议使用自带AD和PWM输出的型号,比如STC12C2052AD、STC12C5A60S2,当然STM8、STM32这些系列的单片机一般也自带AD和PWM输出。
我这里以STC系列的单片机举例。
首先学习STC自带AD采集,网上也有程序,需要的话我也可以提供。采集光敏电阻两端的电压,看不同光照情况下光敏电阻两端的电压的变化情况,最好是让显示器(比如LCD1602)显示出来。
然后后再学习STC自带的PWM输出功能,程序也容易找。设定不同的占空比,看看PWM输出管脚上的LED灯的亮度变化情况。
最后,根据采集到的光敏电阻两端电压的大小改变PWM的占空比 参考技术B -255之间的数值。这就是把模拟电压转换成数字信号。
//有些拧动电位器后数码管数可能不会动态变化,请用户按下实验板上的S22复位按键可更新数据
//这种显象产生的原因是和AD芯片自身的一些特性有关。
#include<reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
sbit rd=P3^7; //IO口定义
sbit wr=P3^6;
sbit cs=P3^5;
sbit r=P3^3;
sbit g=P3^2;
sbit b=P3^1;
unsigned char j,k,v,rh,gh,bh;
uchar cnt;
void delay(unsigned char i) //延时程序
for(j=i;j>0;j--)
for(k=125;k>0;k--);
void TC_init (void)
TMOD |= 0x01;
EA = 1;
TH0 = 0xFF;
TL0 = 0xF6;
ET0 = 1;
TR0 = 1;
void TC0 (void) interrupt 1 using 1
TH0 = 0xFF;
TL0 = 0xF6;
if(++cnt>=255)cnt=0;
if(cnt<rh)
r=0;
else
r=1;
if(cnt<gh)
g=0;
else
g=1;
if(cnt<bh)
b=0;
else
b=1;
void main() // 主程序
while(1)
cs=1;
cs=0;
wr=1;
wr=0;
wr=1;
delay(25);
P1=0xff;
rd=1;
rd=0;
delay(5);
v=P1;
delay(5);
rd=1;
cs=1;
P2=v;
TC_init();
if(v>0&&v<6)
rh=255;gh=255;bh=255;
if(v>6&&v<17)
rh=125;gh=255;bh=255; 参考技术C 单片机(以及其他处理器)只能处理数字信号,当单片机想要获取电路上某一点的电压值时,就得用到AD转换了,如果你直接把单片机的引脚接到电路这个点上,单片机只知道这个点的电压是低电平还是高电平,又怎么能得到他的电压值呢?例如数字式的万用表,它测量电压时,先有一个AD转换电路,把电压值转换成一个数值,然后把这个值送个单片机(当然万用表里的用的处理芯片不是单片机),单片机经过计算处理后,再把这电压值显示到显示到屏幕上。单片机(以及其他处理器)只能处理数字信号,当单片机想要获取电路上某一点的电压值时,就得用到AD转换了,如果你直接把单片机的引脚接到电路这个点上,单片机只知道这个点的电压是低电平还是高电平,又怎么能得到他的电压值呢?例如数字式的万用表,它测量电压时,先有一个AD转换电路,把电压值转换成一个数值,然后把这个值送个单片机(当然万用表里的用的处理芯片不是单片机),单片机经过计算处理后,再把这电压值显示到显示到屏幕上。单片机(以及其他处理器)只能处理数字信号,当单片机想要获取电路上某一点的电压值时,就得用到AD转换了,如果你直接把单片机的引脚接到电路这个点上,单片机只知道这个点的电压是低电平还是高电平,又怎么能得到他的电压值呢?例如数字式的万用表,它测量电压时,先有一个AD转换电路,把电压值转换成一个数值,然后把这个值送个单片机(当然万用表里的用的处理芯片不是单片机),单片机经过计算处理后,再把这电压值显示到显示到屏幕上。 参考技术D “用单片机怎样产生频率可调的200khzpwm波”这句话有语病,要么是占空比可调的200khzpwm波,要么是频率可调的pwm波,既然频率可调,200khz什么意思?
占空比可调的200khzpwm波,可以实现,前提是系统时钟频率足够高。方法是使用定时器中断,计算出200khz周期对应的定时器中断装载值,采取两次中断法,两次中断定时器的装载值之和等于200khz频率周期,加这个减那个,就实现占空比可调,这种方式占空比可调范围大。
频率可调的pwm波,也可实现,固定一个相位的定时周期,调整另一相位的周期,即可达到调整占空比和频率的目的,这种方法占空比的调整有一定限度。
MindMotion MM32 单片机上的MicroPython移植-PWM
简 介: 对于MindMotion在11月22日发送过来的移植有PWM功能的MicroPython的软件进行了测试。首先,在两个PWM的通道(PA6,PA7)上可以测试到输出的波形,但信号参数与设置之间还存在着差异: 输出频率比设置频率小; 输出的占空比正好与设置的相反。
关键词
: MM32,PWM,MicroPython
§01 MM32 MicroPython
一、背景介绍
在过去的周末,MindMotion SuYong对于移植的MicroPython中的带有PWM版本进行了修正,发送过来了最新的版本:
MicroPython/MindMotion/firmware-2021-11-22.bin · 卓晴/编程技术 - Gitee.com
这个版本时对于 测试MindMotion MM32F3277 MicroPython -2021-11-20新增PWM版本 所存在的问题进行修复。但程序的主要框架没有改变。即仍然借助于两个Timer完成八个PWM通道的功能。
▲ 图1.1.1 测试实验电路板
二、PWM功能
根据前天的测试,可以知道PWM的主要管脚与内部定时器资源如下:
PWM | 定时器 | GPIO |
---|---|---|
PWM0 | TIM3 | PA6 |
PWM1 | TIM3 | PA7 |
PWM2 | TIM3 | PB0 |
PWM3 | TIM3 | PB1 |
PWM4 | TIM4 | PB6 |
PWM5 | TIM4 | PB7 |
PWM6 | TIM4 | PB8 |
PWM7 | TIM4 | PB9 |
三、下载MicroPython
1、下载MicroPython
将下载的MicroPython下载到 设计带有SD卡的 MM32F3277 MicroPython 实验板 ,然后使用STM32BOOTLOADER进行REPL测试。
▲ 图1.3.1 将新版的MicroPython下载到测试版中
2、上电测试
上电后,在REPL界面显示:
>> Open COM8, baud : 115200
[Y] sdcard ready.
[Y] file system on sdcard ready.
[Y] run the main.py on disk ...
[Y] done. 1
MicroPython v1.16 on 2021-11-22; MB_F3270 with MM32F3277G7P
>>>
§02 测试PWM
一、基本测试
1、测试基本波形
初始化PWM通道0,1,分别占用PA6,PA7输出对应的PWM波形。
(1) 测试代码
from machine import Pin,PWM
import utime
pwm0 = PWM(0, freq=10000, duty=200)
pwm1 = PWM(1, freq=10000, duty=500)
print("Test PWM.")
(2) 输出波形
测量输出波形,如下图所示:
▲ 图2.1.1 PWM输出波形
可以看到这个波形与设置参数之间存在误差:
- 频率误差: 实际的PWM输出频率为9.589kHz,使用FLUKE45数字万用表的频率档测量的信号的频率为9.5914kHz。
- 占空比误差: 设置的duty=200。实际输出则为800。输出波形反向了。
下面是PWM0的duty分别设置为 1, 999对应的波形。
▲ 图2.1.2 PWM0设置duty=1对应的波形
▲ 图2.1.3 PWM0设置duty=999对应的波形
2、动态改变duty
(1)测试代码
from machine import Pin,PWM
import utime
pwm0 = PWM(0, freq=10000, duty=500)
pwm1 = PWM(1, freq=10000, duty=1)
print("Test PWM.")
duty = 1
dutyinc = 20
dir = 0
while True:
if dir == 0:
duty += dutyinc
if duty >= 1000:
duty = 999
dir = 1
else:
if duty < dutyinc:
duty = 1
dir = 0
else:
duty -= dutyinc
pwm1.duty(duty)
utime.sleep_ms(100)
▲ 图2.1.4 动态改变PWM1的占空比
※ 测试总结 ※
对于MindMotion在11月22日发送过来的移植有PWM功能的MicroPython的软件进行了测试。首先,在两个PWM的通道(PA6,PA7)上可以测试到输出的波形,但信号参数与设置之间还存在着差异:
- 输出频率比设置频率小;
- 输出的占空比正好与设置的相反。
▲ 图3.1 设置PWM品味100kHz对应的输出波形
■ 问题溯源
后来经过测试,只初始化PWM0, 而不初始化PWM1,则输出波形的极性正常了。
▲ 图3.1.1 只是初始化PWM0, 输出duty=100对应的波形
如果同时初始化PWM0,PWM1,则输出波形中PWM0 的波形不正常。
下面是初始化PWM0,duty=200, PWM1,duty=100对应的波形:
▲ 图3.1.2 初始化PWM0,duty=200, PWM1,duty=100对应的波形
■ 问题修复
1、信号极性
经过修改,SuYong 修改完底层的BUG之后,极性正常了。
▲ 图3.2.1 底层的HAL存在问题
2、频率误差
频率误差仍然存在问题。尚无法达到准确输出频率。主要是因为分频整除对应的问题。SuYong在这个环节并没有能够进行进一步的 优化。
■ 相关文献链接:
- MicroPython/MindMotion/firmware-2021-11-22.bin · 卓晴/编程技术 - Gitee.com
- 测试MindMotion MM32F3277 MicroPython -2021-11-20新增PWM版本
- 设计带有SD卡的 MM32F3277 MicroPython 实验板
● 相关图表链接:
以上是关于单片机ad与pwm问题的主要内容,如果未能解决你的问题,请参考以下文章