历史上的今天
返回首页

历史上的今天

今天是:2024年10月17日(星期四)

正在发生

2018年10月17日 | 54。I2C通信实验

2018-10-17 来源:eefocus

C语言小知识:

如何定义字符串:

可以通过字符数组或字符指针来定义字符串,也可以用宏定义对常量字符串进行定义。

 //定义字符串的几种方式

char names2[ ] = "jack";   字符串数组

char * names3 = "jack";    字符串指针

字符串是按ASSII码表以十六进制码存储的,比如 W就是0x57, a就是0x61

注意:

声明存储字符串的数组时,数组大小至少比所存储的字符串多1,因为编译器会自动在字符串常量的末尾添加空字符\0。


一。IIC通信协议

(一)概述

54。I2C通信实验

IIC器件的连接方式

54。I2C通信实验
每个器件都有自己相应的地址。

IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据。在 CPU 与被控 IC 之间、IC 与 IC 之间进行双向传送,高速 IIC 总线一般可达 400kbps 以上。I2C 总线在传送数据过程中共有三种类型信号,  它们分别是:开始信号、结束信号和应答信号。

开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。

结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。

应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。

(二)IIC协议

54。I2C通信实验

1. 空闲状态

54。I2C通信实验
SCL和SDA分别接两个上拉电阻,以使IIC在空闲的时候为高电平。

2. 开始信号和停止信号

54。I2C通信实验

3. 应答信号

54。I2C通信实验
有效应答ACK必须在第9个时钟脉冲为高电平期间保持稳定,因此先要将SCL拉低,然后发出ACK信号,再拉高SCL,再把SCL拉低。

4. 数据的有效性

54。I2C通信实验
数据必须要在SCL为高电平期间保持稳定,因此要先把SCL拉低,然后发送数据,再把SCL拉高,再把SCL拉低,这样就保证了在SCL为高电平期间数据是稳定的,再把SCL拉低,在SCL为低电平期间数据才允许变化。

5. 数据传输

54。I2C通信实验

(三)IIC底层驱动程序

 

54。I2C通信实验

STM32 的 CRH 控制着每组 IO 端口(A~G)的高 8 位的模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。

 0X3 表示推挽输出模式(做输出口用,50M 速率)、0X8 表示上/下拉输入模式(做输入口用)。

myiic.h

//IO方向设置,控制IO工作模式

 

#define SDA_IN()   {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}

#define SDA_OUT()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}

//IO操作函数  

#define IIC_SCL    PBout(10) //SCL

#define IIC_SDA    PBout(11) //SDA  

#define READ_SDA   PBin(11)  //输入SDA 

myiic.c

//初始化IIC

void IIC_Init(void)

{     

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟

  

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11); //PB6,PB7 输出高,因为IIC总线在空闲是都为高电平

}

54。I2C通信实验

//产生IIC起始信号

void IIC_Start(void)

{

SDA_OUT();     //sda线输出

IIC_SDA=1;    

IIC_SCL=1;

delay_us(4);

  IIC_SDA=0;//START:when CLK is high,DATA change form high to low 

delay_us(4);

IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 

}

54。I2C通信实验

 

//产生IIC停止信号

void IIC_Stop(void)

{

SDA_OUT();//sda线输出

IIC_SCL=0;

IIC_SDA=0;//STOP:when CLK is high DATA change form low to high

  delay_us(4);

IIC_SCL=1; 

IIC_SDA=1;//发送I2C总线结束信号

delay_us(4);  

}

54。I2C通信实验
要先把SCL拉低,然后准备好ACK应答数据,再拉高SCL,这样就可以保证在SCL为高电平期间ACK信号是稳定的。

//产生ACK应答,也就是有效应答

void IIC_Ack(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=0;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

//不产生ACK应答,无效应答    

void IIC_NAck(void)

{

IIC_SCL=0;

SDA_OUT();

IIC_SDA=1;

delay_us(2);

IIC_SCL=1;

delay_us(2);

IIC_SCL=0;

}

54。I2C通信实验
同样是先把SCL拉低,然后准备好数据,再拉高SCL,然后再拉低SCL,这样是为了保证在SCL为高电平期间数据是稳定的,数据只有在SCL为低电平时才允许改变。

//IIC发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答  

void IIC_Send_Byte(u8 txd)

{                        

    u8 t;   

SDA_OUT();    

    IIC_SCL=0;//拉低时钟开始数据传输

    for(t=0;t<8;t++)

    {              

if((txd&0x80)>>7)  //判断数据最高位是不是1

IIC_SDA=1;    //是1 , SDA输出高

else

IIC_SDA=0;   //是0,SDA输出低

txd<<=1; //数据左移一位

 

delay_us(2);   //对TEA5767这三个延时都是必须的

IIC_SCL=1;

delay_us(2); 

IIC_SCL=0;

delay_us(2);

    }  

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   

u8 IIC_Read_Byte(unsigned char ack)

{

unsigned char i,receive=0;

SDA_IN();//SDA设置为输入


    for(i=0;i<8;i++ )

{

        IIC_SCL=0; 

        delay_us(2);

IIC_SCL=1;

        receive<<=1;

        if(READ_SDA)receive++;   

delay_us(1); 

    }  

    if (!ack)

        IIC_NAck();//发送nACK

    else

        IIC_Ack(); //发送ACK   

    return receive;

}

    

二。24C02操作

54。I2C通信实验
A0,A1,A2为地址线,确定IIC器件的地址

54。I2C通信实验
24C02容量为2K,A0,A1,A2都接地, 读为1,写为0

所以这里24C02读地址为 1010 0001,也就是A1,写地址为 1010 0000,也就是A0。

24cxx.c文件

初始化程序

//初始化IIC接口

void AT24CXX_Init(void)

{

IIC_Init();

}

写一个字节程序

54。I2C通信实验

//在AT24CXX指定地址写入一个数据

//WriteAddr  :写入数据的目的地址    

//DataToWrite:要写入的数据

void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)

{          

    IIC_Start();  

if(EE_TYPE>AT24C16)

{

IIC_Send_Byte(0XA0);    //发送写命令,这里24C02写地址为A0

IIC_Wait_Ack();

IIC_Send_Byte(WriteAddr>>8);//发送高地址

  }else

{

IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据,为了兼容其他型号                                                                                              的IIC芯片

}  

IIC_Wait_Ack();   

    IIC_Send_Byte(WriteAddr%6);   //发送低地址

IIC_Wait_Ack();     

IIC_Send_Byte(DataToWrite);     //发送字节   

IIC_Wait_Ack();         

    IIC_Stop();//产生一个停止条件 

delay_ms(10);  

}

读一个字节程序

54。I2C通信实验
前面一段为DUMMY WRITE,后面才读入一个DATA

//在AT24CXX指定地址读出一个数据

//ReadAddr:开始读数的地址  

//返回值  :读到的数据

u8 AT24CXX_ReadOneByte(u16 ReadAddr)

{  

u8 temp=0;        

    IIC_Start();  

if(EE_TYPE>AT24C16)

{

IIC_Send_Byte(0XA0);   //发送写命令

IIC_Wait_Ack();

IIC_Send_Byte(ReadAddr>>8);//发送高地址

IIC_Wait_Ack();  

}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据,为了兼容其他型号                                                                                                 的IIC芯片  

IIC_Wait_Ack(); 

    IIC_Send_Byte(ReadAddr%6);   //发送低地址

IIC_Wait_Ack();    

IIC_Start();     

IIC_Send_Byte(0XA1);           //进入接收模式 ,这里24C02读地址为A1 

IIC_Wait_Ack();  

    temp=IIC_Read_Byte(0);   

    IIC_Stop();//产生一个停止条件    

return temp;

}

三。实验程序讲解

//要写入到24c02的字符串数组

const u8 TEXT_Buffer[]={"WarShipSTM32 IIC TEST"};  //定义一个字符串数组

#define SIZE sizeof(TEXT_Buffer) //SIZE为数组大小,比定义的数组大1,因为编译器自动在字符串结尾加了                                                           一个结束符 \0

 int main(void)

 {  

u8 a,key;

u16 i=0;

u8 datatemp[SIZE];

delay_init();     //延时函数初始化  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

LED_Init();   //初始化与LED连接的硬件接口

LCD_Init();   //初始化LCD

KEY_Init(); //按键初始化

AT24CXX_Init(); //IIC初始化 

  POINT_COLOR=RED;//设置字体为红色 

LCD_ShowString(30,50,200,16,16,"WarShip STM32");

LCD_ShowString(30,70,200,16,16,"IIC TEST");

LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

LCD_ShowString(30,110,200,16,16,"2015/1/15");

LCD_ShowString(30,130,200,16,16,"KEY1:Write  KEY0:Read"); //显示提示信息

  while(AT24CXX_Check())//检测不到24c02

{

LCD_ShowString(30,150,200,16,16,"24C02 Check Failed!");

delay_ms(500);

LCD_ShowString(30,150,200,16,16,"Please Check!      ");

delay_ms(500);

LED0=!LED0;//DS0闪烁

}

LCD_ShowString(30,150,200,16,16,"24C02 Ready!");    

  POINT_COLOR=BLUE;//设置字体为蓝色

  

while(1)

{

key=KEY_Scan(0);

if(key==KEY1_PRES)//KEY_UP按下,写入24C02

{

LCD_Fill(0,170,239,319,WHITE);//清除半屏    

  LCD_ShowString(30,170,200,16,16,"Start Write 24C02....");

AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);  //写入字符串数组

LCD_ShowString(30,170,200,16,16,"24C02 Write Finished!");//提示传送完成

}

if(key==KEY0_PRES)//KEY1按下,读取字符串并显示

{

  LCD_ShowString(30,170,200,16,16,"Start Read 24C02.... ");

AT24CXX_Read(0,datatemp,SIZE);    //读出字符串数组

LCD_ShowString(30,170,200,16,16,"The Data Readed Is:  ");//提示传送完成

LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串

}

i++;

delay_ms(10);

if(i==20)

{

LED0=!LED0;//提示系统正在运行

i=0;

}   

}

}


