📄 jkb.c
字号:
#include "c8051f020.h"
#include "stdio.h"
#include <intrins.h>
//-----------------------------------------------------------------------------
// C8051F02X 的16 位SFR 定义
//-----------------------------------------------------------------------------
sfr16 DP = 0x82; // 数据指针
sfr16 TMR3RL = 0x92; // 定时器3 重装值
sfr16 TMR3 = 0x94; // 定时器3 计数器
sfr16 ADC0 = 0xbe; // ADC0 数据
sfr16 ADC0GT = 0xc4; // ADC0 大于窗口
sfr16 ADC0LT = 0xc6; // ADC0 小于窗口
//-----------------------------------------------------------------------------
//全局常量
//-----------------------------------------------------------------------------
#define SYSCLK 12000000 //系统时钟频率12MHz
#define BAUDRATE 9600 // UART 波特率9600bps
#define FLASH_SCRATCHSIZE=128//FLASH为128字节
#define SCLCLK=300000//SMB时钟为300KHz
sbit DQ=P2^0;
sbit sda=P0^6;
sbit scl=P0^7;
//sbit DataPortDS1820=P2^0;
//-----------------------------------------------------------------------------
// 函数原型
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);//时钟初始化
void PORT_Init (void);//端口初始化
void UART0_Init (void);//串口初始化
void SMB0_Init(void);//SMB0us初始化
void ADC0_Init (void);//模数转换初始化
float cu50(float);
float cu100(float);
float pt100(float);
float dj(float);
float dk(float);
float dt(float);
float de(float);
float dr(float);
float ds(float);
float db(float);
float dn(float);
int chaiyang(void);//采样
float chaiyangjishuan(int);//将采样值计算成相应的电阻或电压
void tongdao_init(void);//单通道配置
void spi_send(float);//SPI接口发送
void flash_scratch_write(unsigned dest,char *src,unsigned num);//FLASH写
void flash_scratch_read(unsigned src,unsigned num);//FLASH读
void flash_scratch_erase(void);//FLASH擦除
void i2o_write(unsigned short,unsigned short );//数字电位器写
void i2o_read();//数字电位器读
void chan(int t);//通道增益配置参数设置
void delay(word );//延时
void Read_Temperature(void);//读冷端的温度值
//void Delay1us(unsigned char ) ;
//void Delay15us(void);
//void Delay10us(void);
//bit RstDS1820(void);
//void WriteDS1820(unsigned char );
//unsigned char ReadDS1820(void);
//unsigned char ReadDS1820(void);
//void StartADC(void);
// float GetTempValue(void);
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
int chanel_chanshu[24]={0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff,0x0002,0x0000,0x07ff};
typedef unsigned char data byte;
typedef unsigned int data word;
int data lenduan;
int *ptrl;
char *ptrlchar;
int data minlin;
char data COMMAND; //7位从地址+W/R字节
char data WORD; //命令字节
char data OP_CODE; //数据字节
//-----------------------------------------------------------------------------
//主程序
//-----------------------------------------------------------------------------
void main(void)
{
short int data m,n;
float data wendu,dianzu;
int data chaiyangzhi;
WDTCN=0xde;
WDTCN=0xad;
SYSCLK_Init (); // 初始化振荡器
PORT_Init (); // 初始化数据交叉开关和通用IO 口
SMB0_Init();
UART0_Init (); // 初始化UART0
ADC0_Init (); // 初始化和使能ADC
ptrl=chanel_chanshu;
ptrlchar=chanel_chanshu;
flash_scratch_read(0x0000,12);
EIE1 |=2;//SMB中断使能
EA=1;//开中断
BUSY=0;
SI=0;
m=0;
for(n=1;n<9;n++)
{
if((chanel_chanshu[(n-1)*3]>0x0a)|(chanel_chanshu[(n-1)*3]<0))
{m=1;}//判断是否进行过传感器的配置
}
if(m==1)
{//没有进行则将传感器参数配置成原始值
for(n=1;n<9;n++)
{
chanel_chanshu[(n-1)*3]=0x0002;
chanel_chanshu[(n-1)*3+1]=0x0011;
chanel_chanshu[(n-1)*3+2]=0x07ff;
}
//printf("AA \n");
}
ptrl=chanel_chanshu;
ptrlchar=chanel_chanshu;
P3=0xf0;
while(1)
{
/* while(!SPIF);
minlin=SPI0DAT;
SPIF=0;
switch(minlin)
{
case 0x55://单通道配置命令
tongdao_init();
flash_scratch_erase();
flash_scratch_write(0x0000,ptrlchar,96);
ptrl=chanel_chanshu;//重新赋地址
ptrlchar=ptrl;//重新赋地址
break;
case 0x66://单通道读数
while(!SPIF);
minlin=SPI0DAT;
m=minlin;
SPIF=0;
P3=0xf0+m-1;
chan(minlin);
dianzu=chaiyangjishuan(chaiyang());
switch(chanel_chanshu[((minlin-1)*3)])
{
case 0:
wendu=cu50(dianzu);
break;
case 1:
wendu=cu100(dianzu);
break;
case 2:
wendu=pt100(dianzu);
break;
case 3:
wendu=dj(dianzu);
break;
case 4:
wendu=dk(dianzu);
break;
case 5:
wendu=dt(dianzu);
break;
case 6:
wendu=de(dianzu);
break;
case 7:
wendu=dr(dianzu);
break;
case 8:
wendu=ds(dianzu);
break;
case 9:
wendu=db(dianzu);
break;
case 10:
wendu=dn(dianzu);
break;
default:
break;
}
spi_send(wendu);
break;
case 0x77://多通道读数;即循环发送1至8通道貌岸然的温度值
for(minlin=1;minlin<9;minlin++)
{
P3=0XF0+minlin-1;
m=minlin;
//chan(minlin);
chaiyangzhi=chaiyang();
dianzu=chaiyangjishuan(chaiyangzhi);
switch(chanel_chanshu[(minlin-1)*3])
{
case 0:
wendu=cu50(dianzu);
break;
case 1:
wendu=cu100(dianzu);
break;
case 2:
wendu=pt100(dianzu);
break;
case 3:
wendu=dj(dianzu);
break;
case 4:
wendu=dk(dianzu);
break;
case 5:
wendu=dt(dianzu);
break;
case 6:
wendu=de(dianzu);
break;
case 7:
wendu=dr(dianzu);
break;
case 8:
wendu=ds(dianzu);
break;
case 9:
wendu=db(dianzu);
break;
case 10:
wendu=dn(dianzu);
break;
default:
break;
}
SPIF=0;
spi_send(wendu);
while(!SPIF);
}
break;
case 0x88://通道零点调整
while(!SPIF);
minlin=SPI0DAT;
m=minlin;
SPIF=0;
m=0xf0+m-1;
P3=m;
//chan(minlin);
chanel_chanshu[(minlin-1)*3+1]=chaiyang();
flash_scratch_erase();
flash_scratch_write(0x0000,ptrlchar,96);
ptrl=chanel_chanshu;//重新赋地址
ptrlchar=ptrl;//重新赋地址
P3=0XEF;//发送数据准备好中断
SPI0DAT=0xaa;//发送响应命令
SPIF=0;
P3=0XFF;//收回中断
break;
case 0x99://通道满量程调整
while(!SPIF);
minlin=SPI0DAT;
m=minlin;
SPIF=0;
m=0xf0+m-1;
P3=m;
//chan(minlin);
chanel_chanshu[(minlin-1)*3+2]=chaiyang();
flash_scratch_erase();
flash_scratch_write(0x0000,ptrlchar,96);
ptrl=chanel_chanshu;//重新赋地址
ptrlchar=ptrl;//重新赋地址
P3=0XEF;//发送数据准备好中断
SPI0DAT=0xaa;//发送响应命令
SPIF=0;
P3=0XFF;//收回中断
break;
default:
break;
}*/
minlin=1;
m=minlin;
//printf("AA \n");
SPIF=0;
P3=0xf0+m-1;
chan(minlin);
chaiyangzhi=chaiyang();
printf("chaiyangzhi :%x\n",chaiyangzhi);
dianzu=chaiyangjishuan(chaiyangzhi);
printf("dianzu :%f\n",dianzu);
switch(chanel_chanshu[((minlin-1)*3)])
{
case 0:
wendu=cu50(dianzu);
break;
case 1:
wendu=cu100(dianzu);
break;
case 2:
wendu=pt100(dianzu);
break;
case 3:
wendu=dj(dianzu);
break;
case 4:
wendu=dk(dianzu);
break;
case 5:
wendu=dt(dianzu);
break;
case 6:
wendu=de(dianzu);
break;
case 7:
wendu=dr(dianzu);
break;
case 8:
wendu=ds(dianzu);
break;
case 9:
wendu=db(dianzu);
break;
case 10:
wendu=dn(dianzu);
break;
default:
break;
}
printf("wendu :%f\n",wendu);
Read_Temperature();
//wendu=GetTempValue();
printf("%f\n",lenduan);
//spi_send(wendu);
}
}
// 子程序初始化
//-----------------------------------------------------------------------------
// 系统时钟初始化
//-----------------------------------------------------------------------------
// 此程序初始化系统时钟使用12MHz 晶体作为时钟源
//
void SYSCLK_Init (void)
{
int data i; // 延时计数器
OSCXCN = 0x67; // 起动外部振荡器12MHz 晶体
for (i=0; i< 256; i++) ; // 等待振荡器启动 (>1ms)
// while (!(OSCXCN & 0x80)) ; // 等待晶体振荡器稳定
OSCICN = 0x88; // 选择外部振荡器作为系统时钟源并使能丢失时钟检测器
}
//-----------------------------------------------------------------------------
// IO 口初始化
//-----------------------------------------------------------------------------
// 配置数据交叉开关和通用IO 口
//
void PORT_Init (void)
{
XBR0 = 0x06; // 使能UART0,SPI,//07时才同时使能SMB0us0
XBR1 = 0x00;
XBR2 = 0x40; // 使能数据交叉开关和弱上拉
P0MDOUT=0X15;
//P0MDOUT |= 0x01; // 允许TX0 为推挽输出
P1MDOUT |= 0x40; // 允许P1.6(LED)为推挽输出
}
//-----------------------------------------------------------------------------
// UART0 初始化
//-----------------------------------------------------------------------------
// 配置UART0 使用定时器1 产生波特率
//
void UART0_Init (void)
{
SCON0 = 0x50; // SCON0: 模式 1,8 位UART,允许RX
TMOD = 0x20; // TMOD: 1 定时器, 模式2, 8 位重装
TH1 = -(SYSCLK/BAUDRATE/16); // 按波特率设置定时器1 重装值
TR1 = 1; // 起动定时器1
CKCON |= 0x10; // 定时器1 使用系统时钟为时基
PCON |= 0x80; // SMOD00=1
TI0 = 1; // 表示就绪
}
//-----------------------------------------------------------------------------
//SMB0us0初始化
//-----------------------------------------------------------------------------
void SMB0_Init(void)
{
SMB0CN=0X44;
SMB0CR=0xef;//0x14;//SMB时钟速率为300KHz
//SMB0DAT=0X00;
//SMB0ADR=0X58;
}
//-----------------------------------------------------------------------------
// ADC0 初始化
//-----------------------------------------------------------------------------
// 配置ADC0 使用AD0BUSY 作为转换源, 使用左对齐输出模式,
// 使用正常跟踪模式, 测量片内温度传感器器输出
// 禁止ADC0 转换结束中断和ADC0 窗口比较器中断
//
void ADC0_Init (void)
{
ADC0CN = 0x80; // ADC0 使能;正常跟踪模式
// 当写AD0BUSY 时ADC0 转换开始ADC0 数据左对齐
REF0CN = 0x07; // 使能温度传感器片内VREF 和VREF 输出缓冲器
//AMX0SL = 0x0f; // 选择温度传感器作为ADC 多路模拟转换器输出
ADC0CF = (SYSCLK/2500000) << 3; // ADC 转换时钟=2.5MHz
ADC0CF |= 0x01; // PGA 增益=2
AMX0SL=0X00;//选择AIN0作为ADC多路模拟转换器输出
AMX0CF =0X01;
EIE2 &= ~0x02; // 禁止ADC0 EOC 中断
EIE1 &= ~0x04; // 禁止ADC0 窗口比较器中断
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -