日本高清不卡中文字幕-一起草草视频在线观看-亚洲精品一区二区三区色-国产亚洲精品免费视频

你好!歡迎來到深圳市穎特新科技有限公司!
語言
當前位置:首頁 >> 技術(shù)中心 >> 單片機入門 >> 高手經(jīng)驗!STM32單片機學(xué)習(xí)I2C通信

高手經(jīng)驗!STM32單片機學(xué)習(xí)I2C通信

關(guān)鍵字:STM32 單片機 I2C通信 寄存器 作者:admin 來源:不詳 發(fā)布時間:2018-05-18  瀏覽:40

I2C總線是由NXP(原PHILIPS)公司設(shè)計,有十分簡潔的物理層定義,其特性如下:

·  只要求兩條總線線路:一條串行數(shù)據(jù)線SDA,一條串行時鐘線SCL;

·  每個連接到總線的器件都可以通過唯一的地址和一直存在的簡單的主機/從機關(guān)系軟件設(shè)定地址,主機可以作為主機發(fā)送器或主機接收器;

·  它是一個真正的多主機總線,如果兩個或更多主機同時初始化,數(shù)據(jù)傳輸可以通過沖突檢測和仲裁防止數(shù)據(jù)被破壞;

·  串行的8 位雙向數(shù)據(jù)傳輸位速率在標準模式下可達100kbit/s,快速模式下可達400kbit/s,高速模式下可達3.4Mbit/s;

·  連接到相同總線的IC 數(shù)量只受到總線的最大電容400pF 限制。

其典型的接口連線如下:

I2C的協(xié)議很簡單:

數(shù)據(jù)的有效性

在傳輸數(shù)據(jù)的時候,SDA線必須在時鐘的高電平周期保持穩(wěn)定,SDA的高或低電平狀態(tài)只有在SCL 線的時鐘信號是低電平時才能改變 。

起始和停止條件

SCL 線是高電平時,SDA 線從高電平向低電平切換,這個情況表示起始條件;

SCL 線是高電平時,SDA 線由低電平向高電平切換,這個情況表示停止條件。

字節(jié)格式

發(fā)送到SDA 線上的每個字節(jié)必須為8 位,每次傳輸可以發(fā)送的字節(jié)數(shù)量不受限制。每個字節(jié)后必須處理一個響應(yīng)位。

應(yīng)答響應(yīng)

數(shù)據(jù)傳輸必須帶響應(yīng),相關(guān)的響應(yīng)時鐘脈沖由主機產(chǎn)生。在響應(yīng)的時鐘脈沖期間發(fā)送器釋放SDA 線(高)。

在響應(yīng)的時鐘脈沖期間,接收器必須將SDA 線拉低,使它在這個時鐘脈沖的高電平期間保持穩(wěn)定的低電平。

也就是說主器件發(fā)送完一字節(jié)數(shù)據(jù)后要接收一個應(yīng)答位(低電平),從器件接收完一個字節(jié)后要發(fā)送一個低電平。

尋址方式(7位地址方式)

第一個字節(jié)的頭7 位組成了從機地址,最低位(LSB)是第8 位,它決定了傳輸?shù)?普通的和帶重復(fù)開始條件的7位地址格式方向。第一個字節(jié)的最低位是

“0”,表示主機會寫信息到被選中的從機;

“1”表示主機會向從機讀信息。

當發(fā)送了一個地址后,系統(tǒng)中的每個器件都在起始條件后將頭7 位與它自己的地址比較,如果一樣,器件會判定它被主機尋址,至于是從機接收器還是從機發(fā)送器,都由R/W 位決定。

仲裁

I2C是所主機總線,每個設(shè)備都可以成為主機,但任一時刻只能有一個主機。

STM32至少有一個I2C接口,提供多主機功能,可以實現(xiàn)所有I2C總線的時序、協(xié)議、仲裁和定時功能,支持標準和快速傳輸兩種模式,同時與SMBus 2.0兼容。

本實驗直接操作寄存器實現(xiàn)對I2C總線結(jié)構(gòu)的EEPROM AT24c02的寫入和讀取。AT24c02相關(guān)操作詳見 單片機讀取EEPROM(AT24C02)。

庫函數(shù)實現(xiàn)使用STM32的兩個I2C模擬I2C設(shè)備間的數(shù)據(jù)收發(fā),并通過串口查看數(shù)據(jù)交換情況。

直接操作寄存器

首先需要配置I2C接口的時鐘,相關(guān)寄存器如下:

I2C_CR2寄存器低五位:

FREQ[5:0]:I2C模塊時鐘頻率 ,必須設(shè)置正確的輸入時鐘頻率以產(chǎn)生正確的時序,允許的范圍在2~36MHz之間:

000000:禁用 000001:禁用 000010:2MHz ... 100100:36MHz 大于100100:禁用。

用于設(shè)置I2C設(shè)備的輸入時鐘,本例使用的是PLCK1總線上的時鐘所以為36Mhz;

時鐘控制寄存器(I2C_CCR)低12位:

CCR[11:0]:快速/標準模式下的時鐘控制分頻系數(shù)(主模式),該分頻系數(shù)用于設(shè)置主模式下的SCL時鐘。

在I2C標準模式或SMBus模式下:

Thigh = CCR ×TPCLK1

Tlow = CCR ×TPCLK1

時鐘周期為 T = Thigh + Tlow;

例如:在標準模式下,F(xiàn)REQR = 36 即36Mhz,產(chǎn)生200kHz的SCL的頻率

時鐘控制分頻系數(shù) = Freqr /2/f f 為想得到的頻率

配置好時鐘,還需要配置本機地址,I2C支持7位地址和10位地址,這里用的是7位地址:

自身地址寄存器1(I2C_OAR1)[7:1]:接口地址,地址的7~1位。

其他相關(guān)操作參見代碼,有詳細注釋:(system.h 和 stm32f10x_it.h 等相關(guān)代碼參照 STM32 直接操作寄存器開發(fā)環(huán)境配置)

User/main.c

01#include <stm32f10x_lib.h>    
02#include "system.h"
03#include "usart.h" 
04#include "i2c.h"
05  
06#define LED1 PAout(4)
07#define LED2 PAout(5)
08#define LED3 PAout(6)
09#define LED4 PAout(7)
10  
11void Gpio_Init(void);
12  
13int main(void)
14{             
15  
16    Rcc_Init(9);                          //系統(tǒng)時鐘設(shè)置
17  
18    Usart1_Init(72,9600);
19  
20    Nvic_Init(1,0,I2C1_EV_IRQChannel,4);      //設(shè)置搶占優(yōu)先級為1,響應(yīng)優(yōu)先級為0,中斷分組為4
21  
22    Nvic_Init(0,0,I2C1_ER_IRQChannel,4);      //設(shè)置I2C錯誤中斷搶占優(yōu)先級為0
23  
24    Gpio_Init();
25  
26    I2c_Init(0x30);                           //設(shè)置I2C1地址為0x30                    
27  
28    I2c_Start();
29  
30    while(1);       
31}
32  
33  
34void Gpio_Init(void)
35{
36    RCC->APB2ENR |= 1<<2;          //使能PORTA時鐘     
37    RCC->APB2ENR |= 1<<3;          //使能PORTB時鐘;    
38  
39  
40    GPIOA->CRL &= 0x0000FFFF;        // PA0~3設(shè)置為浮空輸入,PA4~7設(shè)置為推挽輸出
41    GPIOA->CRL |= 0x33334444; 
42  
43  
44    GPIOB->CRL &= 0x00FFFFFF;        //PB6 I2C1_SCL ,PB7  I2C1_SDL
45    GPIOB->CRL |= 0xFF000000;        //復(fù)用開漏輸出
46      
47    //USART1 串口I/O設(shè)置
48  
49    GPIOA -> CRH &= 0xFFFFF00F;      //設(shè)置USART1 的Tx(PA.9)為第二功能推挽,50MHz;Rx(PA.10)為浮空輸入
50    GPIOA -> CRH |= 0x000008B0;    
51  
52}

User/stm32f10x_it.c

001#include "stm32f10x_it.h"
002#include "system.h"
003#include "stdio.h"
004#include "i2c.h"
005  
006#define LED1 PAout(4)
007#define LED2 PAout(5)
008#define LED3 PAout(6)
009#define LED4 PAout(7)
010  
011#define  ADDRS_R  0xA1    //讀操作地址
012#define  ADDRS_W  0xA0    //寫操作地址
013  
014u8  go = 0;               //操作步驟標記
015  
016void I2C1_EV_IRQHandler(void)     //I2C1 Event Interrupt 
017{
018    u16 clear = 0;
019  
020    if(I2C1 -> SR1 & 1<<0 )          //已發(fā)送起始條件,寫數(shù)據(jù)寄存器的操作將清除該位
021    {
022        printf("\r\n I2C1 Start .. \r\n");
023  
024        switch(go)
025        {
026            case 0:{ 
027                I2c_Write(ADDRS_W);        //寫入從機地址,寫指令操作地址
028                break;
029            }
030            case 1:{
031                I2c_Write(ADDRS_W);        //寫入從機地址,寫指令操作地址
032                break;
033            }
034            case 2:{
035                I2c_Write(ADDRS_R);        //寫入從機地址,讀數(shù)據(jù)操作地址
036                break;
037           }
038        }
039  
040    }
041  
042    if(I2C1 -> SR1 & 1<<1 )        //從機地址已發(fā)送
043    {
044        printf("\r\n I2C1 has send address .. \r\n");
045        clear = I2C1 -> SR2; //讀取SR2可以清除該位中斷
046  
047        switch(go)
048        {
049            case 0:{ 
050                I2c_Write(0x01);    //寫入待寫入的EEPROM單元地址
051                break;
052            }
053  
054            case 1:{
055                I2c_Write(0x01);    //寫入待寫入的EEPROM單元地址
056                break;
057            }
058            case 2:{
059                delay(100000);
060                printf("\r\n Read 0x%X from At24c02 ,Address 0x01 ..  \r\n",I2c_Read());
061                I2c_Stop();
062                break;
063           }
064        }
065  
066    }
067  
068    if(I2C1 -> SR1 & 1<<2 )        //字節(jié)發(fā)送結(jié)束  發(fā)送地址字節(jié)時,不觸發(fā)此中斷
069    {
070          
071        //printf("\r\n I2C1 send byte success .. \r\n");
072        switch(go)
073        {
074            case 0:{ 
075                I2c_Write(0x86);            //寫入數(shù)據(jù)
076                printf("\r\n Write 0x%X to At24c02 ,Address 0x01 ..  \r\n",0x86);           
077                //I2c_Stop();
078      
079                delay(10000);
080                go = 1;
081                I2c_Start(); 
082                break;
083            }
084  
085            case 1:{
086  
087                delay(10000);
088                go = 2;
089                I2c_Start();
090                break;
091            }
092            case 2:{
093  
094                break;
095           }
096        }
097  
098    }
099  
100    delay(100000);
101    LED3 = 1;
102  
103    //I2C1 -> CR2 &= ~(1<<9);          //事件中斷關(guān)閉
104}
105  
106void I2C1_ER_IRQHandler(void)       //I2C1 Error Interrupt 
107{
108    delay(100000);
109    LED4 = 1;   
110  
111    if(I2C1->SR1 & 1<<10)          //應(yīng)答失敗
112    {
113        printf("\r\n ACK ERROR .. \r\n");
114  
115        I2C1->SR1 &=~(1<<10);      //清除中斷
116    }
117  
118    if(I2C1->SR1 & 1<<14)          //超時
119    {
120        printf("\r\n Timeout .. \r\n");
121  
122        I2C1->SR1 &=~(1<<14);      //清除中斷
123    }
124  
125    if(I2C1->SR1 & 1<<11)          //過載/欠載
126    {
127        printf("\r\n Overrun/Underrun .. \r\n");
128        I2C1->SR1 &=~(1<<11);      //清除中斷
129    }
130  
131    if(I2C1->SR1 & 1<<9)           //仲裁丟失
132    {
133        printf("\r\n Arbitration lost .. \r\n");
134        I2C1->SR1 &=~(1<<9);       //清除中斷
135    }
136  
137    if(I2C1->SR1 & 1<<8)           //總線出錯
138    {
139        printf("\r\n Bus error .. \r\n");
140        I2C1->SR1 &=~(1<<8);       //清除中斷
141    }
142  
143  
144}

Library/src/i2c.c

view sourceprint?

01#include "i2c.h" 
02  
03void I2c_Init(u16 Addr )
04{
05  
06    RCC -> APB1ENR |= 1<<21;           //打開I2C1時鐘
07    //RCC -> APB1ENR |= 1<<22;         //打開I2C2時鐘
08  
09    RCC->APB1RSTR  |= 1<<21;           //復(fù)位I2C1
10    RCC->APB1RSTR  &= ~(1<<21);            //復(fù)位結(jié)束I2C1
11    //RCC->APB1RSTR  |= 1<<22;         //復(fù)位I2C2
12  
13    //I2C1 -> CR1 |=  1<<15;               //復(fù)位寄存器
14  
15    //I2C模塊時鐘頻率,2~36MHz之間
16    I2C1 -> CR2 |=   36 ;                //000000:禁用 000001:禁用 000010:2MHz ... 100100:36MHz
17  
18  
19    I2C1 -> CCR |= 0<<15;              //I2C主模式  0:標準模式的I2C    1:快速模式的I2C
20    //I2C1 -> CCR |= 1<<14;                //快速模式時的占空比 0 Tlow/Thigh = 2    1   Tlow/Thigh = 16/9
21  
22    //得到200kHz頻率
23    I2C1 -> CCR |= 90<<0;              //時鐘控制分頻系數(shù)  = PCLK1 /2/f    f 為想得到的頻率
24  
25    //主模式最大上升時間
26    I2C1 -> TRISE |= 37;             //最大允許SCL上升時間為1000ns,故TRISE[5:0]中必須寫入(1us/(1/36)us = 36+1)。
27  
28    I2C1 -> CR1 |=  1<<10;             //打開ACK應(yīng)答,在接收到一個字節(jié)后返回一個應(yīng)答
29    I2C1 -> CR1 |= 1<<6;               //廣播呼叫使能
30  
31    I2C1 -> OAR1 |= 0<<15;             //尋址模式   1 響應(yīng)10位地址  0  響應(yīng)7位地址   
32  
33    I2C1 -> OAR1 |= 1<<14;             //必須始終由軟件保持為 1
34  
35    I2C1 -> OAR1 |=  Addr <<1 ;            //設(shè)置接口地址的 7~1位
36  
37    //I2C1 -> OAR1 |=  0 ;           //設(shè)置10位地址模式時地址第0位 
38    //I2C1 -> OAR1 |= 0<<8;                //設(shè)置10位地址模式時地址第9~8位
39  
40    //I2C1 -> CR2 |=  1<<10;               //緩沖器中斷使能
41    I2C1 -> CR2 |=  1<<9;              //事件中斷使能
42    I2C1 -> CR2 |=  1<<8;              //出錯中斷使能
43  
44    I2C1 -> CR1 |=   1<<0;             //開啟I2C1
45}
46  
47  
48void  I2c_Start()
49{
50  
51    I2C1 -> CR1 |=   1<<8;             //I2C1產(chǎn)生起始條件
52}
53  
54void  I2c_Stop()
55{
56    I2C1 -> CR1 |=   1<<9;             //I2C1產(chǎn)生停止條件
57}
58  
59  
60void  I2c_Write(u8 data)
61{
62    I2C1 -> DR = data;
63}
64  
65u8  I2c_Read()
66{
67    while(!(I2C1 -> SR1 & 1<<6));      //接收到數(shù)據(jù)標志位
68  
69    return I2C1 -> DR;
70}
71  
72void  I2c_End()                         //關(guān)閉I2C
73{
74    I2C1 -> CR1 &=   ~(1<<0);      
75}

Library/inc/i2c.h

1#include <stm32f10x_lib.h>
2  
3void I2c_Init(u16 Addr );   
4  
5void  I2c_Start(void);
6void  I2c_Stop(void);
7void  I2c_Write(u8 data);
8u8    I2c_Read(void);
9void  I2c_End(void);

串口接收數(shù)據(jù)如下:

I2C1 Start ..

I2C1 has send address ..

Write 0x86 to At24c02 ,Address 0x01 ..

I2C1 Start ..

I2C1 has send address ..

I2C1 Start ..

I2C1 has send address ..

Read 0x86 from At24c02 ,Address 0x01 ..

庫函數(shù)操作

main.c

001#include "stm32f10x.h"
002#include "stdio.h"
003  
004#define  PRINTF_ON  1
005  
006void RCC_Configuration(void);
007void GPIO_Configuration(void);
008void USART_Configuration(void);
009void I2C_Configuration(void);
010void NVIC_Configuration(void);
011  
012  
013u8 I2C1_ADDRESS = 0x30;   //7位 I2C 地址
014u8 I2C2_ADDRESS = 0x31;
015  
016#define Size 4
017  
018vu8 I2C1_Buffer_Tx[Size] = {1,2,3,4};
019vu8 I2C2_Buffer_Rx[Size] = {0};
020  
021u32 BufferSize = Size ;
022  
023int main(void)
024{
025    RCC_Configuration();
026    GPIO_Configuration();
027    USART_Configuration();
028    I2C_Configuration();
029    NVIC_Configuration();
030  
031    I2C_GenerateSTART(I2C1,ENABLE);
032  
033    while(1);   
034}
035  
036void I2C_Configuration(void)
037{
038    I2C_InitTypeDef I2C_InitStructure;
039  
040    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
041    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
042    I2C_InitStructure.I2C_OwnAddress1 = I2C1_ADDRESS;
043    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
044    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
045    I2C_InitStructure.I2C_ClockSpeed = 200000;
046    I2C_Init(I2C1,&I2C_InitStructure);
047  
048    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
049    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
050    I2C_InitStructure.I2C_OwnAddress1 = I2C2_ADDRESS;
051    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
052    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
053    I2C_InitStructure.I2C_ClockSpeed = 200000;
054    I2C_Init(I2C2,&I2C_InitStructure);
055  
056  
057    I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,ENABLE);
058    I2C_ITConfig(I2C2,I2C_IT_EVT|I2C_IT_BUF,ENABLE);
059      
060    I2C_Cmd(I2C1,ENABLE);
061    I2C_Cmd(I2C2,ENABLE);
062}
063  
064void NVIC_Configuration(void)
065{
066    NVIC_InitTypeDef NVIC_InitStructure;
067  
068    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
069  
070    NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
071    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
072    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
073    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
074    NVIC_Init(&NVIC_InitStructure);
075  
076    NVIC_InitStructure.NVIC_IRQChannel = I2C2_EV_IRQn;
077    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
078    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
079    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
080    NVIC_Init(&NVIC_InitStructure);
081}
082  
083void GPIO_Configuration(void)
084{
085    GPIO_InitTypeDef    GPIO_InitStructure;
086  
087    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
088  
089    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
090    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;         
091    GPIO_Init(GPIOB , &GPIO_InitStructure); 
092  
093    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;      
094    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
095    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; 
096    GPIO_Init(GPIOB , &GPIO_InitStructure); 
097  
098  
099    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
100    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
101    GPIO_Init(GPIOA , &GPIO_InitStructure); 
102      
103    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
104    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;           
105    GPIO_Init(GPIOA , &GPIO_InitStructure); 
106}
107  
108void RCC_Configuration(void)
109{
110    /* 定義枚舉類型變量 HSEStartUpStatus */
111    ErrorStatus HSEStartUpStatus;
112  
113    /* 復(fù)位系統(tǒng)時鐘設(shè)置*/
114    RCC_DeInit();
115    /* 開啟HSE*/
116    RCC_HSEConfig(RCC_HSE_ON);
117    /* 等待HSE起振并穩(wěn)定*/
118    HSEStartUpStatus = RCC_WaitForHSEStartUp();
119    /* 判斷HSE起是否振成功,是則進入if()內(nèi)部 */
120    if(HSEStartUpStatus == SUCCESS)
121    {
122        /* 選擇HCLK(AHB)時鐘源為SYSCLK 1分頻 */
123        RCC_HCLKConfig(RCC_SYSCLK_Div1); 
124        /* 選擇PCLK2時鐘源為 HCLK(AHB) 1分頻 */
125        RCC_PCLK2Config(RCC_HCLK_Div1); 
126        /* 選擇PCLK1時鐘源為 HCLK(AHB) 2分頻 */
127        RCC_PCLK1Config(RCC_HCLK_Div2);
128        /* 設(shè)置FLASH延時周期數(shù)為2 */
129        FLASH_SetLatency(FLASH_Latency_2);
130        /* 使能FLASH預(yù)取緩存 */
131        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
132        /* 選擇鎖相環(huán)(PLL)時鐘源為HSE 1分頻,倍頻數(shù)為9,則PLL輸出頻率為 8MHz * 9 = 72MHz */
133        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
134        /* 使能PLL */ 
135        RCC_PLLCmd(ENABLE);
136        /* 等待PLL輸出穩(wěn)定 */
137        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
138        /* 選擇SYSCLK時鐘源為PLL */
139        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
140        /* 等待PLL成為SYSCLK時鐘源 */
141        while(RCC_GetSYSCLKSource() != 0x08);
142    
143    /* 打開APB2總線上的GPIOA時鐘*/
144    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_USART1, ENABLE);
145  
146    //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
147  
148    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2,ENABLE);
149    //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG|RCC_APB1Periph_SPI2, ENABLE);
150          
151}
152  
153   
154void USART_Configuration(void)
155{
156    USART_InitTypeDef USART_InitStructure;
157    USART_ClockInitTypeDef USART_ClockInitStructure;
158  
159    USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
160    USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
161    USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                      
162    USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
163    USART_ClockInit(USART1 , &USART_ClockInitStructure);
164  
165    USART_InitStructure.USART_BaudRate = 9600;
166    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
167    USART_InitStructure.USART_StopBits = USART_StopBits_1;
168    USART_InitStructure.USART_Parity = USART_Parity_No;
169    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
170    USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
171    USART_Init(USART1,&USART_InitStructure);
172  
173    USART_Cmd(USART1,ENABLE);
174}
175  
176#if  PRINTF_ON
177  
178int fputc(int ch,FILE *f)
179{
180    USART_SendData(USART1,(u8) ch);
181    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
182    return ch;
183}
184  
185#endif

stm32f10x_it.c

view sourceprint?

01#include "stm32f10x_it.h"
02#include "stdio.h"
03  
04extern u32 BufferSize ;
05extern u8 I2C1_ADDRESS ;
06extern u8 I2C2_ADDRESS ;
07  
08extern vu8 I2C1_Buffer_Tx[];
09extern vu8 I2C2_Buffer_Rx[];
10vu32 Tx_Counter = 0;
11vu32 Rx_Counter = 0;
12  
13void I2C1_EV_IRQHandler(void)
14{
15    switch(I2C_GetLastEvent(I2C1))
16    {
17        case I2C_EVENT_MASTER_MODE_SELECT: //已發(fā)送啟始條件
18        {
19            I2C_Send7bitAddress(I2C1,I2C2_ADDRESS,I2C_Direction_Transmitter);   
20            break;
21        }
22        case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: //已發(fā)送從機地址
23        {
24            printf("\r\n The I2C1 has send data %d \r\n",I2C1_Buffer_Tx[Rx_Counter]);
25            I2C_SendData(I2C1,I2C1_Buffer_Tx[Tx_Counter++]);
26            break;
27        }
28        case I2C_EVENT_MASTER_BYTE_TRANSMITTED: //第一個數(shù)據(jù)已發(fā)送
29        {
30            if(Tx_Counter<BufferSize)
31            {
32                printf("\r\n The I2C1 has send data %d \r\n",I2C1_Buffer_Tx[Rx_Counter]);
33                I2C_SendData(I2C1,I2C1_Buffer_Tx[Tx_Counter++]);                
34  
35            }else{
36                I2C_GenerateSTOP(I2C1,ENABLE);
37                I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,DISABLE);  //計數(shù)發(fā)送的個數(shù)
38            }
39  
40            break;
41        }
42        default: {break;}
43    }
44}
45  
46  
47void I2C2_EV_IRQHandler(void)
48{
49    switch(I2C_GetLastEvent(I2C2))
50    {
51        case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: //收到匹配的地址數(shù)據(jù)
52        {
53            break;
54        }
55        case I2C_EVENT_SLAVE_BYTE_RECEIVED: //收到數(shù)據(jù)
56        {   
57            if(Rx_Counter < BufferSize )
58            {
59                I2C2_Buffer_Rx[Rx_Counter] = I2C_ReceiveData(I2C2);
60                printf("\r\n The I2C2 has received data %d \r\n",I2C2_Buffer_Rx[Rx_Counter++]); //計數(shù)收到的個數(shù)               
61            }
62            break;
63        }
64        case I2C_EVENT_SLAVE_STOP_DETECTED: //收到結(jié)束條件
65        {
66            I2C_ClearFlag(I2C2,I2C_FLAG_STOPF);
67            I2C_ITConfig(I2C1,I2C_IT_EVT|I2C_IT_BUF,DISABLE);
68  
69            break;
70        }
71        default: {break;}
72    }
73}

編輯:admin  最后修改時間:2018-05-18

聯(lián)系方式

0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08

Copyright © 2014-2023 穎特新科技有限公司 All Rights Reserved.  粵ICP備14043402號-4

永修县| 河间市| 东源县| 阜南县| 竹北市| 河西区| 和田市| 修文县| 屏边| 侯马市| 左云县| 庆阳市| 蒙山县| 富阳市| 疏勒县| 威海市| 佛学| 镇康县| 绥滨县| 龙里县| 沧州市| 聊城市| 兴文县| 淮安市| 青川县| 庆城县| 建昌县| 抚顺县| 新密市| 蓝山县| 郧西县| 安陆市| 公主岭市| 宜宾市| 万年县| 老河口市| 香格里拉县| 仙游县| 宁夏| 称多县| 南川市|