久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> STM32 >> 瀏覽文章

stm32與AT24C02的I2C通信總結(模擬時序)

作者:明入如di   來源:明入如di的博客   點擊數:  更新時間:2014年05月18日   【字體:

從51的時候就學習了I2C通信協(xié)議,但51的功能就那些,內部沒有集成I2C模塊,所以只能通過模擬I2C通信的時序來和EEPROM進行通信,stm32內部集成了I2C通信的片上外設,但由于內部I2C外設復雜和不穩(wěn)定行,所以用的人不是很多,而基本上使用I2C的通信都是通過模擬時序的方式來實現的


首先I2C是同步半雙工的通信方式,需要兩條線即可,SCL時鐘線,同步時鐘由主機產生,SDA數據線用來發(fā)送接收數據,任何時候只能一臺主機發(fā)送數據。
在編程的時候碰到了很多問題,其中一項就是等待從機的應答程序
開始的時候編寫如下
void iic_wait_ack()   錯誤                                                   void iic_wait_ack()          正確的程序            
{                                                                                  {
 SCL=1;                                                                        iic_sda_in();
iic_sda_in();                                                                 SCL=1;
delay_us(2);                                                                delay_us(2);
SDA=1;                                                                       SDA=1;
while(SDAIN);                                                            while(SDAIN);
SCL=0;                                                                       SCL=0;
}                                                                                   }
程序運行的時候總是死在紅色部分的程序,后來用debug單步調試,慢慢的發(fā)現了規(guī)律,以下為個人觀點,不敢保證一定正確:
                    1.SDAIN只會在SCL為低電平的時候拉低
                    2.且在SCL保持高電平的時候,SDAIN比保持低電平
                    3.在SCL變?yōu)楦唠娖街,SDAIN才會拉高
 
上圖為I2C通信的時序圖
 
其中起始信號:在SCL為高電平時,SDA電平由高變低,且高電平SDA高電平持續(xù)時間要大于4.7us,在SCL由高電平變低時,SDA的低電平持續(xù)時間要大于4us
 
終止信號:在SCL為高電平期間,SDA電平由低變高,且高電平持續(xù)時間大于4.7us,低電平持續(xù)時間大于4us
 
起始信號和終止信號無論何時都是由主設備產生的
 
數據幀:在SCL為高電平期間,SDA的電平保持穩(wěn)定
 
主向從寫數據

期間地址為八位:其中高四位為固定位,bit3—bit1為可變位,最低位為操作位 為0時為寫操作,為1時是讀操作
地址發(fā)送完成之后,等待從器件的應答信號,切記此時要將SDA配置為上拉輸入模式

應答信號即為,SCL保持高電平時 SDA一直為低電平。
然后再發(fā)送要寫入數據的地址,收到應答再寫入數據,最后是停止信號
 
首先先配置IO口,PB10為SCL,PB.11為SDA
 
#include
void gpio_init()
{
 RCC->APB2ENR|=1<<2;
 GPIOA->CRH&=0xfffff00f;
 GPIOA->CRH|=0x000008b0;
 GPIOA->ODR|=3<<9;
 
 RCC->APB2ENR|=1<<3;
 GPIOB->CRH&=0xfffff0ff;
 GPIOB->CRH|=0x00000300;
 GPIOB->ODR|=1<<10;
}
 
void iic_sda_out()//此時為主器件發(fā)送數據
{
 RCC->APB2ENR|=1<<3;
 GPIOB->CRH&=0xffff0fff;
 GPIOB->CRH|=0x00003000;
 GPIOB->ODR|=1<<11;
}
 
void iic_sda_in()//此時為主器件接收數據或等待從器件發(fā)送應答信號
{
 RCC->APB2ENR|=1<<3;
 GPIOB->CRH&=0xffff0fff;
 GPIOB->CRH|=0x00008000;
 GPIOB->ODR|=1<<11;
}
 
然后是為頭文件iic.h,如下
#define iic_write 0xa0
#define iic_read 0xa1
void iic_start(void);//起始信號
void iic_end(void);//終止信號
void iic_senddata(u8 data);//主器件發(fā)送一個字節(jié)數據
void iic_master_ack(void);//主機應答信號
void iic_master_nack(void);//主機非應答信號
void iic_wait_ack(void);//等待從機應答信號
void iic_master_write(u8 type,u8 address,u8 data);
u8 iic_master_read(u8 address);
u8 iic_readdata(void);
 
