zhliao2

风雨兼程,一路向北-------fpga (Keep a quiet heart study)
串行通信

本实验选择11.0592晶振,波特率为9600,串行工作方式1( SCON = 0X40 );

最近被Verilog代码搞得头有点晕,或许是没有深入了解硬件思想的原因吧,有或许是没有模块化概念,总之,被它磨的信心有点。。。,不说了,这里是单片机啊,额,看来,不管学什么东西,具体的流程还是要去了解并付诸行动的,好吧,先上流程图先(嘻嘻,懒的自己画,直接copy的O(∩_∩)O~)。

代码:

# include <reg52.h>

unsigned char data byData[10] _at_ 0x70; //在数据存储器70H~79H空间开辟数组
unsigned char data byCounter = 0;      //发送数据的计数器

//这里的定时器1中断不用打开噢
void main (void)
{
    unsigned char data i;
    SP = 0x30;       //设置栈底指针
    TMOD = 0X20;   //定时器1作为波特率发生器,采用定时器方式2
    SCON = 0x40;   //串行口工作于方式1,不允许接受数据
    PCON = PCON & 0X7F;//SMOD置0,若置1,则为 PCON = PCON | 0X8F;,置1为波特率倍增
    TL1 = 0xFD;      //定时器1置初值,设置波特率为9600;
    TH1 = 0xFD;      //定时器1置初值,设置波特率为9600;
    TR1 = 1;      //开定时器1,置重载值
    ES = 1;          //打开串口中断
    EA = 1;          //打开总中断
    
    for (i = 0; i < 10; i ++)
    {
        byData[i] = '0' + i;  //在数据存储器70H-79H空间存放ASCII码0,1,2至9
    }
    
    SBUF = byData[byCounter]; //将要发送的第一个数据放入发送缓冲区,启动发送
    byCounter ++;    //发送缓冲区的计数器加1
    while (1);
}

void UART (void) interrupt 4
{
    if (TI == 1)  //发送中断
    {
        TI = 0;      //清除中断该标志位 
        if (byCounter < 10)
        {
            SBUF = byData[byCounter];     //继续发送数据
            byCounter ++;              //发送数据的计数器加1
        }
    }

    else
    { //接受中断
        RI = 0;      //清除接受中断该标志位
    }
}

汇编:

     ORG 0000H      ;程序的起始地址
     LJMP MAIN    ;开始执行主程序
     ORG 0023H      ; 串口中断服务程序入口地址
     LJMP UART_SERVICE    ;跳转至串口中断服务程序 
     ORG 0030H
 MAIN:
     MOV SP, #30H ;设置栈底指针
    MOV SCON, #40H    ; 串口工作于方式 1,不允许接收数据
    ANL PCON, #7FH    ;SMOD 置 0,波特率倍增;若要置1,如何写?ORL PCON, #80H
    MOV TMOD, #20H     ;定时器/计数器 1 作波特率发生器,采用定时器方式2 
    MOV TL1, #0FDH     ;定时器/计数器 1 置初始值,设置的波特率为9600bps 
    MOV TH1, #0FDH     ;定时器/计数器 1 置重装载值 
    SETB TR1         ;定时器/计数器 1 启动工作
    SETB ES             ;打开串口中断 
    SETB EA             ;打开总中断 

    MOV R0, #70H     ; 以下7 行程序,在数据存储器70H-79H 存放 0 至 9 的ASCII 码
    MOV R7, #10         ;要存放的数有 10 个 
    MOV A, #30H         ;0  的ASCII 码 
MakeData:
    MOV @R0, A          ;将数字对应的 ASCII 码存放到 R0 间接寻址单元 
    INC A              ;存放的数加 1 
    INC R0              ;存放地址加 1 
    DJNZ R7, MakeData ;计数器减 1,不为0 则继续填数
    MOV R0, #70H      ;准备从 70H 单元开始取数 
    MOV R7, #10          ;计数器置 10,要发送的数有 10 个
    MOV SBUF, @R0      ;将数据放入发送缓冲区,启动发送 
LOOP:
    NOP
    NOP
    SJMP LOOP
//关键的步骤在窗口中断里面的
UART_SERVICE:
    JBC RI, EXIT   ;判断是否为接收中断 
                   ;是的话,则清除接收中断标志位并退出中断服务程序                                                
    CLR TI           ;不是接收中断,是发送中断,则清除发送中断标志位 
    INC R0            ;数据指针加 1,准备取下一个数
    DJNZ R7, SEND    ;检查是否发送完毕,没有则继续发送,否则发送程序结束
    SJMP EXIT
SEND:
    MOV SBUF, @R0    ;将数据放入发送缓冲区,启动发送
EXIT:
    RETI
    END
    

 

protus:

结果:

这里有一点小知识点,当你看不到如上图所示的框图时,你该怎么办呢?请看下图:

hey:boy,在VIRTUAL TERMINAL别别忘了以下的设置哦,记着,单片机的是ttl电平(正逻辑),想想,计算机的是负逻辑。

关于第二个实验的

在COMPIM注意两者的波特率要相同:

虚拟串口:

串口调试助手:

posted on 2012-05-17 14:25  zhliao  阅读(874)  评论(0)    收藏  举报