TA的每日心情 | 开心 2019-11-19 15:19 |
|---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
NuMicro M0516-PC通讯协议
$ ]+ D# D; n. L' d2 b+ |' d5 C2 l( K/ \, z# Q% p# f' k0 e
main.c4 a* j) g; c5 v, e+ H
/****************************************************************************/
' x, @& N# U% J9 i9 e7 ^( c( }/* */" X# u9 ?/ W' N/ m/ k ~; Y! g5 L
/* Copyright (c) 2016, 老马工作室 */) d: c6 H- A, F% o2 c% s' a/ V5 h r
/* All rights reserved. */. B6 ?$ v0 E4 F# U8 l9 R% o, q. f1 I+ e
/* */
7 X2 H+ `" D Z/ z6 z/* Email:pcwebmaster@163.com */
/ t, N9 h2 A; H" s Q1 A5 `+ N/****************************************************************************/9 e& u% e3 V" O% n) U0 C$ Q
/****************************************************************************/* b6 ^2 q( x$ ~8 l- [
/* 文 件 名:comint.c */
8 f% H- a k% }6 j/* 版 本:Version 1.0 */
; p$ Y/ i- v B" ]+ z4 z) P, j/ H, c/* 描 述:串行口中断带通讯协议测试 */
1 x( W- D; }6 B; f" Z/* 主控芯片:NuMicro M0516*/
" B" Y; }; U7 r1 L* `) Q, i, D! T/* 晶振频率:11.0592MHz */' H& p( [2 m5 s% T9 n* t
/* 作 者:pcwebmaster(北极狼) */% [7 f! W, [5 L
/* 函 数: */3 `6 q$ U8 ]% Q8 F5 S- ]# a6 H
/* system_init */
$ h3 B$ A J8 @& h( u* C/* com_send_command */8 k) P+ @" S& p
/* com_command_receive*/7 G& l/ x7 s! X L$ i, ~2 s
/*CalCRC16_1021*/
& U3 ]3 X/ X2 I7 {/*command_decoder*/' ]( q" @% e3 W) M, T8 T" m/ |+ a
/*send_command*/ e- N) z l: C1 c1 P
/* 测 试: 发送:16 16 02 01 02 01 00 35 03 94 BD接收:49 AA 15 */
7 M4 m9 T7 B% R$ }: w6 F4 q/* 测试现象: */
6 R- Z+ A: I: W* f/* 历史记录:20016.02.18测试通过 */
2 @& [" V. A& D! g# Z/* 北极狼 20016-02-18 Creat Inital version. (Version 1.0) */
) F0 J9 q- n* s0 N& _" A/****************************************************************************/
# u* K( Y/ Z+ C* M1 [9 k6 @#include <stdio.h>
. Y7 i- g c2 [# [0 ] m/ F$ J: J#include "M051Series.h"
- i- c0 Y# W( ^) f& b; m/ T3 @#include "comint.h"5 ]/ `0 r' H& Q! _' l% A
#define PLL_CLOCK 500000006 Z \% d N" |- d3 a4 \2 V
! T" s s) H0 R: U/ h! s; w
/*---------------------------------------------------------------------------------------------------------*/3 Q( d& \7 J9 p1 v
/* Global variables */
. }( ?0 e* T/ t. L; z$ Y G/*---------------------------------------------------------------------------------------------------------*/
( m W P, k' Y7 n7 L1 f' U) }4 A# Q* ^% ?7 Q) Y \: A
void SYS_Init(void)
0 r- `3 Y6 `& Q4 U F0 s5 C( N{
; i; F7 s- Y0 Z: f! f* I; k /*---------------------------------------------------------------------------------------------------------*/
5 @6 X1 J8 u. u- } /* Init System Clock */7 G+ ?- g3 B3 j+ @! F
/*---------------------------------------------------------------------------------------------------------*/7 F& M, T- e9 _5 V' s
/* Enable Internal RC 22.1184MHz clock */
' |$ ]! l( k# {( F. s Y k: `- y CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
! T- _- [! m. l /* Waiting for Internal RC clock ready */9 J& S% T- h+ G6 c7 j) j
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);8 F* d$ Q: }2 Q2 F a/ N4 ?, R# ?
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
0 ^0 J, ^% a* ^+ d$ q CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
% ? C" ]( y4 r/ J' _ /* Enable external XTAL 12MHz clock */
: v' l' D7 h* |0 @9 E* q; j9 ^ CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
, p/ X* w+ ?7 w: @; K" U4 k /* Waiting for external XTAL clock ready */
! a, s5 ?( G2 \! a" K7 Y" q, ? CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);, P* h- Z, R1 [
/* Set core clock as PLL_CLOCK from PLL */' h& O1 U8 b3 L/ }
CLK_SetCoreClock(PLL_CLOCK);
" v5 J* ]) v- O/ W* R /* Enable UART module clock */
2 m+ C4 T1 `3 e8 u$ s: ~ CLK_EnableModuleClock(UART0_MODULE);/ h' A8 _- [' Q U3 X, G
/* Select UART module clock source */$ g9 d$ j K/ @! c9 ]' P
// CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));CLK_CLKSEL1_UART_S_HIRC
" D" n3 }: D2 e, [6 p CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HIRC, CLK_CLKDIV_UART(1));
% t" r; F/ |$ Y4 a. `$ x, \ /*---------------------------------------------------------------------------------------------------------*/
! Q0 G8 V! ?3 k) o4 h" b' L /* Init I/O Multi-function */
$ R! x. l; \0 {5 L( ~ n5 A9 U/ b /*---------------------------------------------------------------------------------------------------------*/
- A2 j8 R, g8 ?4 [8 g: w6 P ? /* Set P3 multi-function pins for UART0 RXD and TXD */
7 _" h$ _7 I- g$ M SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);1 j$ h& q. {' {1 h B
SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);
* ]4 j6 H' |( `5 c}, |! g% D* Q* r7 }3 c! z
# ?6 g9 f3 V; Xvoid UART0_Init()$ k. f3 b8 T. s6 P0 l
{+ r% d9 L2 U- l' D$ S; \
/*---------------------------------------------------------------------------------------------------------*/
& ?6 |$ e0 O9 J( o/ G# h /* Init UART */$ S# X7 g$ _7 H9 P% M! p" _
/*---------------------------------------------------------------------------------------------------------*/, u* L% L" T1 M3 L! {, X7 m' G
/* Reset IP */9 E' ~7 h* ~/ U' q; Z4 T
SYS_ResetModule(UART0_RST);
4 N4 m! J2 m R& c ]7 z /* Configure UART0 and set UART0 Baudrate */
$ v0 P# J+ H: Z) H UART_Open(UART0, 115200);* ]' b2 K% J, F! A/ i) a
//UART_Open(UART0, 9600);
, |1 H5 F& f' n4 L/ N$ v; Q /* Enable Interrupt and install the call back function */
! S+ h3 o. j9 m0 O$ X" X3 I UART_ENABLE_INT(UART0, (UART_IER_RDA_IEN_Msk));// | UART_IER_THRE_IEN_Msk | UART_IER_RTO_IEN_Msk));
: ]( B; m; R5 h NVIC_EnableIRQ(UART0_IRQn);" z; I/ \# p/ c( o: y" \2 E! b
// while(g_bWait);- Q/ m' Y# v- y* {' N6 P5 F3 Q
}3 M7 p/ }. [( L5 Y/ u" E: H( J' C
' s5 W* C0 _- R" l7 o5 Z) [void Uart0Send(int32_t Bytes)* m$ p" |$ c& ?' K9 {
{
- G1 ? N; J8 yUART0->THR = Bytes;
6 s4 K" Y3 n/ o. i* M& Kwhile ((UART0->FSR&TX_EMPTY) != 0x00); //检查发送FIFO是否为空 8 V2 |/ P" ^( P1 Y
}
' ~* e3 R' t" |# d0 U$ K/*---------------------------------------------------------------------------------------------------------*/4 A" H' k+ i8 ]2 J
/* MAIN function */' M) E, R% p% {3 Y
/*---------------------------------------------------------------------------------------------------------*/
* |* u/ D; J9 n/ J( @8 `5 ~ v! N( S* n4 z* f9 ~# r3 M" a
int main(void)
( q3 a9 P/ H" W; x' C{3 u- X- V7 Y. @* t* H$ e4 F9 {
//int8_t i,j;
7 o% k) B1 G W) Q SYS_UnlockReg();/* Unlock protected registers */ 6 L# b. k2 |/ s+ ]2 p
SYS_Init();/* Init System, IP clock and multi-function I/O */ % z0 a) Z' V/ n1 B
SYS_LockReg();/* Lock protected registers */
0 X1 i. K* r4 f/ G/ c UART0_Init();/* Init UART0 for printf and testing */
, ]- x0 n- ?! ibuff_init();+ j; Y$ T* ?5 @4 W. P% Y
/*---------------------------------------------------------------------------------------------------------*/
/ R2 g1 w0 F0 _ /* SAMPLE CODE */
& r( p; M& U, H( m7 l/ S /*---------------------------------------------------------------------------------------------------------*/
, x% ^: q7 ~6 R printf("\n\nCPU @ %dHz\n", SystEMCoreClock);
I2 y7 i; c: f5 e% `printf("\r\n 世界,你好!\r\n");
0 Q7 `, f- \9 D5 T3 ~2 H8 fprintf("\r\n USART0测试正常! \r\n");
* S" K" j0 F, m7 q$ Ewhile(1)
% `: V T4 [9 M( q' Z% K{8 E _$ \& x: H$ j s: F
com_command_receive();: ]# K( I! U7 z5 l/ q
}9 m2 i$ V. \9 C# C' x; [
}% q) A, Z$ K, O4 H1 C/ L
! q4 [+ e3 y1 j$ P: R$ ^8 J! j
COMINT.C
6 q9 C, R% z4 s) C# V/****************************************************************************/+ }* l9 A( Z+ S% T5 y
/* *// W7 E1 ~# e. z, T
/* Copyright (c) 2016, 老马工作室 */
4 N/ ?6 D7 S( }: g4 q' Q4 T2 b/* All rights reserved. */0 ]3 @' G4 K* o
/* */+ s( U5 U; e4 v9 q0 u" e
/* Email:pcwebmaster@163.com */1 ~. B5 r+ M! W4 K8 d. [
/****************************************************************************/
: \- L' Z: l: ~0 N- J/****************************************************************************/2 i! h' x8 \ h2 h1 a7 X
/* 文 件 名:comint.c */, B, S3 c G% {+ ?" l
/* 版 本:Version 1.0 */
7 K, g$ ~1 {, q$ f7 L/* 描 述:串行口中断带通讯协议测试 */% w. Y8 r5 @; f, q& {8 K
/* 主控芯片:NuMicro M0516*/
$ p7 ^ v' F6 s: f; ~$ j/* 晶振频率:11.0592MHz */) h- U+ p0 Y# R- G. I
/* 作 者:pcwebmaster(北极狼) */
" }8 A9 v* R( m* d. Q8 S8 M/* 函 数: */" X# U0 I2 E; o5 @# o$ l
/* system_init */" D: F6 Z/ ^' S
/* com_send_command *// ~ i; R3 S7 `3 R
/* com_command_receive*/! r) [! m# O, S- T+ K) b
/*CalCRC16_1021*/3 K+ W" m7 }4 W- y
/*command_decoder*/
0 f3 x N. b {/ O- a/*send_command*/: I) q* d/ k0 T: }
/* 测 试: 发送:16 16 02 01 02 01 00 35 03 94 BD接收:49 AA 15 */
7 D3 U) S7 T; J, k" h2 F/* 测试现象: */2 T$ R# h# X, v
/* 历史记录:20016.02.18测试通过 */- i, \, _0 z9 T& }/ ^
/* 北极狼 20016-02-18 Creat Inital version. (Version 1.0) */7 |: X" S2 a$ |- q4 ^- F0 k
/****************************************************************************/1 I4 F1 j9 ^/ z! n( ]
#include "comint.h"
' y/ U1 n0 A+ u8 s) l" |" @& Q5 g7 B
uint8_t pint_buf[MAX_RINTL]; /* 串口接收缓冲区 */2 f% N4 }8 g x/ _/ G- L) ^/ B
uint8_t pint_read; /* 串口缓冲区读指针 */7 o) m6 E9 [5 x H4 t$ F# A m
uint8_t pint_write; /* 串口缓冲区写指针 */4 E! R# n! G6 s2 G% |4 E" \8 h
uint8_t psend_int; /* 串口发送允许标志 */
: V& j r* }* y3 j9 ]uint8_t serial_flag = 0; /* 串口接收数据标志位 */
6 L$ M b% u& W& Y# B. B2 M& q6 Z: v# _: o( l/ l
- d; L/ B3 S' i& m$ x) |* X% yuint8_t prec_buf[MAX_COMMAND_LEN];/* 命令接收缓冲区 */! q* F* E" I2 A1 i7 F2 z" S% D6 j
uint8_t prec_num; /* 命令接收缓冲区字节数 */
; @" _6 E6 G$ [, f* X2 Q0 q
! A3 k: M2 F T1 }( \- ruint8_t serial_lengthl = 0; /* 消息命令长度低8位 */
7 Q2 G4 a7 }& }# x7 H/ s8 Zuint16_t serial_length = 0; /* 消息命令长度16位 */
! m2 `; ~$ k4 q" f$ G4 `# q) h
, p! G6 b; v" Y* n' E6 {5 fuint8_t ADDRESS[2]={ZU,ZHAN}; /* byte0:通讯组地址, byte1:开发板地址 */
. A6 G3 p/ {3 N+ g7 S; B9 y/ @& R, _* p2 e- @6 G' s
/* 串口发送一个字节 */
7 Z' `$ z6 F- @, v$ Uvoid com_send_command(uint16_t Data)
1 f B3 n) b$ x6 X{2 Z5 _+ n) h* l0 W: a0 O
UART0->THR = Data;5 e4 N N5 U% S; z. S& j, @4 i
while ((UART0->FSR&TX_EMPTY) != 0x00); //检查发送FIFO是否为空
' W! N7 e, x0 Z. X m}
' A: X* y% S: b0 B* G8 Z8 c8 m+ A5 \: L( ^8 F
/* 串口接收数据处理 */
7 N0 p4 }5 R" P8 Kvoid com_command_receive(void)
3 J- k9 E' m/ h4 b$ u9 h{
7 L* u2 ^1 V; u uint8_t var1,var4;
, q& R% |0 {3 w6 G uint16_t crc_data = 0;
9 C- a% v$ w6 G0 m+ Z var4 = pint_read;, b5 Y1 `! N, _& q. r
8 `) }% k: w+ Q7 b: Z
if (var4 != pint_write)
7 z7 ~) L+ m3 _. c2 Q8 m {
* I+ m" Y" H8 H1 K* m; M var1 = pint_buf[var4];- _# C4 p( j% h% k( y+ n; B
var4 = var4+1;
! k; F& Y7 }: j) z if (var4 >= MAX_RINTL)8 b. J$ J$ X& z/ D
var4=0; j1 D ^' u' s& m, v4 I0 M ?
: J" l# H( s& |* C- F3 [
pint_read = var4;( m$ Y! g2 f8 g9 N+ c( T7 P
2 o2 o3 M) N1 w; Q& S. E% W3 T- l- }
switch(serial_flag)
+ G5 p* t! C! P3 L4 m$ g- W {
% x7 d8 W: C+ `+ R; x case 0: /*收到起始位*/
0 [; Y/ i! D- N5 s/ a if (var1 == SYN)( d! c) a, P/ w. l) ~1 O4 N4 O
{' c% E! j8 r0 l1 G$ f/ ^* V( P
serial_flag = 1;
; b i5 M9 m3 `- O# }' n//com_send_command(0x01); //测试 \- Y# d. \9 C1 l7 P$ Q k7 |
}
8 @5 z, g! s3 e3 n( `1 E1 S0 M else
, e, b6 d& K: b2 s5 x {% n5 `' P+ B' o) {! u8 k1 a7 {* c
serial_flag = 0;
4 t9 M4 H1 G0 F9 E }+ Z1 G. P( `. w" e6 T' ]$ }: B5 u( j
break;
+ y6 U6 R* |* b: _
4 t9 H/ H3 p2 O* x case 1:/*收到起始位*/4 w3 r2 i& i) G& S, N
if (var1 == SYN)
- u/ z: W, X f3 \4 K2 F0 L# u {
* Y3 X: T' Z5 s3 C7 y6 C1 Y( ^ serial_flag = 2;, _/ ]0 Z( G2 u' N- U
//com_send_command(0x02); //测试+ \" M+ P0 `% f$ I
}$ Z" L2 ?# _7 s* J2 V- }! k
else9 e0 ^2 Y( E. \) U& T d( s
{
9 E4 D f/ t: F1 |5 @: O serial_flag = 0;
, B) i0 b' n* ~5 l1 t, h$ N$ C5 J }
6 I9 O5 f; A+ p& r) q: j' L; Y break;& E: f1 P2 H3 ~& D7 T
- W* x. D. K4 y1 o$ P
case 2:/*收到同步位*/
& j6 j- h0 f3 z' I& k if (var1 == STX)
4 h% Z0 P% _2 ?: F* R1 @ {
6 m0 E0 q! _; b0 w serial_flag = 3;" [1 x) a9 C4 T" F9 \
//com_send_command(0x03);//测试9 i$ q1 |" r0 P' S x3 k' y
}1 R- Q" b& P5 R$ a
else
2 C: L7 E$ H: X9 h1 G) F c {
* o. k, Y1 _7 O% L serial_flag = 0;5 x8 D) `7 Z3 M4 @
}2 p8 O$ s6 c* S: S) y( O" Z
break;
: h( ], r9 i, I: }7 S8 V# ~3 y, U) I
case 3: /*收到组地址*/
. v' w Y7 ?) m2 L6 r1 ` if (var1 == ADDRESS[0])
2 z1 I; s; p9 {. N9 a1 x {
4 D7 C" w9 }- x0 }' h4 x serial_flag = 4;
' S i: k6 q& A7 @% J" q prec_num = 1;5 b/ H4 B1 B/ ]' I" Z
prec_buf[0] = var1;
- M! }& F8 B. j& R g* @//com_send_command(0x04); //测试
# M* B* K' A( q! r5 c7 a& ~ }" P2 ]' ~% K: p7 q8 _
else
/ l7 s _7 n% m- q {% s$ a0 U% z* t L
serial_flag = 0;
& q" @* Q6 ?0 ]. e: \ }' v/ M- G& V' a' ^6 O2 s7 X: g9 b) V% u/ @
break;
/ u4 ]$ {: y: s1 D$ Y
7 ?: w, M3 Q1 `- b7 l, g6 z# i case 4:/*收到本机地址或者广播地址*/3 b/ q# @+ R0 Y/ H( ^/ t/ l
if ( (var1 == ADDRESS[1]) || (var1 == 0) )
) F8 v7 u1 C6 [, f c {7 l# |5 E& E3 q% U( ]! ?8 y; L
prec_num = 2;9 U" |2 t* L& _2 E/ D
prec_buf[1] = var1;, |2 q7 i2 H9 _1 X- s i& K; `
serial_flag = 5;4 d- s- _/ z6 Z, \4 ^( D% d
//com_send_command(0x05); //测试, Z( L5 g: t% [5 D
}/ W- ^ U' u+ J; O" ~, ^% i
else
5 Y. n% u: m3 h8 Y3 ~ {
% \3 @* ~+ N; L8 F9 t" y serial_flag = 0;9 N+ P. X- c# S/ k& c
}; ^/ V7 Y, m0 d ~% O/ u
break;' w6 ~7 D4 H' L# L9 d; Y
) Y2 P' \) C8 v) A7 Z( Y( H
case 5:/*数据长度*/" T# c! z- d! ~) S! a1 S" n& k
prec_num = 3;7 n8 ?3 R; T3 W2 O
prec_buf[2] = var1;
5 R, e9 x3 M( y serial_lengthl = var1;0 s. l2 R' V, E
serial_flag = 6;
( Q5 V/ |! h# G. x//com_send_command(0x06);//测试9 v% K9 N! Q, p9 K: D
break;: l7 ^, V8 u( ]& V
1 q1 m; v" X0 L
case 6:0 [3 J6 e8 Q! a+ M
prec_num = 4;& s* [4 S2 v7 p9 O
prec_buf[3] = var1;* [- O' u, C+ c+ R0 e
serial_length |= var1;
d" H8 N) m: f' g' W5 u1 d+ b! X, r serial_length = ( (serial_length << 8) & 0xff00 ) + serial_lengthl + 3;* e& I9 d* m& ~$ r
serial_flag = 7;4 k1 k" l3 |0 ~0 x# G
//com_send_command(0x07);//测试
+ W- G4 a& v7 X+ A; D break;
" u1 d' @. U- P0 `9 }9 }( e. p( D2 z L; S. }+ Q0 q2 }
case 7:
4 }3 {# Q6 ` A+ H4 J9 g+ b% \ C/ Z prec_buf[prec_num] = var1;$ V# K6 o7 }+ h# @
prec_num++;9 l" h& T& y2 e
serial_length--;9 f+ G' O" [6 d) k
if (serial_length == 0)& s- \* B% [* H, ?' K
{( b/ L- j( E1 `9 R7 A$ W
crc_data = CalCRC16_1021(prec_buf, prec_num - 2); /* 计算crc校验和(从组地址开始到ETX )*/
2 l3 ~0 t' t! S, E! g3 J0 h+ \: Y& U7 s X" M6 N
if ( ( (crc_data & 0x00ff) == prec_buf[prec_num - 2]) && ( ( (crc_data >>8) & 0x00ff) == prec_buf[prec_num - 1]) ) /* 校验和正确 */
& v! k3 ]5 ~; a# c! Q2 A8 P {& b8 p, w2 ~/ i( u8 ^' v8 G- V
prec_num = 1;
4 M; M& A) U5 J% z var1 = 0;/ q1 F" c$ X/ |$ }# m; J
0 B6 `! A0 A5 k: i& z. P
if ( (prec_buf[4] >= 0x31) && (prec_buf[4] <= 0x3b) ) /* 命令有效 */
( w7 Q! V D2 ^4 X+ q. p+ j {
8 O& X1 c, e: v7 h9 H if (prec_buf[1] != 0x00) /* 如果不是广播地址则回应ACK*/ I! n5 R. I' {' g+ [, b
com_send_command(0x49);//测试 msg_last_push(MSG_ACK,0);. [0 J: P* z1 i
//send_command(ACK); //测试
1 k3 J" S( Z* u6 F
1 t" g' _0 P/ v8 p- q7 I1 | w1 i command_decoder(); /* 如果校验和正确,则进行命令解码 */% C( w x- P. n" y. [' u3 |
}
6 P+ t& m- R& J' L6 I" O: v% v" d else
0 D" C8 v3 E" S& q {5 d$ l5 `& T5 }# K; v! b t* O' \3 ?% z
& q& z7 `# c: w6 E
send_command(NAK); //测试
: o$ L" D" o5 _ }
+ L+ a1 v$ S" `& r }
$ r0 x! Z" U/ m8 c/ ` else
: }% ]2 N# G( e: [ {
/ Q4 a' O+ X2 t2 d
, Q! O& J- r* Z. ksend_command(NAK); //测试
2 }- d3 U# E# S, D! z }9 v/ Q! H# F1 h/ i" X
serial_flag = 0;
2 [( X& |/ n0 g/ e1 G, K: U prec_num = 1;) m& n$ H: k J8 |0 S
}
3 `% x1 |/ n( p& \+ @ break;4 J1 K2 R/ x* P- ? O% n. h( }) ]8 s
& K# f1 j- b! e; a, C default:! F- y6 j' S, Y1 |# D J. I; E
serial_flag = 0;
; ?3 k o4 j2 ^( Q, R3 ~2 K* ~6 D9 t prec_num = 1;
. [$ E6 f8 z: J( ~% T# B; O break;! L* h/ y/ F2 a% } ^- U7 ?
}9 s* V+ u" k6 B7 T0 Q! c; L
}
# O+ k) m6 c/ }& w3 y- \}$ }; y$ X( C5 R1 i
/* 命令解码子程序 */
0 s$ n& X( P e7 m# d1 qvoid command_decoder(void)$ [( P) Q* |0 |2 y' B7 Z
{
/ ~% p# f4 }4 m* l4 @2 k5 D: y// uint8_t i = 0;
2 |& i8 a) _4 Y4 C9 b. c' V( n' q6 h% S) k, G% J7 U
if (prec_buf[4] == 0x31) /* 设置报警阈值 */
L9 A% c. d Q9 s7 H5 a' W; t$ G; H { - F, ?; e7 p: ]2 L
com_send_command(0x11);//测试
0 m% w/ h* U5 C5 `+ b2 ^9 t1 x R return;" B4 [( `- R" q. ], d
}
* Y) c1 a3 F# H0 W2 L else if (prec_buf[4] == 0x32) /* 请求报警阈值 */' I& O! a# {6 {! B4 E
{$ F' ?1 v0 }: F8 B' ^2 y4 b
com_send_command(0x12);//测试?+ G' G& r$ K+ ^4 m6 ^
return;1 a0 m' c( ?2 W. z+ m2 u0 C( x# b1 p& P
}
/ x R: M. S: ^+ y else if (prec_buf[4] == 0x33) /* 修改当前时间 */# p9 a* W' W7 V/ A' q
{" {) p7 t* b! A1 {7 `* n' A6 R
com_send_command(0x13);//测试- o- m& K b1 M1 o) E# g& g. M* ?
return;" ]% w8 S9 F& t
}/ p$ ^+ q- J. i& f( f
else if (prec_buf[4] == 0x34) /* 请求当前时间 */& J9 J5 u, b: K
{: t2 r5 o' {) U
com_send_command(0x14);//测试/ `% R _5 h8 d$ r' e% {- Z
return;5 s, w1 q$ T: I; ?( }0 H3 W) I3 _
}
4 o0 M. i6 V8 R4 d1 `, o! ^ else if (prec_buf[4] == 0x35) /* 请求当前数据 */3 T) q* @" B6 [6 W: W; ?3 e
{
0 b V1 m+ y6 d5 i# icom_send_command(0xAA);//测试
" T5 ^7 V" x% c& q, l4 f//__nop();
, V0 ~$ y$ e0 r7 @) H: vcom_send_command(0x15);//测试
* F( y& N: a% l9 E, b3 s& S/ w return;) j: X6 J7 f% l& `" L
}; y/ f) m- g& P6 ~, o
else if (prec_buf[4] == 0x36) /* 请求看门狗信息*/1 F- m- D2 `( Y9 F8 n
{
. O. C6 a* J+ @6 Wcom_send_command(0x16);//测试* B4 ~& A! ^# m' U/ |0 h
return;( y: Q8 X) y# e$ |* @
}
! P+ x P+ T6 }1 i8 k6 }2 u5 @7 b else if (prec_buf[4] == 0x37) /* 请求报警情况 */
' r. ` ~: L/ R3 Q1 I; y4 C0 C$ \ {
3 D; j/ Z/ d; x) pcom_send_command(0x17);//测试* m5 F. A2 z5 u4 b( t$ ]" ~7 R
return;" Q% o4 R& O: ] y$ }
}" U) |' g2 t4 o' K5 Z, h: b
else if (prec_buf[4] == 0x38) /* 配置设备地址 */* C' U6 E4 }% J! [6 l7 J6 s
{
# |* ~! x* g6 Q) t$ b7 z ADDRESS[0] = prec_buf[5]; /* 通讯组地址 */
$ k4 `( e- e' O& \5 i) G' T4 O ADDRESS[1] = prec_buf[6]; /* 开发板地址 */3 j! i5 I: z, ^2 N
com_send_command(0x181);//测试
: r/ P8 A) W, U# | return;/ u5 N# W0 I! L# X4 V2 X. e
}6 f* k0 a7 J! T+ }
else if (prec_buf[4] == 0x39) /* 请求设备地址 */& U% k6 F' ]$ g! p' d% F
{6 B8 U; g. \8 z5 r
com_send_command(0x19);//测试: d% G4 [7 S2 Z2 K% h# W
return;
o+ w# V9 F7 G }4 J. j) Z( n! r# \
else if (prec_buf[4] == 0x3a) /* 控制模拟量输出 */
@# e% W9 s* i, {9 F) N& C {# }4 n; O) T, [: ~/ k5 T
com_send_command(0x1A);//测试?
o, r1 k# W7 k. z g return;3 c+ n. m5 B+ Y7 j4 Q1 v
}
: s: t ? L; t" u" E) N' P% p else if (prec_buf[4] == 0x3b) /* 控制开关量输出 */
0 ~) p! z- z. K {
( g: g( |% N0 w8 H4 M+ ocom_send_command(0x1B);//测试( |7 p) ]2 F9 d7 {& J# {; d
return;) p2 C4 a6 |9 N+ \& O4 A: m' t5 X: l
}
8 O8 z% p$ m& T& L0 P) v2 `//if (prec_buf[4] == 0x00) /* 如果是广播地址 *// m7 K$ g! N" g' r* Q, S
// { * x. h5 G' l8 [: x" q
//com_send_command(SYN);. o9 [* f( R" n. |! F6 s
//com_send_command(0x00);. X( a) G( y$ K* C& {' n& D
//com_send_command(SYN);
5 u. f. P0 y6 Z: [! { F// return;
) c2 v! ^6 u& n3 w// }4 U' z+ E4 U$ N7 H+ B8 C4 F
}
+ W0 @' o& Z! j/ k/ Z
2 j0 o3 d2 G3 ~+ x2 @3 j/* 向PC主机发送消息帧,入口参数:消息类型 */; o3 g/ `- E# v+ s% [ R
void send_command(uint8_t command)
( F h: g, M `- e0 I6 J( I{+ o0 h/ d; e8 ~8 X& a7 T- I7 [" K
switch (command)
8 ]% f4 {3 s3 B3 G' _0 u" O3 ? {- Q: W, u3 M& o
case ACK:
( V+ }0 u& P$ I1 R8 ? com_send_command(SYN);- H& k7 e& z! y0 r
com_send_command(SYN);4 t; G+ B1 \3 H) D6 Q% Q2 @9 K# j
com_send_command(ACK);) ^, E$ P+ E5 Y/ F
break;
3 [' W) s) c2 j4 R+ O6 t1 ~
; X3 p$ S/ e5 E6 x4 z case NAK:
0 P9 n2 {/ C& A, X, [6 @ com_send_command(SYN);
, \1 o4 M" B# t5 l4 C com_send_command(SYN);
}, l- w2 R0 M$ U* [) x com_send_command(NAK);9 l9 Z! t i$ h; L
break;
. d- G0 w$ x) ?6 N/ ]5 [
" M' |) [0 Y6 I& Y u& ? default:
. J% f3 j ^ f @* Q3 x break;
3 O+ X$ E/ ^5 G8 ~8 v2 \ }% Q/ B) f& b5 I8 f; `
}6 j. c& J8 w) }5 M) Q& \
void buff_init(void)
) K# ]" P; I* o5 S& F{
3 m& H, y- {6 n! q) p% g uint8_t loop;
0 W; `; y6 K9 ~9 F2 A, K loop = UART0->RBR; /* 清串口缓冲区 */, H" E4 y& I1 \ X
for (loop=0; loop<MAX_RINTL; loop++)8 j3 k( V) \; e6 Q1 m
{
2 G8 G9 y) y. m" M1 f1 t/ X- S pint_buf[loop] = 0;* q# j9 `0 ~$ f$ h
}( y- H4 n( L6 ]8 y3 F
}
4 U3 S3 F o) n! p2 `: d9 Z/*计算CRC校验和使用MTT(0X1021)& q" @; V k/ X/ p4 P4 r+ i
参数:
& b: S' b6 t' z7 \1 G5 w1 MpBuff 为需计算CRC的缓冲区的头指针: h4 q+ I$ q: r9 m* l4 p6 G
BufferLen 缓冲区长度(以字节计)
, r$ b6 P1 \# J! U& i" m7 q5 R*/2 [4 m/ T( Q- u$ ?8 Z6 O
u_short CalCRC16_1021(uint8_t x[], u_short BufferLen)
; s {/ a( ?2 c! j/ h, c{' K: l! `" i8 |/ Y
u_short i;
0 N+ k4 m8 M- J& j' o3 ]" W \* h2 Y uint8_t j;- P, ?& ?- H+ R
u_short crc16 = 0;2 V2 k. G( q0 d% F8 m6 I: H; Z" U
u_short mask = 0x1021;
; K. t7 @% a( V: E* C: x uint8_t *pByteBuffer;0 E& w- D; q. Z- V7 E
uint8_t tmpbyte;8 S* j% s" }/ c( b
u_short calval;
$ p2 @0 G/ D/ F2 G+ `3 L% [9 R0 o& ? x$ I
pByteBuffer = &x[0];
5 o0 F# l0 M* `0 G: I. u% F& C
! b2 k4 I8 x" ? ]* g# q) B for (i = 0; i < BufferLen; i++): Z- T* P( W- i. B V4 p; l @
{& ~8 ?0 ^3 ?) \# c
tmpbyte = *pByteBuffer;
4 u& Z, W9 Z) o( M) A calval = tmpbyte << 8;9 P' i5 f' p/ z' v5 \
for (j = 0; j < 8; j++)
& Z& a7 E2 ^8 | k+ |" C3 W* S' K {
5 D# M( e0 u5 s C: T) b if ((crc16 ^ calval) & 0x8000)5 @ b E9 @ y$ M& M
crc16 = (crc16 << 1) ^ mask;
Q+ A. c7 V$ c9 j' P; }8 { { else0 W+ h) D0 d6 c
crc16 <<= 1;0 Z) s. w9 t: W, h
- h# j _ m- `% q8 O calval <<= 1;$ R; z f* Z* d
}7 t- _. d; z; v- r* q& U
pByteBuffer++;
3 G6 E3 s5 q6 s1 R }( g7 d0 v: d5 q( M$ E
return crc16;0 y+ k# `- }% [/ k4 _* k
}3 Y: ~* E5 A$ e2 x
4 _0 \& n! l$ M, f$ m/*---------------------------------------------------------------------------------------------------------*/
: m7 c1 Y+ ]( Q: U" p/* ISR to handle UART Channel 0 interrupt event */# P! w4 ~4 ]/ Z z
/*---------------------------------------------------------------------------------------------------------*/
5 B/ F) H' ?( k6 r |7 ?void UART0_IRQHandler(void)
5 H2 L7 j, Z& ]! a, n% X6 s{2 o# ]& U( g4 S. v0 j
uint8_t temp;
. g; Q0 X' {% {8 V& G+ M* P, p uint8_t temp1;
: L1 {4 `; {- O4 i9 B& r0 U
( P' R# h% a5 v' F8 M& A$ n# ?if(UART0->ISR & RDA_INT) //检查是否接收数据中断
Y+ y1 A% ~2 ?$ R* M5 E{
& x; `' D! v [5 X- H) @1 ]while(UART0->ISR & RDA_IF) //获取所有接收到的数据
. i- u5 h/ D$ F2 E; n{1 C0 ^6 T9 ?; U$ F# O
while (UART0->FSR & RX_EMPTY); //检查接收FIFO是否为空4 c0 V% X3 G0 S! r- H
temp1 = UART0->RBR; //读取数据
. X$ ^6 q# e" g9 p7 |temp = pint_write + 1; /* 判断是否可以写入 */
1 K; m5 }4 F( }0 uif (temp == MAX_RINTL)2 e" B7 {2 }1 J8 [/ y+ f
{
! M/ i3 k' Z& x! K! \! ^temp=0;3 S1 o. T# ~9 T4 E% D! s3 {' H' ~
}
) @% f" M& q3 C5 n# h; e9 Zif (temp != pint_read)
* I2 p: i/ H$ F$ M{: c; m* e0 g/ ~) a0 x( R0 T
pint_buf[pint_write] = temp1; /* 读取数据 */
0 q2 }- ~) x# s$ ^7 U2 E; jpint_write = temp;% f1 w. `1 k) _1 q6 D+ [; A) {+ @
}+ q$ m# |% X2 L- z2 P
}. E$ G6 l2 ~6 C7 y. m" y
}' R) w3 v6 }" @ V
}
j: A* F. T5 R7 L5 h2 u; K. q- Y& c% O" N' J" \- S
COMINT.h- Z0 G/ e& ?! }6 a! k
* t; Y* o5 X& }: t; P8 |/ N; n# ]
#ifndef __COMINT_H__
2 f7 c) C: a' @& m( j#define __COMINT_H__
" q: I# U0 u7 H% s8 k( D& h J. B, I! L* t! W B( i" B3 ~ X
#include <stdio.h>) v4 g4 }4 X9 ]$ F
#include "M051Series.h"" l8 i+ E8 e7 m) q0 \
7 [$ P9 }. |2 T! f+ D$ ~- G1 r* V#define RXBUFSIZE 8//1024
9 ~* ~$ y# ^: h$ [/ z9 c#define TX_EMPTY(1<<22)
! f( |6 G* u5 F D/ F' A8 Y#define RX_EMPTY(1<<14)
N5 O9 \0 T+ ?. P# Q#define RDA_INT(1<<8)! K y) J9 Z! \# N0 u, f9 p
#define RDA_IF(1<<0); s8 F7 g: G* g7 \' O0 @8 s
7 ^! p2 z6 l6 ~% A) k2 ctypedefunsigned shortu_short;2 j0 p- T! o3 s' q- w
" [$ C) X' F3 d0 u; C& R" M5 K
#define ZU0x01 /*组地址*///通讯地址修改这两项+ v3 N3 d9 a( Q' E
#define ZHAN0x02 /*站地址*///通讯地址修改这两项9 h2 u# v# x8 h$ l
4 E5 r. d m" R _( }. b
#define MAX_RINTL 16 /* 串口接收缓冲区长度 */
& f0 w7 q! X s% S ^#define SYN 0x16 /* 通讯同步位*/
) |; r0 Q' ~" k! Z: V; [+ W3 M+ J& e7 w#define STX 0x02 /* 通讯起始位*/
6 d) K( S9 k0 e4 E' ?1 k. O#define ETX 0x03 /* 通讯结束位*/
( N" j8 Y0 o) k- w% O( v
2 b8 J+ A1 k0 d* b# A) d2 `#define ACK 0x06
: u! E5 f* w; P: u% |6 V6 Z5 C#define NAK 0x15
# Z+ H m3 `2 e4 h! p) J! F0 U; ~& z! Y0 {" T6 `( E
#define MSG_ACK 2 /* 正确应答信息 */' A/ p! Q& o1 e$ P3 K
#define MSG_NAK 3 /* 错误应答信息 */$ o, D6 @$ G# P
#define MAX_COMMAND_LEN 16 /* 串口接受命令长度 */$ @) r. P, { o
7 |6 I" r3 i) Q: K6 b! M J L: i, N( h
extern char str_test[25] ;
1 c! Q( s" T- rextern uint8_t pint_read; // 串口缓冲区读指针 */, O! ]$ i+ T- Q# W
extern uint8_t pint_write; // 串口缓冲区写指针
2 s/ O; k/ d% p( a0 c: i9 a/ ?//extern uint8_t data psend_int; // 串口发送允许标志 * ~" R" r) i5 |4 }; \ }0 F+ @& Q
extern uint8_t pint_buf[MAX_RINTL]; // 串口接收缓冲区
. P/ r3 ^1 O3 B% I8 n P+ z( Uextern uint8_t serial_flag; /* 串口接收数据标志位 */
8 f+ i1 d8 ]3 M' h% ?, Z( r+ X% s- b; c( A
extern uint8_t prec_buf[MAX_COMMAND_LEN];/* 命令接收缓冲区 */
$ t7 t- _# V1 o+ @( S; _7 q# n. `" o, z) F. m, c4 ]
/* 串口发送一个字节 */
( T+ N# S) \0 {, zextern void com_send_command(uint16_t Data);
& |7 P6 H( f& z0 Z5 U/* 串口接收数据处理 */* x/ D1 i- K/ z4 \% j" [2 B
extern void com_command_receive(void);
& y. Z! w4 C0 ?/* 串口接收初始化 */
" a4 c/ a; ]3 w* Cextern void buff_init(void);
8 g8 i6 E, \) j( e, a, W( D' ~$ H$ L0 p: `1 e* [
///* 串口接收一字节数据 */
^ h, E, ] O6 }$ c, Z9 {) j# X' N//unsigned char UartReadChar(void); //reentrant8 X( N" g/ l5 L1 e+ \* w+ s
/*计算CRC校验和使用MTT(0X1021)
6 n& a0 @7 y3 Z7 I5 s* h8 \ L2 h参数:9 \" V# n$ I4 g/ q
pBuff 为需计算CRC的缓冲区的头指针
: ?" m- F% R: M1 ^8 s% L+ G2 @' u+ R$ l: ZBufferLen 缓冲区长度(以字节计)/ v) g. m3 g6 C; X# k2 b
*/
( j% g" |9 I6 n% ]" `2 Pu_short CalCRC16_1021(uint8_t x[], u_short BufferLen);8 Q, g. {% {8 n7 D( G1 U
# J7 f, T# i& S8 q* K& o7 o' h$ b* p- n0 ?/* 命令解码子程序 */
7 }* I* J3 o* J# p9 z, T4 V- uvoid command_decoder(void);
0 `" ]$ e1 Z6 c2 @. t1 V/* 向主机发送消息帧,入口参数:消息类型 */
9 d- y9 v* B( c* q7 }% Fvoid send_command(uint8_t command);6 K& K8 p! J4 X4 ^1 u0 e1 k1 @
( m9 `6 w" y# U& ^4 ~3 P#endif* U5 R8 @" Q% f0 `1 M, B
|
, F; {3 H" K* G, q
1 O# Z" _1 @) S7 T1 Z1 ~2 _' C$ \: Y5 _/ R
; Q( u3 y! g. ?. g. Z, m H( q9 x+ Q; [2 }$ V
|
, O9 T1 u* l. ?" [ | ) [4 P$ d/ T; X/ D6 u4 g8 r
|
|