项目简介$ K9 D% D5 i7 \
利用CubMX生成基于32单片机的HAl库工程,然后编写程序在proteus上仿真验证。本项目最适合没有开发板的同学学习,零成本利用仿真软件率先入门STM32单片机。这是第四部分针对EEPROM 24C02的一个实例,IIC通信是一种比较典型的串行通信方式,在很多情况下都会有所使用,了解并熟悉IIC通信就显得十分重要。本项目之所以使用模拟IIC,而没有使用STM32单片机内置的硬件IIC,主要由于Half库里IIC的坑太多了,自己一开始也是想通过HAL库来开发,但是始终不成功,也有可能仿真软件也有些坑,如果有能够做出来的大佬,也欢迎评论区或私聊我交流,不过在实物32单片机开发板上网上好像验证过可用,但是手上暂时缺开发板,针对硬件IIC这一块的内容,以后有时间会完善。
! [. i' S# ^4 e# @" j$ |) {7 }& I" }) O# f
硬件模块5 N U/ N# Y% ?2 }) i
STM32F103R4
^' P- D$ c* Z$ K 24C02" R) V$ n }2 M2 K7 d6 t. x- S; `
串口模块) f$ ]7 r! m6 C) c( h# `/ j
3 n9 f/ B* q6 w: M0 g/ d7 k软件工具
0 `- _! |; o* ?' a CubMX
' | w- S, _! s B* B Proteus/ k; d% _( A4 _" I2 m, [, d2 K% X+ Y
KEIL
5 B: \! F2 B; ~+ T, k6 T6 r; S4 b6 u7 k1 r
电路连接图5 R3 X- R& r9 W2 }2 c4 t! q
0 q, L8 A* B* q8 Z8 h
! s8 ~7 A' B* h. p1 c, ^& b* ?6 z( r; x. T6 W
. Y# Q+ Y2 }* h1 C4 E& b3 k, S- x6 j: A
工作流程
C- ^, j* f2 N& [2 o7 r 首先创建一个CubMX工程,如果是配置硬件IIC很容易,只要简单选择一下就可以了" }6 }% M, ~' `
2 `& i/ ]3 _7 ^: v( l
, R$ A# |% I/ t! q
) m8 H! p' X" @/ i 默认是标准模式,速度是100kHz,可以选择高速模式400kHz,其余可以保持默认,当然这是硬件IIC的配置方法,咱们用的是模拟IIC,相应的引脚设置在后面生成的Keil工程里编写相应程序即可。
4 [0 L Y0 [% Y9 T# S* ?1 R$ Y R
2 ]" x2 C( u P x
# f* R% O1 z& w# ]2 V. W- w 其余也是保持默认即可
- Y' [6 p" I2 a
1 K! |* Q2 o% [; [8 v
6 u7 K0 A( X7 Q/ M: n& V) U
; q: C1 x" o( w% f7 S7 f
( X u0 F' |5 \
) [4 j7 ]+ p, O5 f' G 之后,在生成的KEIL工程中编写相应的程序,这部分在后面会列出。
' f7 \9 W, l3 H% `/ ?
( x1 Z' y4 E8 v- l5 w# o& _ 然后就是验证了。将提前设置的一组数据写入进24C02中,然后从24C02中读取出来,并用串口打印,提前设置的数据是{1,2,3,4,5,6,7,0} ,串口打印出的数据如下:
% m& A/ _- Y ?+ H0 d& E# j
! L, G' l% `' Y6 B* T) O, O
9 o7 h# l `2 r+ n8 B! v" X% B
$ u: x+ b6 P8 Y& h程序代码) D$ N$ s* O& f% R0 d* L' T& d
main.c
# p$ F" h, s0 z/ I- uint8_t WriteBuffer[2*BufferSize] = {1,2,3,4,5,6,7,0}; //需要写的数据在WriteBuffer当中. U) O; m5 b4 l p2 w. K6 Q
- uint8_t ReadBuffer[2*BufferSize]={0}; //读出来的数据放进ReadBuffer当中$ y1 |3 U6 L* `; y( J# ~0 h
- uint8_t i;
8 T- s, w" O) F# V) [7 D# e - uint8_t data_addr = 0x01;
" Y- Y% ^0 w' [7 Z- C - /* USER CODE END 0 */
4 H/ D0 S: \3 X6 U0 F$ w! R
6 P6 `" X+ ^* n6 {+ k* e- //重定向printf()到串口发送和接收,方便应用8 T, y& y- k1 u$ P: f
- int fputc(int ch, FILE *f){
% H, O' u: b2 F; D8 C& |- A - uint8_t temp[1] = {ch};
Q, F2 ?* q0 ? - HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
2 b- f* f1 [2 P% F% E/ s - return ch;
* [2 O, K @* O( A0 n- C - }
, a1 V2 x- v0 {* H# t9 H - //重定向scanf()函数和getchar()函数,方便应用. S; d% ^" s2 D F/ c5 s& p6 J
- int fgetc(FILE * f)
5 ?5 s6 ~1 n( Z9 T- n# l" H - {
/ \: X' U7 @' g& O4 l& } - uint8_t ch = 0;
1 h7 Q8 `# V& `; m; ^ u& J/ v - HAL_UART_Receive(&huart1,&ch, 1, 0xffff);% m H4 f; c( K0 c
- return ch;) z- j" r& }6 S5 _0 N% H* t& l0 e
- }& S$ S% P; }0 i% m1 A! N/ p* f) m- l
- 6 v/ y0 e* m5 \, ?
- /**
9 D; y% I9 i* U8 X4 m7 s - * @brief The application entry point.
7 D3 R( m8 b6 T9 h) @% j' R/ k# w: ] - * @retval int9 m# \4 J5 u8 |" M7 T4 H
- */
1 {" m' A6 X# i8 Q4 N7 E - int main(void)
, y6 p E G2 W2 S1 A' I - { }. w* x! U! w
- /* MCU Configuration--------------------------------------------------------*/
+ f. m6 m5 @! C5 p - 1 v0 K6 H% P9 o* @9 {) t
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */# w5 S. |1 J4 L! B: \
- HAL_Init();+ T" t+ \6 D) g
6 Z; R0 n0 H" c$ M" w- /* USER CODE BEGIN Init */
. p- Y. @' W' V - : f! ?& ~0 q2 e" V9 ~) b
- /* USER CODE END Init */
) L. [' s3 v J) P6 p
0 n! }2 s0 v6 [- /* Configure the system clock */- F9 n( P9 J0 U; E6 ~
- SystemClock_Config();5 L' V, F9 a4 Q& p4 o" }. O2 b8 ~6 J% E
6 x( b; n" I% r3 ~- /* USER CODE BEGIN SysInit */
0 h* ^5 `) s, w: n! N7 z) U$ H! i; Y
. f7 @) x' Z* m2 f9 @- /* USER CODE END SysInit */
3 e, O# o1 `2 [6 g$ \# \" ?, e$ F - 0 g9 c7 V2 I/ h+ f7 i D' N, i6 q
- /* Initialize all configured peripherals */
( p/ m2 T( [/ m0 m3 U5 ]3 l - MX_GPIO_Init();
" o7 K! Q. J0 g- F! K1 b - MX_USART1_UART_Init();
4 g0 S5 ]0 v6 ` T6 O& s - /* USER CODE BEGIN 2 */9 y0 u$ b3 d4 ~
% M; Y; h* T2 ]$ d5 b2 Y% }- /* USER CODE END 2 */4 c" @' S) |/ L/ w5 n
. O" j3 n3 J0 ^3 Q. _1 Z- /* Infinite loop */
) m% l% E/ I4 }$ W& z - /* USER CODE BEGIN WHILE */1 j/ G9 Q- n F1 B9 ?
- / o' w; B7 }3 p- H, L
- AT_24c02_int();' \" I7 ~" g! B* U
- for(i=0;i<BufferSize;i++)
; I! x; i! Z/ W2 p - {8 w. f/ l! _8 k
- AT_24c02_write_data(data_addr++,WriteBuffer[i]);
; {1 s8 f; A' T- h; ?2 q1 }1 O - HAL_Delay(10);//写完一个字节的数据要记得延时10ms左右,否则会写错5 X' t) k; U! s# I7 R; G2 f
- }0 H) }9 B3 ], {6 m& S
- HAL_Delay(10);+ ?6 O, i/ d8 C. }8 N4 P% y
- data_addr = 0x01;
+ j. X& ?+ |# `" ?6 s2 h - for(i=0;i<BufferSize;i++)
0 y$ S0 @4 C* t2 F - {' Q3 u" ~: C3 f+ t6 ^
- ReadBuffer[i] = AT_24c02_read_data(data_addr++);
. D9 k5 I. \4 l/ } - //HAL_Delay(10);& r7 c- |* q7 R
- }
& h- m2 ~6 L$ a P g& m2 L
0 m3 P& t- p' K1 g5 i4 U0 s" h- /* 测试输出 */4 e8 S7 y( W, ? m1 Y
- for(i=0;i<BufferSize; i++)1 J/ b+ l3 A5 s n7 ~ F
- {! Q# j; T, k# S& r# u* y! D" J$ F
- printf("0x%02X\n ",ReadBuffer[i]);3 s/ J' J4 S: f( p5 |" d4 c- r* [
- //HAL_Delay(1);2 T7 U/ z4 I$ u% z2 g" d
- }
* o r7 |) H( F; i7 D! J - , x6 z2 Q E! a# Z
- * {& O7 X( e6 p1 z4 o; Z) |- y
# H8 Q, m; m0 {2 p" z& v0 r D, i' x9 d- while(1)7 N! R$ V% L4 ?" {, h
- {
& O; P* o3 Z5 r; t: v: U* V
8 ^/ O' H; R) w8 ~- /* USER CODE BEGIN 3 */
U1 Z6 Q' `2 A& O/ F - }2 G- n4 I; k) H' T, E: B0 {" Z
- /* USER CODE END 3 */
# k e! f( K% I - }
复制代码 5 V4 P! P9 b" G4 {
24C02.c
9 Q4 C* ]. [' U p% t* C8 \( E- void AT_24c02_int(void)- s; v& O! Y) q; O" V I+ S8 l- ~: f
- {
2 y7 g( C* |/ w0 ^ - IIC_Init();
, k7 G( D* T/ O$ E5 y: P - }
. T6 l! y1 X6 J# i5 [# | - //data_addr 字节地址' E- P+ x* t W( H9 I) X/ D
- //data 数据
! M7 r. X* q# H6 V$ l. E - void AT_24c02_write_data(uint8_t data_addr,uint8_t data)" R) w7 |2 g0 o8 z
- {
6 Y \% K6 v! ?( f - IIC_Start();
: m& s0 Z1 M5 }! p& X2 A - IIC_Send_Byte(0xa0);
' H7 d s' D9 ]8 Y- k - IIC_Wait_Ack();% ?% S: ?# V6 l- D4 u
- IIC_Send_Byte(data_addr);# B/ ~) j9 H) M
- IIC_Wait_Ack();/ m% [- F1 V( v) s
- IIC_Send_Byte(data);
( d9 Y, W$ G: j0 _0 k* c - IIC_Wait_Ack();
# L, l; c ]. }, \* `- X2 ` - IIC_Stop();
7 p0 }( c" L9 R7 X3 G/ r8 D - }, F- H3 j7 o" N) i
- uint8_t AT_24c02_read_data(uint8_t data_addr)2 X3 | \8 ? P
- {
' s/ C' T# I3 Y0 z/ k" R+ y7 | - uint8_t data=0;) D* N* c" v& h/ \2 P
- IIC_Start();& s( a9 u0 p7 p3 g; _7 m! ?4 C
- IIC_Send_Byte(0xa0);9 c2 C. a" [: b% j
- IIC_Wait_Ack();+ l- p4 b1 H; {$ {+ w/ J2 [
- IIC_Send_Byte(data_addr);6 i8 k9 {5 w/ {+ m8 R: d' g
- IIC_Wait_Ack();
' d$ `" i* ^0 \" I1 a2 H' a" o3 {8 y' ~ - IIC_Start();# a& e' m( O/ a3 L0 t
- IIC_Send_Byte(0xa1);5 ^8 B; S* s7 [! A9 g
- IIC_Wait_Ack();
3 z8 [8 ]; y m7 \- v# C' d - data = IIC_Read_Byte();$ l% v1 g- v @& S7 E: o
- IIC_NAck();
" T. a5 E& k: X. K F$ K - IIC_Stop();
& a0 n/ _0 p7 ^ - return data;3 L% Q; G; d7 q8 b$ x
- }
复制代码 4 e, T% c) I( o# L
作者:jxjajl
, C2 x# I$ g- C- q f! D) W9 @# U+ e, Q3 p" n$ |( }: a2 j
|