1. 程式人生 > >STM32模擬I2C程式

STM32模擬I2C程式

修改自cleanflight

/*******************************************************************************
  測試平臺:STM32F103ZET6最小系統
*******************************************************************************/
static void i2cDelay()
{
    volatile int i = 7;
    while (i)
    i--;
}

// SCL高電平期間,SDA出現下降沿為起始訊號
static bool i2cStart() { SDA_OUT; SCL_H; SDA_H; i2cDelay(); if (!sdaRead) // 如果SDA為低電平,則匯流排忙,退出 return false; SDA_L; if (sdaRead) // 如果SDA為高電平,則匯流排忙,退出 return false; SDA_L; return true; } // SCL高電平期間,SDA出現上升沿為停止訊號 static void i2cStop(void) { SDA_OUT; SCL_L; SDA_L; i2cDelay(); // STOP:when CLK is high DATA from low to high
SCL_H; SDA_H; i2cDelay(); } static void i2cAck(void) { SDA_OUT; SCL_L; i2cDelay(); SDA_L; i2cDelay(); SCL_H; i2cDelay(); SCL_L; } static void i2cNoAck(void) { SDA_OUT; SCL_L; i2cDelay(); SDA_H; i2cDelay(); SCL_H; i2cDelay(); SCL_L; } // SCL高電平期間,SDA電平被從裝置拉低表示應答
static bool i2cWaitAck(void) { uint8_t errTimes = 0; SDA_IN; SDA_H; i2cDelay(); SCL_H; i2cDelay(); while (sdaRead) { if (errTimes++ > 20) { SCL_L; return false; } i2cDelay(); } SCL_L; return true; } // 傳送資料,資料從高位到低位傳輸 static void i2cSendByte(uint8_t byte) { uint8_t i = 8; SDA_OUT; while (i--) { SCL_L; // 時鐘訊號為低電平期間,允許資料線電平變化 i2cDelay(); if (byte & 0x80) SDA_H; else SDA_L; byte <<= 1; i2cDelay(); SCL_H; i2cDelay(); } SCL_L; } static uint8_t i2cReceiveByte() { uint8_t i = 8; uint8_t byte = 0; SDA_IN; SDA_H; while (i--) { byte <<= 1; SCL_H; i2cDelay(); if (sdaRead) { byte |= 0x01; } SCL_L; i2cDelay(); } SCL_L; return byte; } void i2cInit() { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOB clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* Configure GPIOB.6 & GPIOB.7 as open-drain output */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } /** * 通過I2C匯流排寫一位元組資料 * @param[in] dev:裝置I2C地址 * @param[in] reg:暫存器地址 * @param[in] data:要寫入的資料 */ bool i2cWriteOneByte(uint8_t dev, uint8_t reg, uint8_t data) { if (!i2cStart()) return false; i2cSendByte(dev << 1); // 從機地址由高7位+讀寫位構成 if (!i2cWaitAck()) { i2cStop(); return false; } i2cSendByte(reg); i2cWaitAck(); i2cSendByte(data); i2cWaitAck(); return true; } /** * * @param[in] dev:裝置I2C地址 * @param[in] reg:暫存器地址 * @param[in] len:位元組數 * @param[in] data:待寫入的資料 */ bool i2cWriteBytes(uint8_t dev, uint8_t reg, uint8_t len, uint8_t *data) { uint8_t i; if (!i2cStart()) return false; i2cSendByte(dev << 1); if (!i2cWaitAck()) { i2cStop(); return false; } i2cSendByte(dev); i2cWaitAck(); for (i = 0; i < len; i++) { i2cSendByte(data[i]); if (!i2cWaitAck()) { i2cStop(); return false; } } i2cStop(); return true; } /** * 從I2C裝置中讀取資料 * @param[in] dev:裝置I2C地址 * @param[in] reg:暫存器地址 * @param[in] len:資料位元組數 * @param[out] data:讀出的資料 */ bool i2cReadBytes(uint8_t dev, uint8_t reg, uint8_t len, uint8_t *data) { if (!i2cStart()) return false; i2cSendByte(dev << 1); if (!i2cWaitAck()) { i2cStop(); return false; } i2cSendByte(reg); i2cWaitAck(); i2cStart(); i2cSendByte((dev << 1) | 0x01); // 器件地址+讀命令 i2cWaitAck(); while (len) { *data = i2cReceiveByte(); if (len == 1) i2cNoAck(); // 最後一個位元組不應答 else i2cAck(); data++; len--; } i2cStop(); return true; }

相關推薦

STM32模擬I2C程式

修改自cleanflight /******************************************************************************* 測試平臺:STM32F103ZET6最小系統 *******

STM32 模擬I2C (STM32F051)

/** ****************************************************************************** * @file i2c simu.c * @brief simulation

微控制器GPIO軟體模擬I2C通訊程式

文章原始地址:http://feotech.com/?p=98 本程式主要用於使用可程式設計晶片自身的IO管腳,模擬I2C通訊的協議,實現I2C匯流排資料的傳輸. /** ****************************************************

STM32F1 模擬I2C驅動DAC(LTC2605)程式

由於在電路設計上將SCL、SDA線拉太長導致硬體I2C時常出問題,所以考慮用模擬I2C解決,這裡參考別人的程式碼然後自己應用到24位DAC(LTC2605)上,已移植成功。 (1).simulate_i2c.c #include "stm32f10x.h" #include "simulat

STM32 IO口模擬I2C+驅動MPU6050

之後運用MPU6050做了一個平衡小車,可以通過藍芽控制,下載連結: diy平衡小車 一、MPU6050 1. MPU6050介紹 MPU6050 是 InvenSense 公司推出的全球首款整合性 6 軸運動處理元件,相較於多元件 方案,免除

STM32硬體I2C除錯

除錯情況1 現象:主I2C傳送資料而沒有收到應答,則下一次不能正常傳送資料 背景:主I2C每次應該都能正常傳送資料 硬體:野火STM32-MINI,1主0從,SCL和SDA直接上拉 軟體:按鍵觸發中斷,主I2C傳送一次資料,中斷優先順序,按鍵最低,I2C最高,且主I2C中有TIMEOUT計時

STM32F103利用模擬I2C驅動ADS1115

ADS1115通過模擬I2C驅動:(部分程式碼借鑑了網路上的幾個,並且根據引腳進行了配置,都沒有執行成功,今天調了一天,終於在晚上調了出來) 注意:本部分程式碼需要只是ADS1115的部分程式(一些用到的陣列在此沒有寫),模擬II2C的各程式並未給出,大家根據需要進行裁剪,程式碼完全開源,希

stm32實現簡易程式線上更新的原理簡述

stm32要想更新程式,一般的做法就是用j-link或者串列埠下載。那可不可以實現不限通訊方式,實現線上更新呢? 為了實現線上更新的這個功能,我寫了一段簡易的類似BootLoader的程式。原理就是在應用程式執行之前新增一段程式碼,可以選擇一種通訊方式來接收新的應用編譯完成生成的bi

stm32-esp8266驅動程式

esp8266模組是串列埠通訊,通訊的協議是AT指令,要正確的配置對應的AT指令模組才可以工作,這裡就需要知道AT指令有沒有配置成功,這個比較容易實現,一般傳送AT指令配置成功的話,晶片都會返回至少一個OK,當然還有其它資料,我們只需要去解析有沒有接收到OK就知道指令傳送是否

GPIO模擬I2C通訊協議(一)

概要: 從本節開始,我將用3-5篇部落格的篇幅對我為期3個月的本科實習做總結。本節將首先介紹I2C協議的基本時序,然後給出用GPIO模擬實現I2C功能的C程式碼。最後介紹驅動開發的一些思路。 關鍵字

linux核心GPIO模擬I2C例項(轉)

前言: 在許多情況下,我們並沒有足夠的I2C匯流排,本文主在介紹如何利用Linux核心中的i2c-gpio模組,利用2條GPIO線模擬i2c匯流排,並掛載裝置。 思路: 先通過對i2c-gpio所定義的結構體初始化(包括初始化i2c的2條線,頻率

電話鍵盤及撥號的模擬 c程式

程式 #include “reg51.h” #include “intrins.h” #define uint unsigned int #define uchar unsigned char #define out P0 sbit LCD_RS=P2^0; s

開啟linux核心自帶的模擬i2c-gpio模組過程

首先我們要知道核心的makefile是根據配置檔案,也就是kconfig來決定是否編譯一個檔案的。 如果沒有配置核心編譯它,就不會生成.o檔案。 自然就不會開啟這個模組了。 如下是Kconfig 檔

簡單的模擬電話簿程式(java)

要求:  編寫一個模擬電話簿程式,實現對聯絡人的增刪查 提示:    HashMap儲存聯絡人,Key為聯絡人姓名,Value為其電話號碼    在console控制檯中模擬增刪查改   

關於freertos移植到stm32出錯,程式直接跳到HardFault_Handler的問題。

第一次移植freertos,使用野火的是stm32f429,在自己之前寫的程式上移植的。但是移植之後每次執行到vTaskStartScheduler的時候就會跳轉到HardFault。怎麼調都調不好。 我的解決辦法: 我把所有的NVIC中斷的NVIC_PriorityGroup_0改為

Jlink使用技巧之讀取STM32內部的程式

前言 上一篇Jlink系列文章介紹瞭如何使用J-Flash來下載Hex或Bin檔案到微控制器,具體可參考Jlink使用技巧之單獨下載HEX檔案到微控制器,本篇文章介紹,如何使用JFlash來讀取微控制器的程式,學習微控制器程式檔案的讀取,不是為了破解別人的程式,而是學習破解的原理,從而更好保護自己的程式不被

STM32 硬體I2C 到底是不是個坑?

/** ****************************************************************************** * @author    Maoxiao Hu * @version   V1.0.0 * @date       May-2015

STM8 模擬I2C驅動0.91寸OLED屏

#define OLED_SCLK_Clr() GPIO_ResetBits(I2C_PORT, I2C_SDA_PIN )//SDA IIC介面的時鐘訊號 #define OLED_SCLK_Set() GPIO_SetBits(I2C_PORT, I2C_SDA_PIN

i2c抽象/模擬i2c

1.寫在前面 i2c匯流排是由PHILIPS公司開發的一種簡單、雙向二線制同步序列匯流排。關於i2c的使用,並不陌生,C51、ARM、MSP430等,都基本整合硬體i2c,或者不整合i2c的,可以根據匯流排時序圖使用普通IO口翻轉模擬一根i2c匯流排。對於當下流行的stm3

正點原子stm32模擬IIC

#ifndef __MYIIC_H #define __MYIIC_H #include "sys.h" //////////////////////////////////////////////////////////////////////////////////