论坛风格切换切换到宽版
  • 7006阅读
  • 13回复

AVR AT90S2313发莫尔斯电码的源程序 [复制链接]

上一主题 下一主题
离线BA1FB
 
发帖
28695
只看楼主 倒序阅读 0楼 发表于: 2007-04-29
; ** at90s2333 assembly language file **

.include "2333def.inc"

.def      morse_ele = r14
.def      morse_cnt = r15
.def      tm1_status = r17
.def      morse_bits = r18
.equ      cw_tone_on = 7
.equ      afsk_tone_on = 6

.dseg
.org      0x60
sine_ptr:      .byte      2

.cseg
.org      0
           rjmp      init
           reti                  ; external 0 interrupt vector
           reti                  ; external 1 interrupt vector
           reti                  ; timer 1 capture interrupt vector            
           reti                  ; timer 1 comparea interrupt vector
           rjmp      tim1_ovf      ; timer 1 overflow interrupt vector
           rjmp      tim0_ovf      ; timer 0 overflow interrupt vector
           rjmp      spi_handle      ; spi transmit interrupt vector
           reti                  ; uart rx complete interrupt vector
           reti                  ; udr empty interrupt vector
           reti                  ; uart tx complete interrupt vector
           rjmp      adc_comp      ; adc conversion complete interrupt vector
           rjmp      ee_rdy            ; eeprom ready interrupt vector
           reti                  ; analogue comparator interrupt vector

tim1_ovf:                        ; timer 1 overflow interrupt code here
           push      r0
           push      zl
           push      zh
           push      xl
           push      xh
           in      zl, sreg
           push      zl
           
           sbrs      tm1_status, cw_tone_on
           rjmp      sene_afsk_tone
           ldi      xh, high(sine_ptr)
           ldi      xl, low(sine_ptr)
           ld      zl, x+            ; load sine table pointer
           ld      zh, x
           adiw      zl, 1            ; increase sine table pointer
           lpm                  ; load new table vaule
           cpi      zl, low((end_of_cw_sine_tbl<<1)-1)
           brne      cw_load_pwm      ; branch if end of sine table not reached
                             ; reset sine table pointer
           ldi      zl, low((cw_sine_tbl<<1)-1)
           ldi      zh, high((cw_sine_tbl<<1)-1)            
cw_load_pwm:
           st      x, zh            ; save sine table pointer
           st      -x, zl
           out      ocr1l, r0      ; load new pwm vaule
           rjmp      tim1_ovf_ret
           
sene_afsk_tone:
           sbrs      tm1_status, afsk_tone_on      
           rjmp      tim1_ovf_ret
           
tim1_ovf_ret:      
           pop      zl
           out      sreg, zl
           pop      xh
           pop      xl
           pop      zh
           pop      zl
           pop      r0      
           reti
tim0_ovf:                        ; timer 0 overflow interrupt code here
           dec      morse_cnt      ; decrease morse timer every 1/450 second
           brne      tim0_ovf_ret      ; branch if one element not sent
           ldi      zl, morse_ele_tm
           rcall      read_eeprom      
           mov      morse_cnt, r0      ; reload element timer from eeprom preset
           sbr      tm1_status, (1<<cw_tone_on)
           lsl      morse_bits      
           breq      load_morse_ele      ; branch if morse elements have been sent out
           brcs      tim0_ovf_ret      ; 1 - cw tone one, 0 - cw tone off
           cbr      tm1_status, (1<<cw_tone_on)
           rjmp      tim0_ovf_ret
load_morse_ele:
           lsl      morse_ele
           breq      load_morse_char      ; branch if one character has been sent out
           brcs      load_dash      ; 1 - send dash, 0 - send dot
           lsl      morse_ele      ; test morse_ele, if morse_ele = 0x80, then add space between characters
           ldi      morse_bits, 0b10001000
           breq      recover_ele      ;
           ldi      morse_bits, 0b10100000
           rjmp      recover_ele
load_dash:            
           lsl      morse_ele
           ldi      morse_bits, 0b11100010
           breq      recover_ele      
           ldi      morse_bits, 0b11101000
recover_ele:      ror      morse_ele      ; recover damaged value of morse_ele      
           rjmp      tim0_ovf_ret
           
tim0_ovf_ret:
           rjmp      tim1_ovf_ret

