////////////////////////////////////////////////////////////////////////// /// 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: /***************************************************************************** update by cc @201800400 针对多串口 和 单一串口 有区别 每个串口是独立的还是分开的有讲究 程序是复杂的还是软件应用简单是 个需要平衡的事情. clib/clib.c: 公用的函数 和硬件无关 放置串行模式(串口等其他通讯总线类的输出)输出的函数, 一些覆盖模式输出的(lcd等固屏输出的)的也可使用 void Lc_print(void (*L0pf_send_uc)(char ww), char *dat,...) ----------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------- msp/uartx.c 底层代码 和cpu相关 缓存发送也放在里面 L0_UART0_Init UART0_IRQHandler L0_Usend_uc------UserDef ----------------------------------------------------------------------------------------- ********************************************************************************/ #include "uart0.h" //#include "uart2.h" //#include "uart3.h" //#include "uart4.h" #include #include "../ctask/tick.h" #include "../app/common.h" #include "../msp/time.h" // TS_Handle_PH1 volatile s_uart0_rec; // TS_Handle_PH1A volatile s_uart0_rec; TS_Handle_PH4 volatile s_uart0_rec; ///struct _s_uart0_send_buf_ ts_uart_send_shop; //struct _s_uart0_send_buf_ ts_uart_send_depot; volatile Ts_uart_send_buf ts_uart_send_shop; ////volatile Ts_uart_send_buf ts_uart_send_depot; #if(MainFre_5M == D_sys_MainFre) void L0_uart0_init32K_290BPS(void) //290bps@32kHz {//定时器2 16位重载 作为串口波特率 SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 BITN_1(AUXR, BITN5);// f/2 T2L = 0xFE; //设定定时初值 T2H = 0xFF; //设定定时初值 /// 32K 280---290BPS AUXR |= 0x10; //启动定时器2 } #elif(MainFre_27M == D_sys_MainFre) #elif(MainFre_22M == D_sys_MainFre) #if(BRT_115200 == D_uart0_BRT) void L0_uart0_init(void) //115200bps@22.1184MHz {//定时器2 16位重载 作为串口波特率 SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR &= 0xFB; //定时器2时钟为Fosc/12,即12T T2L = 0xFC; //设定定时初值 T2H = 0xFF; //设定定时初值 AUXR |= 0x10; //启动定时器2 } #elif(BRT_4800 == D_uart0_BRT) void L0_Uart0_Init(void) //4800bps@22.1184MHz { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR |= 0x04; //定时器2时钟为Fosc,即1T T2L = 0x80; //设定定时初值 T2H = 0xFB; //设定定时初值 AUXR |= 0x10; //启动定时器2 } #elif(BRT_SIM == D_uart0_BRT) void L0_uart0_init(void) { SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */ TMOD |= 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */ TH1 = 221; /* TH1: reload value for 1200 baud @ 16MHz */ TR1 = 1; /* TR1: timer 1 run */ TI = 1; /* TI: set TI to send first char of UART */ EA = 1; AUXR = 0x40; // TI = 0; RI = 0; D_uart0_ES_INT(1); //打开串口中断 } #endif #else ///MainFre_11M #if(BRT_115200 == D_uart0_BRT && SBIT_1 == D_uart0_SBIT) void L0_uart0_init(void) //115200bps@11.0592MHz { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR &= 0xFB; //定时器2时钟为Fosc/12,即12T T2L = 0xFE; //设定定时初值 T2H = 0xFF; //设定定时初值 AUXR |= 0x10; //启动定时器2 } #elif(BRT_19200 == D_uart0_BRT && SBIT_1 == D_uart0_SBIT) void L0_uart0_init(void) //19200@11.0592MHz { xxxx SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR |= 0x04; //定时器2时钟为Fosc,即1T T2L = 0x70; //设定定时初值 T2H = 0xFF; //设定定时初值 AUXR |= 0x10; //启动定时器2 } #elif(BRT_19200 == D_uart0_BRT && SBIT_2 == D_uart0_SBIT) void L0_uart0_init(void) //19200@11.0592MHz { //使用第9位数据模拟1个停止位,可变波特率;SM2=0, TB8=1(第9bit总为1模拟1个停止位) SCON = 0xD8; AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR |= 0x04; //定时器2时钟为Fosc,即1T T2L = 0x70; //设定定时初值 T2H = 0xFF; //设定定时初值 AUXR |= 0x10; //启动定时器2 } #elif (BRT_9600 == D_uart0_BRT) void L0_uart0_init(void) //9600bps@11.0592MHz { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x01; //串口1选择定时器2为波特率发生器 AUXR &= 0xFB; //定时器2时钟为Fosc/12,即12T T2L = 0xE8; //设定定时初值 T2H = 0xFF; //设定定时初值 AUXR |= 0x10; //启动定时器2 } #endif #endif//D_sys_MainFre) void L1_uart0_buf_init(void) { /// ts_uart_send_depot.p = ts_uart_send_depot.buf; ts_uart_send_shop.now = 0; s_uart0_rec.head = 0; s_uart0_rec.ok = 0; s_uart0_rec.num = 0; // L1_s2b_PH4_init(&s_uart0_rec,G.p.slaver_id); // s_uart0_rec.sp = s_uart0_rec.buf; // s_uart0_rec.cmd = 0; // head_0 = D_CMD_Filter1_ff; // s_uart0_rec.head_1 = D_CMD_Filter2_fe; // s_uart0_rec.sp = (U8*)&(s_uart0_rec.ts_ccmodbus); L0_uart0_init(); // L0_uart0_init(); BITN_0(P3M1,BITN1);BITN_1(P3M0,BITN1);/// p31 01 tuiwan ts_uart_send_shop.ok = D_ready; D_uart0_ES_INT(1); //打开串口中断 } //115200 0.1ms /Byte 115200/4800=23 0.1*23=2.3ms /// 4800 uartb波形 2.1ms 一个数据 b8s 共10bits 1000ms 发送480个Bytes 大约就是2.1ms 一个数据 //// ````\_b_|___________________________/``s`|```2.1ms 0x00 sscom 测试 //// s 1 1 1 1 1 1 1 0 b11111111s //// ````\_b_/```````````````````````````|``s`|```200us 0xff //// ````\_b_|__/```\__/```\__/```\__/```|``s`|```1.9ms`\0xaa //// b 1 0 1 0 1 0 1 0 b10101010s //// //// ````\_b_|__/```\__/```\__/```\__/```|``s`|```1.9ms`\0xaa //// b 1 0 1 0 1 0 1 0 b10101010s /// 1.9ms`\0xaa 0xaa 0xaa //// ````\_b_|__/```\__/```\__/```\__/```|``s`|\_b_|__/```\__/```\__/```\__/```|``s`|\_b_|__/```\__/```\__/```\__/```|``s`| //// b 1 0 1 0 1 0 1 0 s b 1 0 1 0 1 0 1 0 s b 1 0 1 0 1 0 1 0 s //// ````\_200us_/`````0xff //// ````\_200us_/`````0xff void L0_uart0_uc(U8 ww) { L0_uart0_sendArray(&ww,1); } extern void L2_waitFree_uart0(void); #define D_waitFree_uart0() L2_waitFree_uart0() /********* while(ts_uart_send_shop.ok != D_ready)\ {\ if(ts_uart_send_shop.over ++ > 600000)\ {\ break;\ }\ }\ *********************/ void L0_uart0_us(vU32 ww) { U_U16 uStemp; uStemp.word = ww; L0_uart0_uc(uStemp.BYTE2.h); L0_uart0_uc(uStemp.BYTE2.l); } void L0_uart0_ul(vU32 ww) { L0_uart0_uc(ww >> 24 & 0xFF); L0_uart0_uc(ww >> 16 & 0xFF); L0_uart0_uc(ww >> 8 & 0xFF); L0_uart0_uc(ww >> 0 & 0xFF); } void L0_uart0_uchex(U8 ww) { D_waitFree_uart0(); ts_uart_send_shop.buf3[0] = cguHex2Char[D_uc_high(ww)][1]; ts_uart_send_shop.buf3[1] = cguHex2Char[D_uc_low(ww)][1]; L0_uart0_sendArray(ts_uart_send_shop.buf3,2); } // void L0_uart0_ushex(U16 ww) // { // L0_uart0_uchex(ww >> 8 & 0xFF); // L0_uart0_uchex(ww >> 0 & 0xFF); // } void L0_uart0_ulhex(U32 ww) { L0_uart0_uchex(ww >> 24 & 0xFF); L0_uart0_uchex(ww >> 16 & 0xFF); L0_uart0_uchex(ww >> 8 & 0xFF); L0_uart0_uchex(ww >> 0 & 0xFF); } void L0_uart0_uldec(U32 ww) { L0_uart0_uc(ww / 1000000 % 10 + '0'); L0_uart0_uc(ww / 100000 % 10 + '0'); L0_uart0_uc(ww / 10000 % 10 + '0'); L0_uart0_uc(ww / 1000 % 10 + '0'); L0_uart0_uc(ww / 100 % 10 + '0'); L0_uart0_uc(ww / 10 % 10 + '0'); L0_uart0_uc(ww / 1 % 10 + '0'); } /********** void L0_uart0_uc_debug(U8 ww) { L0_uart0_sendArray(&ww,1); while(0 != ts_uart_send_shop.now){} } void L0_uart0_ushex(vU16 ww,U8 hex) { U8 buf3[4]; U_F16 k; k.us = ww; if(16 == hex ) { buf3[0] = cguHex2Char[D_uc_high(k.BYTE2.H)][1]; buf3[1] = cguHex2Char[D_uc_low(k.BYTE2.H)][1]; buf3[2] = cguHex2Char[D_uc_high(k.BYTE2.L)][1]; buf3[3] = cguHex2Char[D_uc_low(k.BYTE2.L)][1]; L0_uart0_sendArray(buf3,4); }else if(2 == hex) { buf3[0] = (k.BYTE2.H); buf3[1] = (k.BYTE2.L); L0_uart0_sendArray(buf3,2); }else { buf3[0] = 0x55; buf3[1] = 0x66; L0_uart0_sendArray(buf3,2); } } k.us = 0x1234 uc [0]=0x12 [1]=0x34 byte2 H=0x12 L=0x34 **********/ void L0_uart0_ushex(vU16 ww,U8 hex) { U_F16 k; k.us = ww; D_waitFree_uart0(); if(16 == hex ) { ts_uart_send_shop.buf3[0] = cguHex2Char[D_uc_high(k.BYTE2.H)][1]; ts_uart_send_shop.buf3[1] = cguHex2Char[D_uc_low(k.BYTE2.H)][1]; ts_uart_send_shop.buf3[2] = cguHex2Char[D_uc_high(k.BYTE2.L)][1]; ts_uart_send_shop.buf3[3] = cguHex2Char[D_uc_low(k.BYTE2.L)][1]; L0_uart0_sendArray(ts_uart_send_shop.buf3,4); } /**************** else if(2 == hex) { ts_uart_send_shop.buf3[0] = (k.BYTE2.H); ts_uart_send_shop.buf3[1] = (k.BYTE2.L); L0_uart0_sendArray(ts_uart_send_shop.buf3,2); }else { ts_uart_send_shop.buf3[0] = 0x55; ts_uart_send_shop.buf3[1] = 0x66; L0_uart0_sendArray(ts_uart_send_shop.buf3,2); } */ } void L2_waitFree_uart0(void) { while(ts_uart_send_shop.ok != D_ready) { if(ts_uart_send_shop.over ++ > 600000) { break; } } } void L0_uart0_sendArray(U8 *buf,U16 len) { //D_485_TX(); //切换到输出状态 D_waitFree_uart0(); // P31 = 1; ts_uart_send_shop.over = 0; ts_uart_send_shop.p = buf; ts_uart_send_shop.max = len; ts_uart_send_shop.now = 1; ts_uart_send_shop.ok = D_clear; L0_uart0_set(ts_uart_send_shop.p[0]); } /************************************************* UART 中断 *************************************************/ void INTERRUPT_UART(void) interrupt D_SERVE_UART// using 2 { NOP(); NOP(); NOP(); if(L0_uart0_IntRI()) //如果是U0接收中断 { L0_uart0_IntRIClear(); //清除接收中断标志 //s_nos_tick.tp_count = 0; L0_timer1_reset(); s_uart0_rec.reg = L0_uart0_get(); L1_s2b_PH4(&s_uart0_rec); } if(L0_uart0_IntTI()) //如果是U0发送中断 { L0_uart0_IntTIClear(); //清除发送中断标志 if(ts_uart_send_shop.max != ts_uart_send_shop.now) { L0_uart0_set(ts_uart_send_shop.p[ts_uart_send_shop.now]); ts_uart_send_shop.now ++; } else { ts_uart_send_shop.ok = D_ready; ts_uart_send_shop.max = 0; ts_uart_send_shop.now = 0;//可以发送下一个数据 // P31 = 0; //切换到接收状态 //D_485_RX(); } } else { //其他中断 } NOP(); NOP(); NOP(); } #if 1 void timer1_isrHanddle (void) interrupt D_ISR_timer1 {// TF1 = 0; //s_nos_tick.uart0_free = 1; if(s_uart0_rec.head == 1) //收到一条协议 { s_uart0_rec.head = 0; P10 ^= 1; if(s_uart0_rec.ok == 0) { s_uart0_rec.ok = 1; //Lc_buf_copy_uc(); } } } #else void timer1_isrHanddle (void) interrupt D_ISR_timer1 {// TF1 = 0; //s_nos_tick.uart0_free = 1; if(s_uart0_rec.head == 1) //收到一条协议 { s_uart0_rec.head = 0; s_uart0_rec.ok = 1; L3_task_uart0_modbus_handler(&s_uart0_rec); } } #endif