www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]I2C總線是由NXP(原PHILIPS)公司設(shè)計(jì),有十分簡(jiǎn)潔的物理層定義,其特性如下:· 只要求兩條總線線路:一條串行數(shù)據(jù)線SDA,一條串行時(shí)鐘線SCL;· 每個(gè)連接到總線的器件都可以通過(guò)唯一的地址和一直存在的簡(jiǎn)

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

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

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

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

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

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

其典型的接口連線如下:

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

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

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

起始和停止條件

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

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

字節(jié)格式

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

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

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

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

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

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

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

“0”,表示主機(jī)會(huì)寫信息到被選中的從機(jī);

“1”表示主機(jī)會(huì)向從機(jī)讀信息。

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

仲裁

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

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

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

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

直接操作寄存器

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

I2C_CR2寄存器低五位:

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

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

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

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

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

在I2C標(biāo)準(zhǔn)模式或SMBus模式下:

Thigh = CCR ×TPCLK1

Tlow = CCR ×TPCLK1

時(shí)鐘周期為 T = Thigh + Tlow;

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

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

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

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

其他相關(guān)操作參見(jiàn)代碼,有詳細(xì)注釋:(system.h 和 stm32f10x_it.h 等相關(guān)代碼參照 stm32 直接操作寄存器開(kāi)發(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   
11 void Gpio_Init(void);
12   
13 int main(void)
14 {             
15   
16     Rcc_Init(9);                          //系統(tǒng)時(shí)鐘設(shè)置
17   
18     Usart1_Init(72,9600);
19   
20     Nvic_Init(1,0,I2C1_EV_IRQChannel,4);      //設(shè)置搶占優(yōu)先級(jí)為1,響應(yīng)優(yōu)先級(jí)為0,中斷分組為4
21   
22     Nvic_Init(0,0,I2C1_ER_IRQChannel,4);      //設(shè)置I2C錯(cuò)誤中斷搶占優(yōu)先級(jí)為0
23   
24     Gpio_Init();
25   
26     I2c_Init(0x30);                           //設(shè)置I2C1地址為0x30                    
27   
28     I2c_Start();
29   
30     while(1);       
31 }
32   
33   
34 void Gpio_Init(void)
35 {
36     RCC->APB2ENR |= 1<<2;          //使能PORTA時(shí)鐘     
37     RCC->APB2ENR |= 1<<3;          //使能PORTB時(shí)鐘;    
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ù)用開(kāi)漏輸出
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   
014 u8  go = 0;               //操作步驟標(biāo)記
015   
016 void 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);        //寫入從機(jī)地址,寫指令操作地址
028                 break;
029             }
030             case 1:{
031                 I2c_Write(ADDRS_W);        //寫入從機(jī)地址,寫指令操作地址
032                 break;
033             }
034             case 2:{
035                 I2c_Write(ADDRS_R);        //寫入從機(jī)地址,讀數(shù)據(jù)操作地址
036                 break;
037            }
038         }
039   
040     }
041   
042     if(I2C1 -> SR1 & 1<<1 )        //從機(jī)地址已發(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é)時(shí),不觸發(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   
106 void 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)          //超時(shí)
119     {
120         printf("\r\n Timeout .. \r\n");
121   
122         I2C1->SR1 &=~(1<<14);      //清除中斷
123     }
124   
125     if(I2C1->SR1 & 1<<11)          //過(guò)載/欠載
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)           //總線出錯(cuò)
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   
03 void I2c_Init(u16 Addr )
04 {
05   
06     RCC -> APB1ENR |= 1<<21;           //打開(kāi)I2C1時(shí)鐘
07     //RCC -> APB1ENR |= 1<<22;         //打開(kāi)I2C2時(shí)鐘
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模塊時(shí)鐘頻率,2~36MHz之間
16     I2C1 -> CR2 |=   36 ;                //000000:禁用 000001:禁用 000010:2MHz ... 100100:36MHz
17   
18   
19     I2C1 -> CCR |= 0<<15;              //I2C主模式  0:標(biāo)準(zhǔn)模式的I2C    1:快速模式的I2C
20     //I2C1 -> CCR |= 1<<14;                //快速模式時(shí)的占空比 0 Tlow/Thigh = 2    1   Tlow/Thigh = 16/9
21   
22     //得到200kHz頻率
23     I2C1 -> CCR |= 90<<0;              //時(shí)鐘控制分頻系數(shù)  = PCLK1 /2/f    f 為想得到的頻率
24   
25     //主模式最大上升時(shí)間
26     I2C1 -> TRISE |= 37;             //最大允許SCL上升時(shí)間為1000ns,故TRISE[5:0]中必須寫入(1us/(1/36)us = 36+1)。
27   
28     I2C1 -> CR1 |=  1<<10;             //打開(kāi)ACK應(yīng)答,在接收到一個(gè)字節(jié)后返回一個(gè)應(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位地址模式時(shí)地址第0位 
38     //I2C1 -> OAR1 |= 0<<8;                //設(shè)置10位地址模式時(shí)地址第9~8位
39   
40     //I2C1 -> CR2 |=  1<<10;               //緩沖器中斷使能
41     I2C1 -> CR2 |=  1<<9;              //事件中斷使能
42     I2C1 -> CR2 |=  1<<8;              //出錯(cuò)中斷使能
43   
44     I2C1 -> CR1 |=   1<<0;             //開(kāi)啟I2C1
45 }
46   
47   
48 void  I2c_Start()
49 {
50   
51     I2C1 -> CR1 |=   1<<8;             //I2C1產(chǎn)生起始條件
52 }
53   
54 void  I2c_Stop()
55 {
56     I2C1 -> CR1 |=   1<<9;             //I2C1產(chǎn)生停止條件
57 }
58   
59   
60 void  I2c_Write(u8 data)
61 {
62     I2C1 -> DR = data;
63 }
64   
65 u8  I2c_Read()
66 {
67     while(!(I2C1 -> SR1 & 1<<6));      //接收到數(shù)據(jù)標(biāo)志位
68   
69     return I2C1 -> DR;
70 }
71   
72 void  I2c_End()                         //關(guān)閉I2C
73 {
74     I2C1 -> CR1 &=   ~(1<<0);      
75 }

