salon 发表于 2020-7-26 20:44:21

请问几个串口的波特率一样,可以用同一个定时器做波特率发生器吗?

请问几个串口的波特率一样,可以用同一个定时器做波特率发生器吗?
如果可以,这部分代码要怎么改呀?
void UartInit()
{
    SCON = 0x50;
    T2L = BRT;
    T2H = BRT >> 8;
    AUXR = 0x15;
    wptr = 0x00;
    rptr = 0x00;
    busy = 0;
}
void Uart2Init() ;void Uart3Init()    ; void Uart4Init();

XTXB 发表于 2020-7-26 21:15:46

同时使用不可以,一个串口占一个定时器。分时复用应该可以。

wye11083 发表于 2020-7-26 23:23:49

XTXB 发表于 2020-7-26 21:15
同时使用不可以,一个串口占一个定时器。分时复用应该可以。

stc的串口我记得是可以的,是4t时序。

XTXB 发表于 2020-7-27 09:20:00

本帖最后由 XTXB 于 2020-7-27 09:50 编辑

wye11083 发表于 2020-7-26 23:23
stc的串口我记得是可以的,是4t时序。

谢谢!试了一下,确实是可以的,之前我太想当然了。

国学芯用 发表于 2020-7-27 09:25:10

可以的

wye11083 发表于 2020-7-27 09:41:37

国学芯用 发表于 2020-7-27 09:25
可以的

话说24mhz下用keil默认中断服务入口完整一次中断服务大概要多少us?假设服务里面就对一个32位数自增操作。

salon 发表于 2020-7-27 13:37:14

谢谢{:loveliness:}{:loveliness:}{:loveliness:}

modbus 发表于 2020-7-27 13:43:40

wye11083 发表于 2020-7-27 09:41
话说24mhz下用keil默认中断服务入口完整一次中断服务大概要多少us?假设服务里面就对一个32位数自增操作 ...

从响应中断到中断返回应该要25个时钟周期

小李非刀 发表于 2020-7-27 22:06:18

没问题,STC15系列或STC8系列有多串口的,均可使用定时器2做波特率,只要波特率相等。

armok. 发表于 2020-8-3 11:38:26

打赏!

庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏
https://www.amobbs.com/thread-5735948-1-1.html

salon 发表于 2020-8-3 18:41:06

armok. 发表于 2020-8-3 11:38
打赏!

庆祝论坛“打赏”功能实施, 现在开始发技术主题,可以获得打赏


谢谢老大{:shy:}

jswd2420 发表于 2022-2-7 20:53:40

国学芯用 发表于 2020-7-27 09:25
可以的

请问版主有没有4个串口DMA同时收发的例程?

yyts 发表于 2022-2-7 21:15:26

jswd2420 发表于 2022-2-7 20:53
请问版主有没有4个串口DMA同时收发的例程?

STC有dma吗?

jswd2420 发表于 2022-2-7 21:43:17

yyts 发表于 2022-2-7 21:15
STC有dma吗?

STC8AK?D4的有,现在8H的也有了

jiki911 发表于 2022-2-8 09:48:31

好久不用51了,正常情况下,波特率不同是不能用的,必须分啊开。

小李非刀 发表于 2022-2-8 16:50:24

jswd2420 发表于 2022-2-7 20:53
请问版主有没有4个串口DMA同时收发的例程?

请到STC官网下载DMA例程。www.stcmcudata.com

jswd2420 发表于 2022-2-8 20:32:39

小李非刀 发表于 2022-2-8 16:50
请到STC官网下载DMA例程。www.stcmcudata.com

版主,官网的程序我下载下来了,那个例程是单个串口的DMA,我现在单个的可以正常通讯了,多个串口的DMA有点问题

国学芯用 发表于 2022-2-10 10:35:52

请参考这个

小李非刀 发表于 2022-2-10 10:56:50

jswd2420 发表于 2022-2-8 20:32
版主,官网的程序我下载下来了,那个例程是单个串口的DMA,我现在单个的可以正常通讯了,多个串口的DMA有 ...

多个串口的,程序要协调一下。

jswd2420 发表于 2022-2-11 15:49:18

国学芯用 发表于 2022-2-10 10:35
请参考这个

谢谢版主!

huangyu_ninbo 发表于 2022-2-16 14:24:51

国学芯用 发表于 2020-7-27 09:25
可以的
(引用自5楼)

里面的源码,4个uart初始化程序,貌似不对啊。不是公用一个定时器2的。 要是同时用的话,波特率要一样的吧。

主程序:

/*********************************************************/
#define MAIN_Fosc                24000000L      //定义主时钟

