在线情况
楼主
  • 头像
  • 级别
  • 门派
  • 职务总版主
  • 声望+9
  • 财富5
  • 积分3065
  • 经验390701
  • 文章6744
  • 注册2006-03-07
MSP430-IO模拟串口通讯实验[这个可学到很多知识]
 <<MSP430F1121的Timer_A实现模拟串口功能例程>>
 [URL=http://www.microcontrol.cn/datasheet/MSP430/MSP430base/MSP430Timer_A_USART.pdf]http://www.microcontrol.cn/datasheet/MSP430/MSP430base/MSP430Timer_A_USART.pdf[/URL]

      [IMGA=0,absMiddle]../../upload/2006/06/16/023502.gif[/IMGA]
 
   为了加强你对MSP430的Timer A模块应用知识,新手门不防做做这个DIY实验。
      [IMGA=0,absMiddle]../../upload/2006/06/16/023150.jpg[/IMGA]
      
   上图是我当年初学MSP430单片机时自己动手制作的,图片右边的IC是一个485通讯驱动器,直接做成485通讯之用。现在想起来当年做的这个小玩意还是很有意思的,这当中可以让新手们可以学到TA和串口实验原理。看例子也许你能看得明白,但真正自己动起手来又是另外一回事了。建议在校的学生哥们多多动手,读大学并不是拿了文凭就那么回事。更重要的是理论结合实战动手能力,做到毕来后要文武双全。        
[ 此贴最后由DC在2008-8-12 1:06:05编辑过 ]
[COLOR=#0000ff]欢迎发贴分享设计心得、开源DIY...[/COLOR]
在线情况
2
  • 头像
  • 级别
    • 积分21
    • 经验8680
    • 文章183
    • 注册2006-05-23
    棒极了,我上次有release的帮忙汇编实验成功了.
    下面是汇编程序,供大家参考!!
    ;主要函数及其功能:1."Set_DCO"校准(Calibrate) DCO
    ;                 2."TA0_ISR" TIME_A中断子程序
    ;                 3."RX_Ready"准备接收UART ready to RX one Byte
    ;                 4."TX_Byte"发送接收到的一个字节
    ;备注:可用串口调试助手2.2测试     
    ;******************************************************************************
    ;说明: 发送1个字节,接收1个字节,格式:TX:"01",RX:"01"
    ;   This program demonstrates a half-duplex 9600-baud UART using
    ;   Timer_A3 and a 32kHz crystal.  The program will wait in LPM3, echoing back
    ;   a received character using 8N1 protocol.  The Set_DCO subroutine will
    ;   calibrate the DCOCLK to ~2Mhz, which is used as the Timer_A clock.
    ;   ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO
    ;   //*External watch crystal installed on XIN XOUT is required for ACLK*//       
    ;
    ;                MSP430F1121
    ;             -----------------
    ;         /|\|              XIN|-  
    ;          | |                 | 32k
    ;          --|RST          XOUT|-
    ;            |                 |
    ;            |   CCI0A/TXD/P1.1|-------->  
    ;            |                 | 9600 8N1
    ;            |   CCI0B/RXD/P2.2|<--------
    ;-------------------------------------------------------------
    ;   CPU registers used
    #define      RXTXData R4                   
    #define      BitCnt   R5
    ;Conditions for 9600 Baud HW/SW UART, SMCLK = DCOCLK ~ 2Mhz
    Bitime_5     equ    0104                    ; ~ 0.5 bit length
    Bitime       equ    0208                    ; ~ 9615 baud
    Delta        equ    0488                    ; DCOCLK = (Delta)/(32768/8)

    RXD          set    004h                    ; RXD on P2.2
    TXD          set    002h                    ; TXD on P1.1
    ;
    ;   M.Buccini
    ;   Texas Instruments, Inc
    ;   January 2004
    ;******************************************************************************
    #include  "msp430x11x1.h"
    ;------------------------------------------------------------------------------
                ORG     0FC00h                  ; Program Start
    ;------------------------------------------------------------------------------
    RESET       mov.w   #300h,SP                ; Initialize Stackpointer
    StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT
    SetupBC     bis.b   #DIVA_3,&BCSCTL1        ; ACLK=LFXT1CLK/8=4096
    Setup_TA    mov.w   #TASSEL_2+MC_2,&TACTL   ; Timer_A输入信号为SMCLK, 连续增计数0H->0FFFFH->0H->0FFFFH
                call    #Set_DCO                ; 校准(Calibrate) DCO
    SetupC0     mov.w   #OUT,&CCTL0             ; TXD Idle as Mark
    SetupP1_2   bis.b   #TXD,&P1SEL             ; P1.1/TA0 for TXD function
                bis.b   #TXD,&P1DIR             ; TXD output on P1
                bis.b   #RXD,&P2SEL             ; P2.2/TA0 as RXD input
                                                ;
    Mainloop    call    #RX_Ready               ; 准备接收UART ready to RX one Byte
                bis.w   #LPM3+GIE,SR            ; Enter LPM3 w/ int until Byte RXed
                call    #TX_Byte                ; 发送接收到的一个字节TX Back RXed Byte Received
                jmp     Mainloop                ;
                                                ;
    ;-----------------------------------------------------------------------------
    TX_Byte   ; Subroutine that Transmit One Byte from RXTXData Buffer.
    ;-----------------------------------------------------------------------------
                bis.b   #04h,&P1DIR             ;打开端口方向
                bis.b   #04h,&P1OUT             ;定义使能端
                mov.w   &TAR,&CCR0              ; TA定时器值送CCR0(Current state of TA Counter)
                add.w   #Bitime,&CCR0           ; 加一个位时间(Some time till first bit)
                bis.w   #0100h, RXTXData        ; 置停止位Add mark stop bit to RXTXData
                rla.w   RXTXData                ; 算术左移Add space start bit
                mov.w   #10,BitCnt              ; 10位Load Bit Counter, 8data + ST/SP
                mov.w   #OUTMOD0+CCIE,&CCTL0    ; 输出模式,允许中断TXD = mark = idle
    TX_Wait     bit.w   #CCIE,&CCTL0            ; 等待发送完成Wait for TX completion
                jnz     TX_Wait                 ;
                ret                             ;
                                                ;
    ;-----------------------------------------------------------------------------
    RX_Ready  ; Subroutine that will Receive One Byte into RXTXData Buffer.
              ; !! Sync capture not possible as DCO=TACLK=SMCLK can be off !!
    ;-----------------------------------------------------------------------------
                bis.b   #08h,&P1DIR             ;打开端口方向
                bic.b   #08h,&P1OUT             ;定义使能端
                mov.w   #08,BitCnt              ; Load Bit Counter, 8 data bits
    SetupRX     mov.w   #CM1+CCIS0+OUTMOD0+CAP+CCIE,&CCTL0  ;上升沿捕获,选择CCI0A为捕获的输入信号源,
                                      ;输出模式,捕获模式,允许中断(Neg Edge,Cap)          
                ret                             ;
                                                ;
    ;-----------------------------------------------------------------------------
    TA0_ISR  ;  CCR0/UART ISR:   RXTXData Buffer holds UART Data.
    ;-----------------------------------------------------------------------------
                add.w   #Bitime,&CCR0           ; 1个位时间Time to Next Bit
                bit.w   #CCIS0,&CCTL0           ; RX on ISCCIB?
                jnz     UART_RX                 ; 为1跳(即选择CCI0B为捕获的输入信号源)Jump --> RX
                                            ; 为0(即选择CCI0A为捕获的输入信号源)
    UART_TX     cmp.w   #00h,BitCnt             ; 10为是否发完
                jne     TX_Next                 ; 未完跳Next bit?
                bic.w   #CCIE,&CCTL0            ; 完了清除中断All Bits TX or RX, Disable Int.
                reti                            ;
    TX_Next     bic.w   #OUTMOD2,&CCTL0         ; 清除TX Mark
                rra.w   RXTXData                ; 算术右移LSB is shifted to carry
                jc      TX_Test                 ; 为1跳Jump --> bit = 1
    TX_Space    bis.w   #OUTMOD2,&CCTL0         ; 为0 PWM翻转/复位TX Space
    TX_Test     dec.w   BitCnt                  ; 位计数减1位All bits sent (or received)?
                reti                            ;
                                                ;
    UART_RX     bit.w   #CAP,&CCTL0             ; 是否为捕获模式Compare mode for start bit edge
                jz      RX_Bit                  ; 不是跳Start bit edge?
    RX_Edge     bic.w   #CAP,&CCTL0             ; 是,清除捕获模式Switch to Compare mode
                add.w   #Bitime_5,&CCR0         ; 加半位时间First databit 1.5 bits from edge
                mov.w   #CPUOFF+GIE,0(SP)       ; !!! DCO needs to remain on !!!
                reti                            ;
    RX_Bit      bit.w   #SCCI,&CCTL0            ; 为1时C=1,为0时C=0,Get bit waiting in receive latch
                rrc.b   RXTXData                ; 带进位右移Store received bit
    RX_Test     dec.w   BitCnt                  ; 位计数减1 All bits sent (or received)?
                jnz     RX_Next                 ; 不位0继续接收Next bit?
    ;>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    RX_Comp     bic.w   #CCIE,&CCTL0            ; 为0清除中断使能All Bits RXed, Disable Interrupt
                mov.w   #GIE,0(SP)              ; Decode Byte= Active in Mainloop
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    RX_Next     reti                            ;
    ;
    ;-----------------------------------------------------------------------------
    Set_DCO;    Subroutine: Sets DCO to selected frequency based on Delta.
    ;           R14 and R15 are used, ACLK = 32768/8 Timer_A clocked by DCOCLK
    ;-----------------------------------------------------------------------------
                clr.w   R15                     ;                                         
    Setup_CC2   mov.w   #CM_1+CCIS_1+CAP,&CCTL2 ; 上升沿捕获,选择CCI2B为捕获的输入信号源,选择捕获模式
    Test_DCO    bit.w   #CCIFG,&CCTL2           ; Test 捕获(capture) flag
                jz      Test_DCO                ; 未捕获继续查
                bic.w   #CCIFG,&CCTL2           ; Clear capture flag
                                                ;
    AdjDCO      mov.w   &CCR2,R14               ; R14 = captured SMCLK
                sub.w   R15,R14                 ; R14 = capture difference,R14=R14-R15
                mov.w   &CCR2,R15               ; R15 = captured SMCLK
                cmp.w   #Delta,R14              ; Delta(488) = SMCLK/(32768/8)
                jlo     IncDCO                  ; R14<488跳
                jeq     DoneDCO                 ; R14=488跳
    DecDCO      dec.b   &DCOCTL                 ; DCOCTL=DCOCTL-1(Slow DCO with DCO and MOD)
                jnz     Test_DCO                ; |=0跳(Slower?)
                cmp.b   #XT2OFF+DIVA_3,&BCSCTL1 ; Can RSEL.x be decremented?
                jz      DoneDCO                 ; 相等返回(jmp>DCO at slowest setting)
                dec.b   &BCSCTL1                ; BCSCTL1=BCSCTL1-1(Decrement RSEL.x)
                jmp     Test_DCO                ; 跳
    IncDCO      inc.b   &DCOCTL                 ; DCOCTL=DCOCTL+1(Speed DCO with DCO and MOD)
                jnc     Test_DCO                ; 没有溢出跳(Faster?)
                cmp.b   #XT2OFF+DIVA_3+07h,&BCSCTL1 ; Can RSEL.x be increased?
                jz      DoneDCO                 ; 相等返回(jmp> DCO at fastest setting)
                inc.b   &BCSCTL1                ; BCSCTL1=BCSCTL1+1(Increment RSEL.x)
                jmp     Test_DCO                ; 跳
    DoneDCO     clr.w   &CCTL2                  ; Stop CCR2
                ret                             ; Return from subroutine
                                                ;
    ;-----------------------------------------------------------------------------
    ;           Interrupt Vectors Used MSP430x11x1          
    ;-----------------------------------------------------------------------------
                ORG     0FFFEh                  ; MSP430 RESET Vector
                DW      RESET                   ;
                ORG     0FFF2h                  ; Timer_A0 Vector
                DW      TA0_ISR                 ;
                END
                
    [ 这个贴子最后由tomlinson在2006-8-16 18:52:20编辑过 ]
    微控网感谢您的参与
    在线情况
    3
    • 头像
    • 级别
      • 积分21
      • 经验8680
      • 文章183
      • 注册2006-05-23
      very good!  谢谢DC的分析!!
      [ 这个贴子最后由tomlinson在2006-6-16 15:25:44编辑过 ]
      微控网感谢您的参与
      在线情况
      4
      • 头像
      • 级别
        • 积分15
        • 经验908
        • 文章47
        • 注册2006-05-12
        谢谢楼主了
        微控网感谢您的参与
        在线情况
        5
        • 头像
        • 级别
        • 门派
        • 职务总版主
        • 声望+9
        • 财富5
        • 积分3065
        • 经验390701
        • 文章6744
        • 注册2006-03-07
        CCR0加半位时间的原因是当捕获比较功能捕获到起始位后,再加上半位的时间产生中断。以后在读取每一位时间时都能采样到每的中间值。以确保读数的准备性。
                        *
                    |-------|
            --------         -------   相差半位时间,后面读数都是在每位的中间采样。这样就能准确点。
        [COLOR=#0000ff]欢迎发贴分享设计心得、开源DIY...[/COLOR]
        在线情况
        6
        • 头像
        • 级别
          • 积分21
          • 经验8680
          • 文章183
          • 注册2006-05-23
          电路图好象标错了,P1.1------TXD
                           P2.2------RXD
          微控网感谢您的参与
          在线情况
          7
          • 头像
          • 级别
          • 门派
          • 职务总版主
          • 声望+9
          • 财富5
          • 积分3065
          • 经验390701
          • 文章6744
          • 注册2006-03-07
          是的,图将两脚标反了。谢谢提醒!
          我可要去改正过来....
            图片与文件已修正过来。
          [em07]
          [ 这个贴子最后由DC在2006-6-17 16:16:26编辑过 ]
          [COLOR=#0000ff]欢迎发贴分享设计心得、开源DIY...[/COLOR]
          在线情况
          8
          • 头像
          • 级别
            • 积分1
            • 经验52
            • 文章5
            • 注册2006-07-13
            用汇编写的啊
            有些看不太懂啊
            微控网感谢您的参与
            在线情况
            9
            • 头像
            • 级别
              • 积分1
              • 经验356
              • 文章6
              • 注册2006-07-26
              不错,我喜欢看汇编写的程序
              微控网感谢您的参与
              在线情况
              10
              • 头像
              • 级别
              • 门派
              • 职务总版主
              • 声望+9
              • 财富5
              • 积分3065
              • 经验390701
              • 文章6744
              • 注册2006-03-07
              呵呵...只要你欢迎什么都行。但是用C的会更多,建议学学。对你在将来有莫大的帮助!
              [COLOR=#0000ff]欢迎发贴分享设计心得、开源DIY...[/COLOR]
              在线情况
              11
              • 头像
              • 级别
                • 积分3
                • 经验2419
                • 文章47
                • 注册2006-06-22
                            bis.b   #08h,&P1DIR             ;打开端口方向
                            bic.b   #08h,&P1OUT             ;定义使能端

                这两句是什么意思? P1.3使能什么?
                微控网感谢您的参与
                在线情况
                12
                • 头像
                • 级别
                • 门派
                • 职务总版主
                • 声望+9
                • 财富5
                • 积分3065
                • 经验390701
                • 文章6744
                • 注册2006-03-07
                  从tomlinson的例子电路图来看,是没有用到P1.3口的。还有一种可以是用在RS485方式时用于控制使能之用的。因为刚好是RX_Ready程序代码段,并写明了使能端。有可以是485驱动芯片的使能端的。
                  这个可以由tomlinson解释下了。
                [COLOR=#0000ff]欢迎发贴分享设计心得、开源DIY...[/COLOR]
                Powered by LeadBBS 9.2 .
                Page created in 0.2031 seconds with 5 queries.