load_morse_char:

spi_handle:                        ; spi transmit interrupt code here
           reti
adc_comp:                        ; adc conversion complete interrupt code here
           reti
ee_rdy:                              ; eeprom ready interrupt code here
                             ; note: eeprom ready interrupt bit not set (eecr.3) - see data book
           reti      
           ; if emulation is to be used, do not insert code in marked block
           ; **************** start of block*******************************************
init:          
           ;     stack pointer setup code  
                             ; add following code only when at90s4433 used
                             ; ldi      r16, 0x00      ; stack pointer setup
                             ; out      sph,r16            ; stack pointer high byte
           ldi      r16, 0xdf      ; stack pointer setup
           out      spl, r16      ; stack pointer low byte
           ; **************** end of block ********************************************
           ; ******* watchdog timer setup code ****
           ldi      r16, 0b00001110      ; wdt setup
                             ; bit 4 - wdtoe: watch dog turn-off enable
                             ; bit 3 - wde: watch dog enable
                             ; bits 2..0 - wdp2, wdp1, wdp0: watch dog timer prescaler 2, 1 and 0
                             ; wdp2 wdp1 wdp0 number of wdt oscillator cycles typical time-out(3v,5v)
                             ; 0   0   0      16k cycles      47 ms      15 ms
                             ; 0   0   1      32k cycles      94 ms      30 ms
                             ; 0   1   0      64k cycles      0.19 s      60 ms
                             ; 0   1   1      128k cycles      0.38 s      0.12 s
                             ; 1   0   0      256k cycles      0.75 s      0,24 s
                             ; 1   0   1      512k cycles      1.5 s      0.49 s
                             ; 1   1   0      1,024k cycles      3.0 s      0.97 s
                             ; 1   1   1      2,048k cycles      6.0 s      1.9 s
           out      wdtcr, r16      ; wdt enabled - 0.97s
           
           ; ******* timer0 setup code ****
           ldi      r16, 0b00000011      ; timer 0 setup 7.3728mhz t0ovf 450hz
                             ; bits 2,1,0 - cs02, cs01, cs00: clock select0, bit 2,1 and 0
                             ; cs02 cs01 cs00 description
                             ; 0   0   0       stop, timer/counter0 is stopped.
                             ; 0   0   1       ck
                             ; 0   1   0       ck / 8
                             ; 0   1   1       ck / 64
                             ; 1   0   0       ck / 256
                             ; 1   0   1       ck / 1024
                             ; 1   1   0       external pin t0, falling edge
                             ; 1   1   1       external pin t0, rising edge
           out      tccr0, r16      ; timer - ck

           ; ******* interrupts setup code ****
           ldi      r16, 0b00000000      ; external interrupt enables
                             ; bit 7 - int1: external interrupt request 1 enable
                             ; bit 6 - int0: external interrupt request 0 enable
           out      gimsk, r16      ; int0 enabled int1 disabled
           ldi      r16, 0b00001010      ; sleep and interrupt edges
                             ; bit 5 - se: sleep enable
                             ; bit 4 - sm: sleep mode
                             ; bits 3, 2 - isc11, isc10: interrupt sense control 1 bit 1 and bit 0
                             ; isc11 isc10      description
                             ; 0      0      the low level of int1 generates an interrupt request.
                             ; 0      1      any logical change on int1 generates an interrupt request.
                             ; 1      0      the falling edge of int1 generates an interrupt request.
                             ; 1      1      the rising edge of int1 generates an interrupt request.
                             ; bits 1, 0 - isc01, isc00: interrupt sense control 0 bit 1 and bit 0
                             ; isc01 isc00      description
                             ; 0      0      the low level of int0 generates an interrupt request.
                             ; 0      1      any logical change on int0 generates an interrupt request.
                             ; 1      0      the falling edge of int0 generates an interrupt request.
                             ; 1      1      the rising edge of int0 generates an interrupt request.
           out      mcucr, r16      ; int0 - falling edge int1 - falling edge
           ldi      r16, 0b10000010      ; timer interrupt enables
                             ; bit 7 - toie1: timer/counter1 overflow interrupt enable
                             ; bit 6 - ocie1: timer/counter1 output compare match interrupt enable
                             ; bit 3 - ticie1: timer/counter1 input capture interrupt enable
                             ; bit 1 - toie0: timer/counter0 overflow interrupt enable
           out      timsk, r16      ; timer 1: overflow, timer 0: overflow enabled
           ; ******* comparator setup code ****
           ldi      r16,0b10000010      ; interrupt enabled on falling o/p edge
                             ; bit 7 - acd: analog comparator disable
                             ; bit 6 - ainbg: analog comparator bandgap select
                             ; bit 5 - aco: analog comparator output
                             ; bit 4 - aci: analog comparator interrupt flag
                             ; bit 3 - acie: analog comparator interrupt enable
                             ; bit 2 - acic: analog comparator input capture enable
                             ; bits 1,0 - acis1, acis0: analog comparator interrupt mode select
                             ; acis1 acis0      interrupt mode
                             ; 0      0      comparator interrupt on output toggle
                             ; 0      1      reserved
                             ; 1      0      comparator interrupt on falling output edge
                             ; 1      1      comparator interrupt on rising output edge
           out      acsr, r16      ; comparator disabled, input capture disabled
           ; ******* adc setup code ****
           ldi      r16,0b10001110      ; adc interrupt enabled, adc enabled
                             ; bit 7 - aden: adc enable
                             ; bit 6 - adsc: adc start conversion
                             ; bit 5 - adfr: adc free run select
                             ; bit 4 - adif: adc interrupt flag
                             ; bit 3 - adie: adc interrupt enable
                             ; bits 2..0 - adps2..adps0: adc prescaler select bits
                             ; adps2 adps1 adps0 division factor
                             ; 0      0   0      2
                             ; 0      0   1      2
                             ; 0      1   0      4
                             ; 0      1   1      8
                             ; 1      0   0      16
                             ; 1      0   1      32
                             ; 1      1   0      64
                             ; 1      1   1      128
           out      adcsr, r16      ; adc single conversion mode, prescaler:ck/64 115khz
           ldi      r16,0x00
                             ; bit 6 - adcbg: adc bandgap select
                             ; bits 2..0 - mux2..mux0: analog channel select bits 2-0
                             ;
           out      admux, r16      ; channel 00 selected
           ; ******* uart setup code ****
                             ; uart baud rate setup
                             ; ldi      r16, 0x17      ; baud rate 19200 osc is 7.3728 mhz
                             ; out      ubrr, r16      ; uart baud rate generator
           ldi      r16, 0b00000000      ; uart interrupt enables and uart settings
                             ; bit 7 - rxc: uart receive complete
                             ; bit 6 - txc: uart transmit complete
                             ; bit 5 - udre: uart data register empty
                             ; bit 4 - fe: framing error
                             ; bit 3 - or: overrun
                             ; bit 0 - mpcm: multi-processor communication mode
           out      ucsra, r16      ; interrupts: rx complete, udr empty, tx complete, -settings: rx enable, tx enable, 9-bit disable
           ; ******* spi setup code ****
           ldi      r16, 0b00000000      ; spi setups- spi disable, msb 1st, cpol - sck low, cpha clear
                             ; bit 7 - spie: spi interrupt enable
                             ; bit 6 - spe: spi enable
                             ; bit 5 - dord: data order
                             ; bit 4 - mstr: master/slave select
                             ; bit 3 - cpol: clock polarity
                             ; bit 2 - cpha: clock phase
                             ; bits 1,0 - spr1, spr0: spi clock rate select 1 and 0
                             ; spr1 spr0 sck frequency
                             ; 0      0      fcl / 4
                             ; 0      1      fcl / 16
                             ; 1      0      fcl / 64
                             ; 1      1      fcl / 128
           out      spcr, r16      ; slave , spi interrupt enabled
           ; ******* port b setup code ****
           ldi      r16, 0xf2      ; ain0+ain1,
           out      ddrb , r16      ; port b direction register
           ldi      r16, 0x00      ; init value
           out      portb, r16      ; port b value
           ; ******* port c setup code ****
           ldi      r16, 0xff      ; i/o direction values
           out      ddrc, r16      ; port c direction register
           ldi      r16, 0x00      ; init value
           out      portc, r16      ; port c value
           ; ******* port d setup code ****
           ldi      r16, 0xb2      ; i/o: rxd,txd, int0, int1, oc1b, icp-pb6,
           out      ddrd, r16      ; port d direction register
           ldi      r16, 0x00      ; init value
           out      portd, r16      ; port d value
           ; ******* timer1 setup code ****
           ldi      r16, 0b00000001      ; 8-bit pwm mode comparea o/p non-inverting
                             ; bits 7,6 - com11, com10: compare output mode1, bits 1 and 0
                             ; com11 com10      description
                             ; 0      0      timer/counter1 disconnected from output pin oc1
                             ; 0      1      toggle the oc1 output line.
                             ; 1      0      clear the oc1 output line (to zero).
                             ; 1      1      set the oc1 output line (to one).
                             ; bits 1,0 - pwm11, pwm10: pulse width modulator select bits
                             ; pwm11 pwm10      description
                             ; 0      0      pwm operation of timer/counter1 is disabled
                             ; 0      1      timer/counter1 is an 8-bit pwm
                             ; 1      0      timer/counter1 is a 9-bit pwm
                             ; 1      1      timer/counter1 is a 10-bit pwm
           out      tccr1a, r16      ; compareb o/p non-inverting
           ldi      r16, 0x00      ; pwm value match a
           out      ocr1h, r16      ; high byte
           ldi      r16, 0xff      ; pwm value match a
           out      ocr1l, r16      ; low byte
           ldi      r16, 0b00000001      ; timer : ck
                             ; bit 7 - icnc1: input capture1 noise canceler (4 cks)
                             ; bit 6 - ices1: input capture1 edge select
                             ; bit 3 - ctc1: clear timer/counter1 on compare match
                             ; bits 2,1,0 - cs12, cs11, cs10: clock select1, bit 2,1 and 0
                             ; cs12 cs11 cs10 description
                             ; 0   0   0       stop, the timer/counter1 is stopped.
                             ; 0   0   1       ck
                             ; 0   1   0       ck / 8
                             ; 0   1   1       ck / 64
                             ; 1   0   0       ck / 256
                             ; 1   0   1       ck / 1024
                             ; 1   1   0       external pin t1, falling edge
                             ; 1   1   1       external pin t1, rising edge
           out      tccr1b, r16      ; input capture on rising edge
           ldi      xh, high(sine_ptr)
           ldi      xl, low(sine_ptr)
           ldi      r16, low((cw_sine_tbl<<1)-1)
           st      x+, r16
           ldi      r16, high((cw_sine_tbl<<1)-1)
           st      x+, r16            
           sbr      tm1_status, (1<<cw_tone_on)
           sei                  ; enable all interrupts
           
