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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1127|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

STM32單片機(jī)模擬IIC通用驅(qū)動(dòng)程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
要用到IIC程序網(wǎng)上找了許多參考大多不完整,或不完善,不盡如意。參考他人程序?qū)懥艘环菽M程序,通用性強(qiáng),略做修改引腳即可移植到51單片機(jī)平臺,測試可使用多種芯片,功能完善可單個(gè)程序讀寫一個(gè)數(shù)據(jù),也可連續(xù)讀寫一組數(shù)據(jù),速度快,具有速度調(diào)節(jié)。可靠具有超時(shí)檢測,故障重啟功能。目前使用它驅(qū)動(dòng)4線OLED顯示和讀寫時(shí)鐘,達(dá)到設(shè)計(jì)目標(biāo),使用過程可以任意通斷一條線,線路恢復(fù),顯示和時(shí)鐘讀寫恢復(fù)正常。有需要高可靠性讀寫EEPRAM的可以,進(jìn)一步采用寫后復(fù)讀比對。   

單片機(jī)代碼
//=====================MRI2C.h===========================
#ifndef __MRI2C_H
#define __MRI2C_H
#include "stm32f10x.h"

#include "wei_bit.h" //位帶操作

#define W_SCL     PBout(8)   // 定義輸出SCL引腳
#define W_SDA     PBout(9)   //定義輸出SDA引腳
#define R_SDA     PBin(9)    //定義SDA輸入用于讀取狀態(tài)

// 如果要啟用高速 I2C,則定義 IIC_HS 注釋掉下面一行降速
#define IIC_HS

// 條件編譯的代碼
#ifdef IIC_HS    //電平改變后無延時(shí) 最高速度 約300Khz
    #define W_SCL_H   W_SCL=1
    #define W_SCL_L   W_SCL=0
          #define W_SDA_H   W_SDA=1
    #define W_SDA_L   W_SDA=0                        
#else    //電平改變后延時(shí)達(dá)到減低速度目的 約100Khz
          #define W_SCL_H   W_SCL=1 ; IIc_Delay(10)     //SCL拉高 并延時(shí)
    #define W_SCL_L   W_SCL=0 ; IIc_Delay(10)     //SCL拉低 并延時(shí)
          #define W_SDA_H   W_SDA=1 ; IIc_Delay(5)      //SDA拉高 加延時(shí)
    #define W_SDA_L   W_SDA=0        ; IIc_Delay(5)      //SDA拉低 并延時(shí)
#endif

#define PCF8575_ADDRESS                0x40                //IIC的I2C從機(jī)地址
#define PCF8574_ADDRESS                0x4E                //IIC的I2C從機(jī)地址
#define PCF2129_ADDRESS           0xA2   //pcf2129
#define PCF8563_ADDRESS           0xA2   //pcf8563
#define R8025_ADDRESS             0x64   //R8025

extern  uint8_t   IIC_EEr ;       //錯(cuò)誤標(biāo)志

extern void I2C1_Init(void);                // IIC初始化
extern void I2C1_Reset(void);               //I2C故障重啟

extern void I2C1_Read (uint8_t ADDRESS        , uint8_t addr,uint8_t *pData,uint8_t len);
extern void I2C1_Write(uint8_t ADDRESS        , uint8_t addr,uint8_t *pData,uint8_t len);

#endif
//====================MRI2C.c========================
//***************模擬IIC程序************************************
/*無延時(shí),最高速度,時(shí)鐘脈寬1.25us,間歇2.5us */
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "MRI2C.h"

#include "stm32f10x_i2c.h"


uint8_t   IIC_EEr = 0;          //錯(cuò)誤標(biāo)志。
uint16_t  EER_coner   = 0;     //錯(cuò)誤計(jì)數(shù)器

//*********************************************************
void IIc_Delay(uint16_t ys)
{ uint16_t ystm;
            ystm=ys;
                                while(ystm--){}                        
}

//產(chǎn)生IIC起始信號
void MyI2C_Start(void)
{
W_SDA_H;
W_SCL_H;
W_SDA_L;
W_SCL_L;
}
//產(chǎn)生IIC停止信號
void MyI2C_Stop(void)
{
W_SDA_L;
W_SCL_H;
W_SDA_H;
        
}
/**
  * 函    數(shù):I2C發(fā)送一個(gè)字節(jié)
  * 參    數(shù):Byte 要發(fā)送的一個(gè)字節(jié)數(shù)據(jù),范圍:0x00~0xFF
  * 返 回 值:無
  */
