有谁知道如何用汇编代码编写随机生成的8位数字?
我正在使用 ATmega8535 和 Atmel AVR 汇编器以及 AVR 模拟器的调试。(AVR 工作室 4)
抱歉,我是新手,如有任何帮助,将不胜感激,谢谢
我目前正在为 AVR 微控制器上的 USB 设备创建固件。由于 USB 时序非常严格,因此我不能允许非 USB 中断阻塞超过几个指令周期。因此,我的 USART RXC(接收到的字符)中断如下所示:
\n\nvoid usart_rxc_wrapped() __attribute__ ((interrupt));\nvoid usart_rxc_wrapped(){\n uint8_t c=UDR;\n if(!ringBufferFull(&rx)){\n ringBufferWrite(&rx, c);\n }\n // Reenable nterrupt\n UCSRB|=1<<RXCIE;\n}\n\n// This cannot be ISR_NOBLOCK, since the interrupt would go\n// into infinite loop, since we wouldn\'t get up to reading\n// UDR register. Instead, we use assembly to do the job\n// manually and then jump to the real handler.\nISR(USART_RXC_vect, ISR_NAKED){\n // Disable this interrupt by clearing its Interrupt Enable flag.\n __asm__ volatile("cbi %0, %1"::\n "I"(_SFR_IO_ADDR(UCSRB)),"I"(RXCIE));\n …Run Code Online (Sandbox Code Playgroud) 我可以像这样使用 cli() 和 sei() 吗:
ISR(EXT_INT0_vect)
{
cli();
MyFunction();
sei();
}
Run Code Online (Sandbox Code Playgroud)
听说是禁止的。或者我可以像上面那样使用 cli() 和 sei() 吗?
提前道歉,因为我对这个主题还不太了解,并且仍在学习编译器的内部工作原理。
我目前正在研究在嵌入式系统中使用 D 的可能性,并发现一篇文章提到 AVR 后端如何合并到上游 LLVM 项目中,以便开发人员可以致力于为他们的语言创建 AVR 支持。D 有 LDC 编译器,它使用 LLVM 后端。不过,这篇文章还提到了 avr-gcc 的使用,这让我对在哪个阶段使用哪些工具从 D 源代码到 AVR 二进制文件有点困惑。我假设 LDC 将源代码转换为 LLVM IR,然后转换为二进制,所以我不确定 avr-gcc 的用途。
有人可以更详细地向我解释这一点吗?
我已经开始深入研究 MCU 编程并一直在使用一些基本代码。我首先使用 Arduino 完成此操作,但现在我尝试使用 ATTINY1616 MCU,并且我对如何创建使 LED 调暗和关闭的 PWM 效果感到困惑。我以为我有一个有效的代码,但由于某种原因,它只能与一个引脚一起工作。我已阅读数据表,它确认有更多引脚可用于 PWM,并且没有发现我可能会错过使用其他引脚的命令或语句。
\n无论我选择哪个引脚作为输出,代码都会编译,但在 MCU 中,PB0 是唯一可以工作的引脚。其他引脚不会执行任何操作,不会给出任何输出,并且软件(Microship Studio)不会显示任何错误。我什至把 MCU 换成了新的。
\n我\xe2\x80\x99m 不太擅长阅读数据表,但我真的没有\xe2\x80\x99t 看到任何专门允许某些引脚成为 PWM 的命令(https://ww1.microchip.com/downloads/en/DeviceDoc /ATtiny1614-16-17-DataSheet-DS40002204A.pdf,特别是 TCA 的第 20 节)。我的理论是,由于 PB0 显示为 TCA0 的 WO0,因此该引脚就像 TCA 功能的默认引脚,我需要一个命令来指示我想使用另一个引脚,但我无法\xe2\x80\x99 找到任何有效的引脚。
\n#define F_CPU 20000000\n#include <avr/io.h>\n#include <avr/interrupt.h>\n#include <util/delay.h>\n#include <stdint.h>\n\n\n\nvoid PWM_init() {\n // Configure Timer/Counter 0 (TC0) for PWM generation\n\n // Set TC0 waveform generation mode to Fast PWM\n TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc | TCA_SINGLE_CMP0EN_bm;\n\n // Set TC0 period (TOP value) to …Run Code Online (Sandbox Code Playgroud) 解决方案:
\n事实证明它与 USART 没有任何关系。问题出在 Makefile 中。我重复使用了长期以来一直用于 atmega328p 和 atmega2560 的 Makefile。但是在将 elf 转换为 hex 文件时,此 Makefile 不包含 .rodata 部分。我想这部分从来没有用于“旧的”atmega 部件。在十六进制文件中包含 .rodata 部分后,一切都按 atmega4809 的预期工作。
\nMakefile 之前的部分:
\n$(OUT).hex: $(OUT).elf\n rm -f $(OUT).hex $(OUT).eep.hex\n $(OBJCOPY) -j .text -j .data -O ihex $(OUT).elf $(OUT).hex\n $(SIZE) $(OUT).hex\nRun Code Online (Sandbox Code Playgroud)\n之后的 Makefile 部分:
\n$(OUT).hex: $(OUT).elf\n rm -f $(OUT).hex $(OUT).eep.hex\n $(OBJCOPY) -j .text -j .data -j .rodata -O ihex $(OUT).elf $(OUT).hex\n $(SIZE) $(OUT).hex\nRun Code Online (Sandbox Code Playgroud)\n原问题:
\n以下代码的结果是:
\n\n$(OUT).hex: $(OUT).elf\n rm -f …Run Code Online (Sandbox Code Playgroud) 我花了很长时间用我的AVR开发系统设置了完整的GCC工具链(一切都是最新的当前稳定版本),我用它解决了大多数问题.
以下代码给出了一个我没有得到的错误.AVR汇编手册指出sbi指令可以接受0-7作为常量表达式,但它仍然在我身上出错.谁能解释为什么这样做呢?
#ifndef __AVR_ATmega168__
#define __AVR_ATmega168__
#endif
#include <avr/io.h>
rjmp Init
Init:
ser r16
out DDRB, r16
out DDRD, r16
clr r16
out PORTB, r16
out PORTD, r16
Start:
sbi PORTB, 0
rjmp Start
Run Code Online (Sandbox Code Playgroud)
有问题的线是sbi PORTB,0.
编译/组装:
avr-gcc ledon.S -mmcu = atmega168
我有堆栈初始化行的问题,因为avr-gcc返回
LED_Blink.asm:10:错误:行尾的垃圾
在线:
ldi r17, low(RAMEND)
ldi r17, high(RAMEND)
Run Code Online (Sandbox Code Playgroud)
我很困惑.我已经定义了RAMEND.我在这个命令中使用了avr-gcc:
avr-gcc -x assembler -mmcu = atmega328p LED_Blink.asm
我的汇编代码:
.equ SPL, 0x3d
.equ SPH, 0x3e
.equ RAMEND, 0x8ff
.equ PORTB, 0x05
.equ DDRB, 0x04
.org 0x000000
rjmp main
main:
ldi r17, low(RAMEND)
out SPL, r17
ldi r17, high(RAMEND)
out SPH, r17
ldi r16, 0xff
out DDRB, r16
out PORTB, r16
loop:
ldi r16, 32
rcall outer_loop
cbi PORTB, 5
ldi r16, 32
rcall outer_loop
sbi PORTB, 5
rjmp loop
outer_loop:
clr …Run Code Online (Sandbox Code Playgroud) 我编写了以下代码,以使ATMEGA168A闪烁一个小的led:
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL
int main(void)
{
DDRB = 0b00000010;
PORTB = 0b00000000;
while(1)
{
PORTB ^= 1 << 1;
_delay_ms(1000);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器向我发出如下警告:
Warning #warning "F_CPU not defined for <util/delay.h>"
Run Code Online (Sandbox Code Playgroud)
这是此警告的来源(delay.h)
#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么?我的声明不正确吗?
我刚刚在十六进制整数(例如0xFFFF)与十进制整数(例如2)相乘时,在我的代码中发现了一个错误.这是出现问题的代码:
print_int_new_line(0xFFFF*2);
print_int_new_line(65535*2);
Run Code Online (Sandbox Code Playgroud)
执行此代码会给我以下结果:
65534
131070
Run Code Online (Sandbox Code Playgroud)
这是相关的UART代码:
void print_int_new_line(uint64_t data) {
print_int(data);
print_new_line();
}
void print_int(uint64_t data) {
char data_buffer[(int)(log(data)+2)]; // size of the number (log(number)+1) + 1 for the /0
ultoa(data, data_buffer, 10); // convert the int to string, base 10
// print the newly created string
print_string(data_buffer);
}
void print_string(char * data) {
// transmit the data char by char
for(; *data != '\0'; data++){
USART_transmit(data);
}
}
void USART_transmit(const char * data){
/* Wait for empty transmit …Run Code Online (Sandbox Code Playgroud)