【STC12C5A60S2】TOF250(IIC)基于51系列开发板的运用

7 篇文章 0 订阅
2 篇文章 0 订阅


一、前言

此片文章主要介绍如果通过51系列开发板来读取TOF250(IIC接口)数据的教程
由于51芯片一般不太有IIC接口,此篇主要介绍通过模拟IIC来读取的案例。
提示:以下的案例仅供参考学习使用


二、硬件准备

  • TOF250 :测距传感器

  • 51系列开发板:STC12C5A60S2 主频12M
    提示:51系列开发板种类较多,此处不专门举例

详细资料可以参考:STC 官网

  • 电脑 :Windows 7/10/11

  • TTL转USB:本次测试使用CH340芯片转接板
    在这里插入图片描述

  • 杜邦线:各类(若干)
    在这里插入图片描述

  • TOF250尾线:购买时自带有一根尾线
    在这里插入图片描述


二、软件准备

  • KEIL IDE:参考官网下载安装教程
    在这里插入图片描述

三、硬件接线图

在这里插入图片描述

提示:实际在测试过程中不建议接上图黄色的线
说明:

  • STC12C5A60S2共有两个串口,不过此次测试仅使用一个串口,方便理解
  • 此时使用的是模拟IIC接口来读取TOF250的数据
  • USB打印结果需要用到串口1的TX

四、例程源码

mian.c

/**************************************************************
**技术论坛:https://blog.csdn.net/HCJ_Application/article/details/124058266
**修改日期:2022/4/24
**技术说明:基于STC12C5A60S2单片机,主频12M
**版本:V1.0
**作者:深圳市弘成基科技有限公司
**************************************************************/


#include <STC12C5A60S2.h>
#include <stdio.h>
#include "myiic.h"

#define TOF250_DIST_H 0x00             //TOF250距离值高8位
#define TOF250_DIST_L 0x01             //TOF250距离值低8位
#define TOF250_READ_L    2             //TOF250读取的长度
#define TOF250_ID     0x52             //TOF250的IIC地址

unsigned char data RxData[10];          //IIC接口接收数据区


unsigned int  Tof250_dist = 0;         //读取到TOF250的具体数值

void Uart1_SendChar(unsigned char Udat) ;



void UartInit(void)		//9600bps@12.000MHz
{
    PCON |= 0x80;		//使能波特率倍速位SMOD
    SCON = 0x50;		//8位数据,可变波特率
    AUXR |= 0x40;		//定时器时钟1T模式
    AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
    TMOD &= 0x0F;		//设置定时器模式
    TMOD |= 0x20;		//设置定时器模式
    TL1 = 0xB2;		//设置定时初始值
    TH1 = 0xB2;		//设置定时重载值
    ET1 = 0;		//禁止定时器%d中断
    TR1 = 1;		//定时器1开始计时

    ES = 1;     //打开串口接收中断
    EA = 1;			//打开所有中断
}
char putchar(char c)
{
    Uart1_SendChar(c);
    return c;
}

void Uart1_SendChar(unsigned char Udat)
{
    SBUF=Udat; //将要发送的数据放入串口数据缓冲区
    while(!TI); //等待发送完成
    TI=0;      //清零TI发送完成标记
}

//定义一个延时
void Delay100ms()		//@12.000MHz
{
	unsigned char i, j, k;

	i = 5;
	j = 144;
	k = 71;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
    UartInit();                 //串口初始化,使用9600波特率打印IIC读到的距离值

    while(1) {
			tof250_i2c_read(TOF250_ID,TOF250_DIST_H, &RxData[0], TOF250_READ_L);    //通过IIC读取TOF250距离值信息
			
			Tof250_dist = RxData[1] + RxData[0]*256;                                //转换成距离值
			printf("%u cm\n",Tof250_dist);                                          //串口1直接打印输出
			Delay100ms();                                                           //延时100ms,TOF250默认更新速度10HZ
   }
}

myiic.h

#ifndef _MYIIC_H_
#define _MYIIC_H_
#include <STC12C5A60S2.h>

sbit SCL = P2^3;
sbit SDA = P2^4;

void tof250_i2c_read(unsigned char tof_ID,unsigned char word_adress, unsigned char *rdata, unsigned char num);

#endif

myiic.c

#include "myiic.h"
/*
*********************************************************************************************************
*   函 数 名: i2c_Delay
*   功能说明: I2C总线位延迟,最快400KHz
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{
    unsigned char i;

    /* 
        IIC 延时时间根据具体情况自行决定for循环延迟时间的大小

        实际应用选择小于400KHz左右的速率即可
    */
    for (i = 0; i < 10; i++);
}

void i2c_Start(void)
{
    /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
    SDA = 1;
    SCL = 1;
    i2c_Delay();
    SDA = 0;
    i2c_Delay();
    SCL = 0;
    i2c_Delay();
}

