////////////////////////////////////////////////////////////////////////// /// COPYRIGHT NOTICE /// Copyright (c) 2015, 传控科技 /// All rights reserved. /// /// @file main.c /// @brief main app /// ///(本文件实现的功能的详述) /// /// @version 1.1 CCsens technology /// @author CC /// @date 20150102 /// /// /// 修订说明:最初版本 /// Modified by: /// Modified date: /// Version: /// Descriptions: // 20160413 CC-ACC-VH02 // 连接至 J22 RXD0 TXD0 //P5_DIR &= ~BITN1; //p5.1输出TXD //P5_DIR |= BITN0; //p5.0输入RXD //P5_SEL0 &= ~(BITN0 +BITN1); //设置P5.0 P5.1为UART0 RXD TXD //P5_SEL1 |= BITN0 +BITN1; /***************************************************************************** update by cc @201700110 针对多串口 和 单一串口 有区别 每个串口是独立的还是分开的有讲究 程序是复杂的还是软件应用简单是 个需要平衡的事情. clib/clib.c: 公用的函数 和硬件无关 放置串行模式(串口等其他通讯总线类的输出)输出的函数, 一些覆盖模式输出的(lcd等固屏输出的)的也可使用 void Lc_print(void (*L0pf_send_uc)(char ww), char *dat,...) ----------------------------------------------------------------------------------------- uartcom/Uprotocol2app 协议到应用 为了适应不同的通讯协议需要不同的uart口来对应 和应用相关 typedef struct _ts_lcm_pro_; 应用协议包的定义? LCM的协议------------ L3_UARTcom0_exp_protocol 解析应用协议 ----------------------------------------------------------------------------------------- uartcom/urec2protocol: 接收到的数据放入到指向特定协议的缓存中,和协议的格式有关 一般分为 标头式或者标尾式 公用的串口通讯定义 struct _s_uart_rec_ 的公共协议包(关键的结构体)的声明------struct _s_uart_rec_ void L1_uart_2buf(struct _s_uart_rec_ *p)串行数据保存到指向特定协议的缓冲中 -------------------------------------------------------------------------------------------- msp/uartx.c 底层代码 和cpu相关 缓存发送也放在里面 L0_UART0_Init UART0_IRQHandler L0_Usend_uc------UserDef ----------------------------------------------------------------------------------------- ********************************************************************************/ #include "uart2.h" #include "../bsp/bsp_485.h" #include "../app/app_common.h" struct _s_uart2_send_buf_ s_uart2_send_shop; struct _s_uart2_send_buf_ s_uart2_send_depot; #define FOSC 11059200L //系统频率 //#define BAUD2 4800 //串口波特率 //#define BAUD2 9600 //串口波特率 #define BAUD2 115200 //串口波特率 void L0_uart2_init(void) { S2CON = 0x50; //8位数据,可变波特率 AUXR |= 0x04; //定时器2时钟为Fosc,即1T T2L = 0xE8; //设定定时初值 T2H = 0xFF; //设定定时初值 AUXR |= 0x10; //启动定时器2 //设置txd2为强推挽 BITN_1(P1M0,BITN1); BITN_0(P1M1,BITN1);//P11 //对于433模块,CPU可以控制的情况下需要拉低(PWDN), //如果不能控制需要人为短路 D_uart2_ES_INT_OPEN(); //打开串口中断 } void L1_uart2_buf_init(void) { s_uart2_send_depot.p = s_uart2_send_depot.buf; s_uart2_send_shop.now = 0; L0_uart2_init(); } void L0_uart2_uc(U8 ww) { s_uart2_send_depot.max = 1; s_uart2_send_depot.buf[0] = ww; s_uart2_send_depot.p = s_uart2_send_depot.buf; L0_uart2_sendbuf(); } void L0_uart2_sendstr(U8 *str) { //L0_uart2_sendbuf(str,strlen(str)); s_uart2_send_depot.max = strlen(str); s_uart2_send_depot.p = str; L0_uart2_sendbuf(); } void L0_uart2_sendArray(void *buf,U8 len) { D_485_TX(); //切换到输出状态 //L0_uart2_sendbuf(str,strlen(str)); s_uart2_send_depot.max = len; s_uart2_send_depot.p = buf; L0_uart2_sendbuf(); } // 发送buf数组 中的0----(num-1) void L0_uart2_sendbuf(void) { register unsigned char n = 0; if(s_uart2_send_depot.max >= D_send2_buf_max) { s_uart2_send_depot.max = 3; } D_uart2_ES_INT_CLOSE(); if(0 == s_uart2_send_shop.now) {/// 上次的已经发送完毕了,或者第一次开始 /// (s_uart2_send_shop.now == s_uart2_send_shop.max = 0 buf中为空) for(n = 0;n < s_uart2_send_depot.max; n++) { s_uart2_send_shop.buf[n] = s_uart2_send_depot.p[n]; } s_uart2_send_shop.max = s_uart2_send_depot.max; L0_uart2_IntTIClear(); s_uart2_send_shop.now = 1; L0_uart2_set(s_uart2_send_shop.buf[0]); }else {// 需要插入 /// [0]--?--[pool.now]--?--[pool.max-1]....................................... /// [0]--?--[pool.now]--?--[pool.max]+[bath.0]--?---[bath.max-1]............. for(n = 0;n < s_uart2_send_depot.max; n++) { s_uart2_send_shop.buf[s_uart2_send_shop.max] = s_uart2_send_depot.p[n]; s_uart2_send_shop.max ++; if(s_uart2_send_shop.max >= D_send2_buf_max) { s_uart2_send_shop.max = D_send2_buf_max; } } } D_uart2_ES_INT_OPEN(); } /************************************************* UART 中断 *************************************************/ #define D_SERVE_uart2 interrupt 8 void INTERRUPT_uart2(void) D_SERVE_uart2// using 2 { D_uart2_ES_INT_CLOSE(); //------------------------------------------------ if(L0_uart2_IntRI()) //如果是U0接收中断 {L0_uart2_IntRIClear(); //清除接收中断标志 //UART0_PUTCHAR('%'); //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>用户程序 添加协议>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /// input: 解析协议函数 和对应的结构体变量 /// output: 对应的结构体变量中携带 缓存buf和协议ok的标志 //s_uart2_rec.reg = L0_uart2_get(); //s_uart2_rec.ok = 1; G.modbusstmp = s_nos_tick.t_5ms; (*Lp0_uart2_fun)(L0_uart2_get()); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } //------------------------------------------------ else { if(L0_uart2_IntTI()) //如果是U0发送中断 { L0_uart2_IntTIClear(); //清除发送中断标志 #if 1 //433焊反 txd2->rxd2短路,暂时禁止发送数据,以免冲突 if(s_uart2_send_shop.max != s_uart2_send_shop.now) { L0_uart2_set(s_uart2_send_shop.buf[s_uart2_send_shop.now]); s_uart2_send_shop.now ++; }else { s_uart2_send_shop.max = 0; s_uart2_send_shop.now = 0;//可以发送下一个数据 D_485_RX(); } #endif } } D_uart2_ES_INT_OPEN(); } void timer0_isrHanddle (void) interrupt 1 { NOP(); TF0 = 0; //modbus协议处理 if(s_uart2_rec.head == 1 && G.modbusstmp - s_nos_tick.t_5ms >= 1) //收到一条协议 { s_uart2_rec.head = 0; crc16_irq(s_uart2_rec.crc,s_uart2_rec.buf,s_uart2_rec.num - 2); if(s_uart2_rec.crc[0] == s_uart2_rec.buf[s_uart2_rec.num-2] && s_uart2_rec.crc[1] == s_uart2_rec.buf[s_uart2_rec.num-1]) { if(s_uart2_rec.ok == 0) { s_uart2_rec.ok = 1; } //D_P32_REV(); } } //tick处理 #if 0 /// 65535*65535 /3600/24/365=139nian/s=1.39nian/10ms ///相当于1.39年后t_10ms 溢出,对于电池供电的系统而言 完全可以满足 // 4,294,836,225 = 65535*65535 ;3600*24*60*60 = 31,536,000秒/年 s_nos_tick.t_10ms ++;//D_led_D1_REV(); 20160522 验证 #else L1_tick_tick(); ///系统中的1sflag 和以10ms为颗粒的延时使用 为tdelay服务 #endif NOP(); }