我不能让这个项目运行。不知道还能做什么。此代码是MSP430微控制器汇编语言程序的一部分。它设置堆栈,停止看门狗定时器,设置时钟分频器,初始化寄存器,设置LED控制引脚,设置ADC10用于温度传感器读数,存储读数,获取以前的读数,设置阵列,设置定时器中断,并增加了中断服务和向量程序,程序设计为测量和存储温度读数,然后根据读数控制两个LED,LED将根据代码中设置的温度阈值打开或关闭。
#include "msp430.h" ; #define controlled include file
NAME main
PUBLIC main
ORG 0F800h
; Constants for LED control
LED1_ON EQU 0x01 ; Turns on LED1
LED1_OFF EQU 0x00 ; Turns off LED1
LED2_ON EQU 0x01 ; Turns on LED2
LED2_OFF EQU 0x00 ; Turns off LED2
; Temperature thresholds
LOWEST_TEMP EQU 56 ; Lowest temperature that turns on LED1
COOL_ROOM_TEMP EQU 68 ; Cool room temperature that turns on LED1 and LED2
ROOM_TEMP EQU 72 ; Room temperature that turns on LED1 and LED2
HOT_ROOM_TEMP EQU 78 ; Hot room temperature that turns on LED1 and LED2
HIGHEST_TEMP EQU 90 ; Highest temperature that turns on LED2
;Setup for Array
_byte EQU 1
temp_array DS (_byte * 32) ; 16-bit 32 element array
init: ; Set up the stack and stop the watchdog timer
MOV.W #0280h, SP
MOV.W #WDTPW+WDTHOLD,&WDTCTL
BIS.B #DIVS_3,&BCSCTL2 ; Set the clock divider to SMCLK/8
MOV.W #0000h, R14
MOV.W #0000h, R4
MOV.W R15, 0 ; Initialize the location to 0
ADD.W R15, 1 ; Increment the location to store the reading at the next index
setupP1: ; Set P1.0 to output for LED1 control
BIS.B #001h, &P1DIR
; Set P2.0 to output for LED2 control
setupP2:
BIS.B #001h, &P2DIR
; Set up the ADC10 for temperature sensor readings
SetupADC10
mov.w #INCH_10+ADC10DIV_3,&ADC10CTL1 ; Temp Sensor ADC10CLK/4
mov.w #SREF_1+ADC10SHT_3+REFON+ADC10ON+ADC10IE,&ADC10CTL0 ;
BIS.W #GIE,SR ; Enable interrupts
main:
NOP
CALL #get_previous_reading ; Check the temperature every 2 minutes by calling get_previous_reading
CALL #SetupArray ; Set up the array to store the temperature readings
CALL #SetupTimer ; Set up the timer to generate interrupts every 30 seconds
store_reading:
MOV.W &ADC10MEM, temp_array(R15);
ADD.W R15, 1
ret
get_previous_reading:
MOV.W R15, R5
SUB.W R5, 120 ; Subtract 120 to get the temperature reading 2 minutes ago
MOV.W temp_array(R5), R5 ; Return the temperature reading from that location in the array
ret
SetupArray:
MOV.W #0, temp_array ; Initialize the array to store the temperature readings
MOV.W #0, R15 ; Initialize the current location in the array to 0
ret
SetupTimer:
MOV.W #CCIE,&CCTL0 ; CCR0 interrupt enabled
MOV.W #30*1000,&CCR0 ; Generate an interrupt every 30 seconds
ret
;-------------------------------------------------------------------------------
; Interrupt Service Routines
;-------------------------------------------------------------------------------
ADC10_ISR:
call store_reading
reti
;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
ORG 0FFFEh
DC16 init ; set reset vector to 'init' label
ORG 0FFEAh ; ADC10 interrupt vector
DW ADC10_ISR
END
这些是我在2022年12月12日星期一14:20:18得到的错误:警告:奇地址0x1上的字访问
1条答案
按热度按时间2ul0zpep1#
我以前没有使用过这种汇编语言,但是有很多汇编语言都是以类似的方式工作的。警告“Word access on odd address 0x1”通常意味着你的代码试图从一个未对齐的地址读取一个16位的值。下面是你需要修改的地方:
第一个月
这需要变成
ADD.W R15,2
。与C不同,* 汇编不会自动缩放指针算法。* CPU不知道R15
被用作指针,所以你需要加2以避免覆盖前一个值的一半。然而,这可能不足以消除警告,因为大多数汇编程序只能在编译时警告你未对齐的访问。接下来我们来看一下
main
:在汇编语言中,函数标签并不是控制流的一种形式。下面是一些C代码:
花括号不仅仅是在视觉上分隔你的函数。它们自动地拥有必要的控制流命令来正确地退出函数。这是一个抽象的层次,在汇编语言中是不存在的。汇编“函数”需要被告知
ret
或无限循环,否则下面的任何东西都将自动执行。汇编在控制流上类似于BASIC,程序从指定的入口点开始,无论下一条指令是什么,都将运行,除非程序计数器被跳转、调用、返回等改变。为了使程序按预期工作,您需要在转到
main
之前设置好所有内容,并且让main
永远循环(因为无论main
正在做什么,您的中断都将每30秒运行一次。我能看到的唯一的另一个问题是数组索引超出了界限,当
r15
的增量超过数组大小时,就会出现这种情况。谢天谢地,这是一个很容易解决的问题。数组的大小是16个字,所以如果你对R15
和常量值15进行位AND运算,数组索引就会返回到零,永远不会超出界限。是的,你会覆盖旧的条目,但你不需要记住很久以前的温度。