这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【STC32G12K128】使用I2C外设驱动SHT40

共1条 1/1 1 跳转至

【STC32G12K128】使用I2C外设驱动SHT40

专家
2026-06-17 22:25:32     打赏

这是使用STC32G12K128的I2C外设读取SHT40数据的代码


#include "COMM/stc.h"
#include "stdio.h"
#include "usart2.h"
#include "iic.h"

#define SHT40_ADDR 0x88  
#define SHT40_CMD_HIGH_PRECISION 0xFD

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
void sys_init();//函数声明
void delay_ms(u16 ms);//unsigned int 
bit  TIM_10MS_Flag;//10ms的标志位 
u16 Tme_CountDown = 0;//全局变量
u8   dat[32];

void sht40_setPrecision(void) {
   // 发送高精度测量命令
    IIC_START();
   IIC_SENDBYTE(SHT40_ADDR);
   IIC_WAITACK();
   // 精度指令
   IIC_SENDBYTE(SHT40_CMD_HIGH_PRECISION);
   IIC_WAITACK();
    IIC_STOP();
}

// 读取温湿度数据
void sht40_read(u8 *dat) {
    int i = 0;
    sht40_setPrecision();
    delay_ms(10);
   IIC_START();
    // 读数据指令的第一个字节:地址
   IIC_SENDBYTE((u8)(SHT40_ADDR+0x01));
   IIC_WAITACK();
    // 读取6个字节的数据
    for (i=0; i<6; i++) {
        dat[i] = IIC_READBYTE();
        if (i<5) {
            IIC_SENDACK();
        }
    }
    
  IIC_SENDNACK();
  IIC_STOP();
}
void sys_init() {
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
    P3M0 = 0x00;
    P3M1 = 0x00;
    P3M0 &= ~0x03;
    P3M1 |= 0x03;
    //设置USB使用的时钟源
    IRC48MCR = 0x80;    //使能内部48M高速IRC
    while (!(IRC48MCR & 0x01));  //等待时钟稳定
    USBCLK = 0x00;//使用CDC功能需要使用这两行,HID功能禁用这两行。
    USBCON = 0x90;
}
void delay_ms(u16 ms) {
    u16 i;
    do {
        i = MAIN_Fosc/6000;
        while(--i);
    } while(--ms);
}
 
void main() {
   char str[30];
   int i=0;
   float t=0;
   float h=0;
   u16 t0;
   u16 h0;
   sys_init();// IO口初始化
   UART2_config(2);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
   IIC_Init();// iic初始化
  
  EA = 1;// CPU开放中断,打开总中断。
  
  while(1) {
        //-----------------------读取数据-----------------------
        sht40_read(dat);
        for (i=0; i<6; i++) {
            PrintChar(dat[i]);
        }
        PrintString2("\r\n");
        sprintf(str,"Dat=%02X\t%02X\t%02X\t%02X\t%02X\t%02X\r\n", dat[0], dat[1], dat[2], dat[3], dat[4], dat[5]);
        PrintString2(str);
    
        t0 = (u16)(dat[0]*256 + dat[1]);
        h0 = (u16)(dat[3]*256 + dat[4]);
        t= 175.0 * t0 / 65535.0 - 45.0;
        h= 125.0 * h0 / 65535.0 - 6.0;
        sprintf(str,"Dat=%u\t %u\t T:%2.2f,H:%2.2f\r\n",t0, h0, t, h);
        PrintString2(str);
    
        delay_ms(3000);
  }
}

I2C外设映射到P2.4,P2.5上,速度为900KHz左右。

// IIC初始化
void IIC_Init(){
    I2C_S1 = 0;//设置IIC的引脚,S1S0=01 : P2.5=scl, P2.4=sda
    I2C_S0 = 1;
    //I2CCFG = 0xE0;//设置速度和使能IIC,速度200K
    //I2CCFG = 0xC8;//设置速度和使能IIC,速度500K
    //I2CCFG = 0xC4;//设置速度和使能IIC,速度800K
    I2CCFG = 0xC3;//设置速度和使能IIC,速度900K
    I2CMSST = 0;//清空主机状态
}

串口调试映射到P4.6,P4.7上,波特率115200,n,8,1。

void UART2_config(u8 brt) {
    if(brt == 2) {
        SetTimer2Baudraye(Baudrate2);

        S2CFG |= 0x01;     //使用串口2时,W1位必需设置为1,否则可能会产生不可预期的错误
        S2CON = (S2CON & 0x3f) | 0x40;    //UART2模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
        ES2   = 1;         //允许中断
        S2REN = 1;         //允许接收
        S2_S  = 1;         //UART2 switch to: 0: P1.0 P1.1,  1: P4.6 P4.7

        B_TX2_Busy = 0;
        TX2_Cnt = 0;
        RX2_Cnt = 0;
    }
}

void UART2_int (void) interrupt 8 {
    // 如果接受到数据
    if(S2RI) {
       S2RI = 0;    //Clear Rx flag
     RX2_Buffer[RX2_Cnt] = S2BUF;
        if( RX2_Buffer[RX2_Cnt]== '\n' ) {
            if( RX2_Buffer[RX2_Cnt-1]== '\r' ) {
                Rec_Flag = 1;
        }
        RX2_Cnt = 0;
        } else {
            RX2_Cnt++;
      }
   }
   if(S2TI) {
       S2TI = 0;    //Clear Tx flag
      B_TX2_Busy = 0;
   }
}

测试结果:

1.png

I2C总线时序数据:

在进行数据处理的过程中,犯了一些低级错误,表现在:

1、声明变量时,按照了计算机软件编程方式,声明两个类型相同的变量时,使用了下面这种形式

u16 a, b;

结果后面的处理过程中,数据总是不对。应该改成:

u16 a;

u16 b;

2、使用sprintf格式化数据时,使用%d格式化u16数据,结果导致不正常,实际上用应该使用%u。

查了下相关资料,有如下说明:

5.png





关键词: 大懒猫的试用笔记     STC32G12K128     SHT    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]