void MyI2C_SendByte(uint8_t Byte)
{
        uint8_t i;
        for (i = 0; i < 8; i ++)
        {
     W_SDA=(Byte&0x80)>>7;
     Byte<<=1;
                 W_SCL_H;
                 W_SCL_L;
        }
}
/**
  * 函    數(shù):I2C接收一個(gè)字節(jié)
  * 參    數(shù):無
  * 返 回 值:接收到的一個(gè)字節(jié)數(shù)據(jù),范圍:0x00~0xFF
  */
uint8_t MyI2C_ReceiveByte(void)
{
        uint8_t i, Byte = 0x00;
         W_SDA_H;
        for (i = 0; i < 8; i ++)
        {
                W_SCL_H;
        Byte<<=1;
        if(R_SDA)
                        Byte|= 0x01;   
                W_SCL_L;
    }        
        return Byte;
}
/**
  * 函    數(shù):I2C發(fā)送應(yīng)答位
  * 參    數(shù):Byte 要發(fā)送的應(yīng)答位,范圍:0~1,0表示應(yīng)答,1表示非應(yīng)答
  * 返 回 值:無
  */
void MyI2C_SendAck(uint8_t AckBit)
{
         W_SDA=AckBit;
         W_SCL_H;
         W_SCL_L;
}

//============================================================
//等待應(yīng)答信號到來
//返回值:0,接收應(yīng)答失敗 報(bào)錯(cuò)IIC_EEr
//        1,接收應(yīng)答成功
u8 IIC_Wait_Ack(void)
{
        u16 ucErrTime=0;         
          W_SDA_H;
         W_SCL_H;
        while(-R_SDA)
        {  
                  ucErrTime++;
                  if(ucErrTime>10000)
                                      {  
                                              IIC_EEr = 1;     //錯(cuò)誤標(biāo)志 重啟IIC
                                                          EER_coner++;   //錯(cuò)誤計(jì)數(shù)器用于調(diào)試
                                              MyI2C_Stop();
                                              return 0;
                                       }
         }
        W_SCL_L;           
        return 1;  
}
/**
  * 函    數(shù):I2C連續(xù)寫一組數(shù)據(jù)
  * 參    數(shù):ADDRESS 器件碼, addr 起始寄存地址,*pData 要寫的數(shù)組,len 寫入字?jǐn)?shù)
  * 返 回 值:無
  */
void I2C1_Write(uint8_t ADDRESS        , uint8_t addr,uint8_t *pData,uint8_t len)
{
        uint8_t i;
                MyI2C_Start();          //I2C起始
        MyI2C_SendByte(ADDRESS);  //發(fā)送從機(jī)地址,讀寫位為0,表示即將寫入
        if(IIC_Wait_Ack())                                //接受應(yīng)答出錯(cuò)跳過  
        MyI2C_SendByte(addr);     //發(fā)送寄存器地址
        if(IIC_Wait_Ack())                                //接受應(yīng)答出錯(cuò)跳過
        for(i=len;i>0;i--){        
                            MyI2C_SendByte(*pData);pData++;//發(fā)送要寫入寄存器的數(shù)據(jù)
                            IIC_Wait_Ack();                //接受應(yīng)答
                     }
        MyI2C_Stop();                                                //I2C終止
        }

        
/**
  * 函    數(shù):I2C連續(xù)讀一組數(shù)據(jù)
  * 參    數(shù):ADDRESS 器件碼, addr 起始寄存地址,*pData 保存數(shù)組位置,len 讀出字?jǐn)?shù)
  * 返 回 值:無
  */               
void I2C1_Read(uint8_t ADDRESS, uint8_t addr,uint8_t *pData,uint8_t len)
        {
//        uint8_t i;
        MyI2C_Start();                                                //I2C起始
        MyI2C_SendByte(ADDRESS);        //發(fā)送從機(jī)地址,讀寫位為0,表示即將寫入
        if(IIC_Wait_Ack())                                        //接受應(yīng)答出錯(cuò)退出
        MyI2C_SendByte(addr);                        //發(fā)送寄存器地址
        if(IIC_Wait_Ack())                                //接受應(yīng)答出錯(cuò)退出
                      {  MyI2C_Start();                                                        //I2C重復(fù)起始
                         MyI2C_SendByte(ADDRESS | 0x01);        //發(fā)送從機(jī)地址,讀寫位為1,表示即將讀取
                         }
        if(IIC_Wait_Ack()){                                        //接受應(yīng)答出錯(cuò)退出
          while (len)
        {
          *pData = MyI2C_ReceiveByte();                        //接收指定寄存器的數(shù)據(jù)
          if(len == 1)
                      MyI2C_SendAck(1);         //發(fā)送非應(yīng)答,終止從機(jī)的數(shù)據(jù)輸出
          else
                      MyI2C_SendAck(0);        //發(fā)送應(yīng)答, 繼續(xù)從機(jī)的數(shù)據(jù)輸出
          pData++;
          len--;
         }
                                         }
   MyI2C_Stop();                                                //I2C終止
}


