与ARM微控制器的串行通信
我正在尝试通过USB将数据从ARM CORTRX M4微控制器发送到PC.有一个程序在CodeBlocks IDE中以C ++语言编写.基本上,程序设置了串行通信设置,并使用ReadFile函数读取数据. 问题是,即使PC Pro图和微控制器中的波特率相同,我也在输出处获得垃圾值. 我该如何解决这个问题? PC程序如下所示. #include #include int main(void) { HANDLE hComm; // Handle to the Serial port char ComPortName[] = "\\\\.\\COM51"; // Name of the Serial port to be opened, BOOL Status; // Status of the various operati
2 2024-04-10
编程技术问答社区
重新启动后的位域keil硬故障
当我在闪烁设备后使用此结构时,它运行良好,但是在使用此结构(分配到任何位)重新启动(打开/关)后,会导致硬故障IRQ.我将Keil Uvision与STM32F205一起使用.为什么它不起作用?我应该更改/删除/添加以修复它?直接使用gpioc-> odr不会引起任何问题,kail中的bitfields有什么问题? #pragma anon_unions typedef union { struct { __IO uint16_t Data_Bus:8; // 0-7 data bus __IO uint16_t Ctr_Pins:6; // 8-13 control pins __IO uint16_t :2; // 14-15 unused here }; struct { __IO uint16_t D0:1; // 0 data bus pin
4 2024-04-09
编程技术问答社区
如何在STM32F103C8T6上做裸机LED闪烁?
我刚刚开始探索STM32 MCUS.我想在Bluepill(具有STM32F103C8T6 MCU)板上眨眼.我怀疑我被某件事误导了.根据F1系列的参考手册,有3个主要步骤: 启用端口时钟(there portc) 配置CNF/模式寄存器 根据需要配置ODR寄存器,即引脚上的高/低. 我按照手册编写了Keil MDK的代码,但是在加载后,代码不运行,我按重置按钮,然后LED打开,即使我更改了设置为重置&在keil 中运行. 这是参考手册的代码和部分. #include int main(){ RCC->APB2ENR |= 1CRH |= (1ODR |= 0x00002000; for(int i = 0; i
0 2024-04-09
编程技术问答社区
将外部静态库的片段放置到特定位置
我的应用程序调用一些放置在外部静态库中的功能.我将外部静态库链接到我的应用程序,并且一切都起作用(在这种情况下,我正在使用GCC). 然而,链接器选择了文本,.data和.bss部分的文本的位置(地址).我可以通过修改链接脚本来选择/更改其位置,但是由于我必须指定库的所有功能,变量等,这很乏味.我的意思是: . = 0x1000; /* new location */ KEEP(*(.text.library_function1)); KEEP(*(.text.library_function2)); [...] 另一种解决方案是通过为每个函数/变量放置A e节属性来构建外部库,然后通过重新定位整个部分来修改链接器.类似: /* C source file */ unsigned char __attribute__((section (".myLibrarySection"))) variable1[10]; unsigned char __attribute__
0 2024-04-08
编程技术问答社区
C代码中的内联汇编语句和针对ARM Cortex架构的扩展ASM
我试图用 ARM编译器5 对以下两块代码进行微处理器: : 第1部分: static inline void cp15_write_sctlr(uint32_t value) { asm("mcr p15, 0, %0, c1, c0, 0" :: "r"(value)); } static inline uint32_t cp15_read_actlr(void) { uint32_t actlr; asm("mrc p15, 0, %0, c1, c0, 1" : "=r"(actlr)); return actlr; } 第2部分: static inline void dmb(void) { asm("dmb" ::: "memory"); } static inline void dsb(void) { asm("dsb" ::: "memory"); } static inline void isb
0 2024-04-07
编程技术问答社区
如何在Cortex-M3(STM32)上从RAM中执行一个函数?
我正在尝试在Cortex-M3处理器(STM32)上执行RAM的功能.该功能擦除并重写内部闪光灯,因此我绝对需要在RAM中,但是我该怎么做? 我尝试的是:使用memcpy将函数复制到RAM中的字节数组(检查是否正确对齐),将功能指针设置为指向字节数组,然后调用函数(指针). 这可能对10个说明效果很好(我可以使用调试器遵循执行),但随后我会得到一个总线错误,并且处理器重置.总线误差发生在第二次通过的循环中,因此代码应该很好(因为它在第一个通过时起作用).我认为更快的RAM访问以某种方式增加了公交车的时间... 无论如何是否有正确的方法?散点文件看起来会如何自动将功能自动放置(我正在使用Cortex-M3的Keil Uvision)? 编辑:更多信息: 工具链:Realview MDK-ARM v 4.10 编译器:ARMCC v4.0.0.728 汇编器:Armasm v4.0.0.728 链接器:Armlink v4.0.0.728 处理器:STM32F103Z
0 2024-04-07
编程技术问答社区
链接器如何知道一个外部函数的定义在哪里?
我读了几篇文章,并得出结论,Extern告诉编译器:"此功能存在,但是它的代码在其他地方.不要惊慌."但是链接器如何知道函数的定义位置. 我的案子: - 我正在使用Keil Uvision 4.有一个标题文件grlib.h,主要功能在grlib_demo.c中(其中包括grlib.h).现在,有一个函数grcircledraw(),该函数在circle.c中定义并在grlib_demo.c中调用,还有一个语句 extern void grcircledraw(所有参数); 在grlib.h中.我的查询是链接器如何知道grcircledraw()的定义是因为Circle.c不包含在grlib.h和grlib_demo.c 中. 注意: - 文件grlib.h和circle.c在同一文件夹中.代码成功运行. 解决方案 简单的答案是"编译器不需要知道,但是链接器必须能够找到它".通过多个.o文件,或通过库,链接器必须能够找到GrCircleDraw函数的单个定义.
0 2024-04-07
编程技术问答社区
如何在C语言中把无符号字符打印成2位数的十六进制值?
我试图将未签名的字符值打印为2位十六位值,但始终将结果视为4位六位数值,不确定我的代码有什么问题. // unsigned char declaration unsigned char status = 0x00; // printing out the value printf("status = (0x%02X)\n\r", (status |= 0xC0)); 我期望将2位数字结果作为0xC0,但是我总是得到0xC0FF. 同样,当我尝试打印出与%bu格式标识符的无符号字符相同的变量(状态)时,我将输出作为255. . 您如何仅将两个十六进制字符作为输出? 据我所知, 解决方案 keil c Compiler 完全符合C标准.如果是这样,很可能不会完全遵循将char值传递给variadic函数之类的标准促销规则;在8位CPU上,没有自动将8位值扩展到16位或更多的性能优势. 作为解决方法,您可以在将参数传递给printf之前明确截断高阶位.尝试以下
2 2024-04-07
编程技术问答社区
为什么编译器没有警告我有一个空的if语句?
我正在使用我写了以下有意代码: if(condition matched) { // Do something } 当我重建项目时,我收到0个错误,0个警告. 但是,当我偶然地写道: if(condition matched); { // Do something } 我也有0个错误,0个警告. 我几乎不可能发现之后的小;如果条件是问题的根源. 为什么编译器不将其视为警告并通知我? 解决方案 这不是错误,因为一个空语句是有效的语句;但是,由于它当然是可疑的代码,因此是编译器警告的理想候选者 - 实际上,gcc -Wall -Wextra确实警告了: int foo(int x) { if(x); { return 42; } return 64; } /tmp/gcc-explorer-compiler116427-37-l1vpg4/example.cpp: In function 'int foo(i
0 2024-04-06
编程技术问答社区
如何在Stellaris的程序间跳转
我正在为Stellaris LM3S1607芯片的启动加载程序工作. 我正在使用Keil Microvision4 C编译器. 这个想法是创建2个独立固件,一个固件将更新另一个. 在固件中,我下载了固件2文件,然后将其写入地址0x3200中的Flash.直到这里起作用.我还验证了数据正在编写以正确闪烁. 现在我有两个应用程序.一个是我的UIP启动加载程序,SeonCD是我的主要项目. 我想知道如何从第一个程序跳到0x3200的第二个程序. 如果有人可以帮助我跳,它将很棒. 谢谢 解决方案 这将在任何Cortex-M Part ... 上使用 创建一个汇编功能,例如: __asm void boot_jump( uint32_t address ) { LDR SP, [R0] ;Load new stack pointer address LDR PC, [R0, #4] ;Load new program counter addres
0 2024-04-06
编程技术问答社区
我如何在arm inline汇编中访问本地C变量?
我想访问内联臂组件中C中声明的本地变量.我该怎么做? 可以这样访问全局变量, int temp = 0; Function(){ __asm( ".global temp\n\t" "LDR R2, =temp\n\t" "LDR R2, [R2, #0]\n\t" ); } 但是如何访问本地变量?我尝试将" .global"更改为"局部变量". 我正在使用的IDE是keil. 有什么想法吗? 预先感谢. 解决方案 根据GCC文档:您可以通过这样的值: #include int main(int argc, char *argv[]) { int src = 1; int dst; asm ("mov %1,
0 2024-04-06
编程技术问答社区
如何在内存中给定的绝对地址放置一个变量(用GCC)。
Realview ARM C编译器支持在给定的内存地址放置一个变量使用变量属性at(address): int var __attribute__((at(0x40001000))); var = 4; // changes the memory located at 0x40001000 GCC是否具有类似的变量属性? 解决方案 我不知道,但是您可以轻松地创建这样的解决方法: int *var = (int*)0x40001000; *var = 4; 不是完全一样的 完全是相同的东西,而是在大多数情况下是完美的替代品.它将与任何编译器一起使用,而不仅仅是GCC. 如果您使用GCC,我认为您还使用 gnu ld (当然,这不是确定的),LD支持放置变量您想要他们. 我想让链接器做那个工作很普遍. 受@Rib的答案启发,我补充说,如果绝对地址是某些控制寄存器,我将在指针定义中添加volatile.如果只是ram,那没关系. 其他解决
0 2024-04-06
编程技术问答社区
Cortex M3的引导程序
我正在使用MBED(带有Cortex M3 CPU)的LPC 1768板,并且我正在尝试在这里实现一些目标,主要是从SD卡升级用户应用程序,我正在编写两个程序,首先是Bootloader/nano--内核和用户应用(Helloworld将为开始): bootloader/nano-kernel在0x00地址运行时,它将进行一些检查,并最终在SD卡上获取二进制文件 bootloader/nano-kernel将在地址0x9000复制此二进制文件(可能以后必须更改,但是Bootloader/Nano-Kernel不使用此空间,因此应该可以是可以的) ) Bootloader在0x9000 + 4 跳到用户应用程序 SD卡非常容易锻炼,我在跳跃部分有问题.这是跳跃功能的代码. void run(void) { void (*user_code_entry)(void); unsigned *p; SCB->VTOR = (USER_FLASH_S
0 2024-04-02
编程技术问答社区
如何在ARM7中进行原子式比较和交换?
我想修改一个全局变量,该变量由RTO中的不同任务和IRQ上下文共享.因此,我需要在原子上修改此变量. 在我当前的实现中,我一直在使用enable_irq/disable_irq函数来原子修改语句. extern int g_var; void set_bit_atomic(int mask) { disable_irq(); g_var |= mask; enable_irq(); } 我已经在GCC __sync_bool_compare_and_swap函数>文档作为原子操作的助手. 我当前的工具链是Keil MDK,我想切换到下面显示的方法, void set_bit_atomic(int mask) { volatile int tmp; do { tmp = g_var; } while (!__sync_bool_compare_and_swap(&g_var, tmp, tmp | ma
2 2024-03-18
编程技术问答社区
字面意义上的游泳池太遥远了?
我正在keil Uvision 5环境中的自由kl46z板上编写手臂组装语言.我的代码非常冗长,但是在代码的主要部分,每当我尝试加载(ldr)常数或变量时,我都会得到此错误: 错误:A1284E:字面的池太远,使用ltorg在4KB 内组装它 我不知道这意味着什么或如何修复它.错误发生的位置都在类似的指令上.例如,第一个错误是在读取的指令上: ldr r1,=时间 时间定义为: 时空4 该实例是一个变量,但也发生在定义的常数上.谁能帮我弄清楚如何解决此错误? 解决方案 错误消息或多或少地说明了您需要做的事情.插入一个好地方是在函数的末端(或在函数输入标签之前)出现错误的地方.如果距离超过4K,那么您需要在功能中找到无条件的分支或返回指令.如果没有这样的说明,那么您必须插入一个无条件的分支指令,该指令只能跳过代码中某个地方的LTORG语句.
2 2024-03-17
编程技术问答社区
在ARM汇编中进行数字比较时,是否有一种正确的方法来存储数值?
因此,我正在制作一些能够读取数字列表的代码,将其分为3块,并确定这3个数字中的哪个是最大的.然后,我将从每个块中获取最大的值,然后将它们全部添加在一起. 为此,我将我的值存储在几个寄存器中: MOV r1,#0 ;loop counter MOV r2,#0 ;compare store 1 MOV r3,#0 ;compare store 2 MOV r4,#0 ;compare store 3 MOV r5,#0 ;sum of values MOV r6,#0 ;which was greater in value LDR r8,=data_values ;the list of values 我正在使用 cmp 但是,这些值,但是我不确定我的方法是否正确存储和添加值.目前我得到了这个: MOV r6,CMP r2,r3 ;Moving the comparison value into r6, my store for the greater
0 2024-03-17
编程技术问答社区
什么是非对齐访问?(ARM/Keil)
我正在用keil为臂7编写组装. 我有以下运行时错误: Non-aligned Access: ARM Instruction at 000000F8H, Memory Access at 7F7F7F7FH Data Abort: ARM Instruction at 000000F8H, Memory Access at 7F7F7F7FH 这并没有真正帮助我,因为我不知道"不结盟的访问"是什么(显而易见的是,但我真的不理解它的含义)我 am 尝试访问(存储)到0x7F7F7F7F,这是什么问题? 搜索我只发现了使用C的几个类似问题,并通过某种方式解决了与其代码非常具体的,并且与此问题无关. 我正在做: LDR R0, =0x7F7F7F7F LDR R1, LABEL STR R1, [R0] i然后用不同的标签做类似的事情,R0的偏移,但首先失败. 解决方案 问题是,您用于32位(4字节)内存操作的地址必须与4字节边界对齐.这意味着地
0 2024-03-17
编程技术问答社区
为什么STR只对0x40000000和0x40003FFF之间的地址有效?
代码: dest EQU 0x40000000 AREA name, CODE, READONLY ENTRY MOV r0, #2 LDR r1, =dest STR r0, [r1] stop B stop END 此代码将2的值写入内存位置0x40000000. 当我将其更改为0x20000000时,2未能在那里写入. 0x3fffffff同样的事情.当我将内存位置设置为0x40003fff时,将2个打印到该位置,但是当我将地址更改为0x40004000时,2未能在那里打印.对于任何地址位置,例如0x50000000.因此,根据这些输出,似乎str仅将值写入0x40000000和0x40003fff的有限内存范围. 有人知道为什么是这种情况吗?还是我的代码有问题?我正在使用keil uvision5,nxp lpc2140. 解决方案 我找不到" LPC2140"的数据表,但是我找到了一个看起来像是一个设备家族的数据表,并且您拥有的
4 2024-03-03
编程技术问答社区
如何在Keil中启用链接器MAP文件的生成?
如何启用keil mdk-arm中链接器映射文件的生成 ,在IAR嵌入式工作台中,我使用以下步骤 选项>链接器>列表>检查生成的链接器地图文件. 我试图在MDK-ARM的Keil使用相同的步骤,但它不起作用,任何帮助都将不胜感激 解决方案 project->目标目标名称 ...-> listing tab->链接器列表复选框,请根据需要选择子选项.. P> 也有用: in project->目标目标名称 ...-> Linker Tab-> MISC控件,添加以下内容: --info=summarystack --info=stack 然后,各种堆栈用法分析将包含在地图文件中.
2 2024-03-03
编程技术问答社区