推荐阅读

史海拾趣

Gardner Denver公司的发展小趣事

Galaxy Semi-Conductor Co Ltd(尽管通常指的是三星电子在半导体领域的业务,但“Galaxy Semi-Conductor”并非一个直接对应的公司名,这里我们假设其代表三星电子的半导体部门)在电子行业中的发展可以通过以下几个关键故事来概述:

1. 苏州工业园区的崛起

三星半导体(中国)研究开发有限公司,作为三星电子在中国的重要研发基地,于2003年在苏州工业园区成立。这家公司由韩国三星电子株式会社独资兴办,注册资本达到450万美元,专注于电子零部件和集成电路的软件与硬件设计,以及电子产品解决方案的研发。随着公司的不断发展,它不仅在技术研发上取得了显著成果,还积极推动了半导体技术的本地化应用,成为三星电子全球研发网络中的重要一环。

2. 半导体技术的全球领先地位

三星半导体自1983年起就拥有了半导体全线工程技术,并迅速成为世界上第三个超大规模集成电路(VLSI)生产商。这一技术突破标志着三星在半导体领域的崛起。此后,三星持续投入研发,不断推动半导体技术的创新与发展。例如,三星在DRAM(动态随机存取存储器)和NAND Flash存储技术方面取得了全球领先地位,推出了多款具有划时代意义的行业标杆产品,如高性能的SSD固态硬盘,这些产品在全球范围内得到了广泛应用。

3. 绿色工厂的环保实践

三星电子一直致力于可持续发展,其半导体工厂也不例外。例如,三星电子(苏州)半导体有限公司在2019年入选了工业和信息化部绿色工厂名单。这家工厂在生产过程中注重节能减排,采用先进的环保技术和设备,有效降低了生产过程中的能耗和排放。同时,三星还积极推动绿色供应链管理,与供应商共同致力于环境保护和可持续发展。

4. 技术创新与产品多元化

三星半导体不仅在存储技术方面取得了卓越成就,还在其他多个领域进行了广泛的技术创新和产品多元化。例如,三星在移动处理器(如Exynos系列)和图像传感器(如ISOCELL系列)方面也取得了显著进展。这些产品不仅提升了三星自身产品的竞争力,还为全球电子行业的发展注入了新的活力。

5. 全球化布局与战略合作

三星半导体在全球范围内进行了广泛的布局,建立了多个研发中心和生产基地。这些基地不仅负责本地市场的产品研发和生产,还积极参与全球供应链的建设和合作。同时,三星还积极寻求与其他企业的战略合作,共同推动半导体技术的发展和应用。例如,三星与联发科技在移动平台上的合作,以及与红帽在CXL存储生态系统上的合作,都体现了三星在全球化布局和战略合作方面的远见卓识。

这些故事共同展示了三星半导体在电子行业中的发展历程和成就,也体现了其在技术创新、可持续发展和全球化布局方面的努力与贡献。

Aces Electronics Co Ltd公司的发展小趣事

随着技术的不断进步和产品的日益成熟,Aces开始将目光投向国际市场。公司积极参与国际电子展会和技术交流,与多家国际知名企业建立了合作关系。通过引进国外先进的技术和管理经验,Aces不断提升自身竞争力,逐渐在国际市场上占据了一席之地。同时,公司还积极拓展海外市场,将产品销往全球多个国家和地区。

明波通信(BWAVE)公司的发展小趣事

随着国内市场的日益饱和,明波通信开始将目光投向全球市场。公司先后在日本东京和江苏常州设立了子公司,通过技术合作和市场拓展,进一步巩固了公司在全球通信领域的地位。同时,明波通信也积极参与国际技术交流和合作,不断提升自身的技术水平和创新能力。这一系列的国际化战略举措,为明波通信的未来发展奠定了坚实的基础。

