-
2021-12-08 17:28:47
哈夫曼又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种
该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
作用:即利用哈夫曼算法的理论构建出字符char和对字符进行编码code,的一个二叉树的字典 如:a->101其主要原理是:
1、通过对需要编码的字符串resource中字符char的出现频率进行统计得出相应的映射关系,
2、依据字符出现的频率对字符char进行编码 code
3、构建哈夫曼二叉树HuffmanTree(二叉树的节点data(char(字符串中出现的每一个char)、weight字符出现的权重、left,right左右子节点、节点data的对应编码code)),且二叉树的排序的规则以字符出现的权重进行排序
4、将字符串resource 和 HuffmanTree 的字符编码字典进行字符的迭代编码从而形成一串01的字符串
5、解码的过程是通过将01的串进行迭代,并构建一个临时的缓存区st,将011010…串的字符进行st入栈,并将st的串和HuffmanTree 中节点的code进行编码比对,当比对结果是true时,则表示当前的code对应是节点的data,从而将st清空,并继续对0110001…进行迭代解码实例
统计字符的概率
字符 概率 a 0.12 b 0.40 c 0.15 d 0.05 e 0.25 字符编码
我们现在要将文本编码成0/1序列从而使得计算机能够进行读取和计算。为了保证每个字符的独一性,所以我们给予不同的的字符以不同的编码。如果给每个字符赋予等长的编码的话,会使得平均的编码长度过长,影响计算时的性能,浪费计算机的资源(定长编码的缺点)。这时我们就想到了变长编码,理所当然的,给出现概率较大的字符赋予##### 统计字符的概率,概率较小的字符赋予较长的编码,这样在计算的时候不就可以节省很多时间了吗?可这样我们又面临到了一个巨大的问题,我们来看下面这种情况,我们对字符进行编码:
字符 概率 编码 a 0.12 01 b 0.40 0 c 0.15 00 d 0.05 10 e 0.25 1 构建哈夫曼树
假设现在文本中的字符是bcd,转换之后的0/1序列为00010,可我们要在转换成文本的时候究竟是把第一位的0读作b还是把前两位的00读作c呢?为了解决这个问题,就又有了前缀码的概念。顾名思义,前缀码的含义就是任意字符的编码都不是其他字符编码的前缀。那么该如何形成前缀码呢?首先我们要构造一棵二叉树,指向左孩子的"边"记作0,指向右孩子的点记作“1”,叶子节点为代编码的字符,出现概率越大的字符离根的距离就越近。
代码实现
定义树的节点
public class Node<T> implements Comparable<Node<T>> { private T data; private double weight; private Node<T> left; private Node<T> right; String code; public Node(T data, double weight){ this.data = data; this.weight = weight; this.code = ""; } public T getData() { return data; } public void setData(T data) { this.data = data; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public Node<T> getLeft() { return left; } public void setLeft(Node<T> left) { this.left = left; } public Node<T> getRight() { return right; } public void setRight(Node<T> right) { this.right = right; } public String getCode(){ return code; } public void setCode(String str){ code = str; } @Override public String toString(){ return "data:"+this.data+";weight:"+this.weight+";code: "+this.code; } @Override public int compareTo(Node<T> other) { if(other.getWeight() > this.getWeight()){ return 1; } if(other.getWeight() < this.getWeight()){ return -1; } return 0; } }
定义哈夫曼树。(主要包含两个方法createTree(),breadth())
createTree方法返回一个结
- createTree方法返回一个结点,也就是根结点。首先把所有的nodes结点类都储存在一个List中,利用Collections的sort方法把结点按照权值的大小按照从大到小的顺序进行排列。然后把List中的倒数第二个元素设为左孩子,倒数第一个元素设为右孩子。这个时候要注意:它们的双亲结点为以左右孩子的权值的和作为权值的构成的新的结点。然后删去左右孩子结点,将形成的新结点加入的List中。直到List中只剩下一个结点,也就是根结点时为止
- 广度遍历的方法,在遍历的时候,每遍历到左孩子,就把结点中的code变量加上“0”,这里的加不是简单的数学运算,而是字符串的叠加。每遍历到右孩子,就把结点中的code变量加上“1”,这样遍历过一遍后,叶子结点中的code储存的就是对应的哈夫曼编码值。
import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Queue; public class HuffmanTree { /** * 构建哈夫曼树 * @param nodes * @return */ public <T> Node<T> createTree(List<Node<T>> nodes) { while (nodes.size() > 1) { Collections.sort(nodes); Node<T> left = nodes.get(nodes.size() - 2); left.setCode(0 + ""); Node<T> right = nodes.get(nodes.size() - 1); right.setCode(1 + ""); Node<T> parent = new Node<T>(null, left.getWeight() + right.getWeight()); parent.setLeft(left); parent.setRight(right); nodes.remove(left); nodes.remove(right); nodes.add(parent); } return nodes.get(0); } /** * 在构建哈夫曼树的类中还实现了一个广度遍历的方法,在遍历的时候,每遍历到左孩子,就把结点中的code变量加上“0”,这里的加不是简单的数学运算,而是字符串的叠加。每遍历到右孩子,就把结点中的code变量加上“1”,这样遍历过一遍后,叶子结点中的code储存的就是对应的哈夫曼编码值。 * @param root * @return */ public <T> List<Node<T>> breadth(Node<T> root) { List<Node<T>> list = new ArrayList<Node<T>>(); Queue<Node<T>> queue = new ArrayDeque<Node<T>>(); if (root != null) { queue.offer(root); root.getLeft().setCode(root.getCode() + "0"); root.getRight().setCode(root.getCode() + "1"); } while (!queue.isEmpty()) { list.add(queue.peek()); Node<T> node = queue.poll(); if (node.getLeft() != null) node.getLeft().setCode(node.getCode() + "0"); if (node.getRight() != null) node.getRight().setCode(node.getCode() + "1"); if (node.getLeft() != null) { queue.offer(node.getLeft()); } if (node.getRight() != null) { queue.offer(node.getRight()); } } return list; } }
处理需要编码的字符串
public static class readtxt { char[] chars = new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s' ,'t','u','v','w','x','y','z','P',' '}; int[] number = new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; public String txtString(File file){ StringBuilder result = new StringBuilder(); try{ BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 String s = null; while((s = br.readLine())!=null){//使用readLine方法,一次读一行 result.append(System.lineSeparator()+s); num(s); } br.close(); }catch(Exception e){ e.printStackTrace(); } return result.toString(); } public String txtString(String reusrce){ StringBuilder result = new StringBuilder(); try{ BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件 num(reusrce); }catch(Exception e){ e.printStackTrace(); } return result.toString(); } public void num(String string){ for(int i = 0;i<28;i++){ int temp = 0; for(int j = 0;j<string.length();j++){ if(string.charAt(j) == chars[i]) temp++; } number[i] += temp; } } public int[] getNumber(){ return number; } public char[] getChars(){ return chars; } }
测试方法
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.ArrayList; import java.util.List; public class TestMain { public static void main(String[] args) { // File file = new File("F:\\input1\\input1.txt"); //编码的原始数据 String temp = "please go to the attendance management to update in time when the national holidays change"; //文本进行处理,定义两个数组获得文本中出现的字符和字符出现的次数 readtxt read = new readtxt(); // String temp = read.txtString(file); System.out.println(temp); System.out.println("***************"); int[] num = read.getNumber(); char[] chars = read.getChars(); //利用一个循环把对应的data值和weight权重值构造成结点加入到list中。 List<Node<String>> list = new ArrayList<>(); for(int i = 0;i<28;i++){ System.out.print(chars[i]+":"+num[i]+" "); list.add(new Node<String>(chars[i]+"",num[i])); } //构建哈夫曼树并得到根结点。 HuffmanTree huffmanTree = new HuffmanTree(); Node<String> root = huffmanTree.createTree(list); List<Node<String>> list2 = new ArrayList<>(); list2=huffmanTree.breadth(root); List<String> list3 = new ArrayList<>(list2.size()); List<String> list4 = new ArrayList<>(list2.size()); for(int i = 0;i<list2.size();i++){ if(list2.get(i).getData()!=null) { Node<String> node = list2.get(i); list3.add(node.getData()); list4.add(node.getCode()); } } String result = ""; for(int i = 0;i<temp.length();i++){ for(int j = 0;j<list3.size();j++){ if(temp.charAt(i) == list3.get(j).charAt(0)){ result += list4.get(j); } } } System.out.println("哈夫曼算法编码结果"); System.out.println(result); List<String> list5 = new ArrayList<>(result.length()); for(int i = 0;i<result.length();i++){ list5.add(result.charAt(i)+""); } String temp2 = ""; String temp3 = ""; while (list5.size()>0){ temp2 = temp2+"" +list5.get(0); list5.remove(0); for(int i=0;i<list4.size();i++){ if (temp2.equals(list4.get(i))) { temp3 = temp3+""+list3.get(i); temp2 = ""; } } } System.out.println("***********"); System.out.println(temp3); } }
运行结果
更多相关内容 -
金佛零记忆数字笔画输入法 v2.33.zip
2019-07-13 11:03:39如果要快速输入汉字或者词组,请使用我的专利输入法,编码规则简单,双笔画记忆很有规律,甚至完全不需要记忆,自己随手可以背着画出编码表。 我现在一直在电脑和手机上使用我的这个输入法,彻底抛弃其它输入法... -
论文研究-Tunstall编码与自适应编码算法 .pdf
2019-08-26 02:50:17Tunstall编码与自适应编码算法,王东昊,田宝玉,Tunstall码是Tunstall在1968年提出的一种V-B码,其使用前提是信源的静态特性和无记忆特性,但在实际中,信源多是动态变化的,此时就需要� -
(第五天)编写训练记忆软件--扑克编码V2.0
2014-07-11 19:55:401.编码初始化 必须初始化1.编码初始化
一副扑克,一个一个录入程序,最后到54号的时候,会自动保存文件txt。
以后每次打开软件,就直接点击“读取文件”,就可以进行后面的练习。
2.单组练习
练习反应速度,一是看扑克反应编码,二是看编码反应扑克。
3.多组练习
分两种多组练习,一是看数字反应编码,二是看编码反应数字。
4.计时训练
(1)随机打乱一副54张牌的扑克,每行13张,最后一行2张
(2)每次记完后,可以把记忆用时写入列表。
(3)训练完后,把时间列表导入excel文件中。
-
卷积码编码和维特比译码性能的对比分析
2021-01-20 05:48:15卷积码的编码器是由一个有k位输入、n位输出,且具有m位移位寄存器构成的有限状态的有记忆系统,通常称它为时序网络。编码器的整体约束长度为v,是所有k个移位寄存器的长度之和。具有这样的编码器的卷积码称作[n,k,v... -
基础电子中的卷积码编码和维特比译码性能的对比分析
2020-10-20 07:30:57卷积码的编码器是由一个有k位输入、n位输出,且具有m位移位寄存器构成的有限状态的有记忆系统,通常称它为时序网络。编码器的整体约束长度为v,是所有k个移位寄存器的长度之和。具有这样的编码器的卷积码称作[n,k,v... -
金佛零记忆双笔画输入法(词组全形码电脑版) v4.28.zip
2019-07-13 10:55:262.25个双笔画编码与小学生都熟悉的英文字母表(abcdefg…)完全对应,因此,编码能够很快记住,如果不愿意记忆,可以随时自己背着把编码表画出来,到达零记忆的效果。汉字和词组编码规则简单,如果某汉字不认识,... -
(第二天)编写训练记忆软件--数字编码矩阵V1.0
2014-07-08 21:00:041. 记忆编码初始化( 00~99和0~9 对应程序的 0~99 和 100~109) 从0~109,一个一个录入程序,最后会自动保存文件txt。 以后每次打开软件,就直接点击“读取文件”,就可以进行后面的练习。 2. 单组练习 ...1. 记忆编码初始化( 00~99和0~9 对应程序的 0~99 和 100~109)
从0~109,一个一个录入程序,最后会自动保存文件txt。
以后每次打开软件,就直接点击“读取文件”,就可以进行后面的练习。
2. 单组练习
分两种单组练习,一是看数字反应编码,二是看编码反应数字。
3.多组练习
分两种多组练习,一是看数字反应编码,二是看编码反应数字。
4.计时训练
(1)随机生成150个数字,分成5行,每行有5组,每组有6个数字。
(2)每次记完后,可以把记忆用时写入列表。
(3)训练完后,把时间列表导入excel文件中。
-
STM32编码器的学习笔记
2021-04-27 20:38:25STM32编码器的学习笔记 顺时针旋转就是一个递增的计数器 逆时针旋转就是一个递减的计数器 编码器的使用: 设置从模式寄存器的SMCR(SMS) 工作模式:编码器模式1,编码器模式2,编码器模式3;...编码器
编码器参数:
- 分辨率:指编码器能够分辨的最小单位。对于增量式编码器,其分辨率表示为编码器转轴旋转一圈所产生的脉冲数,即脉冲数/转 (Pulse Per Revolution 或 PPR)。码盘上透光线槽的数目其实就等于分辨率,也叫多少线,较为常见的有 5-6000 线。对于绝对式编码器,内部码盘所用的位数就是它的分辨率,单位是位 (bit),具体还分单圈分辨率和多圈分辨率。
- 精度:首先明确一点,精度与分辨率是两个不同的概念。精度是指编码器每个读数与转轴实际位置间的最大误差,通常用角度、角分或角秒来表示。例如有些绝对式编码器参数表里会写 ±20′′,这个就表示编码器输出的读数与转轴实际位置之间存在正负 20 角秒的误差,精度由码盘刻线加工精度、转轴同心度、材料的温度特性、电路的响应时间等各方面因素共同决定。
- 最大响应频率:指编码器每秒输出的脉冲数,单位是 Hz。计算公式:最大响应频率 = 分辨率 * 轴转速/60。
- 信号输出形式:对于增量式编码器,每个通道的信号独立输出 上图就是常规信号输出,还有正弦信号输出形式,输出电路形式通常有集电极开路输出、推挽输出、差分输出等。对于绝对式编码器,由于是直接输出几十位的二进制数,为了确保传输速率和信号质量,一般采用串行输出或总线型输出,例如同步串行接口 (SSI)RS485CANopen 或 EtherCAT 等,也有一部分是并行输出,输出电路形式与增量式编码器相同。
STM32编码器接口介绍,
- 如果计数器仅在 TI2 边沿处计数,在 TIMx_SMCR 寄存器中写入 SMS=“001”;
- 如果计数器仅在 TI1 边沿处计数,写入 SMS=“010”;
- 如果计数器在 TI1 和 TI2 边沿处均计数,则写入 SMS=“011”。
- 通过编程 TIMx_CCER 寄存器的 CC1P 和 CC2P 位,选择 TI1 和 TI2 极性。
- 如果需要,还可 对输入滤波器进行编程。CC1NP 和 CC2NP 必须保持低电平。
- TI1 和 TI2 两个输入用于连接增量编码器。如果使能计数器(在 TIMx_CR1 寄 存器的 CEN 位中写入“1”),则计数器的时钟由 TI1FP1 或 TI2FP2 上的每次有效信号转 换提供。
- TI1FP1 和 TI2FP2 是进行输入滤波器和极性选择后 TI1 和 TI2 的信号,如果不进行 滤波和反相,则 TI1FP1=TI1,TI2FP2=TI2。
- 将根据两个输入的信号转换序列,产生计数脉冲和方向信号。
- 根据该信号转换序列,计数器相应递增或递减计数,同时硬件对 TIMx_CR1 寄存器的 DIR 位进行相应修改。
- 任何输入(TI1 或 TI2)发生信号转换时,都会计算 DIR 位,无论计数器是仅在 TI1 或 TI2 边沿处计数,还是同时在 TI1 和 TI2 处计数。
- 编码器接口模式就相当于带有方向选择的外部时钟。
- 这意味着,计数器仅在 0 到 TIMx_ARR 寄存器中的自动重载值之间进行连续计数(根据具体方向,从 0 递增计数到 ARR,或从 ARR 递减计数到 0)。因此,在启动前必须先配置 TIMx_ARR。
- 同样,捕获、比较、预分频 器、重复计数器及触发输出功能继续正常工作。编码器模式和外部时钟模式 2 不兼容,因此 不能同时选择。
1. 下图就是电机正转的编码器输出波形,上表的红线计数方式
2. 通道A接TI1,通道B接TI2
3.TI1FP1的计数方向,需要参考TI2的电平
4. TI2FP2的计数方向,需要参考TI1的电平
顺时针旋转就是一个递增的计数器
逆时针旋转就是一个递减的计数器
STM32寄存器介绍
编码器的使用:
- 设置从模式寄存器的SMCR(SMS) 工作模式:编码器模式1,编码器模式2,编码器模式3;
- 设置输入引脚为TI1,TI2
- 设置触发的极性CCER(CC1P,CC2P)
- 设置滤波和分频 SCMR(IC1F,IC1PSC IC2F,IC2PSC)
- 使能计数器 CR1(CEN)
- 硬件会自动设置CR1(DIR)方向位;
不完整代码:
#ifndef __BSP_ENCOEDER_H #define __BSP_ENCOEDER_H #include "stm32f4xx.h" /* 定时器选择 */ #define ENCODER_TIM TIM3 #define ENCODER_TIM_CLK_ENABLE() __HAL_RCC_TIM3_CLK_ENABLE() /* 定时器溢出值 */ #define ENCODER_TIM_PERIOD 65535 /* 定时器预分频值 */ #define ENCODER_TIM_PRESCALER 0 /* 定时器中断 */ #define ENCODER_TIM_IRQn TIM3_IRQn #define ENCODER_TIM_IRQHandler TIM3_IRQHandler /* 编码器接口引脚 */ #define ENCODER_TIM_CH1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define ENCODER_TIM_CH1_GPIO_PORT GPIOC #define ENCODER_TIM_CH1_PIN GPIO_PIN_6 #define ENCODER_TIM_CH1_GPIO_AF GPIO_AF2_TIM3 #define ENCODER_TIM_CH2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define ENCODER_TIM_CH2_GPIO_PORT GPIOC #define ENCODER_TIM_CH2_PIN GPIO_PIN_7 #define ENCODER_TIM_CH2_GPIO_AF GPIO_AF2_TIM3 /* 编码器接口倍频数 */ #define ENCODER_MODE TIM_ENCODERMODE_TI12 /* 编码器接口输入捕获通道相位设置 */ #define ENCODER_IC1_POLARITY TIM_ICPOLARITY_RISING #define ENCODER_IC2_POLARITY TIM_ICPOLARITY_RISING /* 编码器物理分辨率 */ #define ENCODER_RESOLUTION 16 /* 经过倍频之后的总分辨率 */ #if (ENCODER_MODE == TIM_ENCODERMODE_TI12) #define ENCODER_TOTAL_RESOLUTION (ENCODER_RESOLUTION * 4) /* 4倍频后的总分辨率 */ #else #define ENCODER_TOTAL_RESOLUTION (ENCODER_RESOLUTION * 2) /* 2倍频后的总分辨率 */ #endif /* 减速电机减速比 */ #define REDUCTION_RATIO 30 extern __IO int16_t Encoder_Overflow_Count; extern TIM_HandleTypeDef TIM_EncoderHandle; void Encoder_Init(void); #endif /* __BSP_ENCODER_H */
/** ****************************************************************************** * @file bsp_motor_control.c * @author fire * @version V1.0 * @date 2019-xx-xx * @brief 编码器接口 ****************************************************************************** * @attention * * 实验平台:野火 STM32 F407 开发板 * 论坛 :http://www.firebbs.cn * 淘宝 :http://firestm32.taobao.com * ****************************************************************************** */ #include "./Encoder/bsp_encoder.h" /* 定时器溢出次数 */ __IO int16_t Encoder_Overflow_Count = 0; TIM_HandleTypeDef TIM_EncoderHandle; /** * @brief 编码器接口引脚初始化 * @param 无 * @retval 无 */ static void Encoder_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 定时器通道引脚端口时钟使能 */ ENCODER_TIM_CH1_GPIO_CLK_ENABLE(); ENCODER_TIM_CH2_GPIO_CLK_ENABLE(); /* 设置输入类型 */ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; /* 设置上拉 */ GPIO_InitStruct.Pull = GPIO_PULLUP; /* 设置引脚速率 */ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; /* 选择要控制的GPIO引脚 */ GPIO_InitStruct.Pin = ENCODER_TIM_CH1_PIN; /* 设置复用 */ GPIO_InitStruct.Alternate = ENCODER_TIM_CH1_GPIO_AF; /* 调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO */ HAL_GPIO_Init(ENCODER_TIM_CH1_GPIO_PORT, &GPIO_InitStruct); /* 选择要控制的GPIO引脚 */ GPIO_InitStruct.Pin = ENCODER_TIM_CH2_PIN; /* 设置复用 */ GPIO_InitStruct.Alternate = ENCODER_TIM_CH2_GPIO_AF; /* 调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO */ HAL_GPIO_Init(ENCODER_TIM_CH2_GPIO_PORT, &GPIO_InitStruct); } /** * @brief 配置TIMx编码器模式 * @param 无 * @retval 无 */ static void TIM_Encoder_Init(void) { TIM_Encoder_InitTypeDef Encoder_ConfigStructure; /* 使能编码器接口时钟 */ ENCODER_TIM_CLK_ENABLE(); /* 定时器初始化设置 */ TIM_EncoderHandle.Instance = ENCODER_TIM; TIM_EncoderHandle.Init.Prescaler = ENCODER_TIM_PRESCALER; TIM_EncoderHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TIM_EncoderHandle.Init.Period = ENCODER_TIM_PERIOD; TIM_EncoderHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TIM_EncoderHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; /* 设置编码器倍频数 */ Encoder_ConfigStructure.EncoderMode = ENCODER_MODE; /* 编码器接口通道1设置 */ Encoder_ConfigStructure.IC1Polarity = ENCODER_IC1_POLARITY; //上升沿触发 有点不解,不是使用 编码器模式 3 在计数器在 TI1FP1 和 TI2FP2 的边沿计数, Encoder_ConfigStructure.IC1Selection = TIM_ICSELECTION_DIRECTTI; Encoder_ConfigStructure.IC1Prescaler = TIM_ICPSC_DIV1; Encoder_ConfigStructure.IC1Filter = 0; /* 编码器接口通道2设置 */ Encoder_ConfigStructure.IC2Polarity = ENCODER_IC2_POLARITY; Encoder_ConfigStructure.IC2Selection = TIM_ICSELECTION_DIRECTTI; Encoder_ConfigStructure.IC2Prescaler = TIM_ICPSC_DIV1; Encoder_ConfigStructure.IC2Filter = 0; /* 初始化编码器接口 */ HAL_TIM_Encoder_Init(&TIM_EncoderHandle, &Encoder_ConfigStructure); /* 清零计数器 */ __HAL_TIM_SET_COUNTER(&TIM_EncoderHandle, 0); /* 清零中断标志位 */ __HAL_TIM_CLEAR_IT(&TIM_EncoderHandle,TIM_IT_UPDATE); /* 使能定时器的更新事件中断 */ __HAL_TIM_ENABLE_IT(&TIM_EncoderHandle,TIM_IT_UPDATE); /* 设置更新事件请求源为:计数器溢出 这个地方可能会忘记设置 */ __HAL_TIM_URS_ENABLE(&TIM_EncoderHandle); /* 设置中断优先级 */ HAL_NVIC_SetPriority(ENCODER_TIM_IRQn, 5, 1); /* 使能定时器中断 */ HAL_NVIC_EnableIRQ(ENCODER_TIM_IRQn); /* 使能编码器接口 */ HAL_TIM_Encoder_Start(&TIM_EncoderHandle, TIM_CHANNEL_ALL); } /** * @brief 编码器接口初始化 * @param 无 * @retval 无 */ void Encoder_Init(void) { Encoder_GPIO_Init(); /* 引脚初始化 */ TIM_Encoder_Init(); /* 配置编码器接口 */ } /** * @brief 定时器更新事件回调函数 * @param 无 * @retval 无 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { /* 判断当前计数器计数方向 方向代表电机方向 */ if(__HAL_TIM_IS_TIM_COUNTING_DOWN(&TIM_EncoderHandle)) /* 下溢 */ Encoder_Overflow_Count--; else /* 上溢 */ Encoder_Overflow_Count++; } /*********************************************END OF FILE**********************/
-
ng服务记忆发行
2021-03-03 03:10:40节点v12.18.2 前提条件 它使用@angular/localize 。 它被配置为使用ES5。 它加载大对象。 在此存储库中, encoding-japanese库具有用于转换编码的大对象。 配置为生成源地图(默认) 结果 使用localize以及ES5和... -
熵编码原理
2021-05-26 15:34:31熵编码原理一.熵编码原理1.原理介绍2.常见方案3.整数位元法4.熵编码模型二.熵编码CABAC介绍1.二进制化2.上下文建模3.二进制算术编码常规编码区间重归一化旁路编码 一.熵编码原理 1.原理介绍 熵编码即编码过程中按熵... -
编码器分类及原理和测速应用(含代码)
2021-09-13 18:48:18文章目录杂谈前言一、何为编码器二、编码器的分类1、增量式编码器2、绝对式编码器3、霍尔编码器三、带编码器的直流减速电机详解1、直流减速电机的概念2、如何运用编码器进行测速3、脉冲数转变成速度值方法4、程序... -
STM32-增量式旋转编码器测量
2021-02-05 12:10:03一、增量式旋转编码器 二、硬件设计 三、软件设计 Developmentkit:MDK5.14 IDE:UV4 MCU:STM32F103C8T6 回到顶部 一、增量式旋转编码器 1、简介 编码器(encoder)是将信号(如比特流)或数据进行编制... -
编码器的工作原理
2019-11-12 09:03:37最近公司项目用到了编码器 选用的编码器 为360脉冲 为了方便其一圈发360个脉冲 ,当然精度只有一度 ,如果为了高精度可以选用其他类型的 首先简述一下编码器的工作原理 编码器可按以下方式来分类。 1、按码盘的... -
苹果CMSV10整合aliplayer播放器/带记忆播放
2021-02-21 23:41:20aliplayer 阿里播放器的记忆功能很给力,这篇整合教程加了阿里播放器的记忆功能,去除了弹幕,资源预加载等功能。 使用方法: 1、进入[后台],点击顶部到导航[视频],选择左边导航中的[播放器],点击[添加] 状态:... -
三笔输入法 v2.2 官方免费版.zip
2019-07-13 13:29:39三笔输入法是一款将音码、形...6、提供5个简易输入:一种真正使用简单、易学、易记的五笔画输入法,您不需记忆繁琐的字根和编码,只要您会写字就会打字,一分钟学会电脑打字,揭开打字的神秘面纱。 三笔输入法功能截图: -
Ruby小狗v-000
2021-02-20 03:28:40Ruby记忆实验室 学习目标 使用类变量来跟踪创建的类的每个实例 编写一个类方法以访问存储在类变量中的所有类实例的列表 介绍 政府已决定开始追踪每只新出生的小狗,就像我们追踪每一个有出生证明的新孩子一样。 因为... -
编码器杂谈 —— 关于绝对值与绝对式编码器的混淆
2019-07-12 21:25:09旋转编码器是工业中重要的机械位置角度、长度、速度反馈并参与控制的传感器,旋转编码器分增量值编码器、绝对值编码器、绝对值多圈编码器。 从外部接收的设备上讲(如伺服控制器、PLC),增量值是指一种相对的位置... -
DNA编码
2017-12-27 14:42:19DNA编码的学习—-笔记1 虽然一万个不想学这个东西,但还是要先了解一些。书名《DNA编码序列的设计与优化》 第一章 DNA的计算 主要讲了DNA计算相关的内容。 首先说了DNA为什么出现,分子水平的研究成熟,数学上... -
预编码的基本原理
2019-01-08 18:01:05预编码的基本原理 TD-LTE下行传输采用了MIMO-OFDM的物理层构架,通过最多4个发射天线并行传输...LTE的物理层处理过程中,预编码是其核心功能模块,物理下行共享信道的几种主要传输模式都是通过预编码实现的。 在... -
笔画输入法 v2.9
2019-11-01 07:31:35笔画输入法是目前最简单易学的一种汉字输入法。...成为 一种真正使用简单、易学、易记的五笔画输入法,您不需记忆繁琐的字根和编码,只要您会写字就会打字,一分钟学会电脑打字,揭开打字的神秘面纱。 -
全能五笔 v2.2
2019-11-01 08:50:537、使用键盘 Ctrl+~ 启动在线造词,输入一词组后,使用键盘 Ctrl+~ 结束在线造词,则刚才所输入的词组自动被赋予正确的编码而被系统记忆。在线造词过程中,无法人工干预造词词组编码。8、动态码长功能。如:三码唯一... -
几种常用的相对位置编码
2021-11-02 17:56:26绝对位置编码 绝对位置编码一般形式的带绝对位置编码的Attention形式如下: {qi=(xi+pi)WQki=(xi+ki)WKvi=(xi+vi)WVai,j=softmax(qikjT)oi=∑jai,jvj \left\{ \begin{aligned} q_i & = &(x_i+p_i)W_Q \\ k_i... -
预编码技术
2017-10-26 19:21:39预编码的基本原理TD-LTE下行传输采用了MIMO-OFDM的物理层构架,通过最多4个发射天线并行传输多个(最多4个)数据流,能够有效地提高峰值传输速率。LTE的物理层处理过程中,预编码是其核心功能模块,物理下行共享信道... -
文本替换专家 v5.0
2018-07-26 09:06:14智能准确的区分ANSI、UTF-8(包括无BOM的UTF-8)、Unicode、UTF-32等多种文件编码。 特有的文件检索引擎、跟踪引擎以及线程控制机制使文件批量处理更高效,更快速。 支持以ZIP压缩包的方式进行文件备份,避免产生... -
紫光华宇拼音输入法 v5.0
2019-11-01 13:13:12双拼输入时可以实时提示双拼编码信息,无需记忆。大容量精选词库,收录8万多条常用词、短语、地名、人名以及数字,优先显示常用字词,而字词的使用频度(词频〕则从一亿七千万字语料中统计而来。支持GBK大字符集。... -
增量式(相对式)编码器与绝对式编码器工作原理
2021-01-29 19:21:28增量式(相对式)编码器与绝对式编码器工作原理增量式编码器工作原理绝对式编码器工作原理 增量式编码器工作原理 绝对式编码器工作原理 -
编码器及编码器在SMART200中的使用
2020-10-24 11:19:01二、工作方式不同 1、增量式编码器:以转动时输出脉冲,通过计数设备来知道其位置,当编码器不动或停电时,依靠计数设备的内部记忆来记住位置。 2、绝对值编码器:由机械位置确定编码,无需记忆,无需找参考点,... -
格雷码的编码和译码算法.doc
2020-12-20 18:53:23格雷码的编码和译码算法格雷码(Golay Code)的编码和译码算法格雷码在通信中应用广泛。例如早在1980年俄罗斯航天仪表码研究所为了提高“星一地”、“地一星”链路数字指控信息的可靠性,研制和实现了格雷码的编码器和...