Library/inc/i2c.h

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

庫(kù)函數(shù)操作

main.c

001 #include "stm32f10x.h"
002 #include "stdio.h"
003   
004 #define  PRINTF_ON  1
005   
006 void RCC_Configuration(void);
007 void GPIO_Configuration(void);
008 void USART_Configuration(void);
009 void I2C_Configuration(void);
010 void NVIC_Configuration(void);
011   
012   
013 u8 I2C1_ADDRESS = 0x30;   //7位 I2C 地址
014 u8 I2C2_ADDRESS = 0x31;
015   
016 #define Size 4
017   
018 vu8 I2C1_Buffer_Tx[Size] = {1,2,3,4};
019 vu8 I2C2_Buffer_Rx[Size] = {0};
020   
021 u32 BufferSize = Size ;
022   
023 int 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   
036 void 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   
064 void 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   
083 void 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   
108 void RCC_Configuration(void)
109 {
110     /* 定義枚舉類型變量 HSEStartUpStatus */
111     ErrorStatus HSEStartUpStatus;
112   
113     /* 復(fù)位系統(tǒng)時(shí)鐘設(shè)置*/
114     RCC_DeInit();
115     /* 開(kāi)啟HSE*/
116     RCC_HSEConfig(RCC_HSE_ON);
117     /* 等待HSE起振并穩(wěn)定*/
118     HSEStartUpStatus = RCC_WaitForHSEStartUp();
119     /* 判斷HSE起是否振成功,是則進(jìn)入if()內(nèi)部 */
120     if(HSEStartUpStatus == SUCCESS)
121     {
122         /* 選擇HCLK(AHB)時(shí)鐘源為SYSCLK 1分頻 */
123         RCC_HCLKConfig(RCC_SYSCLK_Div1); 
124         /* 選擇PCLK2時(shí)鐘源為 HCLK(AHB) 1分頻 */
125         RCC_PCLK2Config(RCC_HCLK_Div1); 
126         /* 選擇PCLK1時(shí)鐘源為 HCLK(AHB) 2分頻 */
127         RCC_PCLK1Config(RCC_HCLK_Div2);
128         /* 設(shè)置FLASH延時(shí)周期數(shù)為2 */
129         FLASH_SetLatency(FLASH_Latency_2);
130         /* 使能FLASH預(yù)取緩存 */
131         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
132         /* 選擇鎖相環(huán)(PLL)時(shí)鐘源為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時(shí)鐘源為PLL */
139         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
140         /* 等待PLL成為SYSCLK時(shí)鐘源 */
141         while(RCC_GetSYSCLKSource() != 0x08);
142     
143     /* 打開(kāi)APB2總線上的GPIOA時(shí)鐘*/
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    
154 void 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   
178 int 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   
04 extern u32 BufferSize ;
05 extern u8 I2C1_ADDRESS ;
06 extern u8 I2C2_ADDRESS ;
07   
08 extern vu8 I2C1_Buffer_Tx[];
09 extern vu8 I2C2_Buffer_Rx[];
10 vu32 Tx_Counter = 0;
11 vu32 Rx_Counter = 0;
12   
13 void 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ā)送從機(jī)地址
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: //第一個(gè)數(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);  //計(jì)數(shù)發(fā)送的個(gè)數(shù)
38             }
39   
40             break;
41         }
42         default: {break;}
43     }
44 }
45   
46   
47 void 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++]); //計(jì)數(shù)收到的個(gè)數(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 }

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

