Chinaunix首页 | 论坛 | 博客
  • 博客访问: 173768
  • 博文数量: 75
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 405
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-25 01:16
文章分类

全部博文(75)

文章存档

2013年(2)

2012年(73)

我的朋友

分类:

2012-06-10 01:43:46

原文地址:51单片机复习 作者:yaoyabad

  1. 这两天复习51汇编的结果
    MCU:AT89C51
    晶振:11.0592MHz
    波特率:9600
    外部RAM:6116 (8×2K)
    调试平台:Keil uv4+Proteus7.6
  2. 原理图
  3. 汇编调试代码

        org 0000h
        jmp    start
        org 03h
        jmp int_ext0
        org 0bh
        jmp int_timer0
        org 13
        jmp loop
        org 1bh
        jmp loop
        org 23h
        jmp int_uart
        org 2bh
        jmp loop

        org    30h

    start:
        mov p1,#0ffh
        mov dptr,#0000h
        mov a,#1
    initmm:
        setb ti
        movx @dptr,a
        inc dptr
        mov r0,dph
        cjne r0,#09h,initmm
        acall delay
        acall init_int
        clr a
        movx a,@dptr
        
        mov p1,a

        mov dptr,#stringspace
        mov r0,#10
        acall printrom
        jmp loop
    backr:
        acall backreceive
    loop:
        cjne r7,#10h,backr
        jmp    loop


    delay:
        setb rs0
        setb rs1
        mov r7,a
        mov a,#1h
    delay1:
        jz enddelay
        mov r1,#0ffh
    delloop1:
        mov r2,#0ffh
    delloop2:
        nop
        nop
        nop
        nop
        djnz r2,delloop2
        djnz r1,delloop1
        dec a
        sjmp delay1
    enddelay:
        mov a,r7
        clr rs0
        clr rs1
        ret

    init_int:
        setb it0    ;下降沿触发外部中断0
        setb ex0

        ;mov tmod,#01    ;16bit定时器0
        ;mov th0,#69h    ;定时32ms
        ;mov tl0,#0ffh
        
        mov tmod,#05h    ;计数器0
        mov th0,#0ffh    ;计数3次
        mov tl0,#0fch

        setb et0
        setb tr0
        setb pt0

        clr sm0
        setb sm1
        setb ren
        clr rb8
        clr tb8

        mov a,pcon
        anl a,#0fh
        orl a,#080h
        mov pcon,a    ;波特率加倍

        mov a,tmod
        anl a,#0fh
        orl a,#20h
        mov tmod,a     ;8bit定时器1,自动装置
        mov th1,#0fah    ;波特率为9600(晶振频率假设为11.0592MHz)
        mov tl1,#0fah
        setb tr1
        setb es

        setb ea

        mov r7,#10h
        ret
        
    int_ext0:
        cpl p1.7
        clr ie0
        reti
        
    int_timer0:
        cpl p1.6
        mov th0,#0ffh
        mov tl0,#0fch
        reti

    int_uart:
        jnb ri,int_uart_end
        inc r7
        mov a,r7
        acall save_case
        mov r1,a
        mov a,sbuf
        movx @r1,a
        acall back_case
        clr ri
        jmp int_uart_end    
    int_uart_end:
           reti

    backreceive:
    uart_busy:
        jnb ti,uart_busy
        mov a,r7
        mov r1,a
        movx a,@r1
        mov sbuf,a
        clr ti
        dec r7
        ret
        
    printrom:
        ;first address in dptr
        ;size in r0
        mov r1,#0
    printrom_loop:
        mov a,r1
        movc a,@a+dptr
        acall send_b
        inc r1
        djnz r0,printrom_loop
        ret
        
    send_b:
        ;data in a
        jnb ti,send_b    ;busy
        mov sbuf,a
        clr ti
        ret
        
    save_case:
        clr rs0
        setb rs1
        ret

    back_case:
        clr rs1
        ret    

    stringspace:
        db "hello word"
        end


  4. C语言调试代码
     

    #include <reg51.h>
    #define uchar unsigned char
    #define uint unsigned int
    #define ulong unsigned long
    #define T_FIFO char
    #define FOSC 11059200         //晶振频率 Hz

    #define UART_RBUF_SIZE     512    //串口接收缓冲区大小

    #define UART_TBUF_SIZE     20
    #define T_TIMER    0
    #define T_CONUTER 1

    #define NULL 0
    typedef void(*t_func)(void *);

    typedef struct _t_fifo{
        T_FIFO *buf_start;
        T_FIFO *buf_end;
        T_FIFO *head;
        T_FIFO *last;
        T_FIFO *flag;
    }t_fifo,*t_fifo_p;

    typedef struct _t_mydata{
        uint timer0_num;
        uint timer0_ms;
        uint timer0_ms_cur;
        uint timer1_num;
        uint timer1_ms;
        uint timer1_ms_cur;

        t_func timer0_func;
        t_func timer1_func;

        uchar uart_r[UART_RBUF_SIZE];
        uchar *uart_rp;
        t_fifo uart_rfifo;
        //uchar uart_t[UART_TBUF_SIZE];

        uchar *uart_tp_head;
        uchar *uart_tp_end;

        uint tick;
    }t_mydata,*t_mydata_p;



    void fifo_init(t_fifo_p pfifo);
    void* fifo_push(t_fifo_p pfifo,T_FIFO dat);
    T_FIFO fifo_pop(t_fifo_p pfifo)    ;
    char fifo_empty(t_fifo_p pfifo);
    void fifo_set_flag(t_fifo_p pfifo);
    char fifo_flag_changed(t_fifo_p pfifo);

    void init_timer(uchar id,uchar type,uint dat);
    void timer0_routine(void *p);
    void init_irq(uchar id);

    //void putstr(char *dat);

    //void uart_puts(char *dat,uint size);

    void putc(char dat);
    void init_uart(uint baudrate);

    void delaym(uint ms);

    t_mydata xdata _dat;
    const ulong _f=FOSC/12;
    sbit _p17=P1^7;
    bit _uart_t_busy;
    int main()
    {
        _dat.timer1_func=NULL;
        _dat.timer0_func=timer0_routine;
        init_timer(0,T_TIMER,1000);
        init_irq(0);
        init_uart(9600);
        //putstr("hello mm");

        while(1){
            if(!fifo_empty(&_dat.uart_rfifo))
            {
                fifo_set_flag(&_dat.uart_rfifo);
                delaym(10);
                if(!fifo_flag_changed(&_dat.uart_rfifo))
                {
                    while(!fifo_empty(&_dat.uart_rfifo))
                    putc(fifo_pop(&_dat.uart_rfifo));
                }
            }
        }
        //return 0;

    }
    /**
        name:init_timer
        function:initialize timer or conuter
        params:
        @id:timer 0 or 1
        @type:T_TIMER,timer;T_CONUTER,conuter
        @data:if type is T_TIMER,it's the timer by unit is ms;
                else if T_CONUTER,it's the conuter number
    **/

    void init_timer(uchar id,uchar type,uint dat)
    {
        uint num,ms;
        if(type==T_TIMER)
        {
            num=0xffff-_f/1000+1;
            ms=dat;
        }
        else
        {
            num=0xffff-dat;
            ms=0;
        }
        
        if(id==0)
        {
            _dat.timer0_num=num;
            _dat.timer0_ms=ms;
            _dat.timer0_ms_cur=0;
            TMOD&=0xf0;
            TMOD=(type<<2|0x1)|TMOD;
            TH0=(uchar)(num>>8);
            TL0=(uchar)num;
            ET0=1;
            TR0=1;

            _dat.tick=0;
        }
        else if(id==1)
        {
            _dat.timer1_num=num;
            _dat.timer1_ms=ms;
            _dat.timer1_ms_cur=0;
            TMOD&=0x0f;
            TMOD=((type<<2|0x1)<<4)|TMOD;
            TH1=(uchar)(num>>8);
            TL1=(uchar)num;
            ET1=1;
            TR1=1;
        }
        EA=1;
    }

    /**
        name:on_timer0
        function:timer0 is interrupt sevice
        params:
    **/

    void on_timer0(void)interrupt 1 using 1
    {
        TH0=(uchar)(_dat.timer0_num>>8);
        TL0=(uchar)_dat.timer0_num;
        _dat.tick++;
        if(_dat.timer0_ms==(++_dat.timer0_ms_cur)
            &&_dat.timer0_func!=NULL)
        {
            _dat.timer0_ms_cur=0;
            _dat.timer0_func(NULL);
        }    
    }


    /**
        name:timer0_routine
        function:you will do sth when timer0 was come
        params:
            @p:send data
    **/

    void timer0_routine(void *p)
    {
        p=p;
        P1=~P1;
    }

    void init_irq(uchar id)
    {
         if(id>1)return;
         id=1<<(id*2);
         TCON=id|TCON;//edge action

         IE=id|IE;
         EA=1;
    }

    void on_ext0(void)interrupt 0 using 1
    {
        IE0=0;
        //TODO:

        _p17=~_p17;    
    }

    void init_uart(uint baudrate)
    {
        TMOD=(TMOD&0x0f)|0x20;
        TH1=0xff-_f/(16*((ulong)baudrate))+1;
        TL1=TH1;
        ET1=0;
        TR1=1;

        PCON=0x80|PCON;
        SM0=0;
        SM1=1;
        REN=1;
        ES=1;

        _uart_t_busy=0;

        fifo_init(&_dat.uart_rfifo);
        EA=1;
        //PS=1;

        _dat.uart_rp=_dat.uart_r;
        _dat.uart_tp_head=_dat.uart_tp_end=NULL;
    }

    void on_uart(void)interrupt 4 using 1
    {
        if(RI)//receive a data

        {
            
            P1=(uchar)fifo_push(&_dat.uart_rfifo,SBUF);
            RI=0;
        }
        else //sent a data

        {
            TI=0;
            _uart_t_busy=0;
        }
    }
     /*
    void putstr(char *dat)
    {
        _dat.uart_tp_head=dat;
        while(*_dat.uart_tp_head!=NULL)
        {
            putc(*(_dat.uart_tp_head++));
        }
    }

    void uart_puts(char *dat,uint size)
    {
        _dat.uart_tp_head=dat;
        _dat.uart_tp_end=dat+size;
        while(_dat.uart_tp_head<_dat.uart_tp_end)
        {
            putc(*(_dat.uart_tp_head++));
        }
        _dat.uart_tp_head=_dat.uart_tp_end=NULL;
    }
       */

    void putc(char dat)
    {
        while(_uart_t_busy);
        _uart_t_busy=1;
        SBUF=dat;
        while(_uart_t_busy);
    }

    void delaym(uint ms)
    {
        uint to=_dat.tick+ms;
        while(_dat.tick!=to);
    }


    void fifo_init(t_fifo_p pfifo)
    {
        pfifo->buf_start=(T_FIFO*)_dat.uart_r;
        pfifo->buf_end=(T_FIFO*)(_dat.uart_r+UART_RBUF_SIZE-1);
        pfifo->head=pfifo->last=(T_FIFO*)_dat.uart_r;
    }

     //只能在中断函数里面调用

    void* fifo_push(t_fifo_p pfifo,T_FIFO dat) using 1
    {    
        char *tmp=pfifo->last;
        if((++tmp)>pfifo->buf_end)
        {
            tmp=pfifo->buf_start;
        }
        if(tmp==pfifo->head)
            return NULL;
        *pfifo->last=dat;
        pfifo->last=tmp;
        return tmp;
    }

    T_FIFO fifo_pop(t_fifo_p pfifo)
    {
        T_FIFO tmp=*pfifo->head;
        P1=0;
        if(pfifo->head==pfifo->last)return 0;
        pfifo->head++;
        if(pfifo->head>pfifo->buf_end)pfifo->head=pfifo->buf_start;
         return tmp;
    }

    char fifo_empty(t_fifo_p pfifo)
    {
        if(pfifo->head==pfifo->last)return 1;
        return 0;    
    }

    void fifo_set_flag(t_fifo_p pfifo)
    {
        pfifo->flag=pfifo->last;
    }

    char fifo_flag_changed(t_fifo_p pfifo)
    {
        if(pfifo->flag!=pfifo->last)return 1;
        return 0;
    }


  5. 运行基本正常,包括了外部中断,计数器,串口的调试
阅读(737) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~