打印
[国产单片机]

求大侠帮忙解决单片机接收多字节问题和ADM2483问题,谢谢

[复制链接]
1651|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nwjt508|  楼主 | 2015-8-8 13:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序目的:上位机通过485(ADM2483)发送查询代码:address(本板地址)  0xEE  0xEE 0xFF,想先将接收到的这4个代码按顺序分别存到 Revdat[0]、Revdat[1]、Revdat[2]、Revdat[3] 中,并使接收完成标志 Rev_flag=1

本板(下位机)接收到此四个代码后,(通过ADM2483)回答:address(本板地址) 0xCC 0xCC SDV_Conclusion(本板检测到的结果) 0xFF 0xFF  六个代码。

调试方式:串口1接在STC15F2K16S2的P3.0,P3.1(在ADM2483之前),串口2通过232-485转换器接到本板的ADM2483输出端。

遇到的问题:1、从串口2一个一个发送:12(地址) 0xEE 0xEE 0xFF,在串口1的接收区上能看到接收到的12 EE EE FF,但是并没有把这4个数存到 Revdat[0]、Revdat[1]、Revdat[2]、Revdat[3]中,指针变量 RevCS 没有改变,一直处于0.所以接收完成标志 Rev_flag也一直没有置1。上位机发送过快,还会死机。
2、ADM2483的控制也不对,因为串口2的接收区没有显示。

求教这两个问题怎么解决?谢谢大侠们。

#include <stc15f2kxx.h>
#include <stdio.h>
#include <intrins.h>



#define uchar unsigned char
#define uint unsigned int

typedef unsigned char BYTE;
typedef unsigned int WORD;

/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER   0x80            //ADC power control bit
#define ADC_FLAG    0x10            //ADC complete flag
#define ADC_START   0x08            //ADC start control bit
#define ADC_SPEEDLL 0x00            //420 clocks
#define ADC_SPEEDL  0x20            //280 clocks
#define ADC_SPEEDH  0x40            //140 clocks
#define ADC_SPEEDHH 0x60            //70 clocks

void InitADC();
BYTE GetADCResult(BYTE ch);



/*串口有关定义*/
#define FOSC 11059200L          //系统频率
#define BAUD 9600             //串口波特率

#define NONE_PARITY     0       //无校验
#define ODD_PARITY      1       //奇校验
#define EVEN_PARITY     2       //偶校验
#define MARK_PARITY     3       //标记校验
#define SPACE_PARITY    4       //空白校验
#define PARITYBIT EVEN_PARITY   //定义校验位
#define S1_S0 0x40              //P_SW1.6
#define S1_S1 0x80              //P_SW1.7

bit busy;
uint Revdat[4]={0,0,0,0};/*临时接收数据*/
bit Rev_flag=0;
sbit ADM_G=P3^5;  /*ADM2483接收/发送控制端*/
void InitUart();
void SendData(BYTE dat);          //串口发送数据
void SendString(char *s);                //串口发送字符串       




bit on=0;off=1;
const int Zhengchang=0x00/*正常*/;Duansi=0x01/*断丝*/;Jichuan=0x02/*击穿*/;Duanlu=0x03/*断路*/;
uint I_F1,/*控制电流临界点*/  I_F1_1,/*控制电流回差*/ I_F2,/*工作电流临界点*/I_F2_1;/**工作电流回差*/
uint I_ctr,/*可控硅的实时控制电流*/ I_work,/*电炉丝的实时工作电流*/        qyCTR=0,/*取样控制*/ I_ctr_tmp[6], I_work_tmp[6];
sbit V_scr=P2^5;/*可控硅两端电压状态*/        SDV_Conclusion;/*电炉丝判断结论*/
uint address;/*本板地址*/

void Delaya(WORD n);         //延时函数


                  



