我用的是STC8A8K64S4A12這一款單片機,模擬I2C讀取溫度,以及ADC讀取電阻分壓后電壓計算 LM75A
- #include"main.h"
- char xdata temp_[3]; //
- char xdata test[15];
- bit temp_flag;
- void Delay_us(int i) //iic延時
- {
- int j;
- for(j=0;j<i;j++);
- }
- void IIC_init(void) //iic初始化
- {
- SCL = 1;
- Delay_us(5);
- SDA = 1;
- Delay_us(5);
- }
- void iic_start(void) //iic通信起始信號
- {
- SDA = 1;
- Delay_us(2);
- SCL = 1;
- Delay_us(2);
- SDA = 0;
- Delay_us(2);
- }
- void iic_stop(void) //iic通信終止信號
- {
- SDA = 0;
- Delay_us(2);
- SCL = 1;
- Delay_us(2);
- SDA =1;
- }
- void iic_ack(void) //發送應答信號函數
- {
- SCL = 0;
- SDA = 0;
- Delay_us(2);
- SCL = 1;
- Delay_us(2);
- SCL = 0;
- Delay_us(1);
- SDA = 1;
- }
- void read_ack(void) //iic應答函數
- {
- SCL = 0;
- Delay_us(2);
- SDA = 1;
- SCL = 1;
- Delay_us(2);
- SCL = 0;
- }
- void iic_nack() //iic非應答函數
- {
- SDA = 1;
- Delay_us(2);
- SCL = 1;
- Delay_us(2);
- SCL = 0;
- }
- u8 get_byte(void) //輸入一個字節
- {
- u8 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(u8 dd) //輸出一個字節
- {
- u8 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;
- }
- //寫入器件地址和所需讀取寄存器的地址
- void iic_write_addr(u8 addr,u8 data_addr)
- {
- iic_start();
- out_byte(addr);
- read_ack();
- out_byte(data_addr);
- read_ack();
- }
- //iic總線讀取多個數據
- void IICA_Read(u8 id, u8 addr, u8 *p, u16 len)
- {
- int i;
- bit EA_SAVE = EA;
- EA = 0;
- iic_write_addr(id|0,addr);
- iic_start();
- out_byte(id|1);
- read_ack();
- for (i=0;i<len;i++)
- {
- *p++ = get_byte();
- if (i!=(len-1))
- iic_ack();
- }
- iic_nack();
- iic_stop();
- EA = EA_SAVE;
- }
- //讀取并計算當前溫度
- void readTemperature()
- {
- u8 id=0x90; //設備地址
- u8 addr=0x00; //溫度寄存器地址
- u32 temp_high; //儲存高字節
- u8 temp_low; //儲存低字節
- u8 temp[2]={0};
- u8 a = 0;
-
- IICA_Read(id,addr,temp,2); //將溫度的兩個字節存到temp中
- temp_high = temp[0]; //溫度高
- temp_low = temp[1]; //溫度低
-
- temp_high = (temp_high << 8) + temp_low;
- temp_high = temp_high >> 5;
-
- memset(test,0,sizeof(test));
-
- if((temp_high & 0x0400) == 0x0400)
- test[a++] = '-';
- else
- test[a++] = '+';
-
- temp_high = temp_high * 125;
-
- if(temp_high >= 25500)
- temp_flag = 1;
-
- if(temp_high >= 100000)
- test[a++] = temp_high / 100000 % 10 + '0';
-
- test[a++] = temp_high / 10000 % 10 + '0';
- test[a++] = temp_high / 1000 % 10 + '0';
- test[a++] = '.';
- test[a++] = temp_high / 100 % 10 + '0';
- test[a++] = temp_high % 100 / 10 + '0';
- test[a++] = temp_high % 10 + '0';
- test[a++] = 'C'; //℃
- }
復制代碼 ADC
- #include"main.h"
- char xdata AD1_V[7];
- extern bit voltage_flag;
- void adc_init(void)
- {
- P1M0 &= 0x7F; //設置P1.7為ADC口
- P1M1 |= 0x80;
- ADCCFG = 0x21; //設置ADC時鐘為系統時鐘/2/16/16
- ADC_CONTR = 0x80; //使能ADC模塊
- }
- int adcread()
- {
- int res;
- ADC_CONTR |= 0x47; //啟動AD轉換P17
- _nop_();
- _nop_();
- while (!(ADC_CONTR & 0x20)); //查詢ADC完成標志
- ADC_CONTR &= ~0x20; //清完成標志
- res = ADC_RES;
- res = (res << 8) + ADC_RESL; //讀取ADC結果
-
- return res;
- }
- void adc_test(void)
- {
- u32 AD1;
- char a=0;
-
- AD1 = adcread(); //P17
-
- AD1 = AD1 * 86813; //3555/4095
- //AD1 = AD1 * 43596; //3555/4095
- AD1 = AD1 / 100000;
- AD1 = (AD1 *115) / 15; //11.5= R1+R2 分壓
- AD1 = AD1 / 10;
-
- if(AD1 <= 2000) //主板供電電壓小于20V報警
- voltage_flag = 1;
-
- memset(AD1_V,0,sizeof(AD1_V)); //清buff,防止小于10V時會出現兩個V
-
- if(AD1 >= 1000)
- AD1_V[a++] = AD1 / 1000 % 10 + '0';
-
- AD1_V[a++] = AD1 / 100 % 10 + '0';
- AD1_V[a++] = '.';
- AD1_V[a++] = AD1 % 100 / 10 + '0';
- AD1_V[a++] = AD1 % 10 + '0';
- AD1_V[a++] = 'V';
- }
復制代碼
以上代碼:
i2c,adc.rar
(2.34 KB, 下載次數: 32)
2020-4-29 09:29 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|