问题标签 [pic]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 处理 1-256 字节的函数的最佳实践
我有一些旨在处理 1-256 字节的函数,在嵌入式 C 平台上运行,其中传递一个字节比传递一个 int 更快、更紧凑(一条指令对三条指令),它的首选编码方式是什么:
- 接受一个 int,如果为零则提前退出,否则将计数值的 LSB 复制到一个无符号字符并在 do {} while(--count); 中使用它 循环(参数值 256 将被转换为 0,但会运行 256 次)
- 接受一个无符号字符,如果为零则提前退出,并有一个 256 字节的特殊版本的函数(这些情况将提前知道)。
- 接受一个无符号字符,如果为零则运行 256 次。
- 有一个像上面这样的函数,但是通过表现为 (0-255) 和 (256 only) 的包装函数调用它。
- 具有与上述类似的函数,但通过行为为 (0-255) 和 (256 only) 的包装宏调用它。
预计系统繁忙时,函数的内循环大概占处理器执行时间的15%-30%;它有时用于少量字节,有时用于大字节。该函数使用的内存芯片具有每个事务的开销,我更喜欢让我的内存访问函数在内部执行 start-transaction/do-stuff/end-transaction 序列。
最有效的代码是简单地接受一个 unsigned char 并将参数值 0 视为执行 256 字节的请求,依靠调用者来避免任何意外尝试读取 0 字节。不过,这似乎有点危险。其他人是否在嵌入式系统上处理过此类问题?他们是如何处理的?
编辑 平台是一个PIC18Fxx(128K代码空间;3.5K RAM),连接到一个SPI闪存芯片;当预期更少时读取 256 字节可能会超出 PIC 中的读取缓冲区。写入 256 字节而不是 0 会损坏闪存芯片中的数据。如果不检查忙状态,PIC 的 SPI 端口被限制为每 12 个指令次一个字节;如果这样做会慢一些。典型的写事务除了要接收的数据外,还需要发送 4 个字节;读取需要一个额外的字节用于“SPI 周转”(访问 SPI 端口的最快方法是在发送下一个字节之前读取最后一个字节)。
编译器是 HiTech PICC-18std。
我一般都喜欢 HiTech 的 PICC-16 编译器。HiTech 似乎已经将他们的精力从 PICC-18std 产品转移到了编译时间更慢的 PICC-18pro 系列,似乎需要使用 3 字节“const”指针而不是 2 字节指针,并且有关于内存分配的自己的想法。也许我应该多看看 PICC-18pro,但是当我尝试在 PICC-18pro 的 eval 版本上编译我的项目时,它不起作用,我也没有弄清楚为什么——也许是关于可变布局的一些不同意我的 asm 例程——我一直在使用 PICC-18std。
顺便说一句,我刚刚发现 PICC-18 特别喜欢 do {} while(--bytevar); 尤其不喜欢 do {} while(--intvar); 我想知道编译器在生成后者时的“思维”是什么?
编译器加载一个指向变量的指针,甚至不使用 LFSR 指令(需要两个字),而是使用 MOVLW/MOVWF 的组合(需要四个字)。然后它使用这个指针进行递减和比较。虽然我承认 do{}while(--wordvar); 不能产生像 do{}while(wordvar--); 这样好的代码 该代码比后一种格式实际生成的要好。进行单独的递减和while-test(例如while (--lpw,lpw))会产生合理的代码,但看起来有点难看。后递减运算符可以为向下计数循环产生最佳代码:
但它反而会生成比 --lpw 更糟糕的代码。最好的代码是向上计数循环:
但编译器不会生成它。
编辑 2 我可能使用的另一种方法:为字节数分配一个全局 16 位变量,并编写函数,使计数器在退出前始终归零。那么如果只需要一个 8 位的值,则只需要加载 8 位。我会使用宏来处理东西,以便可以调整它们以获得最佳效率。在 PIC 上,对已知为零的变量使用 |= 永远不会比使用 = 慢,而且有时更快。例如, intvar |= 15 或 intvar |= 0x300 将是两条指令(每种情况只需要处理结果的一个字节,而可以忽略另一个);intvar |= 4(或 2 的任何幂)是一条指令。显然在其他一些处理器上, intvar = 0x300 会比 intvar |= 0x300; 快 如果我使用宏,它可以适当地调整。
c - 按位运算
我理解对了吗?
11111111 0 或 1 或 2 的算术左移两位
方法:
亲切的问候,索尼特
input - 为输入和输出配置 PIC 引脚
我正在开发一个使用 PIC24FJ64GA002 单片机的项目。我正在研究一种位敲击串行通信功能,它将使用一根线发送数据,然后切换到接收模式以在同一引脚上接收数据。一个单独的引脚将用于时钟,它总是由不同的板控制(总是一个输入)。我想知道有没有一种方法可以将引脚配置为集电极开路操作,它可以用作输入和输出,还是每次从读取到写入时我都必须更改引脚配置?
controller - 对游戏控制器进行编程
我希望使用控制器来操作水下机器人。我想使用带有多个按钮的操纵杆。我想对图片进行编程并制作自己的电路板。我没有使用电脑。我在哪里寻找有关编程图片的帮助?
谢谢,
科里
algorithm - 将数据发送到串口的最佳方式是什么?
这与微控制器有关,但考虑将其发布在这里,因为这是算法和数据类型的问题,而不是任何硬件问题。我会解释这个问题,以便没有任何硬件知识的人仍然可以参与:)
在微控制器中有一个 10 位分辨率的模数转换器。(它将输出一个介于 0 和 1023 之间的值)
我需要使用串行端口将此值发送到 PC。
但是一次只能写入 8 位。(您需要写入字节)。这是微控制器的限制。
所以在上述情况下,至少我需要发送 2 个字节。
我的 PC 应用程序只是读取一系列数字进行绘图。所以它应该捕获两个连续的字节并重新构建数字。但是在这里我们也需要一个分隔符。但定界符仍然具有 0 - 255 之间的 ascii 值,那么它将混淆该过程。
那么最简单的方法是什么?我应该将值作为字符序列发送吗?
总之,我需要以最快的方式通过 Serial 发送一系列 10 位数字。:)
usb - Pic to PIC 和 PC USB 怎么转?
我想制作一个应用程序,PIC18F4550 通过 USB 将其内部 eeprom 数据发送到 pc。我还想使用相同的 USB 连接器通过 USB 将数据下载到另一个 PIC18F4550。
如何为此目的使用 ccs 示例代码的 ex_usb_serial.c。如果有人可以给我原理图以及在PC端做什么。在这方面的早期帮助将不胜感激。
最好的问候丹妮
c - PIC18F 发送数据快速锁定
我正在使用 PIC18F 并尝试通过超级终端发送数据。当我通过每半秒按下一个键以慢速发送数据时,它会接收数据并正确回显它,但是当我开始以更快的速度按下键时,MCU 会锁定。不知道是什么原因造成的。
在 PIC 和超级终端上,波特率都是 2400。
这是我们的接收循环。sendData 只是我们发送说“已收到”的调试代码。这就是我们知道它何时冻结的方式。
它不会每次都以相同数量的循环冻结,这仅取决于我们输入数据的速度。
controller - 编写将使用 xbox 控制器和图片来控制电机的程序
我正在寻找有关编写 ac 代码程序的建议,该程序将使用 xbox 控制器和 pic 来激活电机。有人对从哪里开始有建议吗?
谢谢,
bit-manipulation - 如何旋转单词中的位
我正在使用 dsPIC33F 和 GCC。我想将一个单词中的位向左或向右旋转一次,如下所示:
(如果不清楚,LSB 移动到 MSB 的位置进行右旋转,反之亦然。)
我的处理器已经有一个右旋转(rrnc,rrc)和左旋转指令(rlnc,rlc),所以我希望编译器会优化它。如果没有,我可能不得不使用内联汇编。
python - py连续读取3次后冻结
我们正在对图片进行编程,并且我们已经诊断出,如果我们在尝试向我们发送数据时将数据发送到串行端口,则程序将锁定(我们的 python 代码和超级终端在测试时都会崩溃)。它在超级终端中工作并缓慢输入(笔画之间>.5 秒),并且在敲击键盘时会崩溃。所以我们所做的是引入一个超过 0.5 秒的 time.sleep,但它仍然无法正常工作。
这是我们的测试代码。
我们的接收数据功能。我们过去每次收到一个字符时都会发送“ok”(这就是我们知道它在 3 次迭代后冻结的方式)。我们把它带到了循环之外,看看这是否导致了问题,但事实并非如此。它根本没有用这个代码发送“ok”。