我用的是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)
|