打印

串口通讯程序

[复制链接]
1772|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xvezhe|  楼主 | 2013-10-31 09:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xvezhe 于 2013-10-31 09:55 编辑

寻找串口通讯,串口中断接收部分的程序。。。。

   TMOD = 0x21;                 //定时器1工作方式2,定时器0工作方式1
        TH0  = 0x4c;                 // 50ms
    TL0  = 0x00;                                  //

    TH1  = 0xFD;                 //波特率定义 9600
    TL1  = 0xFD;                                  //  
    SCON = 0x50;                 //定义串口通讯工作方式1 接收模式
        PCON = 0x00;                                 //波特率不变
        EA = 1;                                                 //开总中断
        ES = 1;                                                 //开串行中断
        PS = 1;                                                 //串行中断优先
        ET1 = 1;                                         //开定时器1
        ET0 = 1;                                          //开定时器0
        //TR0 = 1;                                         //启动定时0
        TR1        = 1;


请指教一下小弟。。。


相关帖子

沙发
huhuashizhe| | 2013-10-31 09:56 | 只看该作者
没整过

使用特权

评论回复
板凳
xvezhe|  楼主 | 2013-10-31 10:01 | 只看该作者
huhuashizhe 发表于 2013-10-31 09:56
没整过

刚开始学串口通讯

使用特权

评论回复
5
xvezhe|  楼主 | 2013-10-31 10:34 | 只看该作者
tyw 发表于 2013-10-31 10:26
〓 Visual C++TurboC串口通信编程实践 568页 高...
〓 大话无线通信 361页 18.0M 高清书签版 〓
〓 通信 ...

谢谢T叔

使用特权

评论回复
6
Dick00| | 2013-10-31 11:10 | 只看该作者
你的意思就是,接受SBUF的数据,然后中断再发送呗?

使用特权

评论回复
7
xvezhe|  楼主 | 2013-11-6 08:19 | 只看该作者
Dick00 发表于 2013-10-31 11:10
你的意思就是,接受SBUF的数据,然后中断再发送呗?

就单独接收程序。。。不需发送

使用特权

评论回复
8
dong00520| | 2013-11-6 09:04 | 只看该作者
楼上的资料 满详细了

使用特权

评论回复
9
xvezhe|  楼主 | 2013-11-7 10:37 | 只看该作者
tyw 发表于 2013-10-31 10:26
〓 Visual C++TurboC串口通信编程实践 568页 高...
〓 大话无线通信 361页 18.0M 高清书签版 〓
〓 通信 ...

T叔请指点一下 。。。。:)

//初始化函数
void  sysinit(void)
{
    TMOD = 0x21;                 //定时器1工作方式2,定时器0工作方式1
        TH0  = 0x4c;                 // 50ms
    TL0  = 0x00;                                  //

    TH1  = 0xFD;                 //波特率定义 9600
    TL1  = 0xFD;                                  //  
    SCON = 0x50;                 //定义串口通讯工作方式1 接收模式
        PCON = 0x00;                                 //波特率不变
        EA = 1;                                                 //开总中断
        ES = 1;                                                 //开串行中断
        PS = 1;                                                 //串行中断优先
        ET1 = 1;                                         //开定时器1
        ET0 = 1;                                          //开定时器0
        TR1        = 1;                                         //启动定时1

        HUNDRED = 0;                                 //关百位显示
        read_flag = 0;
        SG_PLAY = 0;
        i = 0;
        SG_COMM = 0;
    timer_count = 0;
        subtract = 0;
        RETWDT();                                         //复位
}

//主函数
void main ()                      //主函数
{
           sysinit();                          //初始化
        while(1)
        {
                GETJUMP();              //读取拨码状态
                if (read_flag)    //如果取数标志已置位,就将读到的数从串口取出
                {                        
                        read_flag = 0;//复位取数标志                        
                        if((0x20&dat_bug[0])==0x20)   {SG_COMM=1;TR0 = 1; TH0  = 0x4c; TL0  = 0x00;}                                                
                        jiaoym = 0x7f&(dat_bug[0]^dat_bug[1]^dat_bug[2]);   //取校验码
                        if(jiaoym==dat_bug[3])                                                                //若校验和正确,则显示
                        {                                       
                                        DCBT_D1 = dat_bug[1]&0x0f;                //百位,取低4位        十六进制
                                        DCBT_D2        = dat_bug[2]&0xf0;                //十位,取高4位
                                        DCBT_D3        = dat_bug[2]&0x0f;                //个位,取低4位

                                    switch(DCBT_D1)                                        //百位十六进制转十进制
                                        {
                                                case 0x00:num1=0;break;
                                                case 0x01:num1=1;break;
                                                case 0x02:num1=2;break;
                                                case 0x03:num1=3;break;
                                                case 0x04:num1=4;break;
                                                case 0x05:num1=5;break;
                                                case 0x06:num1=6;break;
                                                case 0x07:num1=7;break;
                                                case 0x08:num1=8;break;
                                                case 0x09:num1=9;break;
                                        }
                                        switch(DCBT_D2)                                        //十位十六进制转十进制
                                        {
                                                case 0x00:num2=0;break;
                                                case 0x10:num2=1;break;
                                                case 0x20:num2=2;break;
                                                case 0x30:num2=3;break;
                                                case 0x40:num2=4;break;
                                                case 0x50:num2=5;break;
                                                case 0x60:num2=6;break;
                                                case 0x70:num2=7;break;
                                                case 0x80:num2=8;break;
                                                case 0x90:num2=9;break;
                                        }
                                        switch(DCBT_D3)                                        //个位十六进制转十进制
                                        {
                                                case 0x00:num3=0;break;
                                                case 0x01:num3=1;break;
                                                case 0x02:num3=2;break;
                                            case 0x03:num3=3;break;
                                                case 0x04:num3=4;break;
                                                case 0x05:num3=5;break;
                                                case 0x06:num3=6;break;
                                                case 0x07:num3=7;break;
                                                case 0x08:num3=8;break;
                                                case 0x09:num3=9;break;
                                        }
                                data_num = num1*100+num2*10+num3;             //提取收到时间和
                                num1=0;num2=0;num3=0;                                                                                                           
                                LOADADDR = P0&0x07;                                                                                         //取本倒计时地址码
                                if(((0x1c&dat_bug[0])>>2)==LOADADDR)         SG_PLAY = 1;                 //开显示(取收到的地址码同本倒计时地址码比较)
                                else                                                              SG_PLAY = 0;
                        }
                        else                                                                        //若校验码不正确
                        {
                                        SG_PLAY = 0;                                         //不允许显示标志
                        }                                       
           }
           display();  //显示数据

           if((timer_count==20)&&SG_COMM)                        
           {                                 
                         data_num--;              //倒计时自行自减
                         timer_count = 0;
           }                                                   
           RETWDT();   //喂狗                              
        }
}
//定时器中断0
void timer0() interrupt 1                                 //定时器0
{
        TH0  = 0x4c;                 // 50ms
           TL0  = 0x00;
        timer_count++;               
}

//串口中断
void timer1() interrupt 4
{        
         if(RI)
         {
                ES = 0;
                         RI = 0;
                        ch = SBUF;                                            //接收串口数据
                        if(ch==0xfe)                                    //数据帧开始
                        {
                                        i = 0;
                        }
                        if(ch!=0xfe)
                        {                                       
                                        dat_bug = ch;           //存储串口数据
                                        i++;                                   //地址自加
                                        if(i>=4)                            //接收到最后的字节
                                        {
                                                i = 0;
                                                        read_flag= 1 ; //就置位取数标志
                                        }
                        }
                        ES = 1;
         }
}


以上的程序目的:接收到串口中断数据,之后按照1秒定时器倒计时开始倒数,直到下次串口中断的接收到数据更新。。。。。
为什么以上的程序,收到的数据是正确的,到定时器1s时间不正确,程序跑不按设置的定时器时间。。。  

使用特权

评论回复
10
tyw| | 2013-11-7 15:36 | 只看该作者
本帖最后由 tyw 于 2013-11-7 15:39 编辑

你按范例,先把通讯调试出来.可去下些串口调试小工具,建议去淘宝整个虚拟逻辑分析仪,可收事半功倍之效,不贵的.
http://item.taobao.com/item.htm?spm=a230r.1.14.3.HB2UFn&id=14941998842



通讯出来了,想怎么折腾就怎么折腾.不然毛病出在哪里都搞不清了.

使用特权

评论回复
11
xvezhe|  楼主 | 2013-11-8 12:00 | 只看该作者
tyw 发表于 2013-11-7 15:36
你按范例,先把通讯调试出来.可去下些串口调试小工具,建议去淘宝整个虚拟逻辑分析仪,可收事半功倍之效,不贵 ...

现在收到数据,定时器不起作用(就显示收到数据,不会倒数)。。。。不知是那里出现了问题;
还有:定时器同串口一起工作时,我这个程序初始化是否正确


    TMOD = 0x21;                 //定时器1工作方式2,定时器0工作方式1
//   TMOD |= 0x01;
        TH0  = 0x4c;                 // 50ms
    TL0  = 0x00;
                                          //
//        TMOD |= 0x20;
    TH1  = 0xFD;                 //波特率定义 9600
    TL1  = 0xFD;                                  //  
    SCON = 0x50;                 //定义串口通讯工作方式1 接收模式
        PCON = 0x00;                                 //波特率不变
        TR1        = 1;                                         //启动定时1
        ES = 1;                                                 //开串行中断
        PS = 1;                                                 //串行中断优先
        ET1 = 1;                                         //开定时器1  

        ET0 = 1;                                          //开定时器0        
        TR0 = 1;                                         //**
        EA = 1;                                                 //开总中断


请多多指教

使用特权

评论回复
12
xvezhe|  楼主 | 2013-11-8 12:00 | 只看该作者
tyw 发表于 2013-11-7 15:36
你按范例,先把通讯调试出来.可去下些串口调试小工具,建议去淘宝整个虚拟逻辑分析仪,可收事半功倍之效,不贵 ...

现在收到数据,定时器不起作用(就显示收到数据,不会倒数)。。。。不知是那里出现了问题;
还有:定时器同串口一起工作时,我这个程序初始化是否正确


    TMOD = 0x21;                 //定时器1工作方式2,定时器0工作方式1
//   TMOD |= 0x01;
        TH0  = 0x4c;                 // 50ms
    TL0  = 0x00;
                                          //
//        TMOD |= 0x20;
    TH1  = 0xFD;                 //波特率定义 9600
    TL1  = 0xFD;                                  //  
    SCON = 0x50;                 //定义串口通讯工作方式1 接收模式
        PCON = 0x00;                                 //波特率不变
        TR1        = 1;                                         //启动定时1
        ES = 1;                                                 //开串行中断
        PS = 1;                                                 //串行中断优先
        ET1 = 1;                                         //开定时器1  

        ET0 = 1;                                          //开定时器0       
        TR0 = 1;                                         //**
        EA = 1;                                                 //开总中断

使用特权

评论回复
13
CYMHWT| | 2014-7-27 16:14 | 只看该作者
蛮好的,不知道谁有m051的uart程序,可否发给我一个。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

225

帖子

2

粉丝