文号
t69294
阅读
13922
回复
19
收藏
4
卡壳了,这个51程序怎么没动作啊,求解
2015/01/08
IP:广东
刚学51,串口通讯,卡壳了,P31,P30用示波器量了,没波形,看来程序没动作。

#include <reg51.h>
#include <string.h>


#define INBUF_LEN 4   //数据长度


unsigned char inbuf1[INBUF_LEN]="1234";


void init_serialcomm(void)
{
    SCON=0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr
    TMOD=0x20;       //TMOD: timer 1, mode 2, 8-bit reload
    PCON=0x80;       //SMOD=1;
    TH1=0xF4;       //Baud:4800  fosc=11.0592MHz
    TR1=1;          // timer 1 run
}


//向串口发送一个字符
void send_char_com(unsigned char ch)  
{
    SBUF=ch;
    while(TI==0);
    TI=0;
}


//向串口发送一个字符串,strlen为该字符串长度
void send_string_com(unsigned char *str,unsigned int strlen)
{
    unsigned int k=0;
    do
    {
        send_char_com(*(str + k));
        k++;
    } while(k < strlen);
}


void Delay1ms(int x)   //误差 0us
{
    unsigned char a,b,c;
    for(c=0;c<x;c++)
        for(b=38;b>0;b--)
            for(a=13;a>0;a--);
}


main()
{
    init_serialcomm();  //初始化串口
    while(1)
    {
               send_string_com(inbuf1,INBUF_LEN);
    Delay1ms(300);
    }


}
11年11个月前IP:河北
739445
1楼
总中断EA=1?
ES(IE.4),串行口中断允许位;
EA (IE.7), CPU中断允许(总允许)位
时间比较长了,有些生疏。
引用
评论
11年11个月前修改于 11年11个月前IP:河北
739447
2楼
#include<reg52.h>
unsigned char flag,a;
void main()
{

        TMOD=0x20;//设置定时器1为工作方式2
        TH1=0xfd;
        TL1=0xfd;
        TR1=1;
        REN=1;
        SM0=0;
        SM1=1;
        EA=1;
        ES=1;
        while(1)
                {
                /*        if(RI==1)
                        {
                        RI=0;
                        P1=SBUF;
                        }*/
                        if(flag==1)
                                {
                                        ES=0;
                                        flag=0;
                                        SBUF='1';//28;        
                                        while(!TI);        
                                        TI=0;
                                        SBUF='2';//28;        
                                        while(!TI);        
                                        TI=0;
                                        SBUF='3';//28;        
                                        while(!TI);        
                                        TI=0;
                                        ES=1;
                                }
                }
}

