|
发表于 2008-6-14 00:56:22
|
显示全部楼层
以下程序,我仅使用TIMER0溢出中断,来作为系统时钟节拍。PORTB5接LED用于闪烁,软件仿真是通过了,而写入芯片48时,LED总是灭的,请教一下,什么原因。程序稍长,不过比较简单。还有子程序TIMER_PRESCALE_SYN_PROC(GTCCR设置)时钟同步不知用得对不对。
;===============================================
;文件: temperature
;微控: atmel atmega48
;日期: 2008-02-17
;===============================================
#include "m48def.inc"
#include "test_avr.inc"
.device atmega48
;.EQU TEST_UNIT = 0 ;单元测试
;.EQU TEST_LED_ALL_DISP = 1 ;测试LED显示
;.EQU TEST_NUM_DISP = 2 ;测试LED数字显示
;.EQU TEST_TIMER0_OVF0 = 3 ;测试TIMER0溢出中断
;.EQU TEST_TIMER1_OVF1 = 4 ;测试TIMER1溢出中断
;.EQU TEST_TIMER2_OVF2 = 5 ;测试TIMER2溢出中断
;.EQU TEST_ADC = 6 ;测试ADC转换值
.EQU TEST_DELAY_CONST = 0xff
.dseg
.cseg
.org RSTaddr
rjmp START
.org INT0addr
rjmp NO_USE_INT_PROC
.org INT1addr
rjmp NO_USE_INT_PROC
.org PCI0addr
rjmp NO_USE_INT_PROC
.org PCI1addr
rjmp NO_USE_INT_PROC
.org PCI2addr
rjmp NO_USE_INT_PROC
.org WDTaddr
rjmp NO_USE_INT_PROC
.org OC2Aaddr
rjmp NO_USE_INT_PROC
.org OC2Baddr
rjmp NO_USE_INT_PROC
.org OVF2addr
rjmp NO_USE_INT_PROC
.org ICP1addr
rjmp NO_USE_INT_PROC
.org OC1Aaddr
rjmp NO_USE_INT_PROC
.org OC1Baddr
rjmp NO_USE_INT_PROC
.org OVF1addr
rjmp NO_USE_INT_PROC
.org OC0Aaddr
rjmp NO_USE_INT_PROC
.org OC0Baddr
rjmp NO_USE_INT_PROC
.org OVF0addr
rjmp TIMER0_OVF0_PROC
.org SPIaddr
rjmp NO_USE_INT_PROC
.org URXCaddr
rjmp NO_USE_INT_PROC
.org UDREaddr
rjmp NO_USE_INT_PROC
.org UTXCaddr
rjmp NO_USE_INT_PROC
.org ADCCaddr
rjmp NO_USE_INT_PROC
.org ERDYaddr
rjmp NO_USE_INT_PROC
.org ACIaddr
rjmp NO_USE_INT_PROC
.org TWIaddr
rjmp NO_USE_INT_PROC
.org SPMRaddr ;0x0019
rjmp NO_USE_INT_PROC
;================================
;未使用中断统一处理
;================================
NO_USE_INT_PROC:
nop
nop
nop
reti
;================================
;TIMER0 溢出中断
;================================
TIMER0_OVF0_PROC:
push r31 ;push Z REG
push r30
push r29 ;push Y REG
push r28
push r27 ;push X REG
push r26
push r18 ;SREG TMP
push r17
push r16
in r18,SREG
clr XH
ldi XL,TIMER_INT_FLAG ;设置TIMER0中断发生标志寄存器
ori r16,0xc0
st X,r16
out SREG,r18
pop r16
pop r17
pop r18
pop r26
pop r27
pop r28
pop r29
pop r30
pop r31
reti
.org PROGaddr ;0x0030
START:
cli ;禁止全局中断
ldi r16,0xff ;设置系统堆栈
out SPL,r16
sbi DDRB,0x2
rcall CLK_CHG_DLY ;系统延时
rcall SYS_CLK_INIT ;系统时钟初始化
rcall SYS_SET_INIT ;系统设置初始化
rcall LED_IO_CTRL_INIT ;LED控制IO初始化
rcall LED_DISP_LIGHT ;显示全点亮
rcall START_LED_DISP_DLY ;保持LED全亮0.5秒
rcall LED_SR_CTRL_INIT ;LED控制寄存器初始化
rcall TIMER_PRESCALE_SYN_PROC ;时钟分频同步
rcall TIMER0_INIT_PROC ;系统时钟.8.2ms
; rcall TIMER_PRESCALE_SYN_PROC ;时钟分频同步
sei ;开全局中断
ldi XL,TEMPERATURE_TIME_SRL
ldi r16,0x0F
st X,r16
ldi XL,TEMPERATURE_TIME_SRH
ldi r17,0x01
st X,r17
clr r19
clr r20
sbi DDRB,5
cbi PORTB,5
MAINLOOP:
rcall DELAY_COMMON
ldi XL,TEMPERATURE_TIME_SRL
ld r16,X
ldi XL,TEMPERATURE_TIME_SRH
ld r17,X
or r16,r17
cpi r16,0x00
breq MLOOP1
rjmp MAINLOOP
MLOOP1:
ldi XL,TEMPERATURE_TIME_SRL
ldi r16,0x0F
st X,r16
ldi XL,TEMPERATURE_TIME_SRH
ldi r17,0x01
st X,r17
cpi r19,0x00
breq MLOOP2
clr r19
sbi DDRB,5
sbi PORTB,5
rjmp MAINLOOP
MLOOP2:
ldi r19,0x08
cbi PORTB,5
nop
nop
nop
rjmp MAINLOOP
;=======================================
; 定时器分频同步
;
;=======================================
TIMER_PRESCALE_SYN_PROC:
ldi r16,0x00 ;
sts GTCCR,r16
ret
;=======================================
;公用延时程序
;产生一次TIMER0中断,TEMPERATURE_TIME_SR减1
;=======================================
DELAY_COMMON:
clr XH
ldi XL,TIMER_INT_FLAG
ld r16,X
andi r16,0x80 ;高两位为TIMER0中断置位标志
cpi r16,0x00
brne DELAY_COMMON_GO
DELAY_COMMON_END:
ret
DELAY_COMMON_GO:
andi r16,0x7f
st X,r16
DELAY_COMMON_B:
ldi XL,TEMPERATURE_TIME_SRL
ld r16,X
ldi XL,TEMPERATURE_TIME_SRH
ld r17,X
or r16,r17
cpi r16,0x00
breq DELAY_COMMON_C
ldi XL,TEMPERATURE_TIME_SRL
ld r16,X
subi r16,0x01
brcs DELAY_COMMON_B_1
st X,r16
rjmp DELAY_COMMON_C
DELAY_COMMON_B_1:
st X,r16
dec r17
ldi XL,TEMPERATURE_TIME_SRH
st X,r17
DELAY_COMMON_C:
nop
nop
ret
;========================================
; 系统初始化程序
;
;说明: 系统功能初始化,INT,WDT,IO,SRAM,
; EEPROM,SLEEP...
;========================================
SYS_SET_INIT:
rcall SYS_INT_INIT
rcall SYS_WDT_INIT
rcall SYS_IO_INIT
rcall SYS_SRAM_INIT
rcall SYS_EEPROM_INIT
rcall SYS_OTHER_CSR_INIT
rcall SYS_SLEEP_INIT
ret
;---------------------------------
;系统其它部分初始化看门狗,无看门狗
SYS_WDT_INIT:
ldi r16,0x00
sts WDTCSR,r16
ret
;---------------------------------
;系统睡眠初始化
SYS_SLEEP_INIT:
ret
;---------------------------------
;选用内部时钟,下载时设置,8MHz;
SYS_CLK_INIT:
ldi r16,SYS_CLK_CALIBRATE
sts OSCCAL,r16
ldi r16,0x80
sts CLKPR,r16 ;EXCLK 8M,Prescale = 0
ret
;=============================================
; 【定时器0初始化子程序】
;
;说明: TIMER0使用溢出中断,作为系统时钟,时钟
; 为8毫秒,不与OCR0A,OCR0B连接,分频256,
; 初始值:0x00,递加.
;=============================================
TIMER0_INIT_PROC:
ldi r16,0x00 ;不与OCR0A,OCR0B相接
out TCCR0A,r16
ldi r16,0x05 ;0x04:256分频 0x05:1024分频
out TCCR0B,r16
ldi r16,0x00 ;清零计数器
out TCNT0,r16
lds r16,TIMSK0 ;使能TIMER0溢出中断
andi r16,0xf8
ori r16,0x01
sts TIMSK0,r16
ldi r16,0x00 ;清零TIMER0中断标志位
out TIFR0,r16
ldi r16,0xff
out OCR0A,r16 ;初始化比较计存器A
out OCR0B,r16 ;初始化比较计存器B
ret
;======================================
; 系统其它控制寄存器初始化
;
;说明: 未使用功能,全部禁止
;======================================
SYS_OTHER_CSR_INIT:
ldi r16,0xc0 ;不使用睡眠模式
sts SMCR,r16
lds r16,EICRA ;INT0,INT1中断触发方式
andi r16,0x0f
sts EICRA,r16
in r16,EIMSK ;屏蔽INT0,INT1
andi r16,0x03
out EIMSK,r16
in r16,EIFR ;清除INT0,INT1中断标志寄存器
andi r16,0x03
out EIFR,r16
lds r16,PCICR ;禁止引脚电平变化中断
andi r16,0x03
sts PCICR,r16
in r16,PCIFR ;清除引脚电平变化中断
andi r16,0x03
out PCIFR,r16
lds r16,PCMSK2 ;禁止PCINT16~PCINT23电平变化中断
andi r16,0x00
sts PCMSK2,r16
lds r16,PCMSK1 ;禁止PCINT8~PCINT14电平变化中断
andi r16,0x80
sts PCMSK1,r16
lds r16,PCMSK0 ;禁止PCINT0~PCINT7电平变化中断
andi r16,0x00
sts PCMSK0,r16
in r16,SPCR ;禁止SPI中断
andi r16,0x7f
out SPCR,r16
in r16,SPCR ;禁止SPI功能
andi r16,0xbf
out SPCR,r16
in r16,SPCR ;使用MSB首发
andi r16,0xdf
out SPCR,r16
in r16,SPCR ;先定主机
ori r16,0x10
out SPCR,r16
in r16,SPCR ;上升沿
andi r16,0xf7
out SPCR,r16
in r16,SPCR ;起始沿采样
andi r16,0xfb
out SPCR,r16
in r16,SPCR ;fosc/4
andi r16,0xf8
out SPCR,r16
in r16,SPSR ;清除中断标志,碰撞位,倍速位
andi r16,0x00
out SPSR,r16
in r16,SPDR ;清零SPI发送数据
andi r16,0x00
out SPDR,r16
;--------------------
lds r16,UCSR0B ;禁止发送,接收,空,中断
andi r16,0x00
sts UCSR0B,r16
lds r16,UCSR0C ;使用异步,禁止校验,1字节停止位,5位长度
andi r16,0x0
sts UCSR0C,r16
lds r17,UBRR0H ;设置波特率
andi r17,0x00
lds r16,UBRR0L
andi r16,0x00
sts UBRR0H,r17
sts UBRR0L,r16
lds r16,UCSR0A ;
andi r16,0x00
sts UCSR0A,r16
;---------------------
lds r16,TWCR ;
andi r16,0x00
sts TWCR,r16
lds r16,TWSR
andi r16,0x00
sts TWSR,r16
lds r16,TWDR
andi r16,0x00
sts TWDR,r16
lds r16,TWAR
andi r16,0x00
sts TWDR,r16
lds r16,TWAMR
andi r16,0x00
sts TWAMR,r16
ret
;======================================
;系统其它部分初始化
;======================================
SYS_OTHER_INIT:
ldi r16,0x00
sts MCUSR,r16
ret
;======================================
; 系统SRAM初始化
;======================================
SYS_SRAM_INIT:
ret
;====================================
; EEPROM初始化
;====================================
SYS_EEPROM_INIT:
ret
;====================================
; 系统中断初始化
;====================================
SYS_INT_INIT:
ret
;====================================
; 系统端口初始化
;说明: 设置所有GPIO全部为输入口
;====================================
SYS_IO_INIT:
lds r16,MCUCR ;使能上拉功能
ori r16,0x10
sts MCUCR,r16
ldi r16,0x00
out DDRB,r16
out PORTB,r16
out PINB,r16
out DDRC,r16
out PORTC,r16
out PINC,r16
out DDRD,r16
out PORTD,r16
out PIND,r16
ret
;----------------------------------
;改变系统时钟,加入延时以待其工作稳定
CLK_CHG_DLY:
ldi r16,0x80
DLY_XX:
ldi r17,0xff
DLY_XX1:
mov r17,r17
brcc DLY_XX2
dec r17
rjmp DLY_XX1
DLY_XX2:
mov r16,r16
brcc DLY_XX3
dec r16
rjmp DLY_XX
DLY_XX3:
ret
.eseg
.exit |
|