|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 岁月如歌21 于 2025-11-17 17:23 编辑
( j- t% R, J! h/ D; T# b) A9 @
5 y" ^% ~4 C. f% I' @9 G" S2 FModBus_RTU(4组串口任选+DMA传输的主/从机)的lib库使用,STC32位8051实现$ {8 @( U% x# `; d7 m+ b/ _
一、准备好自己的代码工程
0 y! N: s1 M6 [这里以STC32位8051的点灯工程为例0 Q/ x& w5 g" Z4 [4 j
9 [9 n; ^$ `6 F, O( J$ A编写该代码,可以看到这个0错误,下载进去之后可以看到屠龙刀板子上的P2端口的8个LED开始闪烁,表示这个代码工程无问题
) \" l7 N, }$ S: p' h$ f1 U
$ K# |6 J) h4 n: ~9 E4 v, `) D. e: w4 H9 }. L5 f) e. K0 W A( A
二、添加库文件到自己的工程里里
2 K& P0 _. \$ W6 [3 F1.添加附件代码包到工程里* _ g. b5 h( q4 v; j
6 J3 q9 J! f/ d' j; y2.然后按照如下方法调用一下头文件的路径2 F% G$ Z- s1 {& t7 Z
0 \7 F3 h$ `/ B2 }& \8 B0 R/ r# a
3.将库文件添加到工程列表2 U1 b: z5 W" f8 l% B1 C
: d8 u8 c% @# w. n6 V6 Q4.修改配置文件
. P& s; e e; O0 X# r) Q4.1头文件7 j9 R6 f7 u3 g1 e4 E d) V
1 [2 w3 g. O8 `. f6 K) m" f; V
因为用到了串口,在115200的波特率下,我一般用这个系统时钟,后面所有要使用系统时钟的地方均需要调用config.h,调用这个MAIN_Fosc的宏来获取系统时钟,
3 f; w$ r' Y6 z
, v Z+ [/ G6 w/ O8 i% }7 x
由于原来的工程里也有,且宏定义名称都一样,所以只需要把这个宏删掉,然后修改调用的头文件为config.h即可
( h% x9 E6 o8 h( z7 f' M! K' T7 w6 B+ ?7 s. l% _1 M- S
4.3宏定义
* i/ l, Q( {6 J' i) W
) `* I* j8 q0 j如果自己的工程里也有这部分的宏定义,可以屏蔽自己的,统一调用这个config.h来获取数据。
, R) g. b' O1 n" c( n' P) J
F: [7 k, a9 _$ Q# w+ z# E
9 \+ Z% R0 k, P" P5按照如上的代码改完,工程应该可以编译通过了
4 D& }- t; m/ h4 K% ~* K* O% \
, |$ e# k" m4 G) b3 ~$ J
可以看到工程已经0错误,0警告了 H+ i9 ~- j: F
5 L6 z* ]* B5 H. ~" p! ^三、开始测试串口收发的代码
% t* T; c. U7 G5 R. y1添加系统时钟计时变量/ g: Z% a. p2 r1 [' z4 i
2 a J( f$ J1 U; `( j j! c X- M
主函数添加这一变量,用来记录系统运行的上一次的时刻6 n* M K8 v, b( W& i: i6 W
% b g. F$ p; c2 c& z4 v+ M2.添加头文件到代码里: p! k" A9 Y; W2 A% o: I" }
2 A0 p0 x! ~8 G n8 k+ {
这个是串口和485口的配置头文件,配合lib文件一起使用的
. `' {7 g4 W5 `2 `" m: S2 `0 `# k- |* G# g: W
3选择串口的参数
& o- D7 e& b3 m% Y; @
( Z8 @$ m0 l+ F$ f- X' v
' \/ ?8 u9 W. Z1 ^ O
3 v* \# w6 V- u1 i
记得最后在工程里添加串口初始化的函数哦!!% [2 k7 I& N0 ^
3 |+ T3 ~3 F, a* [, n+ R h' ~4.编写如下的串口处理代码' O6 L6 ?% r% y) U/ T) @- L& J
, A+ O' r* q' o& H' `" z
再来看下这个代码的含义:) W5 N; y, h/ o6 Y' U$ L
Usart_RecCheck是数据接收检查的函数
4 H! |7 r# U8 i( y* I. \9 v第一个入口参数是串口结构体的指针,串口1-4分别对应g_tUart1-g_tUart4,这个函数对四个串口均有效
/ ]/ j. ]+ U& z第二个入口参数是运行时间,因为要用超时处理,这里需要提供时间间隔,所以本次时刻减去上一次的时刻就是时间间隔# A* x; O9 l2 ~9 Q& P
' j' L" G B. B8 u函数返回值是当前状态 0:未接收到数据 1:接收中 2:接收完成(超过一定的时间没有收到表示接受完成)
4 h. Z. F7 I; o4 M' j
+ Z( Y/ y2 `- w7 _# P6 \& L$ M" LUsart_Send是数据发送的函数1 C$ Y( _: k# f9 l/ V* g' o
7 |) z: Y, S) C* W+ [6 P
第一个入口参数是串口结构体的指针,串口1-4分别对应g_tUart1-g_tUart4,这个函数对四个串口均有效
/ I3 z5 m; v! _1 q" d6 ^
5 P7 h/ {2 r7 D第二个入口参数是要发送的数据
& q" K1 b7 n& }) f: [第三个入口参数是要发送的数据长度. ^* k5 {/ |! i( p
& ]" v7 W9 }7 S- z5 n) ^' l1 h6 c/ R
Usart_RecSet是数据接收初始化的函数(用的DMA接收数据,没有超出缓冲区就不会触发DMA接收完成中断,这里用的软件超时中断来判断接收完成,用STC32G8K64可以用串口超时寄存器)9 x- J2 l! r* M8 ?! b. ]1 D# C7 k. M
/ _; h/ I$ x4 k H4 [# [5 d
1 _ C6 t4 n: l第一个入口参数是串口结构体的指针,串口1-4分别对应g_tUart1-g_tUart4,这个函数对四个串口均有效% ]( d* D h0 A
6 T7 z/ {) X7 R5 `2 y o第二个入口参数是超时时间,超过一定时间没有接收到数据表示错误,Usart_RecCheck会返回0xff
b8 C' Z G. N8 w0 b) E% b* m# r+ m4 S+ d+ _
& K! B+ ]; W' |. e' x m8 j因为接受到的数据会保存到g_tUart1.g_RxBuf这个数组里,所以直接调用这个数组返回即可, 这里检测的是g_tUart1,也就是串口1, L3 _6 v' p, y
) p* E, j, w! [
编写完成之后开始编译:
& ~' Y* ~- H! w0 K n" m2 I
5 k, q/ {9 L5 g7 y8 {' U6 `1 G9 F& a3 j
这里编译完0错误,再来下载,记得要改下图的参数,
% j) w: b( ^! ~: O8 c% C/ Z
& E( d. V1 g; Y! x6 S9 P' I
$ ~6 E0 z6 u0 X0 h |
|