EDA365电子论坛网

标题:  NuMicro M0516-PC通讯协议 [打印本页]

作者: Allevi    时间: 2018-10-29 09:32
标题:  NuMicro M0516-PC通讯协议
NuMicro M0516-PC通讯协议
9 D' T2 b( u. B, h) J+ }

. ]2 o( H  N4 `4 o  F3 F1 n9 G) A
main.c
2 W7 m2 s& r+ K, Y) l/****************************************************************************/
$ G* @5 V5 l9 x1 A' ~# \' I  X/*                                                                          */! }. L* R7 [" [0 F8 ^
/*                Copyright (c) 2016, 老马工作室                            *// c  l0 C9 S5 k2 r4 P2 {
/*                     All rights reserved.                                 */( K9 f1 e$ I6 r) K" r
/*                                                                          */, e+ z; \$ x6 x+ {, l6 b, ~
/*      Email:pcwebmaster@163.com                                           */1 G9 b  j0 }/ ~- g! e2 y0 K' B6 t) q
/****************************************************************************/
& _1 t% @3 h* d/****************************************************************************/1 A7 y; i' y3 Z5 s0 ~9 j( H
/* 文 件 名:comint.c                                                       */
: D# t& b' b( K/* 版    本:Version 1.0                                                    */
. [& x5 Z$ n; Y8 D) @6 b( f0 u/* 描    述:串行口中断带通讯协议测试                                       */
2 r5 B  _! q  P. s2 X& r/* 主控芯片:NuMicro M0516*// a/ J& v+ i9 O+ Y; y$ K
/* 晶振频率:11.0592MHz          */; @4 l: u9 O/ X" l5 G
/* 作    者:pcwebmaster(北极狼)                                            */
. Z" T6 F! R( f' W7 ?  I( g7 J7 {/* 函    数:                                                               */5 ~, O+ r( h4 \% Z. [* [# I- S- \, c
/*         system_init                                                     */
- P% @6 L( H  w/*         com_send_command                                                */! o9 `  p( s; x' Q% q; j& {
/*         com_command_receive*/) q9 N2 S1 r' j: @8 M$ F$ L
/*CalCRC16_1021*/
/ f) f: r3 k( `+ a& ~$ }2 u/*command_decoder*/
0 @  _1 B0 A4 @$ X( y/*send_command*/5 A' I! O$ ^+ u0 t0 X5 U8 Y
/* 测    试: 发送:16 16 02 01 02 01 00 35 03 94 BD接收:49 AA 15 */; A' }% B! a# P& `3 V! \
/* 测试现象:  */9 U, M' M2 K* {/ S, o' h
/* 历史记录:20016.02.18测试通过                                            */3 U6 @% g0 X, K* p( }% D
/* 北极狼          20016-02-18     Creat Inital version. (Version 1.0)      */0 U5 I) ?% A" }7 X
/****************************************************************************/
* {7 b# U9 w$ }- r* M#include <stdio.h>, M7 s: K# A/ h% `" h. ~$ c
#include "M051Series.h"
1 P' q8 e7 s% B$ S. ~#include "comint.h"' _( {8 O# p+ V$ a7 p. r, s9 A! R0 `
#define PLL_CLOCK           50000000
, ~$ [% K/ ?7 j0 a% y6 a0 |
- }+ d! g5 q1 {* f1 m$ A/*---------------------------------------------------------------------------------------------------------*/
, s, n: u3 `- N4 B8 k$ p4 w/* Global variables                                                                                        */; K5 [! e: L8 C8 K4 E
/*---------------------------------------------------------------------------------------------------------*/5 E( Y" q" v8 Y9 h# Y
0 v9 ~* M2 b! e' n( S& C  |
void SYS_Init(void)
. s1 Y2 `7 K) [% \! p. U9 B/ H3 V{! W* Z8 {) |; S& p% l/ I
    /*---------------------------------------------------------------------------------------------------------*/
' U. T3 V# `8 C9 `* `; v8 z! G    /* Init System Clock                                                                                       */
. p0 O2 ]! x/ c' j- B    /*---------------------------------------------------------------------------------------------------------*/5 N- |6 p5 f. z4 S. ~
    /* Enable Internal RC 22.1184MHz clock */0 v# p, b5 \' K
    CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);, _9 j% R3 k! c5 S3 F: l' ?
    /* Waiting for Internal RC clock ready */2 g: O2 x5 Y' W
    CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);4 A9 K6 r) D) D- }7 [1 n
    /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */- h6 z* {9 v& q+ R& {$ O
    CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
* L+ X* E7 h: y9 s/ b3 A5 t    /* Enable external XTAL 12MHz clock */9 r4 i6 M3 u: L
    CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);* s2 ]) m8 T1 U& a7 f; n# ~% N# `
    /* Waiting for external XTAL clock ready */