以上五个故事都是基于明波通信在电子行业中的发展历程和公开资料进行的概括性描述。虽然无法涵盖所有细节和具体事件,但希望能够展现出明波通信在创业、技术创新、市场拓展和国际化等方面的努力和成就。

Ferranti Electric Inc公司的发展小趣事

为了更好地满足全球客户的需求,Ferranti Electric Inc公司积极实施全球化战略。公司不仅在英国本土拥有生产基地和研发中心,还在全球范围内设立了多个分支机构和办事处。通过全球化布局,公司能够更好地了解不同市场的需求和特点,为客户提供更加定制化的产品和服务。同时,公司也积极参与国际竞争和合作,提升其在全球电气行业的影响力。

AUK Contractors Co Ltd公司的发展小趣事

AUK Contractors Co Ltd深知人才是企业发展的核心。因此,公司一直注重人才培养和团队建设。通过定期的培训、交流以及激励机制,公司吸引并留住了一批批优秀的电子工程师和技术人才。这些人才为公司的发展提供了源源不断的动力。

智浦欣(Chipstar)公司的发展小趣事

随着公司规模的不断扩大和业务的快速发展,智浦欣公司意识到,必须加强内部管理和人才培养才能确保公司的持续健康发展。于是,公司引进了一套先进的管理体系和人才培养计划。在管理体系方面,公司建立了完善的组织架构和业务流程,提高了工作效率和协同能力;在人才培养方面,公司注重员工的个人发展和职业规划,提供了多样化的培训和学习机会,激发了员工的工作热情和创新能力。

问答坊 | AI 解惑

介绍一种新型“数字温湿度传感器”

这是采用双线串行数字接口的温湿度传感器,与单片机接口非常方便,时序也很简单。 测量的温度/湿度精度很高。我们使用以后觉得很好用,所以,介绍给大家。 特点如下: 相对湿度和温度测量 _ 兼有露点 _ 全标定输出,无需标定即可互换使用 ...…

查看全部问答>

关于IO0PIN指令的疑惑

关于IO0PIN指令的疑惑 最近在调一个键盘程序(LPC2103),用到了IO0PIN读端口指令(据说这是飞利浦系列的BUG),发现这个指令没有手册上说的那么简单呐,直接读是读不出来的。有人说要读一个输入状态的端口,要先把它设为输出,然后置高,最后再设 ...…

查看全部问答>

为什么我的按键中断在程序启动的时候总自动进入

为什么我的按键中断在程序启动的时候总自动进入,不是按下按键以后,而是程序一运行的时候就自动进入中断函数,请问这是什么原因呢?…

查看全部问答>

?哪里有Wince5.0 Pocket PC SDK

微软下载中心验证我的操作系统不是正版下不下来,请哪为高手帮忙?急需非常感谢!!!!…

查看全部问答>

SIM卡费用问题

我以前没接触过GMS,现在正在开发一个项目,需要用到GSM短信。我手头有个GSM模块的资料,但里面没有有关SIM卡剩余话费。请问各位大侠都是怎么解决的?我希望如果话费余额不足能在软件中提前显示出来。…

查看全部问答>

各位手上有什么比较好用的bootloader吗?要求可以将nk.bin文件下载到内存中运行。

有的话给我发推荐一份啊,如果有时间的话麻烦给我发一份。 我的邮箱cy757#21cn.com(#改为@)…

查看全部问答>

用verilog HDL 实现网络加密算法md5

用verilog HDL 实现一个网络加密的算法(md5),有没有哪位高手能给点帮助,我邮箱是poppy220@126.com 先谢过啦!^_^ …

查看全部问答>

STM8S有相应的低电压版本的吗?

有个项目用了STM8S105,电池供电(3节镍氢),系统中带DC-DC给功放供电,当DC-DC启动时或输出功率较大时,经常引起MCU复位。 STM8S有没有相应的低电压版本(即管脚,软件都一样,只是工作电压不同的)?…

查看全部问答>

一个很莫名其妙的问题

最近刚刚开始接触STM32,今天调试串口的时候发现一个很无奈的问题,源代码基本都是使用keil自带的demo,就不列举了。修改以下这些设置:/* PLLCLK = 12MHz * 6= 72 MHz */     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6 ...…

查看全部问答>

想了想,还是把它出掉好了,STM32+W5100+SPI Flash+TFT,有点给力

这其实不是个开发板,而是个接近完成的产品(接近完成是指研发流程已经走完,但还未能进入市场)但资源比较给力--------------->    STM32ZET6,带外部总线于是可以用总线挂TFT--------------->    W5100,硬件TCP/IP协议 ...…

查看全部问答>