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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

I2C實(shí)驗(yàn)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:856808 發(fā)表于 2020-12-8 15:08 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
新建工程,在Hardware目錄下添加myiic.c24cxx.c其中myiic.c文件存放iic驅(qū)動(dòng)代碼,24cxx.c文件存放24C02驅(qū)動(dòng)代碼
編輯myiic.c文件:
#include "myiic.h"
#include "delay.h"
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PB時(shí)鐘使能
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);//初始化GPIO
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 輸出高
}
//產(chǎn)生IIC起始信號
void IIC_Start(void)
{
SDA_OUT();     //sda線輸出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}
//產(chǎn)生IIC停止信號
void IIC_Stop(void)
{
SDA_OUT();//sda線輸出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//發(fā)送I2C總線結(jié)束信號
delay_us(4);
}
//等待應(yīng)答信號到來
//返回值:1,接收應(yīng)答失敗
//        0,接收應(yīng)答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN();      //SDA設(shè)置為輸入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//時(shí)鐘輸出0
return 0;  
}
//產(chǎn)生ACK應(yīng)答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不產(chǎn)生ACK應(yīng)答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//IIC發(fā)送一個(gè)字節(jié)
//返回從機(jī)有無應(yīng)答
//1,有應(yīng)答
//0,無應(yīng)答
void IIC_Send_Byte(u8 txd)
{  
u8 t;   
SDA_OUT();
IIC_SCL=0;//拉低時(shí)鐘開始數(shù)據(jù)傳輸
for(t=0;t<8;t++)
{  
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2);   //TEA5767這三個(gè)延時(shí)都是必須的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//1個(gè)字節(jié),ack=1時(shí),發(fā)送ACKack=0,發(fā)送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA設(shè)置為輸入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;   
delay_us(1);
}
if (!ack)
IIC_NAck();//發(fā)送nACK
else
IIC_Ack(); //發(fā)送ACK   
return receive;
}
該部分為IIC驅(qū)動(dòng)代碼,實(shí)現(xiàn)包括IIC的初始化(IO口)、IIC開始、IIC結(jié)束、ACKIIC讀寫等功能,在其他函數(shù)里面,只需要調(diào)用相關(guān)的IIC函數(shù)就可以和外部IIC器件通信了,這里并不局限于24C02,該段代碼可以用在任何IIC設(shè)備上。
接下來編輯myiic.h文件:
#define SDA_IN()  {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=8<<12;}
#define SDA_OUT() {GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=3<<12;}
然后編輯24cxx.c文件:
#include "24cxx.h"
#include "delay.h"
//初始化IIC接口
void AT24CXX_Init(void)
{
IIC_Init();
}
//AT24CXX指定地址讀出一個(gè)數(shù)據(jù)
//ReadAddr:開始讀數(shù)的地址
//返回值:讀到的數(shù)據(jù)
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
IIC_Start();  
if(EE_TYPE>AT24C16)
{
IIC_Send_Byte(0XA0);//發(fā)送寫命令
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr>>8);//發(fā)送高地址
}else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //發(fā)送器件地址0XA0,寫數(shù)據(jù)
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256);  //發(fā)送低地址
IIC_Wait_Ack();
IIC_Start();  
IIC_Send_Byte(0XA1);           //進(jìn)入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//產(chǎn)生一個(gè)停止條件
return temp;
}
//AT24CXX指定地址寫入一個(gè)數(shù)據(jù)
//WriteAddr  :寫入數(shù)據(jù)的目的地址
//DataToWrite:要寫入的數(shù)據(jù)
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
IIC_Start();  
if(EE_TYPE>AT24C16)
{
IIC_Send_Byte(0XA0);//發(fā)送寫命令
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr>>8);//發(fā)送高地址
}else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));  //發(fā)送器件地址0XA0,寫數(shù)據(jù)
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr%256);  //發(fā)送低地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite);     //發(fā)送字節(jié)
IIC_Wait_Ack();  
IIC_Stop();//產(chǎn)生一個(gè)停止條件
delay_ms(10);
}
//AT24CXX里面的指定地址開始寫入長度為Len的數(shù)據(jù)
//該函數(shù)用于寫入16bit或者32bit的數(shù)據(jù).
//WriteAddr  :開始寫入的地址
//DataToWrite:數(shù)據(jù)數(shù)組首地址
//Len        :要寫入數(shù)據(jù)的長度2,4
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{  
u8 t;
for(t=0;t<Len;t++)
{
AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
}
}
//AT24CXX里面的指定地址開始讀出長度為Len的數(shù)據(jù)
//該函數(shù)用于讀出16bit或者32bit的數(shù)據(jù).
//ReadAddr   :開始讀出的地址
//返回值:數(shù)據(jù)
//Len        :要讀出數(shù)據(jù)的長度2,4
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{  
u8 t;
u32 temp=0;
for(t=0;t<Len;t++)
{
temp<<=8;
temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
}
return temp;
}
//檢查AT24CXX是否正常
//這里用了24XX的最后一個(gè)地址(255)來存儲標(biāo)志字.
//如果用其他24C系列,這個(gè)地址要修改
//返回1:檢測失敗
//返回0:檢測成功
u8 AT24CXX_Check(void)
{
u8 temp;
temp=AT24CXX_ReadOneByte(255);//避免每次開機(jī)都寫AT24CXX
if(temp==0X55)return 0;
else//排除第一次初始化的情況
{
AT24CXX_WriteOneByte(255,0X55);
temp=AT24CXX_ReadOneByte(255);
if(temp==0X55)return 0;
}
return 1;
}
//AT24CXX里面的指定地址開始讀出指定個(gè)數(shù)的數(shù)據(jù)
//ReadAddr :開始讀出的地址對24c020~255
//pBuffer  :數(shù)據(jù)數(shù)組首地址
//NumToRead:要讀出數(shù)據(jù)的個(gè)數(shù)
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
while(NumToRead)
{
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
NumToRead--;
}
}  
//AT24CXX里面的指定地址開始寫入指定個(gè)數(shù)的數(shù)據(jù)
//WriteAddr :開始寫入的地址對24c020~255
//pBuffer   :數(shù)據(jù)數(shù)組首地址
//NumToWrite:要寫入數(shù)據(jù)的個(gè)數(shù)
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
while(NumToWrite--)
{
AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
這部分代碼實(shí)際就是通過IIC接口來操作24Cxx芯片,理論上是可以支持24Cxx所有系列的芯片的(地址引腳必須都設(shè)置為0),但是本實(shí)驗(yàn)只測試了24C02,其他器件有待測試。
編輯main.c函數(shù):
//要寫入到24c02的字符串?dāng)?shù)組
const u8 TEXT_Buffer[]={"WarShipSTM32 IIC TEST"};
#define SIZE sizeof(TEXT_Buffer)
int main(void)
{
u8 key;
u16 i=0;
u8 datatemp[SIZE];
delay_init();//延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設(shè)置中斷優(yōu)先級分組為組2
uart_init(115200);//串口初始化為115200
LED_Init();//初始化與LED連接的硬件接口
LCD_Init();//初始化LCD
KEY_Init();//按鍵初始化
AT24CXX_Init();//IIC初始化
POINT_COLOR=RED;//設(shè)置字體為紅色
LCD_ShowString(30,50,200,16,16,"WarShip STM32");
LCD_ShowString(30,70,200,16,16,"IIC TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2015/1/15");
LCD_ShowString(30,130,200,16,16,"KEY1:Write  KEY0:Read");//顯示提示信息
while(AT24CXX_Check())//檢測不到24c02
{
LCD_ShowString(30,150,200,16,16,"24C02 Check Failed!");
delay_ms(500);
LCD_ShowString(30,150,200,16,16,"Please Check!      ");
delay_ms(500);
LED0=!LED0;//DS0閃爍
}
LCD_ShowString(30,150,200,16,16,"24C02 Ready!");   
POINT_COLOR=BLUE;//設(shè)置字體為藍(lán)色
while(1)
{
key=KEY_Scan(0);
if(key==KEY1_PRES)//KEY1按下,寫入24C02
{
LCD_Fill(0,170,239,319,WHITE);//清除半屏
LCD_ShowString(30,170,200,16,16,"Start Write 24C02....");
AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);
LCD_ShowString(30,170,200,16,16,"24C02 Write Finished!");//提示傳送完成
}
if(key==KEY0_PRES)//KEY1按下,讀取字符串并顯示
{
LCD_ShowString(30,170,200,16,16,"Start Read 24C02.... ");
AT24CXX_Read(0,datatemp,SIZE);
LCD_ShowString(30,170,200,16,16,"The Data Readed Is:  ");//提示傳送完成
LCD_ShowString(30,190,200,16,16,datatemp);//顯示讀到的字符串
}
i++;
delay_ms(10);
if(i==20)
{
LED0=!LED0;//提示系統(tǒng)正在運(yùn)行
i=0;
}
}
}
該段代碼通過KEY1按鍵來控制24C02的寫入,通過另外一個(gè)按鍵KEY0來控制24C02的讀取。并在LCD模塊上面顯示相關(guān)信息。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 综合久久色| 久久69精品久久久久久久电影好 | 成人黄色电影免费 | 精品国产一区二区三区性色av | 免费精品视频 | 91久久爽久久爽爽久久片 | 亚洲一区自拍 | 亚洲精品一区二区网址 | 成人久久久 | 精品伊人| 久草在线在线精品观看 | 日韩中文在线视频 | 亚洲成人精品免费 | 国产精品精品久久久 | 日韩av免费在线观看 | av黄色在线 | 成人免费精品视频 | 亚洲精品一区在线观看 | 成年人在线观看视频 | 在线观看特色大片免费网站 | 成人免费网站 | 日韩欧美精品在线 | 久久久久亚洲精品 | av一级毛片| 国产精品久久久久久影视 | 精品国产欧美日韩不卡在线观看 | 亚洲精品一区二区三区蜜桃久 | 日韩小视频| 亚洲欧美综合精品另类天天更新 | 日韩一区二区福利视频 | 中文字幕乱码一区二区三区 | 麻豆国产一区二区三区四区 | 日韩精品免费在线 | 请别相信他免费喜剧电影在线观看 | 亚洲精品乱码久久久久久黑人 | 欧美综合视频在线 | 在线播放中文字幕 | 一区二区三区在线电影 | www日本高清| 国产精品福利久久久 | 欧美精品一二三 |