⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jkb.c

📁 此程序是一底层开发驱动代码,里面包括了I2C芯片(MAX5417)及1 wire sensor、AD驱动的源代码!稍作改动就能用于自己的产品开发中!
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -