中微SC8F5771模拟IIC通信——指令运行速度的探索(附编译软件与烧录软件)


文章目录

  • 一、中微单片机烧录与使用
    • 编译软件
    • 烧录软件
    • 下载地址
    • 烧录软件
  • 二、模拟IIC
  • 三、逻辑分析仪下的时序


一、中微单片机烧录与使用

编译软件

中微所使用编译软件为SCMCU_IDE,不过个人不推荐使用这个软件写代码(十分不好用,不能跳转,只能全部搜索一个个查,而且不能替换),大家可以利用VScode打开代码项目文件(直接拖入桌面VScode图标或者打开VScode再打开项目文件),VScode永远的神。
在这里插入图片描述

烧录软件

烧录软件是SCMCU WRITER,买个中微的烧录器直接接好线烧录即可(每次编译完会提醒你代码改变了)
在这里插入图片描述

下载地址

中微官网是:https://www.mcu.com.cn(顺带提一嘴,好牛皮的域名)
进入他的支持界面,开发工具,规格书,DEMO什么的应有尽有。
在这里插入图片描述

烧录软件

在官网下载好软件之后安装即可,进入文件夹即可看到编译软件。
在这里插入图片描述

二、模拟IIC

虽然硬件IIC运行速度很快,但是由于单片机性能受限,并不是所有单片机都有硬件IIC,软件IIC模拟IIC协议通信,进行读写操作,我以中微SC8F5771单片机为例,利用其RB0和RB1口分别作为SDA和SCL口。此处我仅给出大概模板。

void iic_init(void);//iic初始化,调GPIO,也就是选用的sda和scl口,由于最开始要输出,所以设置为输出模式,iic通信最开始都是高电平
void iic_deinit(void);//有初始化肯定有取消初始化,将sda和scl设置为输入模式
void iic_write(unsigned char dev_addr, unsigned char reg_addr, unsigned char date)//iic写入,最为关键的一步,把控协议主体思路
{
	iic_start();
	delay_us();
	write_iic_byte(dev_addr & 0xFE)//iic的地址位最后一位是读写方式,所以是与0xFE,如果忘了就去查一查
	iic_wait_ack();//等待应答
	delay_us();
	write_iicbyte(date);//地址完了就轮到数据
	iic_wait_ack();//等待应答
	delay_us();
	iic_stop();//一次数据写入完成,停止通信
}
void iic_start(void);//开始iic时需要scl和sda置高,然后sda拉低,表明开始,然后再scl拉低,好让sda可以拉高或保持低作为检测的数据。
void iic_stop(void);//停止时需要sda和scl都置高,满足下一次通信的起始状态
void write_iic_byte(unsigned char iic_byte)//一个很经典的写法
{
	unsigned char i=8;
	unsigned char temp;
	unsigned char data;
	data = iic_byte;
	iic_sclk_clr();
	while(i--)
	{
		temp=data>>7;
		data<<1;
		if(temp)
		{
			iic_sdin_set();
		}
		else
		{
			iic_sdin_clr();
		}
		iic_sclk_set();
		delay_3us();
		iic_sclk_clr();
		delay_3us();
		
	}
}
void iic_wait_ack(void);//进行应答

三、逻辑分析仪下的时序

为了让IIC通信更快(该芯片晶振是16MHz的),为了验证其置高低电平和nop、以及空函数调用时间,我利用逻辑分析仪,在while循环里面写了如下代码,观测到的时序如图所示。

   	 			sclk = 1;//delay_us是空的,里面什么都没有,此处只是对比在此单片机中空函数和nop区别时间究竟相差多少
                delay_us();
                delay_us();
                delay_us();
                delay_us();
                delay_us();

                delay_us();
                delay_us();
                delay_us();
                delay_us();
                delay_us();

                delay_us();
                delay_us();
                delay_us();
                delay_us();
                delay_us();

                delay_us();
                delay_us();
                delay_us();
                delay_us();
                delay_us();
                sclk = 0;

                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us

                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us

                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us

                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us
                NOP();//0.25us

在这里插入图片描述

我们可以很清楚的看到高电平之后延时20个空函数,再低电平,执行20个nop指令,最终显示一个周期内,高电平持续33us,低电平持续6.25us,后续又将20个空函数和nop改为1个空函数和1个nop,以及不加n空函数和nop的测试,可以大致得出,置一次高低电平需要2us,一个nop指令花费0.2us-0.25us,一个空函数调用大致在1.2us。
由于时间关系我并没有去验证太多,测出结果可能也不太严谨,学过汇编的同学知道,调用函数时先跳转再返回,以51汇编为例,不同位置的函数使用对应不同的跳转指令,范围越大的跳转指令耗费时间也更久,由于我是跨文件调用,应该是对应汇编中的LCALL长跳转,并且RET返回,所以花费nop指令5-6倍的时间似乎也合理(nop本身就只占一个时钟周期)。

以上为个人分析,无法确定其正确性,仅凭客观数据以及主观猜测,如有错误,请您指正。
非常感谢各位的观看!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知何人

万分感谢诸位观看

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值