#include      "STC8xxxx.H"


/*************      功能说明      **************

4串口全双工中断方式收发通讯程序。

通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回.

默认参数:
所有设置均为 1位起始位, 8位数据位, 1位停止位, 无校验.
每个串口可以使用不同的波特率.
串口1(P3.0 P3.1): 115200bps.
串口2(P1.0 P1.1):57600bps.
串口3(P0.0 P0.1):38400bps.
串口4(P0.2 P0.3):19200bps.


******************************************/

/*************      本地常量声明      **************/
#define      RX1_Length      128                /* 接收缓冲长度 */
#define      RX2_Length      128                /* 接收缓冲长度 */
#define      RX3_Length      128                /* 接收缓冲长度 */
#define      RX4_Length      128                /* 接收缓冲长度 */

#define      UART_BaudRate1      115200UL         /* 波特率 */
#define      UART_BaudRate2         57600UL         /* 波特率 */
#define      UART_BaudRate3         38400UL         /* 波特率 */
#define      UART_BaudRate4         19200UL         /* 波特率 */


/*************      本地变量声明      **************/
u8      xdata      RX1_Buffer;      //接收缓冲
u8      xdata      RX2_Buffer;      //接收缓冲
u8      xdata      RX3_Buffer;      //接收缓冲
u8      xdata      RX4_Buffer;      //接收缓冲

u8      TX1_read,RX1_write;      //读写索引(指针).
u8      TX2_read,RX2_write;      //读写索引(指针).
u8      TX3_read,RX3_write;      //读写索引(指针).
u8      TX4_read,RX4_write;      //读写索引(指针).

bit      B_TX1_Busy,B_TX2_Busy,B_TX3_Busy,B_TX4_Busy;      // 发送忙标志


/*************      本地函数声明      **************/
void      UART1_config(u8 brt);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
void      UART2_config(u8 brt);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
void      UART3_config(u8 brt);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
void      UART4_config(u8 brt);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
void         PrintString1(u8 *puts);
void         PrintString2(u8 *puts);
void         PrintString3(u8 *puts);
void         PrintString4(u8 *puts);




//========================================================================
// 函数: void main(void)
// 描述: 主函数
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void main(void)
{
      EAXRAM();

      UART1_config(1);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
      UART2_config(2);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
      UART3_config(3);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
      UART4_config(4);      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
      
      EA = 1;

      PrintString1("STC8 serial USART1 Test Prgramme!\r\n");
      PrintString2("STC8 serial USART2 Test Prgramme!\r\n");
      PrintString3("STC8 serial USART3 Test Prgramme!\r\n");
      PrintString4("STC8 serial USART4 Test Prgramme!\r\n");

......
}


//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void      SetTimer2Baudraye(u16 dat)      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
      AUXR &= ~(1<<4);      //Timer stop
      AUXR &= ~(1<<3);      //Timer2 set As Timer
      AUXR |=(1<<2);      //Timer2 set as 1T mode
      T2H = dat / 256;
      T2L = dat % 256;
      IE2&= ~(1<<2);      //禁止中断
      AUXR |=(1<<4);      //Timer run enable
}


//========================================================================
// 函数: void      UART1_config(u8 brt)
// 描述: UART1初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void      UART1_config(u8 brt)      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
      u8      i;
      /*********** 波特率使用定时器2 *****************/
      if(brt == 2)
      {
                AUXR |= 0x01;                //S1 BRT Use Timer2;
                SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate1);
      }

      /*********** 波特率使用定时器1 *****************/
      else
      {
                TR1 = 0;
                AUXR &= ~0x01;                //S1 BRT Use Timer1;
                AUXR |=(1<<6);      //Timer1 set as 1T mode
                TMOD &= ~(1<<6);      //Timer1 set As Timer
                TMOD &= ~0x30;                //Timer1_16bitAutoReload;
                TH1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) / 256;
                TL1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) % 256;
                ET1 = 0;      //禁止中断
      //      INT_CLKO &= ~0x02;      //不输出时钟
                INT_CLKO |=0x02;      //输出时钟
                TR1= 1;
      }
      /*************************************************/

      SCON = (SCON & 0x3f) | (1<<6);      // 8位数据, 1位起始位, 1位停止位, 无校验
//      PS= 1;      //高优先级中断
      ES= 1;      //允许中断
      REN = 1;      //允许接收
      P_SW1 = P_SW1 & 0x3f;                              P3n_push_pull(0x02);      //切换到 P3.0 P3.1
