基于累加的PDM算法的原理

2023-05-16

基于累加的PDM算法原理

基于累加的PDM算法(2)


 PDM编码原理如下:


  单片机能输出Sin(t)吗?能,DA。

  没有DA怎么办?PWM。

  没有PWM怎么办?

  事情就是这么来的。20多年前,不要说单片机内没有PWM,而且当时的MCS-51系列内连Timer2还没有呢。这个算法就是20多年前逼出来的。

  下面看我怎样在数字端口输出SQRT(0.5)= 0.70710678…。

  假设我们要输出实数值x,x在[0,1)。

  我们只需要一个变量存累计数,事实上,我们只须保存尾数,不妨就叫它为Mantissa。Mantissa可以有[0,1)范围内的任意初始值。

  下面一段程序是在定时中断内执行的。中断间隔是由你系统的需要和MCU的能力确定的。

Timer_ISR:

Mantissa += x ;

If (Mantissa >= 1) { Pout = 1 ; Mantissa -= 1 ; }

Else Pout = 0 ; //从哪个数字口Pout输出由你定

END of Timer_ISR.

  每中断一次,端口输出一个0或1。

  我们看一下当x= 0.7071…和初值Mantissa=0.5时,每次中断输出的实例:

  1,0,1,1,1,0,1,1,0,1,1,0,1,…

  那么输出序列中1的个数(h)/中断次数(n):

  h/n=

  1/1,1/2,2/3,3/4,4/5,4/6,5/7,6/8,6/9,7/10,8/11,8/12,9/13,…,11/16,…,23/32,…,45/64,…,91/128,…,181/256,…,…,23170/32768,…

  化做小数容易对比,h/n=

1,0.5,0.6667,0.75,0.8,0.6667,0.7143,0.75,0.6667,0.7,0.7273,0.6667,0.6923,…,0.6875(n=16),…,0.71875(n=32),…,0.7031(n=64),…,0.7109(n=128),…,0.70703(n=256),…,…,0.70709(n=32768),…

  我们可以看到,h/n是0.70710678…的最佳分数逼近(就同样的分母而言),而且随着n的增加,逼近的精度就越来越高了。如何选择中断间隔和输出端的滤波参数,就看系统对精度的要求了。当然,还受到MCU能力的限制。

  在实际运用中,考虑到MCU的能力限制,我们要把算法变得更高效。例如:

  由精度的要求,考虑一个合适的整数N(N=256,一般就够1%了),那么x也放大N倍成H=x*N;Mantissa也用整数CNT。那么,算法也就如上一篇中抛出的:

Timer_ISR:

CNT += H ;

If (CNT >= N) { Pout = 1 ; CNT %= N; } //CNT -= N,就看哪个快

Else Pout = 0 ;

END of Timer_ISR.

  这个算法的特点就是:在N个时钟周期内,均匀地送出H个1。

  对8位、16位、32位MCU,我们选特定的N=256、N=65536、N=2^32。

  那么一次加法就够了:

Timer_ISR:

CNT += H ;

Pout = Carry_Bit ; //直接输出进位到端口。

END of Timer_ISR.

  20多年前,在8051中,我每一次定时器中断管3个PDM输出。就这么几句汇编:

Timer_ISR:

...

MOV A,CNT1

ADD A,H1

MOV CNT1,A

MOV Px.1,C

MOV A,CNT2

ADD A,H2

MOV CNT2,A

MOV Px.2,C

MOV A,CNT3

ADD A,H3

MOV CNT3,A

MOV Px.3,C

...

RETI

  顺便说,在ARM Cortex-M中,用N=2^32比用N=2^8、N=2^16都要快。反一下汇编就知道了,因为运算是32位的,要8位、16位,还要从32位截下来,白白花费一些CPU周期。ARM Cortex-M系统,在Systick中,用汇编做软件PDM,挺不错的。

  这种算法,用中国的成语说,就叫做“集腋成裘”,狐狸的腋毛积累到够做一件裘衣,就先做一件,剩下的零头归到下次继续积。

  另外,AD、DA也常用到“Sigma-Delta”,我们的这种算法,洋叫法是不是可以叫做“Software Sigma-Delta” ?

  现在MCU内,DA、PWM都不当回事了,还要翻这老黄历干吗?老黄历还有新用场,这就是我晒这粒陈芝麻的用意。后面慢慢道来。

The Priciple of The PWM Algorithm Based On Addition

- A PDM Algorithm Based On Addition (2)

