简体   繁体   English

C 程序在分配变量时停止执行

[英]C program stops execution when assigning variable

I'm not sure if this is happening when assigning a variable specifically but when debugging the assembly code, the compiler executes RJMP $+0000 where it hangs the program.我不确定在专门分配变量时是否会发生这种情况,但是在调试汇编代码时,编译器会在挂起程序的地方执行RJMP $+0000

EDIT: I added included libraries if that's relevant编辑:如果相关,我添加了包含的库

#define __DELAY_BACKWARD_COMPATIBLE__
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/delay.h>
#include <stdint.h> 

void ReadTemp(uint8_t address){
    
    ADCSRA = ADCSRA | 0b10000111;       //enable ADC, CLK/128 conversion speed
    ADMUX  = ADMUX | 0b01000000;        //Use internal 2.56V Vref and PA0 as input, right-hand justified
        
    ADCSRA |= (1 << ADSC);              //start conversion
        
    while(!(ADCSRA & (1 << ADIF))) {}   // wait until process is finished;

    uint8_t  low_value = ADC & 0x00FF;
// or low_value = ADCL;
    uint8_t high_value = ADC & 0xFF00;   //problem here
...
}

在此处输入图像描述

I don't know what any of this is doing, but I do see an error in the bitwise math.我不知道这是在做什么,但我确实在按位数学中看到了一个错误。

uint8_t  low_value = ADC & 0x00FF;
uint8_t high_value = ADC & 0xFF00;   //problem here

low_value and high_value are both 8 bits ( uint8_t ). low_valuehigh_value都是 8 位 ( uint8_t )。 I am going to go out on a limb here and say ADC is 16 bit.我要去 go 在这里,说ADC是 16 位的。 For high_value , you are and ing ADC with 0xFF00 then truncating the value to 8 bit.对于high_value ,您正在使用0xFF00 and ADC,然后将值截断为 8 位。 high_value will always be zero. high_value将始终为零。

What should be done is:应该做的是:

uint8_t high_value = (ADC & 0xFF00) >> 8;

This will grab the left byte of ADC and shift it right by 8 bits then assign it to the high_value byte storage giving you the correct value.这将抓取 ADC 的左字节并将其右移 8 位,然后将其分配给high_value字节存储,从而为您提供正确的值。

How you are doing low_value is correct.你如何做low_value是正确的。 As a matter of fact, you could simply do:事实上,你可以简单地做:

uint8_t low_value = ADC;

There is something somewhat suboptimal here:这里有一些不太理想的东西:

uint8_t low_value = ADC & 0x00FF;

You are reading ADC , which is a 16-bit register, implemented as a pair of 8-bit registers.您正在阅读ADC ,它是一个 16 位寄存器,实现为一对 8 位寄存器。 As shown in the disassembly, this requires two in instructions, one per byte.如反汇编所示,这需要两个in指令,每个字节一个。 And then you are just throwing away one of those bytes.然后你只是扔掉其中一个字节。 You may think that the compiler is smart enough to avoid reading the byte it is going to discard right away.您可能认为编译器足够聪明,可以避免读取它将立即丢弃的字节。 Unfortunately, it cannot do that, as I/O registers are declared as volatile .不幸的是,它不能这样做,因为 I/O 寄存器被声明为volatile The compiler is forced to access the register as many times as the source code does.编译器被迫与源代码一样多次访问寄存器。

If you just want the low byte, you should read only that byte:如果你只想要低字节,你应该只读取那个字节:

uint8_t low_value = ADCL;

You then wrote:然后你写道:

uint8_t high_value = ADC & 0xFF00;

As explained in the previous answer, high_value will be zero.如上一个答案所述, high_value将为零。 Yet the compiler will have to read the two bytes again, because the I/O register is volatile .然而编译器将不得不再次读取这两个字节,因为 I/O 寄存器是volatile If you want to read the high byte, read ADCH .如果要读取高字节,请读取ADCH

But why would you want to read those two bytes one by one?但是为什么要一个一个地读取这两个字节呢? Is it to put them back together into a 16-bit variable?是将它们重新组合成一个16位变量吗? If this is the case, then there is no need to read them separately.如果是这种情况,则无需单独阅读它们。 Instead, just read the 16-bit register in the most straight-forward fashion:相反,只需以最直接的方式读取 16 位寄存器:

uint16_t value = ADC;

A long time ago, gcc didn't know how to handle 16-bit registers, and people had to resort to reading the bytes one by one, and then gluing them together.很久以前,gcc 不知道如何处理 16 位寄存器,人们不得不求助于一个一个地读取字节,然后将它们粘合在一起。 You may still find very old example code on the Internet that does that.您可能仍然可以在 Internet 上找到非常古老的示例代码。 Today, there is absolutely no reason to continue programming this way.今天,绝对没有理由继续以这种方式编程。

Then you wrote:然后你写道:

//problem here

Nope, the problem is not here.不,问题不在这里。 That is not what generated the rjmp instruction.这不是生成rjmp指令的原因。 The problem is probably right after that line, in the code you have chosen not to post.问题可能就在该行之后,在您选择不发布的代码中。 You have some bug that manifests itself only when optimizations are turned on.您有一些仅在打开优化时才会出现的错误。 This is typical of code that produces undefined behavior : works as expected with optimizations off, then does weird “unexplainable” things when you enable optimizations.这是产生未定义行为的典型代码:在优化关闭时按预期工作,然后在启用优化时执行奇怪的“无法解释”的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM