文章目录
- 一、中微单片机烧录与使用
- 编译软件
- 烧录软件
- 下载地址
- 烧录软件
- 二、模拟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本身就只占一个时钟周期)。
以上为个人分析,无法确定其正确性,仅凭客观数据以及主观猜测,如有错误,请您指正。
非常感谢各位的观看!