void ser() interrupt 4
{
        RI=0;
//        P1=SBUF;
        a=SBUF;
        flag=1;
}
这是郭天祥版本的,看样子好像你没有开中断的使能,,,
引用
评论
ssungirl作者
11年11个月前IP:广东
739460
3楼
引用 捂脸。:
#include<reg52.h>
unsigned char flag,a;
void main()
{

        TMOD=0x20;//设置定时器1为工作方式2
        TH1=0xfd;
       ...
哦,知道了,要开中断使能,波特率才会出来。由于我只要发送,所以把发送程序和中断使能删了。
引用
评论
ssungirl作者
11年11个月前IP:广东
739463
4楼
引用 捂脸。:
#include<reg52.h>
unsigned char flag,a;
void main()
{

        TMOD=0x20;//设置定时器1为工作方式2
        TH1=0xfd;
       ...
        EA=1;
       ES=1; 加了这两句还不行,不知道为什么,P2脚集体产生了动作。你给的例程是接受的,我需要发送的。
引用
评论
11年11个月前修改于 11年11个月前IP:河北
739549
5楼
今天用硬件测试了一下,好像是你主函数循环那的延时过高,改到250以下可以(值越大字符串打印的速度越慢)。具体原因不太清楚。至于前面说的ES=1和EA=1这两句最好不要加,加了输出出错。抱歉了,貌似前面误导你了,,(忙着期末考试,原谅不能给出具体原因。。。)
main()
{
    init_serialcomm();  //初始化串口
    while(1)
    {
       send_string_com(inbuf1,INBUF_LEN);
       Delay1ms(300); //改成250以下,串口助手有输出}
}

引用
评论
11年11个月前IP:北京
739591
6楼
        MOV     TMOD,#00100000B
        MOV     TH1,#230
        MOV     TL1,#230
        SETB    TR1
; =============================
        MOV     SCON,#01110000B
SENDON:
        CLR     TI
        MOV     SBUF,#"1"
        JNB     TI,$
        AJMP    SENDON
引用
评论
ssungirl作者
11年11个月前IP:广东
739630
7楼
引用 捂脸。:
今天用硬件测试了一下,好像是你主函数循环那的延时过高,改到250以下可以(值越大字符串打印的速度越慢)。具体原因不太清楚。至于前面说的ES=1和EA=1这两句最好不要加,加了输出出错。抱歉了,貌似前面误导你了,,(忙着期末考试,原谅不能给出...
我试过,把Delay1ms(300);删了,但是用串口助手接收到的是乱码,应该是循环太快了导致串口助手把杂波当数据了。
引用
评论
ssungirl作者
11年11个月前IP:广东
739631
8楼
引用 pldtv:
MOV     TMOD,#00100000B
        MOV     TH1,#230
        MOV     TL1,#230
        SETB    TR1
; ========================...
谢谢,不懂汇编啊
引用
评论
11年11个月前IP:未同步
741633
9楼
我的贴子不是有个串口通信?
引用
评论
ssungirl作者
11年11个月前IP:广东
741637
10楼
引用 changle:
我的贴子不是有个串口通信?
搞定了,不知道怎么回事,要用4800波特率才能传,9600不行
引用
评论
11年11个月前IP:广东
741656
11楼
引用 ssungirl:
搞定了,不知道怎么回事,要用4800波特率才能传,9600不行
测一测晶振频率是不是11点几,电脑单片机同样传输设置,
引用
评论
ssungirl作者
11年11个月前IP:广东
741657
12楼
引用 changle:
测一测晶振频率是不是11点几,电脑单片机同样传输设置,
11.0592
引用
评论
11年11个月前IP:广东
741668
13楼
引用 ssungirl:
11.0592
引用
评论
11年11个月前IP:广东
741669
14楼
引用 ssungirl:
11.0592
写个循环延时,定时器延时,用秒表对时。或者循环输出P.xx口,测频率。计算看看是不是运行在11M晶振。如果单片机周期确实是约1us,说明是设置问题,或者传输线路有电感电容,经不起高频
引用
评论
11年11个月前IP:广东
741676
15楼
引用 ssungirl:
11.0592
引用
评论
11年11个月前IP:广东
741677
16楼
引用 ssungirl:
11.0592
仔细看了一下代码,是串口初始化错了。51he点com网站抄的吧!真害人,学习时曾经也调试过这串一模一样的代码,变量名,顺序,注释等全部相同
引用
评论
11年11个月前IP:江西
741705
17楼
引用 changle:
仔细看了一下代码,是串口初始化错了。51he点com网站抄的吧!真害人,学习时曾经也调试过这串一模一样的代码,变量名,顺序,注释等全部相同
SCON  = 0x50;         // SCON: 模式 1, 8-bit UART, 使能接收  
TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
TR1 = 1;                  // TR1:  timer 1 打开                    
EA = 1;                  //打开总中断
ES = 1;                  //打开串口中断
引用
评论
ssungirl作者
11年11个月前IP:广东
741725
18楼
引用 changle:
SCON  = 0x50;         // SCON: 模式 1, 8-bit UART, 使能接收  
TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
...
你这个TMOD |= 0x20;是不等于么,貌似不用打开EA和ES吧,我传送成功的4800波特率就没打开这2个啊
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X00; //波特率倍数1
TH1=0XFA; //计数器初始值设置,注意波特率是4800的
TL1=0XFA;
TR1=1; //打开计数器
引用
评论
11年11个月前IP:未同步
741776
19楼
引用 ssungirl:
你这个TMOD |= 0x20;是不等于么,貌似不用打开EA和ES吧,我传送成功的4800波特率就没打开这2个啊
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X00;...
这是完整初始化,
|=/=!,使俩个定时器不冲突,
不加倍是缺省值,不用写PCON,
9600传输快一倍,
没错,中断就是接收
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的