iic.c文件如下
#include
#include"gpio.h"
#include"delay.h"
#include"iic.h"
#include"sys.h"
void iic_start()
{
 iic_sda_out();
 SDA=0;
 SCL=1;
 SDA=1;
 delay_us(5);
 SDA=0;
 delay_us(5);
}
 
void iic_end(void)
{
 iic_sda_out();
 SCL=0;
 SDA=0;
 delay_us(2);
 SCL=1;
 delay_us(5);
 SDA=1;
 delay_us(5);
 SDA=0;
}
 
void iic_senddata(u8 data)
{
 int i;
 iic_sda_out();
 for(i=7;i>=0;i--)
    {
     SCL=0;
SDA=(data>>i);
SCL=1;
delay_us(5);
SCL=0;
}
}
 
 
void iic_master_ack()
{
 iic_sda_out();
 SCL=0;
 SDA=0;
 SCL=1;
 delay_us(5);
 SCL=0;
 SDA=1;
}
 
void iic_master_nack()
{
 iic_sda_out();
 SCL=0;
 SDA=1;
 SCL=1;
 delay_us(5);
 SCL=0;
}
 
void iic_wait_ack()
{
 iic_sda_in();
 SDA=1;
 delay_us(1);
 SCL=1;
 delay_us(1);
 while(SDAIN);
 SCL=0;
 
}
 
void iic_master_write(u8 type,u8 address,u8 data)
{
 iic_start();
 iic_senddata(type);
 iic_wait_ack();
 iic_senddata(address);
 iic_wait_ack();
 iic_senddata(data);
 iic_wait_ack();
 iic_end();
 delay_ms(10);
}
 
u8 iic_master_read(u8 address)
{
 u8 dcb;
 iic_start();
 iic_senddata(0xa0);
 iic_wait_ack();
 iic_senddata(address);
 iic_wait_ack();
 iic_start();
 iic_senddata(0xa1);
 iic_wait_ack();
 dcb=iic_readdata();
 iic_master_nack();
 iic_end();
 return dcb;
}
 
u8 iic_readdata()
{
  int k;
  u8 receive;
  iic_sda_in();
   for(k=7;k>=0;k--)
   {
    SCL=0;
delay_us(2);
SCL=1;
receive<<=1;
if(SDAIN==1)
receive|=1<<0;
else
receive&=~(1<<0);
   }
   return receive;
}
 
主程序
 
#include
#include"delay.h"
#include"usart1.h"
#include"sys.h"
#include"gpio.h"
#include"iic.h"
int main()
{
 u8 temp;
 Stm32_Clock_Init(9);
 delay_init(72);
 gpio_init();
 usart1_init();
 iic_master_write(iic_write,0x00,0xdf);
 temp=iic_master_read(0x00);
 USART1->DR=temp;
 while(1);
}
關閉窗口

相關文章

主站蜘蛛池模板: 日韩在线免费视频 | 久久久久国产视频 | 久久婷婷av | 欧美黄色网 | 天天插日日操 | 午夜小视频在线播放 | 综合国产 | 欧美日韩综合视频 | 在线视频一区二区三区 | 欧美激情精品久久久久久变态 | 欧美xxxⅹ性欧美大片 | 91精品国产乱码久久久久久久 | 欧美激情欧美激情在线五月 | 国产精品精品久久久 | 国内精品一区二区 | 日韩免费一区二区 | 99热这里都是精品 | 中文字幕日韩一区 | 国产福利在线 | 黄色一级大片在线免费看产 | 国产成人精品久久二区二区91 | 亚洲成人网在线播放 | 久草网站 | 亚洲另类自拍 | 日韩有码一区 | 在线观看成人小视频 | 免费观看一级特黄欧美大片 | 久久久久久91香蕉国产 | 欧美精品久久久久久 | 亚洲自拍偷拍免费视频 | 亚洲成年影院 | 日本黄视频在线观看 | 亚洲欧美综合 | 日韩一区中文字幕 | 热99视频| 一级做a爰片性色毛片 | 久久精品国产亚洲 | 日韩天堂av | 免费国产一区二区 | 超碰欧美 | 婷婷免费视频 |