ESPIDF-PWM
ESPIDF-PWM概述ESP32 有两个模块可以产生PWM。一个是 MCPWM ,另一个是 LED_PWM。
MCPWM电机控制脉宽调制器(MCPWM)外设用于电机和电源控制。它提供了六个 PWM 输出,可在几种拓扑结构中运行。常见的拓扑结构之一是用一对 PWM 输出来驱动 H 桥以控制电机旋转速度和旋转方向。MCPWM 的时序和控制资源分为两种主要类型的模块:PWM 定时器和 PWM 操作器。每个 PWM 定时器提供定时参考,可以自由运行,或同步到其他定时器或外部源。每个 PWM 操作器具有用于为一个 PWM 通道生成波形对的所有控制资源。MCPWM 外设还包含专用捕获模块,用于需要精确定时外部事件的系统。ESP32 有两个 MCPWM 外设,分别是 MCPWM0 和 MCPWM1。它们的控制寄存器分别位于从地址 0x3FF5E000 和 0x3FF6C000 开始的 4 KB 内存中。
LED_PWMLED_PWM 主要用于控制 LED 的亮度和颜色,也可以产生 PWM 信号用于其他用途。LED_PWM 有 16 路通道,即 8 路高速通道和 8 路低速通道。这 16 路 ...
ESPIDF-定时器
ESPIDF-定时器概述ESP32 内置 4 个 64-bit 通用定时器。每个定时器包含一个 16-bit 预分频器和一个 64-bit 可自动重新加载向上/向下计数器。ESP32 的定时器分为 2 组,每组 2 个。TIMGn_Tx 的 n 代表组别,x 代表定时器编号。
功能描述16-bit 预分频器每个定时器都以 APB 时钟(缩写 APB_CLK,频率通常为 80 MHz)作为基础时钟。16-bit 预分频器对 APB 时钟进行分频,产生时基计数器时钟(TB_clk)。TB_clk 每过一个周期,时基计数器会向上数一或者向下数一。在使用寄存器 TIMGn_Tx_DIVIDER 配置分频器除数前,必须关闭定时器(清零 TIMGn_Tx_DIVIDER)。定时器使能时配置预分频器会导致不可预知的结果。预分频器可以对 APB 时钟进行 2 到 65536 的分频。具体来说,TIMGn_Tx_DIVIDER为 1 或 2 时,时钟分频器是 2;TIMGn_Tx_DIVIDER 为 0 时,时钟分频器是 65536。如 TIMGn_Tx_DIVIDER 为其他任意值,时钟会被相同数 ...
ESPIDF-GPIO
ESPIDF-GPIO管脚配置1esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)
Configure GPIO’s Mode, pull-up, PullDown, IntrTypepGPIOConfig 为配置管脚的结构体指针
找到 gpio_config_t 如下所示:
1234567typedef struct { uint64_t pin_bit_mask; /*!< GPIO pin: set with bit mask, each bit maps to a GPIO */ gpio_mode_t mode; /*!< GPIO mode: set input/output mode */ gpio_pullup_t pull_up_en; /*!< GPIO pull-up */ ...
FPGA-verilog
FPGA-verilog数据类型常量
整数:整数可以用二进制 b 或 B,八进制 o 或 O,十进制 d 或 D,十六进制 h 或 H 表示。例如:8’b00001111 表示 8 位位宽的二进制整数,4’ha 表示 4 位位宽的十六进制整数。
x 和 z:x 代表不定值,z 代表高阻值。例如:5’b00x11,第三位不定值,3’b00z 表示最低位为高阻值。
下划线:在位数过长时可以用来分割位数,提高程序可读性,如 8’b0000_1111
参数 parameter:parameter 可以用标识符定义常量,运用时只使用标识符即可,提高可读性及维护性,如定义 parameter width = 8 ; 定义寄存器 reg [width-1:0] a; 即定义了 8 位宽度的寄存器。Parameter 可以用于模块间的参数传递,而 localparam 仅用于本模块内使用,不能用于参数传递。localparam 多用于状态机状态的定义。
变量
wire型wire 类型变量,也叫网络类型变量,用于结构实体之间的物理连接,如门与门之间,不能储存值,用连续赋值语句 a ...
ESP32上的FreeRTOS学习(3)
ESP32上的FreeRTOS学习(3)看门狗简介看门狗其实就是一个定时器,从功能上说它可以让微控制器在程序发生意外(程序进入死循环或跑飞)的时候,能重新回复到系统刚上电状态,以保障系统出问题的时候可以重启一次。说的简单一点,看门狗就是能让程序出问题时能重新启动系统。
ESP32看门狗ESP32有两个核心,每个核心都有对应的看门狗。当RTOS调度器开始工作后,为了保证至少有一个任务在运行,空闲任务被自动创建,占用最低优先级(0优先级),这就是IDLE任务。而核心1上还运行着 loopback 任务,包括了 setup() 和 loop()。
core0:IDLE (优先级0)
core1:IDLE (优先级0)、loopback(优先级1)。
默认情况下只有 core0 的 IDLE任务开启了看门狗。
关闭看门狗12disableCore0WDT();disableCore1WDT();
添加看门狗12esp_err_t esp_task_wdt_add(TaskHandle_t handle);esp_task_wdt_add(NULL); // NULL代表本任务
喂狗 ...
ESP32上的FreeRTOS学习(2)
ESP32上的FreeRTOS学习(2)绝对延时相对延时:每次延时都是从执行函数vTaskDelay()开始,直到延时指定的时间结束。绝对延时:每隔指定的时间,执行一次调用vTaskDelayUntil()函数的任务。区别:个人理解,假如一个任务执行完成需要1ms,每10ms要执行一次。使用相对延时的话,就是延时10ms再加上执行任务的1ms,整个过程需要11ms,如果有其他更高优先级的任务,时间还需要更多;而对于绝对延时,这个1ms的任务是在10ms内完成的。
12345678910void TimingTask(void* param){ const TickType_t task_frequency = 2000; TickType_t last_wake_time = xTaskGetTickCount(); // 自动更新 while(1) { Serial.println(last_wake_time); vTaskDelayUntil(&last_wake_time,task_frequ ...
结构体--字节对齐/位域
结构体–字节对齐/位域字节对齐字节对齐规则结构体如下所示:
12345typedef struct A { char a; int b; short c;};
按理来说,char占用1个字节,int占用4个字节,short占用2个字节,因此总共占用7个字节。但实际上,运行下列代码:
123456789int main(){ A x; printf("%d \n",sizeof(x.a)); printf("%d \n", sizeof(x.b)); printf("%d \n", sizeof(x.c)); printf("%d \n", sizeof(x)); return 0;}
得到:字节对齐需满足以下规则:
结构体变量的首地址能够被其最宽基本类型成员的大小所整除。
结构体每个成员相对结构体首地址的偏移量(offset)都是自身有效对齐字节数的整数倍。
结构体内变量的自身有效对齐字节数为自身对齐字节数与系统对齐字节数的较小者;结构体的大小为 ...
图像处理-阈值分割
图像处理-阈值分割
排序算法
排序算法冒泡排序思路两两元素相比,前一个比后一个大就交换,直到将最大的元素交换到末尾位置。这是第一趟。一共进行n-1趟这样的交换将可以把所有的元素排好。
代码123456789101112131415void BubbleSort(int *arry,int num) // 小到大{ for (int i = 0; i < num-1; i++) { for (int j = 0; j < num-1; j++) { if (*(arry + j) > *(arry + j + 1)) { int temp = *(arry + j); *(arry + j) = *(arry + j + 1); *(arry + j + 1) = temp; } } }}
特性总结
时间复杂度:O(N^2)
空间复杂度:O(1)
稳定性:稳定
插入排序思路把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个 ...
函数传递动态内存
函数传递动态内存问题1234567891011void GetMemory(char *p, int num){ p = (char *)malloc(sizeof(char) * num);}int main(){ char* str = NULL; GetMemory(str, 10); return 0;}
运行时报错 str 为 NULL。函数中的参数p是复制原有指针的值,而不是原来的指针,所以即使p重新指向新的地址,但原来的指针指向的地址仍然不变。
解决应该采用二级指针。传递str的地址给函数。
1234567891011void GetMemory(char **p, int num){ *p = (char *)malloc(sizeof(char) * num);}int main(){ char* str = NULL; GetMemory(&str, 10); return 0;}
或者可以改成用函数返回值来传递动态内存。
...