本示例提供STM8S103F核心板的IIC驅(qū)動文件源代碼,親測沒有任何問題,博主使用來驅(qū)動AT24C256和電子羅盤MMC5883MA,IIC通信速率100kHz,可以調(diào)整時序延時時間。
直接貼源碼:
IIC.h
#ifndef _IIC_H
#define _IIC_H
#include "iostm8s103F3.h"
#include "type_def.h"
#define IIC_SCL PC_ODR_ODR5 //設(shè)置SCL為GPIO--PC5
#define IIC_SDA PC_ODR_ODR6 //設(shè)置SDA為GPIO--PC6
#define READ_SDA PC_IDR_IDR6 //PC6引腳為輸入寄存器
#define SET_SCL_OUT() {PC_DDR_DDR5=1; PC_CR1_C15 = 1; PC_CR2_C25 = 0;}//設(shè)置SCL引腳為推挽輸出模式
#define SET_SDA_OUT() {PC_DDR_DDR6=1; PC_CR1_C16 = 1; PC_CR2_C26 = 0;}//設(shè)置SDA引腳為推挽輸出模式
#define SET_SDA_IN() {PC_DDR_DDR6=0; PC_CR1_C16 = 0; PC_CR2_C26 = 0;}//設(shè)置SDA引腳為輸入模式
//IIC所有操作函數(shù)
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //發(fā)送IIC開始信號
void IIC_Stop(void); //發(fā)送IIC停止信號
void IIC_Send_Byte(unsigned char txd); //IIC發(fā)送一個字節(jié)
uint8_t IIC_Read_Byte(unsigned char ack); //IIC讀取一個字節(jié)
uint8_t IIC_Wait_Ack(void); //IIC等待ACK信號
void IIC_Ack(void); //IIC發(fā)送ACK信號
void IIC_Nack(void); //IIC不發(fā)送ACK信號
#endif
IIC.c
#include "IIC.h"
#include "delay.h"
//初始化IIC
void IIC_Init(void)
{
SET_SCL_OUT();//設(shè)置SCL引腳為推挽輸出模式
SET_SDA_OUT();//設(shè)置SDA引腳為推挽輸出模式
IIC_SCL = 1;//IIC總線SDA與SCL同時置高,總線為空閑狀態(tài)
IIC_SDA = 1;
}
//產(chǎn)生IIC起始信號
void IIC_Start(void)
{
SET_SDA_OUT();//設(shè)置SDA引腳為推挽輸出模式
IIC_SDA = 1;//開始前IIC總線SDA與SCL同時置高,總線為空閑狀態(tài),做通信準備
IIC_SCL = 1;
delay_4us();
IIC_SDA = 0;//在SCL為高期間,SDA由高到低的跳變,啟動信號發(fā)出
delay_4us();
IIC_SCL = 0;//SCL拉低鉗住I2C總線,準備發(fā)送或接收數(shù)據(jù)
delay_2us();
}
//產(chǎn)生IIC停止信號
void IIC_Stop(void)
{
SET_SDA_OUT();//設(shè)置SDA引腳為推挽輸出模式
IIC_SCL = 0;//通信結(jié)束,SCL,SDA都為低。
IIC_SDA = 0;
delay_4us();
IIC_SCL = 1;//將SCL置高,當SCL為高期間,SDA由低到高的跳變
IIC_SDA = 1;//發(fā)送I2C總線結(jié)束信號
delay_4us();
}
//等待應(yīng)答信號到來
//返回值:1,接收應(yīng)答失敗
// 0,接收應(yīng)答成功
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime = 0;
IIC_SDA = 1;
delay_us();
IIC_SCL = 1;
delay_us();
SET_SDA_IN();//SDA設(shè)置為輸入
delay_us();
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//時鐘SCL輸出0
return 0;
}
//產(chǎn)生ACK應(yīng)答
void IIC_Ack(void)
{
IIC_SCL = 0;
SET_SDA_OUT();
IIC_SDA = 0;
delay_2us();
IIC_SCL = 1;
delay_2us();
IIC_SCL = 0;
}
//不產(chǎn)生ACK應(yīng)答
void IIC_Nack(void)
{
IIC_SCL = 0;
SET_SDA_OUT();
IIC_SDA = 1;
delay_2us();
IIC_SCL = 1;
delay_2us();
IIC_SCL = 0;
}
//IIC發(fā)送一個字節(jié)
//返回從機有無應(yīng)答
//1,有應(yīng)答
//0,無應(yīng)答
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SET_SDA_OUT(); //設(shè)置SDA引腳為推挽輸出模式
IIC_SCL = 0;//拉低時鐘SCL開始數(shù)據(jù)傳輸
for(t=0;t<8;t++)
{
if((txd & 0x80) >> 7)//發(fā)送最高位
{
IIC_SDA = 1;
}
else
{
IIC_SDA = 0;
}
txd <<= 1; //移位處理
delay_2us();//對特殊IC這三個延時都是必須的//6us,頻率166khz
IIC_SCL = 1;
delay_2us();
IIC_SCL = 0;
delay_2us();
}
}
//讀1個字節(jié),ack=1時,發(fā)送ACK,ack=0,發(fā)送nACK
uint8_t IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SET_SDA_IN();//SDA設(shè)置為輸入
for(i = 0;i < 8;i++ )
{
IIC_SCL = 0;
delay_2us();
IIC_SCL = 1;
receive<<=1;
if(READ_SDA)
{
receive++;
}
delay_us();
}
if (!ack)
{
IIC_Nack();//發(fā)送nACK
}
else
{
IIC_Ack(); //發(fā)送ACK
}
return receive;
}
上一篇:STM8硬件I2C配置
下一篇:STM8S_010_I2C讀寫EEPROM(硬件方式)
推薦閱讀
史海拾趣
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- TE 福利月|有獎?wù){(diào)查、技術(shù)干貨、限時折扣
- 挑戰(zhàn)“仙童”歷史知識 精美禮品等你拿!
- 獨樂樂不如眾樂樂——TI培訓(xùn)“薦課”功能上線公測,邀你提議,參與搶樓!
- 安富利有獎?wù){(diào)查問卷 150+份禮品等你拿
- Intel白皮書下載有獎
- 免費申請TI 樣片, 曬訂單贏好禮!
- 電路圖站2.0版上線,公開征集網(wǎng)友建議,填寫調(diào)查問卷贏積分!
- 有獎直播:Keysight World Tech Day 2024 汽車分論壇|汽車自動駕駛與新能源
- 下資料 看視頻 抽大獎!泰克汽車電子測試解決方案
- 是德科技有獎問答活動之二,小信號測試的示波器方案,答題闖關(guān)贏好禮!
- I2C寄存器方式,每條代碼都有注釋。并且配上庫操作作對比,希望給正在學(xué)習(xí)的人有幫助
- msp430 AD問題求助!
- 使用1G的Nandflash,如何把flash分為兩個盤。如 residentflah 及data Storage
- 拆一個電磁波輻射測試儀
- 為什么在電路中很多“與非”門要取非,而不是直接用與門或者或門?
- 基于2812實現(xiàn)rs485和rs232的串口通信源程序(轉(zhuǎn)載)
- 攝像頭有紅外補光信號,光電開關(guān)能用嗎?
- 寄存柜的柜門控制
- M4板子如何用串口升級程序?
- 求助:在用AD16畫原理圖,更新到pcb出現(xiàn)在錯誤,急求大神解決!!1