8位單片機(jī)在嵌入式設(shè)計(jì)領(lǐng)域已經(jīng)成為半個(gè)多世紀(jì)以來(lái)的主流選擇。盡管嵌入式系統(tǒng)市場(chǎng)日益復(fù)雜,8位單片機(jī)依然不斷發(fā)展,積極應(yīng)對(duì)新的挑戰(zhàn)和系統(tǒng)需求。如今,Microchip推出的8位PIC?和AVR?單片機(jī)系列,配備了先進(jìn)的獨(dú)立...

關(guān)鍵字: 單片機(jī) 嵌入式 CPU

在嵌入式開(kāi)發(fā)中,STM32的時(shí)鐘系統(tǒng)因其靈活性和復(fù)雜性成為開(kāi)發(fā)者關(guān)注的焦點(diǎn)。然而,看似簡(jiǎn)單的時(shí)鐘配置背后,隱藏著諸多易被忽視的陷阱,輕則導(dǎo)致系統(tǒng)不穩(wěn)定,重則引發(fā)硬件損壞。本文從時(shí)鐘源選擇、PLL配置、總線時(shí)鐘分配等關(guān)鍵環(huán)...

關(guān)鍵字: STM32 時(shí)鐘系統(tǒng)

在嵌入式系統(tǒng)開(kāi)發(fā)中,程序燒錄是連接軟件設(shè)計(jì)與硬件實(shí)現(xiàn)的關(guān)鍵環(huán)節(jié)。當(dāng)前主流的單片機(jī)燒錄技術(shù)已形成ICP(在電路編程)、ISP(在系統(tǒng)編程)、IAP(在應(yīng)用編程)三大技術(shù)體系,分別對(duì)應(yīng)開(kāi)發(fā)調(diào)試、量產(chǎn)燒錄、遠(yuǎn)程升級(jí)等不同場(chǎng)景。...

關(guān)鍵字: 單片機(jī) ISP ICP IAP 嵌入式系統(tǒng)開(kāi)發(fā)

在嵌入式系統(tǒng)開(kāi)發(fā)中,STM32系列微控制器的內(nèi)部溫度傳感器因其低成本、高集成度特性,廣泛應(yīng)用于設(shè)備自檢、環(huán)境監(jiān)測(cè)等場(chǎng)景。然而,受芯片工藝差異和電源噪聲影響,其原始數(shù)據(jù)存在±1.5℃的固有誤差。本文從硬件配置、校準(zhǔn)算法、軟...

關(guān)鍵字: STM32 溫度傳感器

在嵌入式系統(tǒng)開(kāi)發(fā)中,看門狗(Watchdog Timer, WDT)是保障系統(tǒng)可靠性的核心組件,其初始化時(shí)機(jī)的選擇直接影響系統(tǒng)抗干擾能力和穩(wěn)定性。本文從硬件架構(gòu)、軟件流程、安全規(guī)范三個(gè)維度,系統(tǒng)分析看門狗初始化的最佳實(shí)踐...

關(guān)鍵字: 單片機(jī) 看門狗 嵌入式系統(tǒng)

本文中,小編將對(duì)單片機(jī)予以介紹,如果你想對(duì)它的詳細(xì)情況有所認(rèn)識(shí),或者想要增進(jìn)對(duì)它的了解程度,不妨請(qǐng)看以下內(nèi)容哦。

關(guān)鍵字: 單片機(jī) 開(kāi)發(fā)板 Keil

隨著單片機(jī)系統(tǒng)越來(lái)越廣泛地應(yīng)用于消費(fèi)類電子、醫(yī)療、工業(yè)自動(dòng)化、智能化儀器儀表、航空航天等各領(lǐng)域,單片機(jī)系統(tǒng)面臨著電磁干擾(EMI)日益嚴(yán)重的威脅。電磁兼容性(EMC)包含系統(tǒng)的發(fā)射和敏感度兩方面的問(wèn)題。

關(guān)鍵字: 單片機(jī) 電磁兼容

以下內(nèi)容中,小編將對(duì)單片機(jī)的相關(guān)內(nèi)容進(jìn)行著重介紹和闡述,希望本文能幫您增進(jìn)對(duì)單片機(jī)的了解,和小編一起來(lái)看看吧。

關(guān)鍵字: 單片機(jī) 復(fù)位電路

在這篇文章中,小編將為大家?guī)?lái)單片機(jī)的相關(guān)報(bào)道。如果你對(duì)本文即將要講解的內(nèi)容存在一定興趣,不妨繼續(xù)往下閱讀哦。

關(guān)鍵字: 單片機(jī) 異常復(fù)位

今天,小編將在這篇文章中為大家?guī)?lái)單片機(jī)的有關(guān)報(bào)道,通過(guò)閱讀這篇文章,大家可以對(duì)它具備清晰的認(rèn)識(shí),主要內(nèi)容如下。

關(guān)鍵字: 單片機(jī) 仿真器
關(guān)閉