基于STC11F04E单片机的信号发生器2----程序设计
以下是驱动程序的主程序,其中用的DA输出部分没有加进来。硬件部分请查阅相关文章。
#include "IODefine.h"
#include "DADriver.h"
#include "DADriver_main.h"
#include "math.h"
#define DEBUG 0 //调试时设为1,否则设为0
/****************************************************
*10us延时子程序
*用示波器调试过的延时程序@22.1184MHz
****************************************************/
void Del10us(unsigned n)
{
unsigned char i;
while(n--)
{
_nop_();
i = 50;
while (--i);
}
}
void Del50us(unsigned n)
{
unsigned char i, j;
while(n--)
{
i = 1;
j = 60;
do
{
while (--j);
} while (--i);
}
}
void Del100us(unsigned n) //@22.1184MHz
{
unsigned char i, j;
while(n--)
{
_nop_();
_nop_();
i = 3;
j = 34;
do
{
while (--j);
} while (--i);
}
}
void Del2ms_DA(unsigned int k,int m,int n,int z)
{
while(k--)
{
WriteTLC5615(m);
Del100us(1);
WriteTLC5615(z);
Del100us(4);
WriteTLC5615(n);
Del100us(1);
WriteTLC5615(z);
Del100us(4);
}
}
void main(void)
{
unsigned int DianYamax; //电压
unsigned char BoXing; //波形
unsigned int TimeCtl;
int i,m,n,k,dd;
int m1,n1,z1;
float sin;
SysConfig();
WriteTLC5615(512); //上电时确保输出电压为0
#if DEBUG
//------------测试输出波形-----------------
TimeCtl = 200;//100*buf[3]
RunFlag = 1;
BoXing = 4;
DianYamax = 100+1*9;//1023-->5V,818-->4V,409-->2V
sin = DianYamax/530.0;
//------------测试输出波形-----------------
#endif
while(1)
{
if(RunFlag) //系统处于运行状态--即治疗状态
{
switch(BoXing)
{
//以下波形,疏[150HZ],密[500HZ],其他[500HZ]
case 1: //疏--150Hz
WriteTLC5615(512);
TimeOutS = 0;
TimeOutD = TimeCtl/10;
TR0 =1;
while(TimeOutS<TimeOutD) //超时等待
{
WriteTLC5615(512+DianYamax); //0.05ms=50us ,脉冲宽度为200us
Del50us(16);
WriteTLC5615(512);
Del50us(250); //3.33ms-0.05ms=3.28ms
WriteTLC5615(512-DianYamax); //50us
Del50us(16);
WriteTLC5615(512);
Del50us(250);
}
TR0 =0;
WriteTLC5615(512);
break;
case 2: //密--500Hz
WriteTLC5615(512);
TimeOutS = 0;
TimeOutD = TimeCtl/10;
TR0 =1;
while(TimeOutS<TimeOutD) //超时等待
{
WriteTLC5615(512+DianYamax); //0.05ms=50us
Del50us(16);
WriteTLC5615(512);
Del50us(62); //1ms-0.05ms=0.95ms=950us
WriteTLC5615(512-DianYamax); //50us
Del50us(16);
WriteTLC5615(512);
Del50us(62); //1ms-0.05ms=0.95ms=950us
}
TR0 =0;
WriteTLC5615(512);
break;
case 3: //疏密
WriteTLC5615(512);
TimeOutS = 0;
TimeOutD = TimeCtl/10;
TR0 =1;
while(TimeOutS<TimeOutD) //超时等待
{
WriteTLC5615(512+DianYamax); //0.05ms=50us
Del50us(16);
WriteTLC5615(512);
Del50us(62); //1ms-0.05ms=0.95ms=950us
WriteTLC5615(512-DianYamax); //50us
Del50us(16);
WriteTLC5615(512);
Del50us(62); //1ms-0.05ms=0.95ms=950us
}
TR0 =0;
/*----------------------------------------------------*/
WriteTLC5615(512);
TimeOutS = 0;
TimeOutD = TimeCtl/10;
TR0 =1;
while(TimeOutS<TimeOutD) //超时等待
{
WriteTLC5615(512+DianYamax); //0.05ms=50us ,脉冲宽度为200us
Del50us(16);
WriteTLC5615(512);
Del50us(250); //3.33ms-0.05ms=3.28ms
WriteTLC5615(512-DianYamax); //50us
Del50us(16);
WriteTLC5615(512);
Del50us(250);
}
TR0 =0;
WriteTLC5615(512);
break;
case 4: //正三角
m=512;
n=512;
//TimeCtl是时间,单位为ms ,DianYamax是电压最大值,k是数据更新的频率
if(TimeCtl>=DianYamax)
{
k=TimeCtl/DianYamax;
dd=1;
}
else
{
k=1;
dd=DianYamax/TimeCtl;
}
for(i=0;i<TimeCtl;i++)
{
Del2ms_DA(1,m,n,512); //1ms
if((i%k)==0) //控制多少时间更新一次数据
{
m+=dd;
n-=dd;
}
if(m>1000)
{
//k=i;
break;
}
}
for(i=0;i<TimeCtl;i++)
{
Del2ms_DA(1,512,512,512);
//if(i>=k)
// break;
}
break;
case 5: //反三角
m=512-DianYamax;
n=512+DianYamax;
if(TimeCtl>=DianYamax)
{
k=TimeCtl/DianYamax;
dd=1;
}
else
{
k=1;
dd=DianYamax/TimeCtl;
}
for(i=0;i<TimeCtl;i++)
{
Del2ms_DA(1,m,n,512); //1ms
if((i%k)==0) //控制多少时间更新一次数据
{
m+=dd;
n-=dd;
}
if(m>512)
{
m=500;
n=524;
Del2ms_DA(1,m,n,512); //1ms
//k=i;
break;
}
}
for(i=0;i<TimeCtl;i++)
{
Del2ms_DA(1,512,512,512);
//if(i>=k)
// break;
}
break;
case 6: //手针(Del10us)
case 7:
sin = DianYamax/530.0;
m=0;
n=64;
m1=(int)(Sin128N[m]*(sin));
n1=(int)(Sin128N[n]*(sin));
z1=(int)(Sin128N[0]*(sin));
k=TimeCtl/32;
dd=2;
for(i=0;i<TimeCtl;i++)
{
Del2ms_DA(1,m1,n1,z1); //2ms
if((i%k)==0) //控制多少时间更新一次数据
{
m+=dd;
n+=dd;
m1=(int)(Sin128N[m]*(sin));
n1=(int)(Sin128N[n]*(sin));
}
if(m>=64) //输出值不能等于64
{
break;
}
}
if(BoXing==7)
{
for(i=0;i<TimeCtl;i++)
{
Del100us(10);
}
}
break;
default: //无效
BoXing = 0x00;
DianYamax = 0x00;
WriteTLC5615(512);
break;
}
}
if(RecOK)
{
switch(Buffer[1]) //功能号服务程序,读取传感器
{
case 0x01: //01号功能,读多线圈
//DianYamax=DianYamax+Buffer[5];
Buffer[0]=Add; //地址
Buffer[1]=0x01; //功能号
Buffer[2]=0x00; //低八位//0x01; //字节个数
Buffer[3]=0x01;//高八位//0x01; //要返回的数据
//CRC16(Buffer,4); //产生前五位的校验码
CRCParity(Buffer,4);
Buffer[4]=CRC16L; //CRC16是低八位在前,高八位在后
Buffer[5]=CRC16H;
SendStrCom(Buffer,6); //回应上位机
break;
case 0x06: //DA输出的电压值及波形
TimeCtl = Buffer[3]*100; //时间单位为ms
BoXing = Buffer[4];
DianYamax = 80+Buffer[5]*10; //Min[50+5*22=160],Max[50+20*22=490]
if(Buffer[5]>40)
DianYamax=480;
if(BoXing==0) //如果波形值为0,则说明要停止输出波形
{
RunFlag=0;
WriteTLC5615(512);
}
else
RunFlag=1;
SendStrCom(Buffer,8);
break;
default:
break;
}
ES = 1;
RecOK = 0;
//RS485_ctl = 0; //允许接收
//rs485_num=0;
//RecStart = 0;
}
}
}
//====================================串口接收中断函数 ======================================
void ReceDatCom () interrupt 4 using 3
{
unsigned char RecDatNum; //要接收的数据字节数
unsigned char ch;
TI=0;
RecDatNum = 8;
if(RI)
{
RI=0;
ch=SBUF;
if(RecStart) //已经开始接收数据
{
if(RecOK==0)
{
Buffer[rs485_num++]=ch;
if(rs485_num>=RecDatNum) //一帧接收完成
{
rs485_num=0;
RecStart = 0;
CRCParity(Buffer,6);
if( (CRC16L==Buffer[6]) && (CRC16H==Buffer[7]) && (Buffer[0]==Add)) //CRC16校验
{
ES = 0; //接收完八字节有效数据,关串行中断
RecOK = 1;
//RS485_ctl = 1; //不再接收新数据
}
}
}
}
else if((ch==0xEB)&&(RecOK==0)) //字符是0xEB且没有接收完成
{
RecStart = 1;
}
}
else
{
TI = 0;
}
_nop_();
}
/**********************定时中断0服务子程序[]*******************************/
//1.每10Ms一个单位,总长时间可通过外部变量TimerCounter设置(TimerCounter*20)
void TimerCTL(void) interrupt 1 using 2 //计时,精确到10Ms
{
TR0 = 0;
if(TimeOutS<TimeOutD)
TimeOutS++;
TH0 = 0xC6; //定时器0,方式1中断,10Ms
TL0 = 0x66;
TR0 = 1;
}
凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!