/*
*********************************************************************************************************
*   函 数 名: i2c_Start
*   功能说明: CPU发起I2C总线停止信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{
    /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
    SDA = 0;
    SCL = 1;
    i2c_Delay();
    SDA = 1;
    i2c_Delay();
}
/*
*********************************************************************************************************
*   函 数 名: i2c_WaitAck
*   功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
*   形    参:  无
*   返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
unsigned char i2c_WaitAck(void)
{
     unsigned char re; //应答信号等于0则应答正确,等于1则没有应答
     SDA = 1;          //释放总线,能让对方拉低
     i2c_Delay();
     SCL = 1;          //此时刻开始,数据保持应答状态稳定
     i2c_Delay();
     if(SDA == 1)
     {
        re = 1;        //没有应答
     }
     else
     {
        re = 0;        //应答正确                                                                                                                                                                            
     }
     SCL = 0;
     i2c_Delay();

     return re;
}
/*
*********************************************************************************************************
*   函 数 名: i2c_SendByte
*   功能说明: CPU向I2C总线设备发送8bit数据
*   形    参:  _ucByte : 等待发送的字节
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(unsigned char _ucByte)
{
     unsigned char i;     //其实信号开始后SCL是被拉低的
     for(i = 0; i < 8; i++)
     {
        if(_ucByte & 0x80)
            SDA = 1;
        else
            SDA = 0;
        SCL = 1; 
        i2c_Delay();
        SCL = 0;      //SCL等于0的时候写数据
        if(i == 7)    //最后一次时释放总线
        {
            SDA = 1;
        }
        _ucByte<<=1;  //左移一位
        i2c_Delay();
     }
}

/*
*********************************************************************************************************
*   函 数 名: i2c_ReadByte
*   功能说明: CPU从I2C总线设备读取8bit数据
*   形    参:  无
*   返 回 值: 读到的数据
*********************************************************************************************************
*/
unsigned char i2c_ReadByte(void)
{
     unsigned char i;
     unsigned char value = 0;
     for(i = 0; i < 8; i++)
     {
        value<<=1;
        SCL = 1;  //稳定状态的时候读数据
        if(SDA == 1)
            value++;
        SCL = 0;  //允许数据变化
        i2c_Delay();
     }

     return value;
}

/*
*********************************************************************************************************
*   函 数 名: i2c_Ack
*   功能说明: CPU产生一个ACK信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
    SDA = 0;//响应
    i2c_Delay();
    SCL = 1;
    i2c_Delay();
    SCL = 0;
    i2c_Delay();   //在SCL为高电平期间SDA都为0即产生一个应答信号
    SDA = 1;       //释放总线
    i2c_Delay();
}

/*
*********************************************************************************************************
*   函 数 名: i2c_NAck
*   功能说明: CPU产生1个NACK信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
     SDA = 1;
     i2c_Delay();
     SCL = 1;
     i2c_Delay();
     SCL = 0;
     i2c_Delay();   //在SCL为高电平期间SDA都为1即产生一个非应答信号
}

void tof250_i2c_read(unsigned char tof_ID,unsigned char word_adress, unsigned char *rdata, unsigned char num)
{
	unsigned char i;
	i2c_Start();
	i2c_SendByte(tof_ID << 1);
	i2c_WaitAck();
	
	i2c_SendByte(word_adress);
	i2c_WaitAck();
	i2c_Stop();
	
	i2c_Delay();
	
	i2c_Start();
	i2c_SendByte(tof_ID << 1 | 0x01);
	i2c_WaitAck();
	if(num > 1){
		        for (i = 0; i < num - 1; i++) {
            *(rdata + i) = i2c_ReadByte();
							i2c_Ack();
        }
	}
	*(rdata + num - 1) = i2c_ReadByte();
	i2c_NAck();
	i2c_Stop();
	
}

五、烧录说明

5.1 烧录接线示意图

在这里插入图片描述

5.2 烧录动态图

请添加图片描述

提示:烧录过程中请先断开TF250与STC12C5A60S2的TX\RX接线,否则无法正常烧录


六、结果输出

通过SSCOM串口软件打印结果(其他串口工具也可以)

提示:注意选择对应的波特率,此次测试使用波特率为9600
请添加图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于STM32F103的TOF测距模块代码主要分为硬件配置和软件实现两部分。 硬件配置方面,首先要连接STM32F103与TOF测距模块。可以将TOF测距模块的VIN、GND、SCL、SDA引脚连接到STM32F103的相应引脚上。然后需要在STM32F103的CubeMX中配置相关外设,比如I2C外设用于与TOF测距模块进行通信。 在软件实现方面,首先需要初始化I2C外设,这包括配置I2C时钟、地址和传输速率等。然后可以编写发送和接收函数,用于与TOF测距模块进行数据的读写。在主程序中,可以通过调用相应函数来进行测距的操作。 具体代码如下所示: ```c #include "stm32f10x.h" #include "i2c.h" #define TOF_ADDRESS 0x52 // TOF测距模块的I2C地址 void TOF_Init() { I2C_Init(); // 初始化I2C外设 } uint16_t TOF_GetDistance() { uint8_t distanceData[2]; // 发送读取数据请求 I2C_Start(); I2C_SendData(TOF_ADDRESS, 0x00, 0xE3); // 发送0xE3表示读取数据 I2C_Stop(); // 延时等待测距模块处理 for (uint32_t i = 0; i < 100000; i++) {} // 读取测距数据 I2C_Start(); I2C_SendData(TOF_ADDRESS|0x01, 0x00, 0x00); // 读取2个字节的测距数据 I2C_ReadData(TOF_ADDRESS|0x01, distanceData, 2); I2C_Stop(); // 将两个字节的测距数据合并为一个16位数据 uint16_t distance = (distanceData[0] << 8) | distanceData[1]; return distance; } int main(void) { TOF_Init(); while (1) { uint16_t distance = TOF_GetDistance(); // 处理测距数据 } } ``` 以上是一个简单的基于STM32F103的TOF测距模块代码示例。在实际应用中,可能还需要根据具体的测距模块和需求进行相应的修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值