#include u32 PressData; u32 TempData; //osr define #define OSR_1024X 0 #define OSR_2048X 1 #define OSR_4096X 2 #define OSR_8192X 3 #define OSR_256X 4 #define OSR_512X 5 #define OSR_16384X 6 #define OSR_32768X 7 //dls define #define OSR_1024X_dls 3//2.5 #define OSR_2048X_dls 4//3.78 #define OSR_4096X_dls 7//6.34 #define OSR_8192X_dls 12//11.46 #define OSR_256X_dls 2//1.54 #define OSR_512X_dls 2//1.86 #define OSR_16384X_dls 35//21.7 #define OSR_32768X_dls 43//42.18 //read commond define #define Read_Temperature 0x08 #define Read_Pressure 0x09 #define Read_P_T 0x0A u8 Sys_Config,P_Config,T_Config; u8 P_OSR_DAT,T_OSR_DAT,DLY_OSR; // MCU TYPE: STM32F103RCT6 //IO方向设置 #define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;} #define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;} //IO操作函数 #define IIC_SCL PCout(12) //SCL PA5 #define IIC_SDA PCout(11) //SDA PA7 #define READ_SDA PCin(11) //输入SDA //系统时钟初始化函数 //pll:选择的倍频数,从2开始,最大值为16 void Stm32_Clock_Init(u8 PLL) { unsigned char temp=0; MYRCC_DeInit(); //复位并配置向量表 RCC->CR|=0x00010000; //外部高速时钟使能HSEON while(!(RCC->CR>>17));//等待外部时钟就绪 RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1; PLL-=2; //抵消2个单位(因为是从2开始的,设置0就是2) RCC->CFGR|=PLL<<18; //设置PLL值 2~16 RCC->CFGR|=1<<16; //PLLSRC ON FLASH->ACR|=0x32; //FLASH 2个延时周期 RCC->CR|=0x01000000; //PLLON while(!(RCC->CR>>25));//等待PLL锁定 RCC->CFGR|=0x00000002;//PLL作为系统时钟 while(temp!=0x02) //等待PLL作为系统时钟设置成功 { temp=RCC->CFGR>>2; temp&=0x03; } } //初始化延迟函数 //当使用OS的时候,此函数会初始化OS的时钟节拍 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟 void delay_init(u8 SYSCLK) { #if SYSTEM_SUPPORT_OS //如果需要支持OS. u32 reload; #endif SysTick->CTRL&=~(1<<2); //SYSTICK使用外部时钟源 fac_us=SYSCLK/8; //不论是否使用OS,fac_us都需要使用 #if SYSTEM_SUPPORT_OS //如果需要支持OS. reload=SYSCLK/8; //每秒钟的计数次数 单位为K reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间 //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右 fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位 SysTick->CTRL|=1<<1; //开启SYSTICK中断 SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次 SysTick->CTRL|=1<<0; //开启SYSTICK #else fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数 #endif } //延时nus //nus为要延时的us数. void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; //时间加载 SysTick->VAL=0x00; //清空计数器 SysTick->CTRL=0x01 ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对72M条件下,nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL=0x01 ; //开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //初始化IIC void IIC_Init(void) { RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟 GPIOC->CRH&=0XFFF00FFF;//PC11/12 推挽输出 GPIOC->CRH|=0X00033000; GPIOC->ODR|=3<<11; //PC11,12 输出高 } //产生IIC起始信号 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA=1; delay_us(4); IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); //IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号 void IIC_Stop(void) { SDA_OUT();//sda线输出 //IIC_SCL=0; IIC_SDA=0; delay_us(4); IIC_SCL=1;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SDA=1;//发送I2C总线结束信号 } //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { IIC_Stop(); return 1; } } IIC_SCL=0;//时钟输出0 return 0; } //产生ACK应答 void IIC_Ack(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //不产生ACK应答 void IIC_NAck(void) { IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0; } //IIC发送一个字节 //返回从机有无应答 //1,有应答 //0,无应答 void IIC_Send_Byte(u8 txd) { u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { IIC_SDA=(txd&0x80)>>7; txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的 IIC_SCL=1; delay_us(2); IIC_SCL=0; delay_us(2); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive<<=1; if(READ_SDA)receive++; delay_us(1); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; } //读寄存器 //A7 A6 A5 A4 A3 A2 A1 W/R //1 1 0 1 1 0 SDO/ADDR 0/1 //读传感器 void Read_Sensor(void) { u8 Status = 0x00; u8 Read_Data[5] = {0x00}; u8 count; IIC_Init(); delay_ms(30); IIC_Start(); IIC_Send_Byte(0xda);//0xda//0xd8 IIC_Wait_Ack(); IIC_Send_Byte(0x30); IIC_Wait_Ack(); IIC_Send_Byte(0x0A);//PT_Read IIC_Wait_Ack(); delay_ms(10); IIC_Stop();// IIC_Start(); IIC_Send_Byte(0xda); IIC_Wait_Ack(); IIC_Send_Byte(0x02); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0xdb);//0xdb IIC_Wait_Ack(); Status=IIC_Read_Byte(1); IIC_Stop(); if(Status&0x01)//判断转换状态 { IIC_Start(); IIC_Send_Byte(0xda); IIC_Wait_Ack(); IIC_Send_Byte(0x06);//存储压力温度值寄存器起始地址 IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0xdb); IIC_Wait_Ack(); Read_Data[0]=IIC_Read_Byte(1);//压力转换数值【23:16】 Read_Data[1]=IIC_Read_Byte(1);//压力转换数值【15:8】 Read_Data[2]=IIC_Read_Byte(1);//压力转换数值【7:0】 Read_Data[3]=IIC_Read_Byte(1);//温度转换数值【15:8】 Read_Data[4]=IIC_Read_Byte(0);//温度转换数值【7:0】 IIC_Stop(); PressData = (Read_Data[0]<<16)|(Read_Data[1]<<8)|Read_Data[2]; TempData = (Read_Data[3]<<8)|Read_Data[4]; } //传感器压力ADC 位为 24 位。数据格式:最高位为符号位(0 为正数,1 为负数) //23位数据位。23 位数据位中有高 N 位整数位,低 n 位为小数位,则要求 n //满足不等式:2^(23-(n+1))