STM32軟體IIC的實現
接上篇,LIS331的例程終於可以正常運行了,接下來就是將其移植到STM32上了,不過第一次接觸STM32的IIC,看例程比較簡單,直接複製到工程後卻讀不出資料,一直停在等待從裝置回覆ACK的死迴圈。
經過一天的修改之後,終於還是捨去了硬體IIC改成了用軟體實現,最終程式碼如下:
.h檔案
#include "stm32f10x.h" #define ANO_GPIO_I2C GPIOB #define I2C_Pin_SCL GPIO_Pin_3 #define I2C_Pin_SDA GPIO_Pin_4 #define ANO_RCC_I2C RCC_APB2Periph_GPIOB /*********************************************/ #define SCL_H ANO_GPIO_I2C->BSRR = I2C_Pin_SCL #define SCL_L ANO_GPIO_I2C->BRR = I2C_Pin_SCL #define SDA_H ANO_GPIO_I2C->BSRR = I2C_Pin_SDA #define SDA_L ANO_GPIO_I2C->BRR = I2C_Pin_SDA #define SCL_read ANO_GPIO_I2C->IDR & I2C_Pin_SCL #define SDA_read ANO_GPIO_I2C->IDR & I2C_Pin_SDA #define EEPROM_DEV_ADDR 0x3a //??(????) #define EEPROM_WR 0x00 //? #define EEPROM_RD 0x01 //? #define EEPROM_WORD_ADDR_SIZE 8 extern u8 databuff[3]; extern u8 x,y,z; int I2C_Start(void); void I2C_Stop(void); void I2C_Ack(void); void I2C_NoAck(void); void I2C_SDA_OUT(void); void I2C_SDA_IN(void); uint8_t I2C_GetAck(void); void I2C_SendByte(uint8_t Data); uint8_t I2C_ReadByte(uint8_t ack); void I2C_delay(void); int EEPROM_ReadByte(uint16_t Addr, uint8_t *Data); int EEPROM_WriteByte(uint16_t Addr, uint8_t Data); void I2C_Initializes(void); u8 Sanzhou_Start(void); u8 Who_Am_I(void); int Read_XYZ(void); #endif
.c檔案
#include "tb_delay.h" #include "i2c.h" void I2C_delay(void) { u8 t = 2; while(t--); return; } int I2C_Start(void) { I2C_SDA_OUT(); SDA_H; SCL_H; I2C_delay(); if(!SDA_read) { return DISABLE; } SDA_L; I2C_delay(); if(SDA_read) { return DISABLE; } SCL_L; return ENABLE; } void I2C_Stop(void) { I2C_SDA_OUT(); SCL_L; SDA_L; SCL_H; I2C_delay(); SDA_H; I2C_delay(); } static void I2C_Ack() { SCL_L; I2C_SDA_OUT(); SDA_L; I2C_delay(); SCL_H; I2C_delay(); SCL_L; } static void I2C_NoAck() { SCL_L; I2C_SDA_OUT(); I2C_delay(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); SCL_L; } uint8_t I2C_GetAck(void) { uint8_t time = 0; I2C_SDA_IN(); SDA_H; I2C_delay(); SCL_H; I2C_delay(); while(SDA_read) { time++; if(time > 250) { SCL_L; return DISABLE; } } SCL_L; return ENABLE; } void I2C_SendByte(uint8_t Data) { uint8_t cnt; I2C_SDA_OUT(); for(cnt=0; cnt<8; cnt++) { SCL_L; I2C_delay(); if(Data & 0x80) { SDA_H; } else { SDA_L; } Data <<= 1; SCL_H; I2C_delay(); } SCL_L; I2C_delay(); } uint8_t I2C_ReadByte(uint8_t ack) { uint8_t cnt; uint16_t data; I2C_SDA_IN(); for(cnt=0; cnt<8; cnt++) { SCL_L; I2C_delay(); SCL_H; data <<= 1; if(SDA_read) { data |= 0x01; } I2C_delay(); } if(ack == 1) { I2C_NoAck(); } else { I2C_Ack(); } return data; } void I2C_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = I2C_Pin_SCL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(ANO_GPIO_I2C,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = I2C_Pin_SDA; GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure); } void I2C_SDA_IN() { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = I2C_Pin_SDA; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure); } void I2C_SDA_OUT() { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = I2C_Pin_SDA; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure); } void I2C_Initializes(void) { I2C_GPIO_Configuration(); SCL_H; SDA_H; } int EEPROM_WriteByte(uint16_t Addr, uint8_t Data) { I2C_Start(); I2C_SendByte(EEPROM_DEV_ADDR | EEPROM_WR); if(!I2C_GetAck()) { I2C_Stop(); return DISABLE; } #if (8 == EEPROM_WORD_ADDR_SIZE) I2C_SendByte((uint8_t)(Addr&0x00FF)); #else I2C_SendByte((uint8_t)(Addr>>8)); I2C_SendByte((uint8_t)(Addr&0x00FF)); #endif I2C_GetAck(); I2C_SendByte(Data); I2C_Stop(); return 1; } int EEPROM_ReadByte(uint16_t Addr, uint8_t *Data) { I2C_Start(); I2C_SendByte(EEPROM_DEV_ADDR | EEPROM_WR); if(!I2C_GetAck()) { I2C_Stop(); return DISABLE; } #if (8 == EEPROM_WORD_ADDR_SIZE) I2C_SendByte((uint8_t)(Addr&0x00FF)); #else I2C_SendByte((uint8_t)(Addr>>8)); I2C_SendByte((uint8_t)(Addr&0x00FF)); #endif I2C_Start(); I2C_SendByte(EEPROM_DEV_ADDR | EEPROM_RD); if(!I2C_GetAck()) { I2C_Stop(); return DISABLE; } *Data = I2C_ReadByte(0); I2C_Stop(); return 1; } u8 Who_Am_I(void) { u8 who; EEPROM_ReadByte(0x20, &who); return who; } u8 Sanzhou_Start() { u8 id; id = Who_Am_I(); if(id) { EEPROM_WriteByte(0x20, 0xE7); return ENABLE; } else return DISABLE; } int Read_XYZ(void) { EEPROM_ReadByte(0x29, &x); databuff[0] = x; EEPROM_ReadByte(0x2b, &y); databuff[1] = y; EEPROM_ReadByte(0x2d, &z); databuff[2] = z; return ENABLE; }
另外;
原始碼本是IF,可能是寫錯了否則進不了迴圈,我改成了while。在通訊過程中可能因兩裝置接受與傳送頻率的不同,造成從裝置在接受到資料時會發送應答,而主裝置檢測應答訊號時,總線上並沒有將測到訊號。該段程式碼的目的正是延長一段時間等待從裝置的回覆。
iic裝置都有一個裝置型別碼,儲存在相應暫存器中。編寫程式時可讀取該暫存器檢測程式正確與否。
相關推薦
STM32軟體IIC的實現
接上篇,LIS331的例程終於可以正常運行了,接下來就是將其移植到STM32上了,不過第一次接觸STM32的IIC,看例程比較簡單,直接複製到工程後卻讀不出資料,一直停在等待從裝置回覆ACK的死迴圈。 經過一天的修改之後,終於還是捨去了硬體IIC改成了用軟體實現,最終程
STM32軟體模擬IIC
IIC匯流排 一、與IIC有關的知識 (1)IIC屬於半雙工通訊方式 (2)IIC的協議 1.空閒狀態:IIC的SCL和SDA兩條線均處於高電平狀態,此時即釋放匯流排 2.起始訊號(Start):
STM32 IO模擬實現軟體串列埠
最近專案中STM32的串列埠資源緊張,於是使用IO口進行模擬串列埠,現進行整理記錄。 1. 實現思路 IO口模擬串列埠的思路也比較簡單,一切按照串列埠協議進行操作即可。 對於傳送,計算好不同波特率對應的延時時間進行資料傳送。 對於接收,稍微複雜。通過外部中斷檢測
stm32之IIC通信協議
art code strong typedef col 上傳 bps eight 系統結構 1 //3?ê??ˉIIC 2 void IIC_Init(void) 3 { 4 GPIO_InitTy
STM32+IAP方案 實現網絡升級應用固件
註釋 tail 啟動 href net stm32 sdn tar log 源:STM32+IAP方案 實現網絡升級應用固件 IAR + STM32固件庫 啟動文件startup_stm32f10x_hd.s功用及註釋STM32+IAP方案 實現網絡升級應用固件
oa管理軟體如何實現全面的協同辦公管理?
隨著科技的不斷髮展,市場上oa管理軟體廠商越來越多,要想在眾多oa管理軟體廠商中脫穎而出,必須要有其“過人之處”。新一代oa管理軟體,加強企業業務監管、推動企業提升執行力,助領導做出快速、準確的決策等。那麼oa管理軟體如何實現全面的協同辦公管理? 1.全面的功能和流程oa管理軟體具有多種功能模組,如目標
智點進銷存軟體如何實現不同操作員管理不同客戶
在使用智點進銷存軟體過程中,經常會遇到不同操作員需要管理不同的客戶資訊,操作員自己只能管理自己的客戶,不能看到其他操作員的客戶資訊,當然其他操作員也看不到自己的的客戶資訊,這樣要怎麼操作才能實現呢? 很簡單,只要建立不同的營銷區域,然後不同操作員繫結不同的營銷區域即可。具體操作如下: 1.首先建立營銷區域
不用無限路由器 不用任何軟體輕鬆實現 發射無線訊號的功能
單擊開始按鈕,輸入“cmd”並按下回車。依次輸入以下兩個命令(其中網路連線名和金鑰自行設定) 命令1:netsh wlan set hostednetwork mode=allow ssid=網路連線名 key=金鑰(至少八位) 命令2:netsh wlan start hostednet
Scrapy爬蟲 -- 編寫下載中介軟體,實現隨機User-Agent
Scrapy爬蟲 -- 編寫下載中介軟體,實現隨機User-Agent 實現步驟: 1. 在middlewares.p中,新建一個下載中介軟體; 2. 建立process_request方法(引擎傳送request物件到下載器時的回撥函式),實現隨機User-Agent的功能; 3.
Django - 使用自定義中介軟體,實現登陸驗證
目錄 一、中介軟體 mymiddelware.py 檔案 二、檢視檔案 三、前端提交資料 一、中介軟體 mymiddelware.py 檔案 from django.utils.deprecation import MiddlewareMixin
知識管理,oa辦公軟體如何實現?
在資訊時代裡,知識已成為最主要的財富來源,組織和個人的最重要的任務就是對知識進行管理。知識管理將使組織和個人具有更強的競爭實力,並做出更好地決策。 那麼,oa辦公軟體能不能做到?又是如何實現的呢? 1、oa辦公軟體可以幫助企業快速積累知識 oa辦公軟體可以幫助
MySQL中介軟體proxysql實現讀寫分離
環境說明: IP 角色 應用 平臺 192.168.161.96 讀寫分離解析主機 proxysql rhel7.4 19
stm32軟體觸發的按鍵長按與短按區分
/* ------------------------------------------------------------------------------------------------ * @fn KeyCoolPressTimeHandle
使用淘寶中介軟體cobar實現mysql分庫分表
cobar 編譯安裝配置筆記 https://github.com/alibaba/cobar windows下使用eclipse匯入cobar專案,eclipse File -> Import -> Git https://github.com/alibab
STM32使用systick實現精確延時
SYSTICK暫存器初始化 void SysTick_Configuration(void) { if (SysTick_Config(SystemCoreClock / 100)) { while (1); } NVIC_SetPriority(
Windows系統下安裝深度學習Caffe軟體及實現MATLAB呼叫的詳細步
下載Caffe,並解壓出原始碼資料夾caffe-master,轉到該資料夾下的windows資料夾下,將CommonSettings.props.example檔案複製到該目錄下並重命名為CommonSettings.props。用文字方式或者VS 2013單獨開啟,修改如下
雲合同電子合同合作矩陣軟體,實現遠端稱重智慧電子簽約
近日,雲合同(yunhetong.com)與“稱重物聯網第一股”公司——山東矩陣軟體工程股份有限公司(以下簡稱“矩陣軟體”)達成戰略合作,為矩陣軟體生態鏈提供專業的第三方電子合同服務。 隨著電商行業的客單量越來越大,物流業物品稱重、分揀的效率受到很大阻礙,因每個物品的
CRC的校驗原理及硬體、軟體演算法實現
轉自:http://blog.163.com/yucheng_xiao/blog/static/76600192201393092918776/ 一、基本原理 CRC檢驗原理實際上就是在一個p位二進位制資料序列之後附加一個r位二進位制檢驗碼(序列),從而構成一個總長為n=p+r位的二進位制序
stm32 web伺服器實現
最近在做stm32 web伺服器的東西,忙了一段時間終於弄完了,把這幾天關於stm32伺服器的工作記錄一下。 剛接到這個任務的時候,不知道怎麼下手,網上資料似乎不是很多,於是在下載了一個官方demo測試了一下,看了一下程式碼,不是很懂,於是繼續百度找資料,找到一個比較有
中國象棋軟體-引擎實現(六)局面評估
前面已經講過了棋局表示、著法生成、搜尋演算法(包括搜尋輔助), 在象棋程式中如果說搜尋演算法是心臟,那麼局面評估就是大腦。搜尋演算法負責驅動整個程式,而局面評估則負責對搜尋的內容進行判斷評價。因而搜尋與局面評估是整個程式的核心。 首先,先介紹一下在局面評估中需要考慮的因素。就不同的棋類可能要考慮的因素略有差