//      P_SW1 = (P_SW1 & 0x3f) | (1<<6);      P3n_push_pull(0x80);      //切换到P3.6 P3.7
//      P_SW1 = (P_SW1 & 0x3f) | (2<<6);      P1n_push_pull(0x80);      //切换到P1.6 P1.7 (必须使用内部时钟)

      for(i=0; i<RX1_Length; i++)                RX1_Buffer = 0;
      B_TX1_Busy= 0;
      TX1_read    = 0;
      RX1_write   = 0;
}


//========================================================================
// 函数: void      UART2_config(u8 brt)
// 描述: UART2初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void      UART2_config(u8 brt)      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
{
      u8      i;
      /*********** 波特率固定使用定时器2 *****************/
      if(brt == 2)      SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate2);

      S2CON &= ~(1<<7);      // 8位数据, 1位起始位, 1位停止位, 无校验
      IE2   |= 1;                        //允许中断
      S2CON |= (1<<4);      //允许接收
      P_SW2 &= ~1;      P1n_push_pull(0x02);      //切换到 P1.0 P1.1
//      P_SW2 |= 1;                P4n_push_pull(0x80);      //切换到 P4.6 P4.7

      for(i=0; i<RX2_Length; i++)                RX2_Buffer = 0;
      B_TX2_Busy= 0;
      TX2_read    = 0;
      RX2_write   = 0;
}

//========================================================================
// 函数: void      UART3_config(u8 brt)
// 描述: UART3初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void      UART3_config(u8 brt)      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
{
      u8      i;
      /*********** 波特率固定使用定时器2 *****************/
      if(brt == 2)
      {
                S3CON &= ~(1<<6);      //BRT select Timer2
                SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate3);
      }
      /*********** 波特率使用定时器3 *****************/
      else
      {
                S3CON |= (1<<6);      //BRT select Timer3
                T4T3M &= 0xf0;                //停止计数, 清除控制位
                IE2&= ~(1<<5);      //禁止中断
                T4T3M |=(1<<1);      //1T
                T4T3M &= ~(1<<2);      //定时
                T4T3M &= ~1;                //不输出时钟
                T3H = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate3) / 256;
                T3L = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate3) % 256;
                T4T3M |=(1<<3);      //开始运行
      }
      
      S3CON &= ~(1<<5);      //禁止多机通讯方式
      S3CON &= ~(1<<7);      // 8位数据, 1位起始位, 1位停止位, 无校验
      IE2   |=(1<<3);      //允许中断
      S3CON |=(1<<4);      //允许接收
      P_SW2 &= ~2;      P0n_push_pull(0x02);      //切换到 P0.0 P0.1
//      P_SW2 |= 2;                P5n_push_pull(0x02);      //切换到 P5.0 P5.1

      for(i=0; i<RX3_Length; i++)                RX3_Buffer = 0;
      B_TX3_Busy= 0;
      TX3_read    = 0;
      RX3_write   = 0;
}

//========================================================================
// 函数: void      UART4_config(u8 brt)
// 描述: UART4初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2016-4-28
// 备注:
//========================================================================
void      UART4_config(u8 brt)      // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
{
      u8      i;
      /*********** 波特率固定使用定时器2 *****************/
      if(brt == 2)
      {
                S4CON &= ~(1<<6);      //BRT select Timer2
                SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate4);
      }
      /*********** 波特率使用定时器3 *****************/
      else
      {
                S4CON |= (1<<6);      //BRT select Timer4
                T4T3M &= 0x0f;                //停止计数, 清除控制位
                IE2   &= ~(1<<6);      //禁止中断
                T4T3M |=(1<<5);      //1T
                T4T3M &= ~(1<<6);      //定时
                T4T3M &= ~(1<<4);      //不输出时钟
                T4H = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate4) / 256;
                T4L = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate4) % 256;
                T4T3M |=(1<<7);      //开始运行
      }
      
      S4CON &= ~(1<<5);      //禁止多机通讯方式
      S4CON &= ~(1<<7);      // 8位数据, 1位起始位, 1位停止位, 无校验
      IE2   |=(1<<4);      //允许中断
      S4CON |=(1<<4);      //允许接收
      P_SW2 &= ~4;      P0n_push_pull(0x08);      //切换到 P0.2 P0.3
//      P_SW2 |= 4;                P5n_push_pull(0x08);      //切换到 P5.2 P5.3

      for(i=0; i<RX4_Length; i++)                RX4_Buffer = 0;
      B_TX4_Busy= 0;
      TX4_read    = 0;
      RX4_write   = 0;
}


页: [1]
查看完整版本: 请问几个串口的波特率一样,可以用同一个定时器做波特率发生器吗?