9 a$ n- u; F% l, D. f5 l& V    CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
% C( g# ^& n' O$ |, C9 @    /* Set core clock as PLL_CLOCK from PLL */
! Y5 E, L  ]/ `4 M    CLK_SetCoreClock(PLL_CLOCK);
+ {0 \5 W6 \1 n: \3 ?2 f5 \    /* Enable UART module clock */
: P7 ]/ L0 Q7 [! p' y9 Q    CLK_EnableModuleClock(UART0_MODULE);
+ ^8 t* E' t% L7 z3 Q. q, W    /* Select UART module clock source */( J' \: ]0 n9 Q; ?' m- P
//    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));CLK_CLKSEL1_UART_S_HIRC
, `6 h# n# W0 R' {/ K% G# [% i    CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_CLKDIV_UART(1));
* J% n# T5 V2 y' ~- K' B! a2 `( f    /*---------------------------------------------------------------------------------------------------------*/2 N. N7 r0 A4 Z- f# c/ E2 z; K; G% v
    /* Init I/O Multi-function                                                                                 */2 [! I- y/ r8 A9 d" n
    /*---------------------------------------------------------------------------------------------------------*/
1 \; G: g$ p8 x: ?& v9 {! h) o    /* Set P3 multi-function pins for UART0 RXD and TXD *// f$ t# b# A9 {# D
    SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
5 F4 r; z$ F( t3 l7 t$ ?; v9 h    SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);5 w* q& u" h4 v& P
}" }( {% o5 u4 U3 B9 d

/ A. P! e) S$ m) `void UART0_Init()
- i$ E- b4 |1 ^( e, _. M" P{
, |+ `/ w9 C, c( H6 U    /*---------------------------------------------------------------------------------------------------------*/! r4 W+ @& G- n8 Q8 n
    /* Init UART                                                                                               */8 L+ U* |- [4 C+ v! N
    /*---------------------------------------------------------------------------------------------------------*/
2 ]/ x. g" ~+ S- `    /* Reset IP */0 Y5 h& ?  O1 f" d# X
    SYS_ResetModule(UART0_RST);
9 d2 E) R& a9 E+ M2 b- H    /* Configure UART0 and set UART0 Baudrate */' I- g# G3 ?; K* ~+ Y
    UART_Open(UART0, 115200);
5 J+ i2 z) ?3 ^" W! R) Y( j5 |9 |+ a//UART_Open(UART0, 9600);
$ r4 |) E- f! [% m$ [, {    /* Enable Interrupt and install the call back function */' y1 s0 D' s1 r, j: O5 W- M0 R
    UART_ENABLE_INT(UART0, (UART_IER_RDA_IEN_Msk));// | UART_IER_THRE_IEN_Msk | UART_IER_RTO_IEN_Msk));
3 O8 O/ [8 U' @4 e0 E' }4 A  d    NVIC_EnableIRQ(UART0_IRQn);6 }! I/ s: i5 r2 Q1 x5 r# e
//    while(g_bWait);
" I, A5 n# K2 b7 O}
% a0 P' v( n/ b1 h9 \/ L2 v! d1 _. k% |& a; Z2 o
void Uart0Send(int32_t Bytes)
( F0 O" {6 {3 X9 ^1 C{
8 N/ J- n- @: B% u. @) `. T1 RUART0->THR = Bytes;
1 Y: O% v( S# Vwhile ((UART0->FSR&TX_EMPTY) != 0x00); //检查发送FIFO是否为空 ' S8 j8 q; M% X/ H/ {4 Y" }
}
  q; e3 U! E3 N* l' c/*---------------------------------------------------------------------------------------------------------*/5 w( _" Y6 m  w: a- H$ L9 f7 d
/* MAIN function                                                                                           *// w1 N% I. I1 p* t; ?. {" f
/*---------------------------------------------------------------------------------------------------------*/
* P, z) k4 L8 P& J5 Y3 |
! b+ e  L: m7 a( a/ k7 l. E7 z. V5 q* Zint main(void)' ?" {5 f( H( y( [% W) d  f
{8 l& M6 p' H1 l! W- }0 E0 k: X; I
//int8_t  i,j;   
% u# w* {6 h; T: @    SYS_UnlockReg();/* Unlock protected registers */   
& g7 r/ y* U7 f    SYS_Init();/* Init System, IP clock and multi-function I/O */    / k4 i( X4 E3 {0 A1 k7 Z( q
    SYS_LockReg();/* Lock protected registers */    % l+ V, b* w$ n0 N5 F1 C3 v1 |
    UART0_Init();/* Init UART0 for printf and testing */
. K& B+ T) ?4 ?. L/ zbuff_init();$ y, ^" K- w4 L+ k5 F
    /*---------------------------------------------------------------------------------------------------------*/
+ ]  s' p* i4 @6 a2 d    /* SAMPLE CODE                                                                                             */1 f. z" i- K) {1 D
    /*---------------------------------------------------------------------------------------------------------*/1 |* S  t9 F8 }; j7 R
    printf("\n\nCPU @ %dHz\n", SystemCoreClock);8 V3 r( H" B4 N8 k! G) C
printf("\r\n 世界,你好!\r\n");  3 r& a1 x" P( r$ H, }# F
printf("\r\n USART0测试正常! \r\n");
! d7 V9 _9 C% b; n9 p( S5 E. t9 |5 Lwhile(1)
. i& U! C6 F; \; N3 ^1 M{
5 i. R% B6 T! n! \) Xcom_command_receive();2 k0 q) M/ z# X9 n( ?9 F- w
}; A# X' q! T+ B6 `
}
4 w, \) `  y! w7 \5 \+ n, S; Q& M/ H
COMINT.C+ b* H/ {  S5 D* d2 I  D9 }5 E7 W) z; F
/****************************************************************************/
% {: `1 c' U; w* \4 g  F+ Y/*                                                                          */
9 A$ m0 T# k* z. W( Q/*                Copyright (c) 2016, 老马工作室                            */5 i! ?7 |- L8 w9 T$ `
/*                     All rights reserved.                                 */6 [- ^0 d9 k) f) _
/*                                                                          */8 h2 z* p6 n4 u6 O$ ?7 a
/*      Email:pcwebmaster@163.com                                           */4 ^) G6 h/ q/ K& t8 X3 V, E
/****************************************************************************/
' A5 O9 s/ R; I, E7 d/****************************************************************************// _5 Y; _+ N0 O+ x* J
/* 文 件 名:comint.c                                                       */
( p$ u5 m1 m6 O: D3 D' O0 }/* 版    本:Version 1.0                                                    */, h- c# v' x& D/ D
/* 描    述:串行口中断带通讯协议测试                                       */- t0 x2 f. l7 C% g7 Z0 Z: r! u
/* 主控芯片:NuMicro M0516*/2 F# H) s, v' n% _  J& w
/* 晶振频率:11.0592MHz          */* T! A% [8 u3 M* Z% Q
/* 作    者:pcwebmaster(北极狼)                                            */  d7 Z& v3 p& ?% d8 g2 X9 a! s1 h
/* 函    数:                                                               */
; x  N$ U" G/ n3 l, I/*         system_init                                                     */) H* \0 M+ F4 J0 q2 {- o
/*         com_send_command                                                */
: p! I% m, a- L) Y9 t: U9 n2 y/*         com_command_receive*/  f8 j* D; u+ `  W. }6 l
/*CalCRC16_1021*/4 ~" W. @# J' E7 J7 \: c8 M
/*command_decoder*/
% u' c3 ~" x. \3 f/*send_command*/
% k$ r9 B  A, q+ j/* 测    试: 发送:16 16 02 01 02 01 00 35 03 94 BD接收:49 AA 15 */9 i& M8 U+ X# c, H, M! O
/* 测试现象:  *// [# P2 C6 Q) v. B- r( F
/* 历史记录:20016.02.18测试通过                                            */3 A% i( L* ?! H3 k* u0 x; l
/* 北极狼          20016-02-18     Creat Inital version. (Version 1.0)      */
! a/ D7 i3 E* q# L" [/****************************************************************************/& B0 b$ }: y  Z) x3 _- \: r( g
#include "comint.h": L( C" t; g4 ~9 A' G( |

9 X6 f' x, I7 wuint8_t  pint_buf[MAX_RINTL];   /* 串口接收缓冲区       */" _3 J4 E# N1 [! R. O0 ^, w7 y
uint8_t  pint_read;             /* 串口缓冲区读指针     */1 U6 y; p" E- u! j+ X2 u7 F# w
uint8_t  pint_write;            /* 串口缓冲区写指针     */; e5 i  Y& F3 w/ }
uint8_t  psend_int;             /* 串口发送允许标志     */
, e, P. X3 ^! duint8_t  serial_flag = 0;       /* 串口接收数据标志位   */
; k$ m" m- d. g
7 w1 d+ X, H; J" C8 @$ B* v) S" k# A9 S
uint8_t  prec_buf[MAX_COMMAND_LEN];/* 命令接收缓冲区    */3 u4 _( ?9 Q( f% Z  _+ m- K1 ?
uint8_t  prec_num;                    /* 命令接收缓冲区字节数 */
. U6 P3 s5 \: g+ g) u# x! {2 H& `+ L+ V9 ?) K* f
uint8_t serial_lengthl = 0;           /* 消息命令长度低8位    *// B6 n. F0 e% X7 ~
uint16_t  serial_length = 0;          /* 消息命令长度16位     */
3 U8 _/ G* ]- U" f: c& O* n6 D
- G9 g/ b4 B( P7 z# S/ Uuint8_t ADDRESS[2]={ZU,ZHAN};       /* byte0:通讯组地址, byte1:开发板地址 */5 G% E7 K5 p8 _

4 o( y, k4 x/ w  Z! w" w# Y( f/* 串口发送一个字节 */
4 \5 L/ h; V9 i3 Y0 U# Wvoid com_send_command(uint16_t Data)3 e2 ^6 K! P6 U, K% b. @( T) ?
{# [( G/ s- I2 v+ q. {
UART0->THR = Data;0 q. {; B. n! {7 g+ `/ H( ~" {
while ((UART0->FSR&TX_EMPTY) != 0x00); //检查发送FIFO是否为空
8 V: B9 }' u- B( h* a6 \}$ K) b* \$ T. X3 j2 p
' Z3 H' I+ |" N6 Q
/* 串口接收数据处理 */
/ i, ^" R* N+ |; ^void com_command_receive(void)9 |8 p5 ^5 L8 ^* R
{7 i% s# n1 P  w0 j
    uint8_t var1,var4;
9 a, C  X! H# \; t/ y0 B    uint16_t crc_data = 0;
. Q( t/ p( J+ k7 F. ~; _    var4 = pint_read;
, z/ U% X8 t$ Y: K7 _$ P. Q; e/ P/ w" J  S0 X" A
    if (var4 != pint_write)1 e# n# S* b  v: _; i" b* k. p+ Z1 ]5 B
    {
& G0 k9 A2 n9 ^; O" r0 o/ R        var1 = pint_buf[var4];
4 f9 f+ d% k6 ~, p$ `        var4 = var4+1;
" d) u' Z/ y% g, v' P2 a$ y3 h        if (var4 >= MAX_RINTL); _- }- J+ ^* A
            var4=0;
# S9 ]' F3 l( n
  K0 L: a8 w* l6 L4 j% H        pint_read = var4;
$ R# ~* R/ }, I6 K0 X# ]  ^- k. @* j! X7 F4 H7 q
        switch(serial_flag)
" l2 S: E# ^& ^( [6 B/ f3 W        {
9 O. F" V2 g  ?, N: B            case 0: /*收到起始位*/3 H+ J) t; \6 ^- Z1 |& t
                if (var1 == SYN)
( E! U' H: t7 l5 ?/ Q$ P3 _8 a6 f  W" i                {4 j& F) Z: H' h, r1 ?! h6 [
                    serial_flag = 1;0 _8 N% K4 V8 ~- W7 q& Q
//com_send_command(0x01); //测试
0 q0 I& `, ], b. E( d5 G/ f                }$ U4 m  d. f3 i
                else" a1 Q9 O% G9 u5 i2 d+ e
                {& i. B  f0 ~* R
                    serial_flag = 0;8 Q% |3 q* ]* G3 Q, U$ {
                }
/ F- U4 T5 K& t                break;% O9 W- s3 [" X- I1 I# @

( A# K7 s5 W" {4 ~1 e            case 1:/*收到起始位*/
2 u3 c3 p5 ]5 T5 p7 w& y& `( `8 n                if (var1 == SYN)8 @! w: Z" A! n+ y: R3 {2 f3 T
                {
6 Z  q' K. R: t- u3 T                    serial_flag = 2;
6 U1 r: [* D( b) s' f//com_send_command(0x02); //测试
2 p& E* c5 h2 F0 k: t                }' U) M6 h6 M% \( `  y5 `/ t
                else
* T: w7 D# [8 s. w  P, G" l7 N                {
1 N) T: A: t& e6 s, j: O                    serial_flag = 0;
. H5 Z4 e" }+ X! h                }
& {( q# U9 e/ M6 r: M6 r                break;! j4 p* c* l' E) s% o1 V

) Z7 V5 P4 Y- M" C$ ?( C. j            case 2:/*收到同步位*/
5 a8 c4 d. u: s/ u                if (var1 == STX)
8 ^$ E& U3 Y* G: _                {
4 j5 L! H1 {% a5 G4 A2 R& p$ t, U: t                    serial_flag = 3;
) Z" `- h! Y+ x1 X, Z# ^//com_send_command(0x03);//测试
) v. p7 f+ C6 O  K3 u# Q8 L                }$ N! @8 X- y- c' x
                else, X- C# J; g9 N
                {: z2 B0 d' h7 T7 |
                    serial_flag = 0;
/ Y5 R- r% u& |9 o                }, v8 p, g) k" k/ @# j: ]
                break;) w2 Z( I5 k* T% z) U
% j: P1 E. ^5 ^. J+ d- e% A
            case 3: /*收到组地址*/
. l- V4 `( O4 M. x" ^3 X5 R                if (var1 == ADDRESS[0])
5 B8 |4 \) V7 t) K# f' E                {( D* F$ Y& M4 ?
                    serial_flag = 4;3 i8 ^' C( U* p8 m' I7 k3 ^
                    prec_num = 1;
* p6 r3 i0 q7 p5 P- ?                    prec_buf[0] = var1;# l! l) A( M- M: m$ [- r8 ^3 J
//com_send_command(0x04); //测试
4 K; c& S4 x, o3 t- y2 n                }5 V& h1 P6 ^$ x
                else
: ?- }% _/ o  b0 t# w4 f6 Z9 p                {- ~& y% V4 \' s4 Q
                    serial_flag = 0;
4 J: t" [& z' H0 A1 O, c8 r# V                }2 o5 ^6 ^; {# i/ g
                break;% T) Y8 u3 o( Y
5 l  T! y+ C/ p! Z' r5 L6 ]9 [
            case 4:/*收到本机地址或者广播地址*/7 u0 F" X  y3 `, V- j6 b  P
                if ( (var1 == ADDRESS[1]) || (var1 == 0) )3 A# \, ~+ X! i/ j# M' \  k. V
                {" _0 o% w( r! @
                    prec_num = 2;
# H( K: ]' K8 H$ H3 u! T+ l                    prec_buf[1] = var1;, |: D; Q) W- E$ x/ z
                    serial_flag = 5;
, ?8 {6 }/ Q6 [* k8 }0 Y//com_send_command(0x05); //测试
# B; H& Z9 b* L* {                }
1 e- Z1 K7 W/ k/ E/ A" R7 x0 S                else
; x9 O0 v& |- O                {
* G. k( e$ s* Z4 ^9 x                    serial_flag = 0;
- a2 K$ F8 E( ^1 h( w  \                }2 M) d& p7 V! o. ?0 k, U
                break;. V9 p. _+ O: q  q6 e" u
* B/ x! o. ?7 P7 z; K" n
            case 5:/*数据长度*/
4 M' P7 @& _3 b6 L. v                prec_num = 3;, w% T+ z' y% a) J7 U: a
                prec_buf[2] = var1;; C" w/ K' L# @+ F; {! q! U
                serial_lengthl = var1;
4 V4 Y3 K: T% _                serial_flag = 6;, V3 f1 f  N5 o" I5 s4 z
//com_send_command(0x06);//测试' ]' B+ `: w7 {! F; i1 \" B
                break;
# y7 T9 U7 m/ b: \3 _7 P
! P* ^9 {# U  S" x  @            case 6:, t4 M: U, }* t+ N% s1 z! P) _! y
                prec_num = 4;
$ T8 {$ {% @1 d- C; i                prec_buf[3] = var1;1 ?0 Z0 A- l: _) b8 K
                serial_length |= var1;6 s- f% Y3 D: I
                serial_length = ( (serial_length << 8) & 0xff00 ) + serial_lengthl + 3;
; E# u1 h$ ?( R% k0 B                serial_flag = 7;/ y: e, |6 W; v% j% H% Z
//com_send_command(0x07);//测试5 l7 h3 U( y9 B* e( g% j' E
                break;
2 x4 y9 s/ x3 Y% G# K- B1 u& h! X" i" q
            case 7:2 m8 T3 u9 j0 [, d$ l" `. Q, t
                prec_buf[prec_num] = var1;1 {* i- e) L" J  x+ B
                prec_num++;
' ?! [0 |3 a: e: r; \* x* i                serial_length--;
/ C3 z8 z/ X" Y, B0 Y                if (serial_length == 0)7 T$ z0 E$ f9 d
                {
9 x+ g+ N/ `; e( V% m                    crc_data = CalCRC16_1021(prec_buf, prec_num - 2); /* 计算crc校验和(从组地址开始到ETX )*/: m7 K: N4 y. d) e, B+ m
7 r; m. w6 q- x! g0 S3 r$ P
                    if ( ( (crc_data & 0x00ff) == prec_buf[prec_num - 2]) && ( ( (crc_data >>8) & 0x00ff) == prec_buf[prec_num - 1]) ) /* 校验和正确 */5 c( j, v5 l% G8 b- |( T  _
                    {
2 i3 {" z' A! ^7 d( _                        prec_num = 1;
/ ^: z$ T( f! b& O. @1 E                        var1 = 0;
( Q* N" \* A" z+ P- Y  h  d9 x* @' S/ _8 g8 G
                        if ( (prec_buf[4] >= 0x31) && (prec_buf[4] <= 0x3b) ) /* 命令有效 */3 Q( _' {& q8 C6 D: T7 T
                        {
0 S; |, j* r1 L- q* x                            if (prec_buf[1] != 0x00) /* 如果不是广播地址则回应ACK*/
3 c$ \. }* D) R" r$ \7 gcom_send_command(0x49);//测试                                 msg_last_push(MSG_ACK,0);
  [8 P! a. M4 U- q//send_command(ACK); //测试    . f3 L$ q9 I/ C; Z, w& A$ }
0 q( p. F; [' F0 p, O
                            command_decoder(); /* 如果校验和正确,则进行命令解码 */
  Q6 c! v7 m4 _1 |. h# F                        }
$ S: E! c. {& v! c! M- X                        else
; B2 R0 K4 Z3 r$ v6 W5 i( B                        {
( |% D6 Z) D' h2 B* S: Z
7 b% @( ~) o/ }' b8 G9 Z+ V* ksend_command(NAK); //测试* f% j. |: \" y; k
                        }$ g8 ]+ |" L& L  i- @8 S
                    }
6 Z' D& N" `% A; @2 u& m; d7 g% s                    else- M) X" O0 b7 Q6 l& b6 i( a
                    {
  i; R, H! g( O8 v7 b! v7 E+ R0 b2 Z2 x: k% D# ^2 }
send_command(NAK); //测试, M5 i! Q2 S  P
                    }1 k$ V! Q4 `) [6 S5 t
                    serial_flag = 0;' [+ m# ^8 J3 u9 ?$ _- i
                    prec_num = 1;  U5 N; B2 Z8 b" e4 I5 J. J
                }5 N: J0 S4 k( Y: v/ t5 @, E
                break;
  O; b: n; s' x, C0 q' d
$ g6 g' W+ }; J; A% `4 b            default:
! z# L& L4 ]- _' A! b                serial_flag = 0;3 O; M1 U% v, [
                prec_num = 1;( V( l: b# x( O9 n5 T* N
                break;4 H" x7 P& Y# [* z2 ], Y
        }
) k5 l3 j$ R6 x# d% e    }; B& k( Y% \1 f! p! P
}( I) d& a4 ^- a: c
/* 命令解码子程序 */
% V- w2 y" U7 z7 m* }3 d) b0 _void command_decoder(void)& q: B; Y+ p( Y, j2 G1 l) d
{
) w+ G7 o" ~0 X2 y8 x- U//    uint8_t i = 0;
& h9 [2 z- p0 x$ K+ |2 W5 v
- _, Y5 A/ v* q0 i4 Z    if (prec_buf[4] == 0x31)       /* 设置报警阈值   */; m: K3 D/ ^" B" H7 T  x/ _
    {  " x- Y: W1 W& q
com_send_command(0x11);//测试
& I* C# K: M* u' g        return;
) C! Y$ b- [7 r; [! f- a7 c! P    }3 B6 s- y' Y( b3 i
    else if (prec_buf[4] == 0x32)  /* 请求报警阈值 */
& R2 u4 c9 z* W7 u* d    {0 H% C3 b& R0 G% l# D8 z8 J
com_send_command(0x12);//测试?
& G4 }. N2 Y3 L3 i. O2 w5 C        return;
6 e3 m3 I) G' A( ~    }
3 n; u) l+ u% W) ~! M    else if (prec_buf[4] == 0x33)  /* 修改当前时间 */% _+ D2 l. k4 N2 o
    {
( ]" P7 a+ L  T  O/ {/ xcom_send_command(0x13);//测试; s+ ~( X# P" m' v: i- b0 @: _
        return;
) ]6 T1 O3 R" j4 j$ p" R1 q! {    }+ Q) p" ?$ g- L( f% N
    else if (prec_buf[4] == 0x34)  /* 请求当前时间 */* _+ L) [# F/ G) `9 `
    {8 V: E: ^5 x1 h+ J2 i; c
com_send_command(0x14);//测试) q/ }' N" t7 Y) t" l8 T9 k
        return;
' G% ?2 _3 A. [    }
! c3 K3 n0 w: Z! |    else if (prec_buf[4] == 0x35)  /* 请求当前数据 */
9 |" c$ y) z: m0 h    {
4 S2 w7 `# H* P5 R% g' @com_send_command(0xAA);//测试* L! i- z5 p9 U' c
//__nop();( l+ M4 z2 ]% R* t; W/ \
com_send_command(0x15);//测试
$ M* i9 h* x0 l: {% _4 U        return;
  t: z* I  `: A$ W+ v, A+ u    }' a8 `, X; |) \. F: |% A
    else if (prec_buf[4] == 0x36)  /* 请求看门狗信息*/
/ H3 s4 @  |! g; I    {
4 j5 o  q$ L2 ]* @com_send_command(0x16);//测试
! h& r, B8 R# Y1 a: v        return;! h/ `6 p) G8 g5 e3 G7 W) Y/ i
    }1 M+ u" K; z/ q" u+ I" ^
    else if (prec_buf[4] == 0x37)  /* 请求报警情况 */
, W; d/ F4 l7 q, M+ }    {
1 i4 L9 A$ k" v, `( M4 pcom_send_command(0x17);//测试4 V+ y. r+ [0 C6 y3 i
        return;- z- ^  H- S- y$ [' R& A
    }
( F8 w# z/ M% c# f  T    else if (prec_buf[4] == 0x38)  /* 配置设备地址 */
, W# c7 K, _+ g' B# ~    {. i$ \! Y1 Y; Y+ o
        ADDRESS[0] = prec_buf[5];  /* 通讯组地址   */
' L( B8 g! }) R( G! f0 k7 m8 A        ADDRESS[1] = prec_buf[6];  /* 开发板地址   */
" n! l- x' w* Y* Z0 H0 k+ W2 W- h) |com_send_command(0x181);//测试
# Q; U# M: \: v  o        return;
+ V, O2 K+ \4 |( U2 M    }$ z4 y, s, u' U# X; e# i, Q
    else if (prec_buf[4] == 0x39)  /* 请求设备地址 */4 }5 \0 }/ j# A, \8 \# E+ I
    {2 P1 C& J; F! G4 k. A% c- ^
com_send_command(0x19);//测试
9 I! d+ K3 P  D& x        return;
9 o6 ^' S. D/ |" O4 |# R    }9 l) R3 w. B. f4 n, c2 z+ O4 Z1 V
    else if (prec_buf[4] == 0x3a)  /* 控制模拟量输出 */
5 c; y* k. J$ m& D! X! e    {
/ {6 c2 v) ~  q" r, j+ S1 Ycom_send_command(0x1A);//测试?2 N$ Z- L5 w# {
        return;. Z& G( Y. E7 l( i$ O$ ]2 S
    }
0 K( ]1 }; H* h0 m. X    else if (prec_buf[4] == 0x3b)  /* 控制开关量输出 */
' Q1 U! J5 A6 P* X+ {0 \    {
2 u+ d4 D9 G  C+ Q7 tcom_send_command(0x1B);//测试, e+ ?7 |0 U. v2 }: T
        return;9 v$ H+ Z0 X, j; [% D; h
    }6 P( D. T2 ^! A
//if (prec_buf[4] == 0x00)       /* 如果是广播地址  */
6 h7 G9 s% a+ ]8 m6 _; p4 Q( Y//    {  
. m$ Z1 [* Z4 {; I( m. p! f' K//com_send_command(SYN);
! X/ O: g. a: |  r" f. f* t2 G6 n//com_send_command(0x00);
' v% o# w" \/ x4 B; X//com_send_command(SYN);( G( p- L5 N$ C2 [
//        return;
+ @* N- D# M$ W1 O//    }
  g! S! O: T( \7 n* P( A3 x. ^}
4 b" v2 _8 C1 v; S
( w; A+ ~2 K- y/* 向PC主机发送消息帧,入口参数:消息类型 */8 v! q! {" T1 X3 T) o* Z& ~
void send_command(uint8_t command)
1 p3 ~8 e1 Y- U4 T( G  h{# [8 t8 n6 d& F! E- m
    switch (command)3 g" u% o1 p1 `9 C1 j1 u8 k
    {
4 z3 s  c( a4 e, s4 O3 _        case ACK:4 D  H5 t  z% r; I" t! a8 g
            com_send_command(SYN);
4 W. Y* G, [# y            com_send_command(SYN);
- v; O. F, x* N- \% x& G            com_send_command(ACK);
% o+ a- S; \7 F            break;
4 T+ G, D* A8 a% R/ e7 _
/ r2 Q- {; N; P, A5 n* Z        case NAK:7 R$ j; f0 C8 L* l% s4 _
            com_send_command(SYN);
4 U. b  n# g/ \* ~- ~            com_send_command(SYN);2 C' J5 D' _3 b# z* K" ]
            com_send_command(NAK);
4 G( Z! V. G8 A& c4 B            break;9 @8 l9 o2 V# O* j( z

( I& h; L9 g- ]1 @$ ^        default:. a' R5 N* [% W" }8 X; m
            break;
. a/ j9 A, h& @% D+ m2 ]  @% g! Y% I    }
/ [: A7 `( t2 [* x4 S4 U+ Q}: x4 V7 d5 P" R8 f' u) M5 x
void buff_init(void)
* B" q5 F, W' W* z( Q{
: b- {( R& _3 s    uint8_t loop;# e, Z6 N& W7 O+ j9 j' U
    loop = UART0->RBR;   /* 清串口缓冲区   */' U+ m4 @" f4 S! u% i9 g
    for (loop=0; loop<MAX_RINTL; loop++)
$ z* T- T+ X- u5 w4 w    {+ }& O( s$ M* t0 [2 s" i8 H! D
        pint_buf[loop] = 0;" I% I( x+ H' X' O
    }& \+ D' v. L4 q( R
}
- L$ y( y1 g' s* ^/*计算CRC校验和使用MTT(0X1021)  a& `1 D* ^- r9 |+ e
参数:
5 O# Q" Y* M0 n$ h! B1 @; ipBuff 为需计算CRC的缓冲区的头指针# a0 _! X; S* D7 A
BufferLen 缓冲区长度(以字节计)
& _$ f1 B) a; ~*/& Z9 t# J7 y+ m5 Y  C  t
u_short CalCRC16_1021(uint8_t x[], u_short BufferLen)
: M2 ?5 V- |9 {" j" ?  m( U{
* S& `2 O. i' m/ A    u_short i;
2 V" o; v8 r: h3 R2 e* I    uint8_t  j;
9 y, E, {" f% F    u_short crc16 = 0;
2 m- J9 K5 r' `" b. ~* h    u_short mask = 0x1021;. O/ {/ ?7 ]2 U) z
    uint8_t *pByteBuffer;0 u: e8 i9 Y7 x- ^
    uint8_t tmpbyte;% B/ H! [5 R; Y; ^# u7 X
    u_short calval;# U& e4 J# Y/ l& C, m) M  i

! S  O; _' z( K    pByteBuffer = &x[0];6 ?( P7 b* C  C1 [
' b* \4 z" Z2 |$ m' q
    for (i = 0; i < BufferLen; i++)9 r1 L+ {( k0 H. L. g
    {' `, `5 y+ ~0 D
        tmpbyte = *pByteBuffer;
& P7 p6 Q9 }4 @% D8 d2 S8 Z% B- _        calval = tmpbyte << 8;' L6 }' Z7 H1 G
        for (j = 0; j < 8; j++)
; i4 q2 y# _* n  I        {
* l3 _. d8 {5 ^/ w8 h8 |- F            if ((crc16 ^ calval) & 0x8000)
/ u. u5 N4 }* T; i8 A. |5 y/ b                crc16 = (crc16 << 1) ^ mask;1 M! m* O! H5 x# d
            else% _3 ]7 d$ J4 y& N4 d
                crc16 <<= 1;
$ l. G4 I0 e3 B( E( _
4 r* s6 U" \/ D* Y            calval <<= 1;& d* ~! }& Z+ N6 P# J2 P" x
        }* E% v( J) x& ~8 F
        pByteBuffer++;
' K8 C% j3 y5 Q: ^    }
& c! M3 h5 D, j    return crc16;4 E7 n+ i9 k' K% a! d. h7 U# l
}$ ]! m% q1 X. T% T& A$ Z& O

' b7 @7 k" d! V3 e: _/*---------------------------------------------------------------------------------------------------------*/$ C5 i  C3 C. Y* l
/* ISR to handle UART Channel 0 interrupt event                                                            */
5 }2 y" n$ o( Q" Z  E/*---------------------------------------------------------------------------------------------------------*/
; C5 m% ]( ]& Q" xvoid UART0_IRQHandler(void)6 K: S3 v: q, z  X% F' W
{" G8 F) Z0 p6 B7 T) f  r! ~2 O
    uint8_t temp;" G% @! `7 L3 U0 z8 l
    uint8_t temp1;$ R0 C  J1 Y; k6 {% j: }/ R
5 ~6 W& b5 Z- ?! r, b$ [
if(UART0->ISR & RDA_INT) //检查是否接收数据中断# Q- y0 k- |$ s" C3 _& q
{
$ @5 L5 @" c7 _4 Y5 Q5 ?4 o4 W9 Y7 dwhile(UART0->ISR & RDA_IF)  //获取所有接收到的数据
0 q. h. V9 Z: Y{
5 `+ `8 d. d& t  Wwhile (UART0->FSR & RX_EMPTY); //检查接收FIFO是否为空1 d& x2 }: O2 A5 `
temp1 = UART0->RBR; //读取数据
3 j; @' O6 P& j( p5 y+ ]* xtemp  = pint_write + 1; /* 判断是否可以写入 */
6 F  ?3 P" S3 [0 P! O. {) [7 mif (temp == MAX_RINTL)/ Y( I7 G9 Z- t9 v" I7 I5 S
{& E6 r. t. z& I2 x. p6 T0 @+ }
temp=0;
. v6 W6 c" p  J! e}% Q2 C# c9 N! \: w; z
if (temp != pint_read)& [" |3 F& s% P! a( J/ T
{& z$ ~* n( L9 v
pint_buf[pint_write] = temp1; /* 读取数据 */, u1 _4 r1 V6 Q6 v7 Q4 A
pint_write = temp;6 q& Q9 Z9 _) [+ P" h8 X8 V9 t
}6 x# Y: x% x1 \- l. D+ t( y( D
}4 Z7 W# Z8 E% N
}
  X+ w9 @# X8 I1 u2 z6 `}  d+ y! L6 k" R0 [
$ _' `* r9 ^5 i, S
COMINT.h8 D: p# \1 D' @2 ~3 p
4 M1 _0 P% c5 f! ]
#ifndef __COMINT_H__
' v# R) u2 z! z2 p5 q5 `: ~. y9 {#define __COMINT_H__
. V4 ]3 m$ z0 n; t5 A% y2 Q/ V5 w  J! b/ t1 D" [  ^) Z2 V
#include <stdio.h>- H4 ^6 x$ e6 E8 g$ Z# I
#include "M051Series.h"
3 o( i$ O8 g: ]! ]1 d8 g& C9 A
  J  k  ^% i3 U5 K' f#define RXBUFSIZE 8//1024" r7 d! d7 o+ R7 S5 d
#define TX_EMPTY(1<<22)8 l7 l. P" H  T1 M7 H
#define RX_EMPTY(1<<14): }8 O7 W' r5 y2 y4 j, n
#define RDA_INT(1<<8)6 X+ ]: {3 ?3 v, t4 w- Q; s
#define RDA_IF(1<<0)) j. g: x0 q, X6 Y- ~
; B, |7 m" u( a5 c7 k6 }
typedefunsigned shortu_short;! i$ ~( s; P1 y) a- m7 V
: E+ ~, k/ i9 C+ w7 [# l
#define ZU0x01 /*组地址*///通讯地址修改这两项
+ V2 ~, ]+ @  g7 x5 z  K4 D) H#define ZHAN0x02 /*站地址*///通讯地址修改这两项
7 t) y3 v6 L) b, @' o+ T0 ~9 b
% d, C' j3 m  v#define MAX_RINTL       16   /* 串口接收缓冲区长度   */
& z1 g& G6 ^; e#define SYN           0x16   /* 通讯同步位*/! `* `" Z. }% P7 o  V8 ]! `
#define STX           0x02   /* 通讯起始位*/! _& d; m- g- L0 U/ \$ n' D
#define ETX           0x03   /* 通讯结束位*/
* v) X* X2 w4 n  ]9 J! Z5 e! u- k* m' T, y, f7 T3 i
#define ACK           0x06$ Q8 Y% \: |: F
#define NAK           0x15
) f( @: E+ ^8 D  p3 h
0 G! o  E8 V* q! P5 B  s+ P7 o# |#define MSG_ACK          2    /* 正确应答信息         */
5 P' f2 \6 n$ L9 S#define MSG_NAK          3    /* 错误应答信息         */- q! y& J) O6 {( v
#define MAX_COMMAND_LEN  16   /* 串口接受命令长度     */4 j% T! y. q/ h/ I5 d- d

/ H5 F8 p. a& [/ W& Jextern char str_test[25]  ;
# i1 {: u9 z, I' k% uextern uint8_t  pint_read;             // 串口缓冲区读指针     */' U4 D) M" L  [6 Q$ i! D4 D
extern uint8_t  pint_write;            // 串口缓冲区写指针) a5 E7 g* H# H9 h" K5 j6 w& o
//extern uint8_t  data  psend_int;             // 串口发送允许标志   
  u2 I; V+ G% v9 wextern uint8_t  pint_buf[MAX_RINTL];   // 串口接收缓冲区      
8 E& E4 n+ c; t" F5 N& ]" Iextern uint8_t serial_flag;              /* 串口接收数据标志位   */
% z( p/ K% {6 \, q5 [, t; q( Q  @% q7 c9 @4 ?
extern uint8_t  prec_buf[MAX_COMMAND_LEN];/* 命令接收缓冲区 */
% b: L( _9 C5 }$ [, \( |7 E6 ^: N2 b& ^4 @2 ^: O
/* 串口发送一个字节 */% @6 g0 R: w/ o  x+ P# o$ C
extern void com_send_command(uint16_t Data);
3 r$ d; b- R; H# b1 B/* 串口接收数据处理 */
7 \; g' I, W  U  Y2 x6 a6 uextern void com_command_receive(void);
& [: J" T7 e, f/ y0 M2 S) w/* 串口接收初始化 */0 J- L  E. [' O" ~
extern void buff_init(void);
: V% J5 G- t! g1 m: q9 [3 t* Z" @0 M" {- H* Z* p8 U; Z
///* 串口接收一字节数据 */
, B/ D' E0 c2 H+ X//unsigned char UartReadChar(void); //reentrant8 v/ x0 f3 [+ s6 b& e/ Q! D% J5 J3 I! {7 K+ S
/*计算CRC校验和使用MTT(0X1021)
. |; I  b* P: |. h* B参数:
$ t2 s, j. ?9 l# V- l6 q; M9 \& opBuff 为需计算CRC的缓冲区的头指针5 Z! n) F* y8 M" h  C' E
BufferLen 缓冲区长度(以字节计)! p9 }' E6 _; M3 f
*/$ E2 t1 j* i* q7 ~# I' C) k2 _( C
u_short CalCRC16_1021(uint8_t x[], u_short BufferLen);. U, x& Y. ^5 |0 L2 k# c7 O3 O3 i9 z

0 A8 }( l; O( F5 F) R4 t0 M2 ^/* 命令解码子程序 */
4 l% \# G5 j+ X, e; nvoid command_decoder(void);
6 w( X0 s! J; g. _- K+ B! j/* 向主机发送消息帧,入口参数:消息类型 */
, Y) h9 C2 M2 t/ Pvoid send_command(uint8_t command);
1 ?- d7 M/ y& }
* M1 L8 ~/ N3 z; J#endif
) I7 y( W2 x6 b) m, D3 B

* |$ |% |6 a0 B& F+ X( ?3 Z. p1 ]: j* v- P5 ^6 A

7 v2 a8 N" E" j
2 e2 g6 x" Z- [+ _0 E
+ p9 Y* d2 f! V2 L

3 h- c! M! @! b/ @3 g
( F" e. d# s* Y

作者: cj223356    时间: 2018-10-29 16:20
看一下




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2