📄 zhudanyuan.#1
字号:
#include <c8051f020.h>
#include <stdio.h>
#include <math.h>
#include <absacc.h>
#include <intrins.h>
//C8051F020的16位SFR定义
/*sfr16 DP = 0x82; // 数据指针
sfr16 TMR3RL = 0x92; // 定时器T3重装值
sfr16 TMR3 = 0x94; // 定时器T3计数器
sfr16 ADC0 = 0xbe; // ADC0数据
sfr16 ADC0GT = 0xc4; // ADC0大于窗口
sfr16 ADC0LT = 0xc6; // ADC0小于窗口
sfr16 RCAP2 = 0xca; // 定时器T2捕捉/重装
sfr16 T2 = 0xcc; // 定时器T2
sfr16 RCAP4 = 0xe4; // 定时器T4捕捉/重装
sfr16 T4 = 0xf4; // 定时器T4
sfr16 DAC0 = 0xd2; // DAC0数据
sfr16 DAC1 = 0xd5; // DAC1数据*/
#define DELAY _nop_();_nop_();_nop_();_nop_();
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define BAUDRATE 5600 // UART波特率(bps)
#define SYSCLK 24000000 // 系统时钟频率(Hz)
#define SAMPLE_RATE 50000 // 采样频率(Hz)
#define N0 5
#define N1 5
//********************************* ***** 系统参数设定 **************************************/
#define CUR_SHG 0.00036 //SHG温控恒流源360uA
#define CUR_THG 0.001000 //THG温控恒流源1000uA
#define SHGSetL 5000 //50摄氏度
#define SHGSetH 7500 //75摄氏度
#define THGSetL 13000 //130摄氏度
#define THGSetH 16000 //160摄氏度
#define DAC_dat 0x012000
#define DAC_cha1 0x000000
#define DAC_cha2 0x002000
uint SHGSet; //SHG晶体设定温度*100
uint SHGAct; //SHG晶体实际温度*100
uint THGSet; //THG晶体设定温度*100
uint THGAct; //THG晶体实际温度*100
uint xdata filter0_buf[N0];
uint xdata filter1_buf[N1];
uchar xdata array0,array1;
void delay(uint i);
void long_delay(void);
void short_delay(void);
void PCA_Init (void);
void PCA_ISR (void);
void StoreData(void);
void Receiveing(uchar in_byte);
void ReceiveingPC(uchar in_byte);
void Send_data( uchar out_byte);
void Send_dataPC(uchar out_byte);
void Spi_Write( uint DACcode);
void GetSHG(uchar channel,float current);
void GetTHG(uchar channel,float current);
uint GetADCData(uchar channel);
uint filter(uchar channel); //递推平均滤波法
uint Set_SHG(uint tem);
uint Set_THG(uint a);
sbit LIGHTH = P2^6;
sbit LIGHTL = P2^7;
//MAX125功能口定义
sbit MAX_CS = P2^0;
sbit MAX_CON = P2^1;
sbit MAX_RD = P2^2;
sbit MAX_WR = P2^3;
sbit MAX_INT = P2^4;
sbit MAX_CLK = P2^5;
//DAC8164功能口定义
sbit DAC_LDAC = P3^0;
sbit DAC_ENAB = P3^1;
sbit DAC_A0 = P3^2;
sbit DAC_SYNC = P3^3;
sbit DAC_SCLK = P3^4;
sbit DAC_DIN = P3^5;
void send_byte( uchar out_byte);
void SYSCLK_Init (void);
void PORT_Init (void);
void UART0and1_Init (void);
void PCA_Init (void);
void DAC8164_Init (void);
void MAX125_Init (void);
void Timer3_Init (int counts);
void DAC8164_ISRA (void);
void DAC8164_ISRB (void);
void Pwm(void);
//主程序
void main (void)
{
unsigned int ch1mv,ch2mv;
unsigned long a;
WDTCN = 0xde;
WDTCN = 0xad; // 禁止看门狗
SYSCLK_Init (); // 初始化振荡器
PORT_Init (); // 初始化数据交叉开关和通用I/O口
UART0and1_Init (); // 初始化UART0及UART1
Timer3_Init (SYSCLK/SAMPLE_RATE); // 初始化Timer3
DAC8164_Init (); // 初始化DAC8164
MAX125_Init (); // 初始化MAX125
PCA_Init (); // PCA初始化成8位脉宽调置
//配置中断优先级
IP = 0x02; //UART0=0; Timer0=1; Timer1=0;
EIP1 = 0x08; //PCA0=1; SMBus=0;
EIP2 = 0x11; //INT6=1; PR4=0; PR3 = 1;
EA = 1;
for(a=0;a<0xffff;a++)
{
LIGHTH = 1;
LIGHTL = 0;
delay(999999);
LIGHTH = 0;
LIGHTL = 1;
}
Set_SHG(SHGSet); //SHG温度设定
delay(1000);
Set_THG(THGSet); //THG温度设定
delay(1000);
DAC8164_ISRA (ch1mv); //A/D转换通道A
delay(1000);
DAC8164_ISRB (ch2mv); //A/D转换通道B
delay(1000);
GetADCData(); //D/A数据采集
}
//系统时钟初始化
void SYSCLK_Init (void)
{
int i; //延时计数器
OSCXCN = 0x67; //启动外部振荡器
for (i=0;i<256;i++) ; //等待振荡器启动
while (!(OSCXCN & 0x80)); //等待晶体振荡器稳定
OSCICN = 0x88; //选择外部振荡器为系统时钟源并使能丢失时钟检测器
}
//I/O口初始化,配置数据交叉开关和通用I/O口
void PORT_Init (void)
{
XBR0 = 0x0e; // 使能CEX0,CEX1,CEX2,UART0和SPI0
XBR1 = 0x80; // 使能T1
XBR2 = 0x44; // 使能数据交叉开关和UART1
P1MDIN = 0xff;
P1MDOUT= 0xfc; // P1.0,P1.1设为漏开方式,P1.2-P1.7设为推挽方式
P2MDOUT= 0xff; // P2口设为推挽方式
P3MDOUT= 0xff; // P3口设为推挽方式
P74OUT = 0xf0; // P4,P5口设为漏开方式
P4 = 0Xff;
}
//配置PCA的CEX0,CEX1,CEX2输出8位PWM信号
void PCA_Init (void)
{
PCA0CN = 0x40; //允许PCA0
PCA0CPM0 = 0x42; //使能PCA0的PWM输出
PCA0MD = 0x02; //系统时钟的4分频
PCA0CPL0 = 0x00;
PCA0CPH0 = 0x7e; //占空比50%
}
//UART0配置
void UART0and1_Init (void)
{
SCON0 = 0x50; // UART0工作模式1, 8-bit UART, 使能RX
SCON1 = 0x50; // UART1工作模式1, 8-bit UART, 使能RX
T2CON = 0x30; // 定时器 2, UART0波特率发生器
TMOD = 0x20; //定时器 1, 模式 2, 8-bit 重装载
CKCON |= 0x20; // Timer2使用系统时钟
PCON |= 0x90; // 禁止UART0及UART1的波特率/2
TH1 = -(SYSCLK/BAUDRATE/16); //设定定时器1为重装载模式
TR1 = 1; // 启动Timer1
ET0 = 1;
TR0 = 0;
ET1 = 0;
TR2 = 1; // 启动Timer2
TI0 = 1; // 表示 TX0 就绪
ES0 = 1;
}
//初始化计时器
TMOD = 0x21; //T1工作方式2,8位重装,作为串口通讯波特率发生时钟源;T0工作方式1,16位计时
CKCON |= 0x18; //T0与T1,T2均使用系统时钟
TH1 = -(SYSCLK/BAUDRATE/16);
TR1 = 1;
//T2CON = 0x00;
//MAX125初始化
void MAX125_Init (void)
{
MAX_CS =01;
MAX_CON =01;
MAX_RD = 1;
MAX_WR = 1;
delay(100);
MAX_CS = 0;
MAX_WR = 0;
P4 = 0X01;
MAX_CS = 1;
MAX_WR = 1;
}
//DAC8164初始化
void DAC8164_Init (void)
{
unsigned int dat;
DAC_LDAC = 0;
DAC_ENAB = 1;
DAC_A0 = 0;
DAC_SYNC = 1;
dat = DAC_dat;
Spi_Write(dat);
}
//----------SHG与THG的温度设定-------------//
unsigned int Set_SHG(uint tem) //SHG 50 -70 度
{
unsigned int dat;
float a,b;
float t;
float v;
float r;
tem = 6000;
t = tem/100.0;
a = 1/(273.15+t)-1/298.15;
b = exp(3.940009*a*1000)*10;
r = 1.01*b-0.03187;
v = r * CUR_SHG*1000;
dat = (uint)(16384/5*v);
if(dat>16383)
{
dat = 16383;
}
else if(dat<0)
{
dat = 0;
}
dat &=0x3fff; //14 bits is vaild.
DAC_A0 = 0;
return dat; //SHG设定, DAC8164通道A
}
unsigned int Set_THG(uint tem) //THG 130 -160 度
{
unsigned int dat;
float v;
tem = 15000;
v = tem/1000.0;
dat = (uint)(16384/5*v);
if(dat>16383)
{
dat = 16383;
}
else if(dat<0)
{
dat = 0;
}
dat &=0x3fff; //14 bits is vaild.
DAC_A0 = 0;
return dat; //THG 设定, DAC8164通道B
}
void DAC8164_ISRA(unsigned int tem)
{
unsigned int dat;
dat = Set_SHG(tem);
dat<<=2;
dat |= DAC_cha1|0x800000;
Spi_Write(dat);
}
void DAC8164_ISRB(unsigned int tem)
{
unsigned int dat;
dat = Set_THG(tem);
dat<<=2;
dat |= DAC_cha2|0x800000;
Spi_Write(dat);
}
void Spi_Write(unsigned int dat)
{
unsigned char i;
DAC_ENAB=0;
_nop_();
DAC_SYNC=0;
DAC_SCLK = 1;
for(i=0;i<24;i++)
{
DAC_DIN = ((dat&0x800000)>0)?1:0;
DAC_SCLK = 0;DAC_SCLK = 1;
dat<<=1;
}
_nop_();
_nop_();
DAC_SYNC=1;
_nop_(); _nop_();
DAC_LDAC=1;
delay(10);
DAC_ENAB=1;
}
//***************************************数据采集******************************//
uint GetADCData(uchar channel)
{
uchar xdata dtt,dth,dtl;
uint xdata sump = 0;
uint xdata i;
MAX_CS = 0;
for(i=0; i<15; i++)
{
MAX_CON = 0;
delay(10);
MAX_CON = 0;
if(MAX_INT = 0);
{
for(i=0; i<2; i++)
{
MAX_RD = 0;
_nop_();
_nop_();
dtt = P5&0x3f;
dth = dtt;
dtl = P4;
sump+= dtl+dth*256;
MAX_RD = 1;
delay(3000);
}
}
delay(30);
}
return sump / 15;
}
//--------------递推平均滤波--------------------//
uint filter(uchar channel)
{
char count;
uint sum = 0;
if(channel == 0)
{
filter0_buf[array0++] = GetADCData(0);
if (array0 == N0)
array0 = 0;
for (count=0;count<N0;count++)
{
sum += filter0_buf[count];
}
return (uint)(sum/N0);
}
else if(channel == 1)
{
filter1_buf[array1++] = GetADCData(1);
if (array1 == N1) array1 = 0;
for (count=0;count<N1;count++)
{
sum += filter1_buf[count];
}
return (uint)(sum/N1);
}
}
//--------SHG与THG的温度读取----------//
void GetSHG( uchar channel, float current)
{
uint adresult;
float v,tem,logval;
float m,n,z;
adresult = filter(channel);
v = adresult*5.0/16384.0;
if(channel == 5)
{
logval = log(v/CUR_SHG);
_nop_();
_nop_();
m = 1.120332914398244e-003 ;
_nop_();
_nop_();
n = 2.354891980894096e-004*logval;
_nop_();
_nop_();
z = 8.289547029771934e-008*logval*logval*logval;
_nop_();
_nop_();
_nop_();
_nop_();;
tem = 1.0/(m + n + z) - 273.15+0.11; //实际温度
_nop_();
_nop_();
SHGAct = tem*100; //SHG实际温度
}
delay(3000);
}
void GetTHG( uchar channel, float current )
{
uint adresult;
float v,tem,res;
adresult = filter(0);
v = adresult*5.0/16384.0;
res = v/CUR_THG;
tem = 0.261643*res-261.643;
THGAct = tem*100.0; //THG实际温度
}
//UART通信
void Receiving()
{
#define PC_data (uchan xdata*) 0x0000; //定义外部数据地址
uchan xdata * point; //定义外部数据指针变量
uchan ch;
uint i;
UART0_Init();
TR1 = 1; //启动波特率发生器
RI0 = 0; //清接受中断标志
point= PC_data; //指针变量赋初值
P4= 0xf0; //CS0=0,CS1=1,选择RAM中的第0页
for (i=0;i<oxffff;i++) //接受64K个数据(超过64K另置页地址)
{
while(!RI0); //接受一个字节数据
*point=SUBF0; //存储一个字节数据到RAM中
point++; //指向下一个地址
RI0 = 0; //清接受中断标志
}
TR1=0; //停止波特率发生器
P4= 0xff;
erase_flash(); //擦除FLASH芯片
point= PC_data; //指针变量赋初值
for (i=0;i<oxffff;i++) //写64K字节数据到FLASH中
{
P4= 0xf0; //选择RAM中第0页
ch= *point; //读RAM
P4= 0x8e; //选择FLASH中第0页
XBYTE[0X5555]= 0xaa; //写一个字节的命令
XBYTE[0X2aaa]= 0x55; //写一个字节的命令
XBYTE[0X5555]= 0xa0; //写一个字节的命令
*point= ch; //写一个字节到FLASH中
delay(500);
point++; //指针变量指向下一个地址
}
P4= 0xff; //CS0=0,CS1=1,重置页地址
}
void Send_data(void)
{
uint i;
P4= 0xf0;
SCON1= 0x40;
TR1 = 1;
point= PC_data;
P4= 0xf0;
for (;point<ffff;)
{ for (i=0;i<10;i++)
{
SUBF1= *point;
while((SCON1&0x02)==0);
SCON1= 0x40;
point++;
}
}
}
//--------------------延时指令定义//-----------------//
void delay(uint i)
{
while (i--) ;
}
void long_delay(void)
{
uchar i;
for( i = 0; i <250; i++)
{
_nop_();
_nop_();
}
}
void short_delay(void)
{
uchar i;
for( i = 0; i <100; i++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -