我在 Arduino 中使用自定义枚举类型时遇到了一些问题。
我在其他地方读到过,由于 Arduino IDE 预处理,自定义类型声明需要使用头文件。所以,我已经这样做了,但我仍然无法使用我的自定义类型。这是我的主要 arduino 文件 (beacon.ino) 中代码的相关部分
#include <beacon.h>
State state;
Run Code Online (Sandbox Code Playgroud)
在信标.h中:
typedef enum {
menu,
output_on,
val_edit
} State;
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试编译时,出现以下错误:
beacon:20: error: 'State' does not name a type
Run Code Online (Sandbox Code Playgroud)
我认为我编写或包含头文件的方式有问题。但是什么?
我最近一直在努力学习关于微控制器的所有知识。由于这是自学,所以我花了一些时间来了解这些东西在裸机上是如何工作的。长话短说,我不想在我的 C 代码中使用 AVR 库;我想使用 C 中的指针通过它们的地址专门访问寄存器。我在网上到处搜索,查看 AVR 头文件,并阅读一本书。如果有人可以帮助我,那就太好了。
我对组装很陌生,我想知道 ret 的行为。如果我在代码过程中从不使用调用,而是在最后放了一个 ret,那么代码就会回到开头。当没有使用呼叫时,这是默认行为吗?如果我使用 jmp,如果仍然没有使用调用,这会影响 ret 的行为吗?
我不确定在专门分配变量时是否会发生这种情况,但是在调试汇编代码时,编译器会RJMP $+0000在挂起程序的地方执行。
编辑:如果相关,我添加了包含的库
#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; …Run Code Online (Sandbox Code Playgroud) 我遇到的问题是
voltage = voltage*2/3;
和
voltage *= 2/3;
给出了不同的结果。该变量正在 uint16_t8 位 AVR 微控制器上运行。
第一个语句给出了正确的结果,第二个语句始终返回 0。
我的一些朋友告诉我,一般不应该使用一元运算符,这让我思考,因为我也使用诸如 PORTC &= ~(1 << csBit);. 对于编译,我使用 avr-gcc(如果这可以给您一个想法)。
在此先感谢您的帮助
编辑#1:
好的,我明白 = 不是一元运算符。根本区别还在于 '''=''' 从右侧开始,而 ''''*, /''' 从左侧开始。
我想对于uints,这两种说法都不正确,我必须写电压=(uint16_t)((float)电压*(float)2/3)
并感谢@Lundin 指出如何正确回应回复
以下代码使用 avolatile uint8_t而不是 avolatile sig_atomic_t作为 C 标准要求,因为在 avr 平台上该类型sig_atomic_t不可用。
这仍然是合法的代码吗?使用合法吗__SIG_ATOMIC_TYPE__?
是否需要包含cli()/sei()宏?
#include <stdint.h>
#include <signal.h>
#include <avr/interrupt.h>
volatile uint8_t flag;
//volatile sig_atomic_t flag; // not available in avr-gcc
//volatile __SIG_ATOMIC_TYPE__ flag; // ok?
void isr() __asm__("__vector_5") __attribute__ ((__signal__, __used__, __externally_visible__));
void isr() {
flag = 1;
}
void func(void) {
for (uint8_t i=0; i<20; i++) {
flag = !flag;
}
}
Run Code Online (Sandbox Code Playgroud) 我知道OCIE0A=0001二进制,所以(1<<OCIE0A)只是0010?我看到这种情况经常被使用,设置寄存器的原因是什么,(1<<OCIE0A)而不是直接将其设置为0010?
有没有办法改进这行代码?我认为这种转换会减慢我的计划速度.我认为可以使用像位移这样的东西,我不确定.
(uint16_t)(0.8*(float)(Value) ?
编辑:我需要编程atmega8微控制器.我的老师说这行代码需要更多的处理能力,并且有一种更简单的方法可以通过位移来实现这一点.
ATmega32 是 8 位还是 16 位微控制器?
在阅读 Mazidi 的 AVR 书籍时,有人指出RAMEND在 ATmega32 中是0x085f16 位地址。摘自这里的书。
可以将立即值(即任何整数)加载或复制到AVR微控制器中的通用寄存器(R0到R30)中,但为什么除GPR之外我们不能将立即值加载到SRAM中?
在c中,有多少内存消耗一个数组,那只是一个单独的数组,即int a[0]; 要么char a[0];
我希望在程序写入纸上时知道它,而不是在编译器上运行的程序这里我不能使用sizeof函数,我的编译器是avrgcc,
在我的程序的一部分,有些地方我需要的数组int a[13];只
或者代替int a[13]; anint a[3];和整数类型,即int i.
特别是我要求如果我需要13个整数数组或4个整数数组以及整数变量.
这是使用较少的内存