// IIC初始化
void I2C1_Init(void) {
        /*開啟時(shí)鐘*/
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);        //開啟GPIOB的時(shí)鐘        
        /*GPIO初始化*/
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);                                        //將PB8和PB9引腳初始化為開漏輸出
        /*設(shè)置默認(rèn)電平*/
        GPIO_SetBits(GPIOB, GPIO_Pin_8 | GPIO_Pin_9);                        //設(shè)置PB8和PB9引腳初始化后默認(rèn)為高電平(釋放總線狀態(tài))        
}
//---------------------------------------------------------------------------------------


void I2C1_Reset(void)     //I2C故障重啟
{ uint8_t i;
    // 手動(dòng)操作SCL和SDA
            W_SDA_L;
    for (i = 0; i < 9; i++)
          {
     W_SCL_H;
                        Delay_us(1); // 延時(shí)
     W_SCL_L;
                        Delay_us(1); // 延時(shí)
    }           
      W_SDA_L; // l拉低SDA
                Delay_us(1); // 延時(shí)
                 W_SCL_H;
          Delay_us(1); // 延時(shí)   
      W_SDA_H;           // 釋放SDA   產(chǎn)生停止信號  必須 用于消除重啟后I2C->SR .BUSY 位
          Delay_us(1);// 延時(shí)
IIC_EEr = 0;      //清除錯(cuò)誤標(biāo)志
}


/*************************例子:main.c *********************************

uint8_t buffer[7]={0,0,0,0,0,0,0};

int main(void)
{   
    uint8_t  Data=0;

             // IIC初始化
    I2C1_Init();
       //I2C故障重啟 消除異常狀態(tài)
    I2C1_Reset();
    I2C1_Write(PCF8563_ADDRESS,0,buffer, 7);    // 將緩沖區(qū)數(shù)據(jù)寫入PCF8563寄存器 時(shí)鐘清零
       //OLED初始化
    OLED_Init();

  while
  {
    I2C1_Read(R8025_ADDRESS,0,buffer, 7);   //讀取時(shí)鐘

    I2C1_Write(0x78,0x40,&Data,1);    Data++;    // 寫一個(gè)數(shù)據(jù)  oled顯示屏驅(qū)動(dòng)測試
                        
                 if (IIC_EEr == 0)    //錯(cuò)誤標(biāo)志{
                                        { disp_p(dis);}     //IIC4線oled顯示驅(qū)動(dòng)程序
                       else {   
                              I2C1_Reset();     //I2C故障重啟                                             
                                                       OLED_Init();//OLED初始化
                                                       num_REST++;                        //錯(cuò)誤計(jì)數(shù)
                              }
        }
   }
}
************************************************************************/



以上3個(gè)文件下載: 3個(gè)文件.7z (3.4 KB, 下載次數(shù): 13)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美理论| 国产美女一区二区 | 日本三级网 | 97久久国产 | 网站一区二区三区 | 国产日韩欧美一区二区在线播放 | 99久久婷婷国产综合精品电影 | 国产成人综合亚洲欧美94在线 | 国产成人精品一区二区三区网站观看 | 日本色婷婷 | 日韩欧美亚洲综合 | 久草精品视频 | 成年人视频在线免费观看 | 亚洲精品亚洲人成人网 | 91精品一区 | 国产免费av网 | 欧美簧片 | 国产精品免费看 | 国产视频一区二区 | 久久精品国产一区二区 | 手机看片在线播放 | 成人精品一区二区 | 亚洲一区中文字幕 | 五月婷婷激情网 | 国产一区久久 | 免费黄色大片 | 999在线精品| 综合久久综合久久 | 日韩av电影院 | 日韩av成人在线 | 国产精品免费一区二区三区四区 | 国产精品久久久亚洲 | 久久这里只有精品首页 | 久久成人人人人精品欧 | 久久亚洲国产精品日日av夜夜 | 国产欧美久久精品 | 中文字幕av一区二区三区 | 国产1页 | 超碰人人爱 | 欧美精品网 | 精品国产一区二区三区性色av |