51微控制器利用IIC匯流排對LM75A溫度進行讀取
阿新 • • 發佈:2019-02-07
#include <INTRINS.H> #include "..\config\c8051f350.h" #include "..\config\const.h" #include "..\driver\system.h" #include "..\driver\other.h" #define IIC_WRITE 0 #define IIC_READ 1 #define VREF 24380 static unsigned long sysclk=24500000; sbit SDA=P0^0; sbit SCL=P0^1; sbit led=P1^2; void Delay_us(unsigned int times){ unsigned int i; for(i=0;i<times;i++){ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } } //延時us函式 void Delay_ms(unsigned int times) { unsigned int i; for (i=0;i<times;i++) Delay_us(1000); } //延時ms函式 void iic_start(void){ SDA = 1; Delay_us(2); SCL = 1; Delay_us(2); SDA = 0; Delay_us(2); } //iic通訊起始訊號 void iic_stop(void){ SDA = 0; Delay_us(2); SCL = 1; Delay_us(2); SDA =1; } //iic通訊終止訊號 void iic_ack(void) { SCL = 0; SDA = 0; Delay_us(2); SCL = 1; Delay_us(2); SCL = 0; Delay_us(1); SDA = 1; } //傳送應答訊號函式 bool read_ack(void) { bool flag; SCL = 0; Delay_us(2); SDA = 1; SCL = 1; Delay_us(2); flag = SDA; SCL = 0; return flag; } //iic應答函式 void iic_nack() { SDA = 1; Delay_us(2); SCL = 1; Delay_us(2); SCL = 0; } //iic非應答函式 unsigned char get_byte(void) { unsigned char dd; int i; dd=0; SDA = 1; for (i=0;i<8;i++) { Delay_us(1); SCL = 0; Delay_us(5); SCL = 1; Delay_us(2); dd<<=1; if (SDA) dd|=0x01; Delay_us(1); } SCL = 0; Delay_us(1); return dd; } //輸入一個位元組 void out_byte(unsigned char dd) { unsigned char i; for(i=0;i<8;i++) { SCL = 0; Delay_us(0); SDA = (dd & 0x80)>>7; Delay_us(2); SCL = 1; Delay_us(3); dd <<= 1; } SCL = 0; } //輸出一個位元組 bool iic_write_addr(unsigned char addr,unsigned char data_addr) { iic_start(); out_byte(addr); read_ack(); out_byte(data_addr); read_ack(); return TRUE; } //寫入器件地址和所需讀取暫存器的地址 void IICA_Read(unsigned char id, unsigned char addr, unsigned char *p, unsigned int len) { int i; bit EA_SAVE = EA; EA = 0; iic_write_addr(id|IIC_WRITE,addr); iic_start(); out_byte(id|IIC_READ); read_ack(); for (i=0;i<len;i++) { *p++ = get_byte(); if (i!=(len-1)) iic_ack(); } iic_nack(); iic_stop(); EA = EA_SAVE; } //iic匯流排讀取多個數據 float readTemperature(){ unsigned char id=0x90; unsigned char addr=0x00; unsigned int len=2; unsigned char temp[2]={0}; float temp_value=0.0; unsigned int temp_high=0; unsigned int temp_low=0; unsigned int low=0; unsigned int tempforh=0; unsigned int judge_posneg=0; IICA_Read(id,addr,temp,2); temp_high=temp[0]; temp_low=temp[1]; low=temp_low>>5; tempforh=temp_high*8+low; judge_posneg=(temp_high & 0x80)>>7; if(judge_posneg==0){ temp_value=tempforh*0.125; return temp_value; }else { tempforh=(tempforh^0x7FF)+1; temp_value=tempforh*(-0.125); return temp_value; } } //讀取並計算當前溫度 float main(){ float tempvalue=0.0; PCA0MD&=~0x40; // 禁止看門狗定時器 Sysclk_Init(); // 配置系統時鐘 SysPort_Init(); // 埠配置 tempvalue=readTemperature(); while(1){ led=1; Delay_ms(1000); led=0; Delay_ms(1000); } SDA=1; return tempvalue; }