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" //////////////////////////////////////////////////////////////////////////////////