assembly 恒温器的汇编语言

yvgpqqbh  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(146)

我不能让这个项目运行。不知道还能做什么。此代码是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上的字访问

2ul0zpep

2ul0zpep1#

我以前没有使用过这种汇编语言,但是有很多汇编语言都是以类似的方式工作的。警告“Word access on odd address 0x1”通常意味着你的代码试图从一个未对齐的地址读取一个16位的值。下面是你需要修改的地方:
第一个月
这需要变成ADD.W R15,2。与C不同,* 汇编不会自动缩放指针算法。* CPU不知道R15被用作指针,所以你需要加2以避免覆盖前一个值的一半。然而,这可能不足以消除警告,因为大多数汇编程序只能在编译时警告你未对齐的访问。
接下来我们来看一下main

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

在汇编语言中,函数标签并不是控制流的一种形式。下面是一些C代码:

int main()
{

}

void store_reading(void)
{

}

花括号不仅仅是在视觉上分隔你的函数。它们自动地拥有必要的控制流命令来正确地退出函数。这是一个抽象的层次,在汇编语言中是不存在的。汇编“函数”需要被告知ret或无限循环,否则下面的任何东西都将自动执行。汇编在控制流上类似于BASIC,程序从指定的入口点开始,无论下一条指令是什么,都将运行,除非程序计数器被跳转、调用、返回等改变。
为了使程序按预期工作,您需要在转到main之前设置好所有内容,并且让main永远循环(因为无论main正在做什么,您的中断都将每30秒运行一次。
我能看到的唯一的另一个问题是数组索引超出了界限,当r15的增量超过数组大小时,就会出现这种情况。谢天谢地,这是一个很容易解决的问题。数组的大小是16个字,所以如果你对R15和常量值15进行位AND运算,数组索引就会返回到零,永远不会超出界限。是的,你会覆盖旧的条目,但你不需要记住很久以前的温度。

store_reading:
MOV.W &ADC10MEM,temp_array(R15);
ADD.W R15,1
AND.W R15,15
RET

相关问题