main:            
       
           rjmp      main
;************************************************
;* read                                    *
;* zl - eeprom address, return increased      *
;* r0 - value got                        *
;************************************************
read_eeprom:
     out      eearl,zl
     sbi      eecr,eere
     in      zl,eedr
     inc      zl
     ret
           
cw_sine_tbl:                        ; 800 hz sine table for cw
           .db 255,247,225,191,150,105,64,30,8,0,8,30,64,105,150,191,225,247
end_of_cw_sine_tbl:


.eseg
.org 0x30
morse_ele_tm:      
           .db.0x80
.org 0x40
morse_table:      
           .db 0b00000000            ;20 space
           .db 0b10101110            ;21 '!'      _._.__
           .db 0b01001010            ;22 '"'      ._.._.
           .db 0b00000000            ;23 '#'      
           .db 0b00010011            ;24 '$'      ..._.._
           .db 0b00000000            ;25 '%'      
           .db 0b00000000            ;26 '&'      
           .db 0b01111010            ;27 '''      .____.
           .db 0b10110110            ;28 '(' _.__._
           .db 0b10110110            ;29 ')' _.__._
           .db 0b00000000            ;2a '*'
           .db 0b01010100            ;2b '+' ._._.
           .db 0b11001110            ;2c ',' __..__
           .db 0b10000110            ;2d '-' _...._
           .db 0b01010110            ;2e '.' ._._._
           .db 0b10010100            ;2f '/'      _.._.


           .db 0b11111100            ;30 Ɔ' _____
           .db 0b01111100            ;31 Ƈ'      .____
           .db 0b00111100            ;32 ƈ'      ..___
           .db 0b00011100            ;33 Ɖ'      ...__
           .db 0b00001100            ;34 Ɗ'      ...._
           .db 0b00000100            ;35 Ƌ'      .....
           .db 0b10000100            ;36 ƌ'      _....
           .db 0b11000100            ;37 ƍ'      __...
           .db 0b11100100            ;38 Ǝ' ___..
           .db 0b11110100            ;39 Ə' ____.
           .db 0b11100010            ;3a ':' ___...
           .db 0b10101010            ;3b '' _._._.
           .db 0b00000000            ;3c '<'
           .db 0b10001100            ;3d '=' _..._
           .db 0b00000000            ;3e '>'
           .db 0b00110010            ;3f '?'      ..__..                                          

           .db 0b00000000            ;40 '@'
           .db 0b01100000            ;41 'a'      ._
           .db 0b10001000            ;42 'b'      _...
           .db 0b10101000            ;43 'c'      _._.
           .db 0b10010000            ;44 'd'      _..
           .db 0b01000000            ;45 'e'      .
           .db 0b00101000            ;46 'f'      .._.
           .db 0b11010000            ;47 'g'      __.
           .db 0b00001000            ;48 'h' ....
           .db 0b00100000            ;49 'i' ..
           .db 0b01111000            ;4a 'j' .___
           .db 0b10110000            ;4b 'k' _._
           .db 0b01001000            ;4c 'l' ._..
           .db 0b11100000            ;4d 'm' __
           .db 0b10100000            ;4e 'n' _.
           .db 0b11110000            ;4f 'o'      ___

           .db 0b01101000            ;50 'p' .__.
           .db 0b11011000            ;51 'q'      __._
           .db 0b01010000            ;52 'r'      ._.
           .db 0b00010000            ;53 's'      ...
           .db 0b11000000            ;54 't'      _
           .db 0b00110000            ;55 'u'      .._
           .db 0b00011000            ;56 'v'      ..._
           .db 0b01110000            ;57 'w'      .__
           .db 0b10011000            ;58 'x' _.._
           .db 0b10111000            ;59 'y' _.__
           .db 0b11001000            ;5a 'z' __..
           .db 0b00000000            ;5b '['
           .db 0b00000000            ;5c '\'
           .db 0b00000000            ;5d ']'
           .db 0b00000000            ;5e '^'
           .db 0b00110110            ;5f '_'      ..__._
离线BA5RW
发帖
48263
只看该作者 1楼 发表于: 2007-04-29
好!有C的就更好……
离线bv2ac
发帖
14169
只看该作者 2楼 发表于: 2007-04-30
sin table 為何用 18 byte, 16 byte 才對吧...?
离线BA1FB
发帖
28695
只看该作者 3楼 发表于: 2007-04-30
'
sin table 為何用 18 byte, 16 byte 才對吧...?
'
这还是2000年写的程式,已经记不清当时是怎么想的了?不过又复习了一下,好像这个程式只能发一个固定tone,大哥的意思是如果是16字节就可以用dds的方式合成不同的tone了,16个字节做dds计算比较简便
离线BA5RW
发帖
48263
只看该作者 4楼 发表于: 2007-04-30
'
sin table 為何用 18 byte, 16 byte 才對吧...?
'
2AC也用AVR做事情吗?小弟最近才开始利用空余时间学习AVR,如有问题能否请教您呢?
离线bv2ac
发帖
14169
只看该作者 5楼 发表于: 2007-04-30
'
这还是2000年写的程式,已经记不清当时是怎么想的了?不过又复习了一下,好像这个程式只能发一个固定tone,大哥的意思是如果是16字节就可以用dds的方式合成不同的tone了,16个字节做dds计算比较简便
'

不是此意, 一般look table 是用一個 reg 作 loop counter, 通常用自然溢位 計數到 8, 16,32 就回到 table 的頭, 你用 18 個 byte 就一定要有 18 計數到 0 或 0 數到 18 再歸零 reload, 但程式找不到 18 12h 的字樣.   你用 18 想必是把 sin wave 劃分為 20 度 整數, 這樣發 800 hz 就用 16000 hz 作 timer int, 也是可以的.

又 :
http://www.aec-electronics.co.nz/wp-content/uploads/2007/01/aec_isp.pdf

這是你的作品吧, 用在 window xp 的打印機 lpt端子好像要特別的驅動許可(dll? sys?), 不知有無解決之道, 我現用 ibm r32 (win xp sp2) 都無法操作 lpt 作 isp 燒錄用途....
离线bv2ac
发帖
14169
只看该作者 6楼 发表于: 2007-04-30
'
2AC也用AVR做事情吗?小弟最近才开始利用空余时间学习AVR,如有问题能否请教您呢?
'

ba1fb 老師是全國 avr 的一哥.... 我沒學過, 只是拿空白的 avr 燒別人公開的程式,.... 我的主打是 8051, avr 與 51 語言近似, 所以有時把 avr 轉成 51 做自己的作品....
离线BA5RW
发帖
48263
只看该作者 7楼 发表于: 2007-05-01
'
ba1fb 老師是全國 avr 的一哥.... 我沒學過, 只是拿空白的 avr 燒別人公開的程式,.... 我的主打是 8051, avr 與 51 語言近似, 所以有時把 avr 轉成 51 做自己的作品....
'
晕,人家是把51转AVR,你倒行逆施啊?!呵呵.
离线BA1FB
发帖
28695
只看该作者 8楼 发表于: 2007-05-01
'
不是此意, 一般look table 是用一個 reg 作 loop counter, 通常用自然溢位 計數到 8, 16,32 就回到 table 的頭, 你用 18 個 byte 就一定要有 18 計數到 0 或 0 數到 18 再歸零 reload, 但程式找不到 18 12h 的字樣.   你用 18 想必是把 sin wave 劃分為 20 度 整數, 這樣發 800 hz 就用 16000 hz 作 timer int, 也是可以的.
'
cpi zl, low((end_of_cw_sine_tbl<<1)-1)
小弟是用这个语句判断是否到了table的尽头,如果到了再将指针指向头端

'

又 :
http://www.aec-electronics.co.nz/wp-content/uploads/2007/01/aec_isp.pdf

這是你的作品吧, 用在 window xp 的打印機 lpt端子好像要特別的驅動許可(dll? sys?), 不知有無解決之道, 我現用 ibm r32 (win xp sp2) 都無法操作 lpt 作 isp 燒錄用途....
'
不是,小弟已经不再写这些程式了,而是拿别人的免费程式来用,如果用xp系统,可以参考这个硬体图纸制作一个烧录器 然后到这个网站下载程式配合使用即可。http://www.lancos.com/prog.html
离线BA1FB
发帖
28695
只看该作者 9楼 发表于: 2007-05-01
ac兄,这张照片蓝线左侧即是小弟按照上面给出的图纸diy的编程器,其中usb接头连接在电脑的usb端口,给目标板提供电源,db25连接到电脑的打印口上。右侧是待烧录的目标板,上面是一片mega8
离线bv2ac
发帖
14169
只看该作者 10楼 发表于: 2007-05-01
謝謝.... 應該是 avr 的燒錄利器, 但是否能燒錄 89s51, 89s52... 我現在用的是 hp + winme + asim khan isp-pgm v3.0a, 就是不認 winxp 打印口...
离线ba1ka
发帖
1044
只看该作者 11楼 发表于: 2007-05-03
fb: 你的贴是专为老蔡写的吧?程式,硬体,烧录。。。。。。俺都晕了!
离线bv2ac
发帖
14169
只看该作者 12楼 发表于: 2007-05-05
1fb 發的可能是他的 '汽球無線電中繼器' 的案子....

另外 @ 字 itu 有公告了

.db 0b01101010 ;40 '@' .--.-.
.db 0b01100000 ;41 'a' ._
.db 0b10001000 ;42 'b' _...
.db 0b10101000 ;43 'c' _._.
离线BA1FB
发帖
28695
只看该作者 13楼 发表于: 2007-05-07
這個程式配合的硬體有一片isd的錄音芯片,一片mt8870 dtmf解碼芯片。原打算用來控制一個電台在2米上發cw和語音字母解釋法,供初學的火腿學習抄手cw用,計劃通過rand函數產生100組報文,通過dtmf遙控發送那一組,以及發送的形式,發送的形式有三種:1.cw加字母解釋法,供學習用;2.cw,供抄收用;3.字母解釋法,供校對用。dtmf由四個數字組成,1001:形式1發送001組報文,2001形式2發送001組報文,3001形式3發送001組報文,等等。但後來聽說法規不允許,再加上沒時間再完善,就擱置了下來。