找回密码
 立即注册
楼主: wuzhengmin

有关DMA,山东大学陈桂友教授

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 20:39:00 | 显示全部楼层
下面是C语言对应的程序:

#include <AI8051U.H>
unsigned char xdata ADDRT[128]; //在外部RAM区定义128个单元

unsigned char num=0;    //声明计数变量
unsigned char xdata *psend;   //指向发送数据区的指针


void main(void)       //主程序,在C语言的主程序中可以不设置堆栈指针
{

        SCON=0x40;        //8位数据,可变波特率
        AUXR &= 0xFE;     //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;     //设定定时器1为16位自动重装方式

        TL1 = 0xE8;       //设定定时初值
        TH1 = 0xFF;       //设定定时初值
        TR1 = 1;          //启动定时器1
       
        ES=1;             //串行口开中断
        psend = ADDRT;      //设置发送数据缓冲区指针
        EA=1;             //开中断
        psend=ADDRT;      //设置发送数据缓冲区指针
        SBUF = *psend;    //发送第一个数据
        while(1);         //等待中断
}

void UART1_ISR(void) interrupt  UART1_VECTOR  //串口1中断服务函数
{

        TI = 0;         //清发送中断标志
        num++;          //修改计数变量值
        if(num==0x7F)
                ES=0;       //判断是否发送完,若已完,则关中断
        else
        {
                psend++;      //否则,修改指针,发送下一个数据
                SBUF= *psend;
        }
}

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 20:56:17 | 显示全部楼层
接收方的汇编源程序:

截图202601212056153403.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 21:18:53 | 显示全部楼层
我们也只能慢慢输入:

//  $include (../comm/AI8051U.INC)

           $INCLUDE (AI8051U.INC) ;包含AI8051U单片机的寄存器定义文件
           ADDRT EQU 1000H
       ORG  0000H

LJMP                   MAINT   ;跳至主程序入口
                        ORG  0023H
                        LJMP UART1_ISR     ;转至串行中断服务程序
                       
                        ORG  0200H
         
MAINT:                 MOV SP, #80H       ;设置堆栈指针
                        MOV SCON, #50H     ;8位数据,可变波特率
                        ANL AUXR, #0FEH    ;串口1选择定时器1为波特率发生器
                        ANL TMOD, #0FH     ;设定定时器1为16位自动重装方式
                        MOV TL1, #0E8H     ;设定定时初值
                        MOV TH1, #0FFH     ;设定定时初值
                        CLR ET1            ;禁止定时器1中断
                        SETB TR1           ;启动定时器1
                        SETB ES            ;串行口开中断
                        SETB EA            ;开总中断

                        MOV DPTR,#ADDRT    ;ADDRT是首址,可以使用EQU定义
                        MOV R0,#00H        ;传送字节数初值
                        MOVX A,@DPTR       ;取第一个发送字节
                        MOV SBUF,A         ;启动串行口发送
                        SJMP $             ;等待中断

                        ;中断服务程序
UART1_ISR:  CLR RI             ;接收中断标志清零

                        MOV A,SBUF         ;取接收的数据
                        MOVX @DPTR,A        ;接收的数据送缓冲区
                        CJNE R0,#7FH,LOOPR ;判断128B是否接收完,若没完,则转LOOPR
                       
                        CLR ES             ;全部接收完毕,禁止串行口中断
                        LJMP ENDR          ;转中断返回
                       
LOOPR:      INC R0             ;修改字节数指针                       
                        INC DPTR           ;修改地址指针,继续取下一发送数据
                       
                                               
ENDR:       RETI               ;中断返回
                        END

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 21:45:16 | 显示全部楼层
对应的C语言接收源程序:

#include <AI8051U.H>
unsigned char xdata ADDRT[128]; //在外部RAM区定义128个单元

unsigned char num=0;    //声明计数变量
unsigned char xdata *prcc;   //指向接收数据区的指针


void main(void)       //主程序,在C语言的主程序中可以不设置堆栈指针
{

        SCON=0x50;        //8位数据,可变波特率
        AUXR &= 0xFE;     //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;     //设定定时器1为16位自动重装方式

        TL1 = 0xE8;       //设定定时初值
        TH1 = 0xFF;       //设定定时初值
        ET1 = 0;         //禁止定时器1中断
        TR1 = 1;          //启动定时器1
        ES=1;             //串行口开中断
        EA=1;             //开中断
       
        prcc = ADDRT;      //设置发送数据缓冲区指针
               
        while(1);         //等待中断
}

void UART1_ISR(void) interrupt  UART1_VECTOR  //串口1中断服务函数
{

        RI = 0;         //清接收中断标志
        num++;          //修改计数变量值
        if(num==0x7F)
                ES=0;       //判断是否接收完,若已完,则关中断
        else
        {
               
                *prcc = SBUF ;
                prcc++;      //修改指针,接收下一个数据
        }
}

回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 21:52:54 | 显示全部楼层
接下来我们看看下一个内容:

截图202601212152524779.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 21:54:03 | 显示全部楼层
串口2 的使用实际例子:

截图202601212154004028.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 21:55:10 | 显示全部楼层
还有多机通信的问题:

截图202601212155082919.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 22:03:17 | 显示全部楼层
多机通信的时候,主机发送地址后,要等待从机的回应

回应之后,再发送数据............

从机:接收主机发来的地址帧信息,并与本机的地址号相比较,若不符合,仍保持SM2=1不变;若相等,则使SM2清零,准备接收后续的数据信息,直至接收完10个数据信息。

截图202601212203145162.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 22:05:44 | 显示全部楼层
SM2 这个标志位很重要,从机是否接收数据,就取决于SM2是否=0

SM2=0就接收数据!

流程图如下:

截图202601212205401562.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:153
  • 最近打卡:2026-03-30 19:54:03
已绑定手机

22

主题

2426

回帖

3422

积分

论坛元老

积分
3422
发表于 2026-1-21 22:12:34 | 显示全部楼层
TB8一开始=1 ,表示主机发送的是地址信息

发送完地址信息就等待中断,因此

进入中断服务程序后,先把发送中断标志TI清零

既然能进入中断服务程序,说明地址已经发送完了

接着就把TB8清零,表示要发送数据了,TB8是在SCON寄存器中

启动发送,循环10次,把数据发生完,恢复现场,返回主程序






回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-1 02:43 , Processed in 0.129237 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表