===



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于累加的PDM算法的原理 的相关文章

  • 新入职项目经理务必避免的七个常见错误

    在国内 xff0c 好多项目经理都是技术专家出身 xff0c 所以标题给了 34 新入职 34 由于旧习惯 xff0c 身上可能存在众多需要改进的地方 一 不明确自身的职责 你不在是个码农 xff1f 公司聘请你不是为了让你去写代码 xff
  • How Android Handles Touches

    Touch System overview Touch Event Framework Custom Touch Handling System Provided Touch Handlers System Provided Gesture
  • MFCC特征介绍

    MFCC特征介绍 在语音识别技术中 xff0c 需要提取音频的特征 xff0c 然后就可以使用该音频进行模型的训练或者是进行识别 xff0c 目前很常用的一种特征叫做MFCC特征 xff0c 又叫做梅尔倒谱系数特征 MFCC特征保留了语义相
  • 字符串大小比较问题

    首先 字符串比较函数 xff1a strcmp xff08 字符串1 字符串2 xff09 xff1b 其使用规则为 xff1a 若字符串1和字符串2相等 xff0c 返回0 若字符串1大于字符串2 xff0c 返回一个正整数 43 1 若
  • OBS 录制没有声音怎么办?

    1 检查obs设置 音频 是否是默认选项 2 检查win10 是否允许使用麦克风 1 xff09 右下角出现麦克风标识 2 xff09 设置 隐私 麦克风 xff0c 查看允许放开你的麦克风是否打开 如果上述还是为解决问题 xff0c 那么
  • android.os.deadObjectException异常

    deadObjectException异常 xff0c 说明应用的service已经停止 xff0c 要么是从操作系统中丧生 xff0c 要么从应用程序中终止
  • 2038问题

    2038年一月19号 xff0c 星期二 xff0c 凌晨3点14分7秒钟的时候 xff0c 如果Linux程序员会做恶梦的话 xff0c 那么梦的内容一定是关于这个日期的 xff0c 在这一秒钟滑过后 xff0c 凡是安装着linux的计
  • ChkBugReport工具for Android

    关于这个工具 xff0c 找到的资料都比较旧了 xff0c 貌似是索尼移动的开发人员开发的 xff0c 2014年左右的文章比较多 xff0c 应该是那个时候索尼移动还是比较鼎盛的时期吧 现在已经很少看到关于这个工具的文章了 xff0c G
  • kernel panic

    Linux kernel panic是很难定位和排查的重大故障 一旦系统发生了kernel panic xff0c 相关的日志信息非常少 xff0c 而一种常见的排查方法 重现法 又很难实现 xff0c 因此遇到kernel panic的问
  • PS域业务与CS域业务的区别

    1 CS和PS是针对核心网部分而言的 xff0c 两者的不同在于交换方式 CS是电路交换 xff0c 通信之前 xff0c 资源预留 xff0c 不同用户独占各自分配的资源 xff0c 没有统计复用 PS是包交换 xff0c 不同的用户可以
  • sh_脚本语法

    介绍 xff1a 1 开头 程序必须以下面的行开始 xff08 必须方在文件的第一行 xff09 xff1a bin sh 符号 用来告诉系统它后面的参数是用来执行该文件的程序 在这个例子中我们使用 bin sh来执行程序 当编写脚本完成时
  • 【深度学习系列(三)】:基于CNN+seq2seq公式识别系统实现 (1)

    这段时间一直在做公式识别相关的项目 xff0c 尝试了传统的方法 xff0c 效果不怎么好 想到能不能使用深度学习的方法进行相关方法 然后在github找到了相关代码 xff0c 这里做下分析 具体github地址 xff1a GitHub
  • 困惑多年,为什么printf可以重定向?

    很多人在用printf函数进行串口打印的时候 xff0c 都会被告知需要重定向fputc函数 xff08 别的平台可能不是这个函数 xff09 xff0c 让字符串数据输出到指定串口 xff0c 按照网上的教程也能很快解决 但是却没人告诉你
  • 多线程并发编程

    文章目录 多线程并发编程一 多线程带来的问题相关概念 二 互斥1 互斥与互斥量2 申请互斥量I 静态方法申请互斥量 xff1a II 动态方法申请互斥量 xff1a 3 利用互斥量加锁与解锁4 销毁互斥量5 互斥量综合应用 模拟抢票6 互斥
  • 【嵌入式】---- 串口UART波形分析

    串口参数的配置 波特率 xff08 bit s xff09 xff1a 大多数使用115200 但有些芯片特殊 xff0c 具体要看数据手册中波特率的容错率 比如中微的CMS32L051就不支持115200bps 停止位 xff1a 一般选
  • 手把手教你用JAVA实现“语音合成”功能(文字转声音)标贝科技

    手把手教你用JAVA实现 语音合成 功能 xff08 文字转声音 xff09 标贝科技 前言 什么是语音合成 xff1f 将文本转换成自然流畅的语音 xff0c 本篇文章将介绍 实时在线合成 xff08 文本长度不得超过1024字节 xff
  • cv::imread(cv::String const&, int)’未定义的引用

    在 Makefile文件的195 行 LIBRARIES 43 61 opencv core opencv highgui opencv imgproc 后面添加 xff1a opencv imgcodecs opencv videoio修
  • 【C/C++】C++ 网络多线程编程

    关键词 xff1a C C 43 43 网络编程 多线程 套接字 UDP 前言 学习C 43 43 网络编程多线程编程的目的 xff1a 巩固C 43 43 xff1b 由于C 43 43 大多用于服务器 xff0c 因此网络和多线程是进入
  • 在ubuntu20.04上配置VINS_Fusion(亲测有效,一应俱全)

    最近在做科研训练的时候配置了HKUST Aerial Robotics实验室的VINS Fusion代码项目 xff0c 经历了一些编译报错的问题 xff0c 在网上查找的时候博客内容良莠不齐 xff0c 且实质针对性意见不多 xff0c
  • 无人机项目跟踪记录二十五--无线接收模块的输入输出

    无线接收模块的功能是接收无线遥控器的命令 xff08 应该对应的是无人机上面的无线接收芯片 xff09 xff0c 无人机根据接收的指令进行不同的处理 用同样方法 xff0c 无线接收模块包含的函数是 xff1a Nrf Irq void

随机推荐