程序目的:上位机通过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++); //发送当前字符
}
} |