?? 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 + -