void main(void)
{
        InitUart();
        ADM_G=0;                            //开ADM2483接收
        InitADC();                      //初始化ADC
            while(1)
        {
                P20=~P20;
                Delaya(2);

                /*以下为电炉丝工作状态判断*/               
                qyCTR++;         //取样频率控制
                if(qyCTR==5000)
                {
                        I_ctr=GetADCResult(5);                //控制电流取样 4-20mA
                        I_ctr=I_ctr<<2|ADC_RESL;

                        I_work=GetADCResult(6);                //工作电流取样
                        I_work=I_work<<2|ADC_RESL;
                        qyCTR=0;
                }
                if(I_ctr>I_F1)        //控制电流大于临界点,可控硅开始加热工作
                {
                //        P20=on;                 //运行灯亮
                        if(I_work>I_F2)         //工作电流大于临界点,
                        {
                                SDV_Conclusion=Zhengchang;        //正常
        //                        P21=on;         //正常灯亮
        //                        P22=off;
        //                        P23=off;
        //                        P24=off;
                        }
                        if(I_work<(I_F2-I_F2_1)) //工作电流小于等于临界点
                        {
                                 if(V_scr==0) //可控硅两端有电压为380V
                                {
                                         SDV_Conclusion=Duanlu;        //可控硅烧断,断路
        //                                P21=off;
        //                                P22=off;
        //                                P23=on;         //断路灯亮
        //                                P24=off;
                                }
                                else   //可控硅两端无电压为0
                                {
                                         SDV_Conclusion=Duansi;         //则电炉丝烧断,断丝
        //                                P21=off;
        //                                P22=on;        //断丝灯亮
        //                                P23=off;
        //                                P24=off;
                                }
                        }       
                }       
                if(I_ctr<(I_F1-I_F1_1))  //控制电流小于等于临界点-回差,可控硅出于停止加热状态
                {
         //        P20=1; //运行灯灭
                        if(I_work<(I_F2-I_F2_1))        //工作电流小于临界点,说明是停止状态
                        {
                                SDV_Conclusion=Zhengchang;        //正常
        //                        P21=on;          //正常灯亮
        //                        P22=off;
        //                        P23=off;
        //                        P24=off;
                        }                                  
                        if(I_work>I_F2) //工作电流大于等于临界点,
                        {
                                 SDV_Conclusion=Jichuan;  //可控硅 击穿
        //                        P21=off;
        //                        P22=off;
        //                        P23=off;
        //                        P24=on;        //击穿灯亮
                        }
                                  
               
                 }
               
                /*以下为结果发送到上位机*/       
                if(Rev_flag==1)
                {
                         ADM_G=1;
                         Delaya(1);
                         P22=~P22;
                         SendData(address);
                         SendData(0xCC);
                         SendData(0xCC);
                         SendData(SDV_Conclusion);
                         SendData(0xFF);
                         SendData(0xFF);
                         Delaya(1);
                         ADM_G=0;
                         

                    }
       
               
       
        }

}





/*----------------------------
Get ADC result
----------------------------*/
BYTE GetADCResult(BYTE ch)
{
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();
        _nop_();
        _nop_();                        //Must wait before inquiry
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
    ADC_CONTR &= ~ADC_FLAG;         //Close ADC

    return ADC_RES;                 //Return ADC result
}

/*----------------------------
Initial ADC sfr
----------------------------*/
void InitADC()
{
    P1ASF = 0x80;                   //Open 8 channels ADC function
    ADC_RES = 0;
        ADC_RESL=0;                   //Clear previous result
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delaya(1);                       //ADC power-on and delay
}


void Delaya(WORD n)
{
    WORD x;

    while (n--)
    {
        x = 5000;
        while (x--);
    }
}






/*----------------------------
串口1初始化
-----------------------------*/
void InitUart()
{
        ACC = P_SW1;
    ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
    P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
   
//  ACC = P_SW1;
//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
//  ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
//  P_SW1 = ACC;  
//  
//  ACC = P_SW1;
//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1
//  ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)
//  P_SW1 = ACC;  

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

    T2L = (65536 - (FOSC/4/BAUD));   //设置波特率重装值
    T2H = (65536 - (FOSC/4/BAUD))>>8;
    AUXR = 0x14;                //T2为1T模式, 并启动定时器2
    AUXR |= 0x01;               //选择定时器2为串口1的波特率发生器
    ES = 1;                     //使能串口1中断
    EA = 1;

}






/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 1
{
    static unsigned char RevCS;
        if (RI)
    {
        Revdat[RevCS]= SBUF;
                RI = 0;                 //清除RI位
        if (Revdat[RevCS]==address)
                {
                        RevCS=1;
                        P22=0;                  /*本行用来调试的*/
                }
                else if(RevCS==1&&Revdat[RevCS]==0xee)
                {
                         RevCS=2;
                        P23=0;                 /*本行用来调试的*/
                }
                else if(RevCS==2&&Revdat[RevCS]==0xEE)
                {
                         RevCS=3;
                        P24=0;                   /*本行用来调试的*/
                }
                else if(RevCS==3&&Revdat[RevCS]==0xFF)
                {
                         RevCS=0;
                        Rev_flag=1;
                       
                }       
                SendData(Revdat[RevCS]);   /*本行用来调试的*/
       
        P21=~P21 ;                                   /*本行用来调试的*/

       
               
               
    }
    if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
       
}

/*----------------------------
发送串口数据
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;                 //写数据到UART数据寄存器
}

/*----------------------------
发送字符串
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //检测字符串结束标志
    {
        SendData(*s++);         //发送当前字符
    }
}

相关帖子

来自 2楼
nwjt508|  楼主 | 2015-8-13 11:52 | 只看该作者
问题找到了,时序问题,单片机速度太快,延时不够。

使用特权

评论回复
板凳
象牙塔| | 2015-8-14 17:10 | 只看该作者
问题不确定吧

使用特权

评论回复
地板
有妖气| | 2015-8-27 11:41 | 只看该作者
看了那么久,还没找到问题点。

使用特权

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

本版积分规则

2

主题

3

帖子

1

粉丝