欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

    標題: I2C實驗 [打印本頁]

    作者: dori    時間: 2020-12-8 15:08
    標題: I2C實驗
    新建工程,在Hardware目錄下添加myiic.c24cxx.c其中myiic.c文件存放iic驅動代碼,24cxx.c文件存放24C02驅動代碼
    編輯myiic.c文件:
    #include "myiic.h"
    #include "delay.h"
    //初始化IIC
    void IIC_Init(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PB時鐘使能
    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 輸出高
    }
    //產生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總線,準備發送或接收數據
    }
    //產生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;//發送I2C總線結束信號
    delay_us(4);
    }
    //等待應答信號到來
    //返回值:1,接收應答失敗
    //        0,接收應答成功
    u8 IIC_Wait_Ack(void)
    {
    u8 ucErrTime=0;
    SDA_IN();      //SDA設置為輸入
    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;//時鐘輸出0
    return 0;  
    }
    //產生ACK應答
    void IIC_Ack(void)
    {
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=0;
    delay_us(2);
    IIC_SCL=1;
    delay_us(2);
    IIC_SCL=0;
    }
    //不產生ACK應答
    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發送一個字節
    //返回從機有無應答
    //1,有應答
    //0,無應答
    void IIC_Send_Byte(u8 txd)
    {  
    u8 t;   
    SDA_OUT();
    IIC_SCL=0;//拉低時鐘開始數據傳輸
    for(t=0;t<8;t++)
    {  
    IIC_SDA=(txd&0x80)>>7;
    txd<<=1;
    delay_us(2);   //TEA5767這三個延時都是必須的
    IIC_SCL=1;
    delay_us(2);
    IIC_SCL=0;
    delay_us(2);
    }
    }
    //1個字節,ack=1時,發送ACKack=0,發送nACK   
    u8 IIC_Read_Byte(unsigned char ack)
    {
    unsigned char i,receive=0;
    SDA_IN();//SDA設置為輸入
    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();//發送nACK
    else
    IIC_Ack(); //發送ACK   
    return receive;
    }
    該部分為IIC驅動代碼,實現包括IIC的初始化(IO口)、IIC開始、IIC結束、ACKIIC讀寫等功能,在其他函數里面,只需要調用相關的IIC函數就可以和外部IIC器件通信了,這里并不局限于24C02,該段代碼可以用在任何IIC設備上。
    接下來編輯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指定地址讀出一個數據
    //ReadAddr:開始讀數的地址
    //返回值:讀到的數據
    u8 AT24CXX_ReadOneByte(u16 ReadAddr)
    {
    u8 temp=0;
    IIC_Start();  
    if(EE_TYPE>AT24C16)
    {
    IIC_Send_Byte(0XA0);//發送寫命令
    IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr>>8);//發送高地址
    }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //發送器件地址0XA0,寫數據
    IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr%256);  //發送低地址
    IIC_Wait_Ack();
    IIC_Start();  
    IIC_Send_Byte(0XA1);           //進入接收模式
    IIC_Wait_Ack();
    temp=IIC_Read_Byte(0);
    IIC_Stop();//產生一個停止條件
    return temp;
    }
    //AT24CXX指定地址寫入一個數據
    //WriteAddr  :寫入數據的目的地址
    //DataToWrite:要寫入的數據
    void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
    {
    IIC_Start();  
    if(EE_TYPE>AT24C16)
    {
    IIC_Send_Byte(0XA0);//發送寫命令
    IIC_Wait_Ack();
    IIC_Send_Byte(WriteAddr>>8);//發送高地址
    }else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));  //發送器件地址0XA0,寫數據
    IIC_Wait_Ack();
    IIC_Send_Byte(WriteAddr%256);  //發送低地址
    IIC_Wait_Ack();
    IIC_Send_Byte(DataToWrite);     //發送字節
    IIC_Wait_Ack();  
    IIC_Stop();//產生一個停止條件
    delay_ms(10);
    }
    //AT24CXX里面的指定地址開始寫入長度為Len的數據
    //該函數用于寫入16bit或者32bit的數據.
    //WriteAddr  :開始寫入的地址
    //DataToWrite:數據數組首地址
    //Len        :要寫入數據的長度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的數據
    //該函數用于讀出16bit或者32bit的數據.
    //ReadAddr   :開始讀出的地址
    //返回值:數據
    //Len        :要讀出數據的長度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的最后一個地址(255)來存儲標志字.
    //如果用其他24C系列,這個地址要修改
    //返回1:檢測失敗
    //返回0:檢測成功
    u8 AT24CXX_Check(void)
    {
    u8 temp;
    temp=AT24CXX_ReadOneByte(255);//避免每次開機都寫AT24CXX
    if(temp==0X55)return 0;
    else//排除第一次初始化的情況
    {
    AT24CXX_WriteOneByte(255,0X55);
    temp=AT24CXX_ReadOneByte(255);
    if(temp==0X55)return 0;
    }
    return 1;
    }
    //AT24CXX里面的指定地址開始讀出指定個數的數據
    //ReadAddr :開始讀出的地址對24c020~255
    //pBuffer  :數據數組首地址
    //NumToRead:要讀出數據的個數
    void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
    {
    while(NumToRead)
    {
    *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
    NumToRead--;
    }
    }  
    //AT24CXX里面的指定地址開始寫入指定個數的數據
    //WriteAddr :開始寫入的地址對24c020~255
    //pBuffer   :數據數組首地址
    //NumToWrite:要寫入數據的個數
    void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
    {
    while(NumToWrite--)
    {
    AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
    WriteAddr++;
    pBuffer++;
    }
    }
    這部分代碼實際就是通過IIC接口來操作24Cxx芯片,理論上是可以支持24Cxx所有系列的芯片的(地址引腳必須都設置為0),但是本實驗只測試了24C02,其他器件有待測試。
    編輯main.c函數:
    //要寫入到24c02的字符串數組
    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();//延時函數初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷優先級分組為組2
    uart_init(115200);//串口初始化為115200
    LED_Init();//初始化與LED連接的硬件接口
    LCD_Init();//初始化LCD
    KEY_Init();//按鍵初始化
    AT24CXX_Init();//IIC初始化
    POINT_COLOR=RED;//設置字體為紅色
    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;//設置字體為藍色
    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;//提示系統正在運行
    i=0;
    }
    }
    }
    該段代碼通過KEY1按鍵來控制24C02的寫入,通過另外一個按鍵KEY0來控制24C02的讀取。并在LCD模塊上面顯示相關信息。





    歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1