我正在为C中的小8位微控制器编写软件.代码的一部分是读取当前变压器(ZCT)的ADC值,然后计算RMS值.流过ZCT的电流是正弦的,但可能会变形.我的代码如下: float adc_value, inst_current; float acc_load_current; // accumulator = (I1*I1 + I2*I2 + ... + In*In) double rms_current; // Calculate the real instantanous value from the ADC reading inst_current = (adc_value/1024)*2.5; // 10bit ADC, Voltage ref. 2.5V, so formula is: x=(adc/1024)*2.5V // Update the RMS va
以下是关于 microcontroller 的编程技术问答
我想为8051做一个RTO,并且非常困惑,因为在8051中,应遵循哪些最低要求,因为8051在RAM和ROM的情况下具有非常有限的资源.这是公正的作业类型问题,但是我真的很困惑,因为我们为8051制作软件不是OS吗?哪些具有与RTO的微控制器的常规规则编码不同的特征?请帮助谢谢 解决方案 典型的RTO至少提供以下内容: 确定性任务计划 任务同步机制 过程间通信机制 计时器服务 RTOS调度程序通常是基于优先级的,并且先发 - 无论优先任务的状态如何,准备运行的最高优先任务将运行. 有杰克·甘斯(Jack Ganssle)在TechOnline上的RTO基础知识可能对您有用.它是由Micrium赞助的,并使用UC/OS-II作为案例研究,但通常适用于大部分. 特别是8051能够由于其多个寄存器库而具有特别有效的任务上下文切换,可通过单个指令进行切换. 其他解决方案 rtos的功能在很大程度上取决于其执行能力特定的工作以确定性和及时的方式.这些通
是否有可用于微控制器的OpenCV交叉编译器? 谢谢 解决方案 OpenCV交叉编译器? errr ...我"我不确定存在这样的东西!让我们不要混合交叉补偿器(例如 gcc ),使用opencv-是 cross-平台库用于计算机视觉. 但是,如果您是为微控制器编译的 opencv ,您可能会找到与您正在合作的平台的一些预构建的二进制文件,但这些都不是OpenCV开发人员的官方版本. 此线程讨论使用OpenCENCVV时涉及的一些挑战在微控制器上: 您将遇到的主要问题是OPENCV使用浮点数学,而大多数微控制器仅具有固定点乘数,因此您要么必须转换一些OPENCV代码,要么在这些特定处理器上运行浮点仿真,这可能是相当相当的慢. 一些帖子建议其他较少资源消耗的替代品,例如 cviptools . 如果您决定坚持使用OpenCV,则可能对本教程感兴趣:如何在Linux环境中使用CMAKE为ARM Cortex-A8平台构建OpenCV .
我不知道有关电子领域和控制器的很多事情. 但是我想知道如何将OpenCV程序与红色交通信号灯相结合? 我知道答案是微控制器的,但我只知道有一个可以编译为C到十六进制然后使用微控制器的编译器AVR. . 但是OpenCV(我认为我不会在C上运行)很高,并且可能无法与AVR一起使用. 那么,我该怎么办? 根据某些原因,更改我的编程语言和库对我来说是如此困难. 我的程序必须是实时的. 如果有另一个系统(不是控制器和...),它的成本不高,可以运行OpenCV程序,我可以使用它. 如果您需要更多的详细信息,请告诉我. 解决方案 我最初报告了这个问题,如可能的重复需要解决的问题. openCV提供 c接口以及 c ++接口,因为 2.0版.因此,从理论上讲,可以使用C编译器配置和构建OpenCV,但是我不知道这项任务的困难,因为我自己从未做过.请注意,大多数C ++接口仅编码为C接口周围的包装器. 关于实现实时处理,这完全取决于设备的处理能力 算法您选
我正在执行一些微控制器编程,并且我有这些代码: #define F_CPU 8000000 #define F_ADC (F_CPU / 64.0) #define T_ADC (1.0/F_ADC) 是否有一种方法可以打印出在编译时说T_ADC的计算值?我尝试将其串起 #define STRINGIFY(s) XSTRINGIFY(s) #define XSTRINGIFY(s) #s #pragma message ("T_ADC " STRINGIFY(T_ADC)) ,但这只是给出宏扩展"(1/(1/(8000000/64)))",而不是实际值. 这是一个微控制器程序,在启动时进行printf是很尴尬的.我正在使用GCC,如果有帮助,我很乐意使用任何非标准的海湾合作委员会功能. 解决方案 作为@mbratch和@freddie说,该计算是由编译器进行的,因此您无法仅使用预处理器指令获得结果. 现在想到的最简单的方法是将宏分配给全局const,然
我对循环副本的时间有一些问题,我不为什么要花费大量时间来复制小数据大小. 我使用的是PIC24FJ256GL406 MCU,一切都很好,但是当操作UART微控制器运行速度很慢,因为在复制缓冲区数据时发生了一些延迟. 让我用代码和调试日志解释您. 在这里,我正在为UART传输张贴功能.该函数通常仅传输第一个字符,其余字节将在中断常规服务中转移. 我的时钟频率为32MHz,因此外围为16 MHz. 我不明白为什么循环仅用于16个字节数据的副本将近20毫秒.因此,如果数据更多,这次将增加. unsigned int UART1_WriteBuffer(const uint8_t *buffer, const unsigned int bufLen) { //transmit first char U1TXREG = buffer[0]; while (!U1STAbits.TRMT); numBytesWritten = bufLe
我使用 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure); 启用中断,然后使用 NVIC_InitStructure.NVIC_IRQChannelCmd=DISABLE; NVIC_Init(&NVIC_InitStructure); 禁用它.那么如何重新启用中断,使用ICER,ISER或任何其他方法? 解决方案 要在 nvic 中启用和禁用中断,只需使用相关的 cmsis 函数: void NVIC_EnableIRQ(IRQn_Type IRQn); void NVIC_DisableIRQ(IRQn_Type IRQn); 其他解决方案 有CMSIS库函数可以启用中断并禁用中断. 使用void NVIC_EnableIRQ(IRQn_Type IRQn);您可以重新启用残疾人中断. 您需要提及中断的IRQ编号以再次启用它.
目前,我有Atmega8 1MHz微控制器.我正在使用C语言. 因此,基本上我的程序显示了7个段显示器上的数字. 每当您按按钮时,都会增加数字+1 现在,我想测量时间,如果用户按按钮3秒钟.我唯一需要的是如何测量中断到3秒钟. 我需要背后的逻辑,我应该使用if语句吗?或者我不知道其他事情 这是我的代码: #define F_CPU 1000000UL #define IRQ1 INT0_vect #define IRQ2 INT1_vect #include #include #include volatile int the_count = 0; volatile int i; volatile int k; ISR(IRQ1){ if (the_count
我只是想知道它们之间的基本区别. 我在某些地方发现陷阱本质上也被称为软件中断,或者类似于例外. 另外,软件中断和异常之间的基本区别是什么? 软件中断可以通过int指令生成,但是陷阱只能由某些场景(例如Divide ot divide)生成?是的吗? 请为此查询提供合适的答案,该查询涵盖,S/W中断陷阱和异常. 解决方案 术语确实有点模糊,可能取决于CPU供应商. 很明显,硬件中断是由硬件信号触发的,并使CPU输入预定义的ISR.这些是(通常是外部)硬件触发的例外. 陷阱的符号在CPU供应商之间有所不同.非智能CPU can (例如,在68000或PowerPC CPU上)的陷阱是软件中断.这些CPU具有陷阱指令.在x86上,该指令将是iNT xxx,在ARM CPU SWI/SVC上,在PowerPC陷阱#XX上.这将是用户程序故意触发的例外(通常用于输入操作系统) Intel World中的陷阱是特殊条件,例如按零分割或其他错误(例如无
1.问题解释了 我正在尝试将OpenOCD用于罕见的东西.我只想检测 ,而不是连接 我想到的过程看起来像这样: 使用propecon File(例如stlink.cfg)启动openocd,以-f参数.因此,OpenOCD知道要使用什么探针,但不知道会找到什么芯片. openOCD检测芯片并以某种方式报告(例如,写东西给stdout).如果可能的话,此操作不应被芯片侵入(例如重置). openOCD关闭. 这里还有一些有关该过程的注释: 注1:,如果OpenOCD未到达服务器状态我需要设置telnet或gdb客户端以与之交互,那将是不错的选择.我很乐意以更方便的方式报告芯片检测,例如在Stdout频道上获取芯片信息. 注2:检测应对芯片不侵入.但是,如果OpenOCD找不到任何东西,我想拥有一种备份方法,openOCD试图更积极地找到芯片(例如按住nRST pin).如果需要,我可以自己调用另一种方法(因此,无需自动执行此操作). 注3:
我正在使用STM32 Nucleo-F401RE微控制器板. 我有一个扬声器编程,以便在操纵杆上/向下推动操纵杆时更改频率.我的问题是,有时(通常)(通常)操纵杆向上/向下推动频率增加/降低多次,这意味着ISR执行了多次.同样,中断素对象设置为触发上升的边缘,但是有时它在落下边缘(当操纵杆上下推动/向下推动后重新启动为中性时)也会执行.要克服这一点有帮助吗? void upISR() { if (greenLED.getStatus()) { myTicker.detach(); frequency+=200; myTicker.attach(callback(&spkr, &Speaker::toggle), 0.5/frequency); } } ' int main() { InterruptIn up(A2); InterruptIn down(A3);
我有4个8x8 LED矩阵,这些矩阵已连接,我与使用SPI协议进行通信. 重写了一些库( rust实施,), 因为它只是在我的系统上不起作用,而我的代码至少可以工作,所以我只能控制四个连接的显示器中的第一个. 这是我的代码在第一个显示上显示类似图像的目标: 矩阵对象: #![allow(dead_code)] use spidev::Spidev; use std::io::prelude::*; // Maximum number of displays connected in series supported const MAX_DISPLAYS: u8 = 8; // Digits per addr const MAX_DIGITS: u8 = 8; // Possible command register values on the addr chip. #[derive(Clone, Copy)] pub enum Command { N
我正在编写代码,以了解Freescale Kinetis微控制器上的USB外围设备.我设法通过Linux主机进行了枚举,并且可以使用EP0上的供应商-Custom代码发送和接收数据包,并与Libusb测试程序进行交互. 看起来我可以在微控制器上配置其他控制端点(非零端点号),但是我看不到将libusb发送/接收控制传输转移到这些端点的方法. (libusb_control_transfer不需要端点号,尽管libusb_bulk_transfer和libusb_interrupt_transfer do.) 非零控制端点是如此罕见或不必要,以至于不值得打扰它们吗?是否有某种方法可以让Libusb执行控制交易到非零端点? 解决方案 是否有某种方法可以使Libusb执行控制交易到非零端点? 您可以尝试在异步I/O API的libusb_transfer结构中修改endpoint字段. 但是,如果您的微控制器实际上可以支持非零的控制端点,那我会让我感到惊讶.
有许多不同类型的 陷阱 在处理器数据表中列出的,例如BusFault,Memmanage故障,使用故障和地址错误. 他们的目的是什么?如何在故障处理中使用它们? 解决方案 陷阱本质上是次级调用,当处理器检测到您的指令流中的某些不寻常的东西时. (有些处理器使它们进入中断,但这主要只是将更多上下文推向堆栈;如果陷阱包括用户和系统地址空间之间的切换,则会变得更加有趣. 这对于处理很少但需要解决的处理条件(例如零)很有用.通常,在执行除法指令之前,有一对额外的指令在执行分隔指令之前测试零是无用的开销,因为从来没有期望除数为零.因此,建筑师让处理器与实际分隔线并行进行此检查,作为分隔说明的一部分,如果除法器为零,则处理器将处理器陷入截止序列的例程.另一个有趣的案例是非法记忆地址.显然,您不需要编码测试才能在使用每个地址之前检查每个地址. 通常会有各种潜在兴趣的故障条件,而设计的处理器将控制到每种不同类型的故障类型的其他陷阱例程(通常是作为向量设置). 处理器具
我正在处理一个微控制器,而无需硬件乘以划分.我需要为这些基本操作烹饪软件算法,这些操作是紧凑的尺寸和效率的很好的平衡.我的C编译器端口将采用这些算法,而不是C开发人员本身. 我的Google-fu在这个主题上大部分噪音很远. 有人可以指出我的内容吗?我可以使用添加/shift指令.基于桌子的算法也可能对我有用,但是我有点担心在编译器的后端塞满太多...嗯,可以这么说. 解决方案 这是一个简单的乘法算法: 从最右边的乘数开始. 如果乘数中的位为1,请添加乘法 将乘数乘以1 在乘数中移至下一个位,然后返回步骤2. 这是一个分区算法: 如果除数大于股息,请停止. 虽然除数寄存器小于股息寄存器,但向左移动. 移动除数寄存器权利右1. 从股息寄存器中减去除数寄存器,然后以与Divisor寄存器的偏移总数相对应的位,将位更改为结果寄存器中的位. 以原始状态的Divisor寄存器从步骤1开始. 当然,您需要进行支票以
我在rs485端口串行沟通时面临问题. 我正在使用Max485的DSPIC33E微控制器. 使用断点我分析了每当我发送" 0x00" 到控制器时,都会收到" 0xff" .然后,我发送" 0x01" ," 0xfd" 在控制器上收到. 我也尝试使用循环背逻辑,意味着发送收到的字符,但是每次我收到" 0x00" 的任何值时. 我无法理解这个问题.以下是我正在使用的代码的快照: // RS485 TRISBbits.TRISB6 = INPUT_PIN; // RX - RB6/RP38 PIN TRISBbits.TRISB7 = OUTPUT_PIN; // TX - RB7/RP39 PIN TRISBbits.TRISB8 = OUTPUT_PIN; // !RE/DE Control Pin RB8/RP40 PIN // RS485 Config #define RS4
首先,我欢迎对这个问题的标题进行编辑,我想不出如何更好地言语,但我对自己的想法不太满意. 这是关于并发的问题,我的应用程序是在C中的微控制器上,但我认为这无关紧要. 我有一个中断的例程,可以更改两个全局变量的值.我有一些可以读取这些变量的主要代码.但是它必须从两者中获得一致的值,这意味着我无法阅读一个,然后阅读另一个值,因为两者之间可能发生中断并更改两者,这使我从一组中读取一组,另一组读取. 通常,我只会禁用读取两个变量的代码的小部分的中断,但我不能这样做,因为需要在正确的时间在呼叫中没有"抖动"的情况下完全调用中断. 4或5个读取和存储变量的说明将导致中断时机的抖动过多. (我正在中断中生成PAL视频,因此任何时间安排中的任何抖动都会导致屏幕上的像素的可见移动). 我可以重新排列代码以不同的方式执行此操作,以使同一中断对这两件事不负责,从长远来看,我可能会做到这一点,但是这样做是很重要的工作.无论如何,这个问题现在对我来说已经变得有趣了,即使我以后将其进行了回顾以避
作为ISR函数中使用的一般概念全局变量("值"),应声明为挥发性,以避免编译器优化.但是,我的疑问是在ISR中调用的子功能" ISR-SUB"中使用的全局变量,是否还需要将ISR中调用的全局变量使用为挥发性? unsigned int STATUS; // -----> needs to be declared as volatile ? void ISR-SUB() { STATUS = 1; -->accessed in sub function invoked in ISR which will be optimized or not } void ISR () { ISR-SUB(); } void main() { /* interrupt occurred and ISR called */ if (1 == STATUS) { code part } } 解决方案 当然你会. volatile不是ISR的特权,它在
关于如何使用字符串数组元素作为函数的一部分(参数)的任何提示? 我的数组是(继续pic输出端口) string Port[5] = {PORTA.0, PORTA.1, PORTA.2, PORTA.3}; 我想将其顺序将逻辑0发送到端口中的循环中,该端口被指定为数组端口 void loop() { Port[2] = 0x00; // sends 0 to PORTA.1 } 如何在C ++ ?? 中执行此操作 解决方案 您的根本问题是要将一组端口引脚发送到功能. 端口引脚不是字符串 标识符PORTA等不是字符串.它们是图片编译器的保留单词.它们代表可寻址位置(端口或内存映射). 点表示法,PORTA.3,是指端口的一些数字. 计数器示例是将值复制到``port_frog.8''. 您是否尝试使用以下内容: const char port_a_3[] = "PORTA.3"; *port_a_3 = 5; 问
我知道基本的SPI协议及其主人的主人.我想知道可以在多个从属上广播数据吗?如果可能的话,那么它是如何工作的. 我听说,即使您不想使用读取数据,也必须从从属中读取任何SPI从属.如果可以广播,这是如何可能的? 解决方案 不,这是不可能的.由于SPI是4线接口. SS行用于从属选择.一个SPI主人可以具有多个从属,但不能一次选择所有从属,因为它使用一些或SS信号来选择从属(并且不能在一次时间选择多个从属)) . SPI以完整的双工模式(大多数时间和案例)工作,并使用Shift寄存器实现.因此,在编写有关MOSI的数据(假设:主写作)时,我们也将数据获取(在主移寄存器中插入数据确实会将数据转移到从位移寄存器中).因此,我们在TX和RX线上获得数据. 其他解决方案 如果您有多个SPI控制器,则可能.我有四个SPI控制器连接到相同类型的四个不同芯片.我控制软件中的SS,因为SPI控制器无法以有用的方式控制它.我的驱动程序已读,写和广播方法.在一个SPI控制器实例上读写A