N76E003包含两个具备增强的自动地址识别和帧错误检测功能的全双工串口。由于两个串口的控制位是一样的,为了区分两个串口控制位,串口1的控制位以“_1”结尾(例如SCON_1)。下述详例以串口0为例。
每个串口都有一种同步工作模式:模式0。三种全双工异步模式:模式1,2,和3,这意味着收发可以同时连续进行。串口接收带有接收缓存,意味着在接收的前一个数据在被读取之前,串口就能接收第二个数据。接收和发送都是对SBUF进行操作访问,写入SBUF数据将直接传到发送寄存器,而读取SBUF是访问一个具有独立物理地址的接收寄存器。串口共有4种操作模式,任何一种模式,任何以操作SBUF的指令都将开始一次传输。注意,在使用串口功能前,串口所用管脚P0.7及 P0.6 (RXD 及 TXD引脚) 或者 P0.2及 P1.6 (RXD_1 及 TXD_1)必须先置1。N76E003提供更灵活的管脚配置,可将串口0的TXD及RXD通过UART0PX (AUXR1.2)更改位置。

13.1 模式 0
模式0是与外部设备进行同步通信的方式。在该模式下,串行数据由RXD脚进行收发,而TXD 脚用于产生移位时钟。这种方式下是以半双工的形式进行通信,每帧接收或发送8位数据。数据的最低位被最先发送或接收,波特率设置为FSYS/12(SM2 (SCON.5) 为 0) 或 FSYS/2 (SM2 为 1)。无论发送或接收数据,串行时钟将一直由MCU产生,因此串口模式 0 为主机模式。图13‑1 显示串口模式0传输时序图

如图所示,数据由双向RXD引脚进行收发,TXD引脚用来输出移位时钟。串口用移位时钟来一位位接收/发送数据与其他串口通讯。数据移入移出由最低位开始,波特率等于TXD的移位时钟频率。

向SBUF的写入数据将会开启发送,此时移位时钟启动数据从RXD脚串行移出,直至8位数据传输完成。传输标志位TI (SCON.1) 置 1表示 1 个字节数据传输完成。
当REN (SCON.4)=1 且 RI(SCON.0)=0 时串口开始接收数据。该条件告诉串口控制器有数据要移位进入。这个过程将持续到8位数据接收完毕,然后接收标志RI将置1。用户可以清零RI,以触发接收下一字节数据。

13.2 模式 1
模式1为异步全双工的工作方式。异步通讯模式通常用于PC间,调制解调器和其它类似接口间通讯。模式1下,10位数据通过TXD发送,通过RXD接收。10位数据组成如下:起始位(逻辑0),8位数据(最低位在前),停止位(逻辑1)。波特率由定时器1决定, SMOD (PCON.7) 设置为1可使波特率加倍.图13‑2为串口模式1发送和接收的时序图.

向SBUF写入数据开始传输,传输发生在TXD引脚上。首先是开始位,随后是8位数据位,最后是停止位。停止位出现后,TI(SCON.1)将置1 表示一个字节传输完成,所有位的传输速度取决于波特率。
当波特率发生器激活且REN(SCON.4) =1时,系统可以随时开始接收操作,当RXD脚上侦测到1到0的跳变时,数据将开始被采样并根据波特率的时钟频率接收,停止位必须符合一定的条件,接收到数据才能装载到SBUF:

1. RI (SCON.0) = 0

2. 要么SM2 (SCON.5) = 0, 要么接收到停止位STOP= 1,同时SM2 = 1且被寻址“Given”或符合广播地址(Broadcast address)匹配时。详见 13.7 多机通讯 和 13.8 自动地址识别。
如果上述条件满足,SBUF将加载到接收数据,RB8(SCON.2)为停止位,和RI将被置1,如果条件不满足,RI保持为0,没有数据加载。完成接收过程后,串口控制器将等待RXD脚上出现另一个1-0传输以开始新的数据接收。

13.3 模式 2
模式2为全双工异步通信, 与模式1不同的是,模式2是11位收发。数据由起始位(逻辑0),8位数据(最低位在前),第9位数据(TB8或RB8)和停止位(逻辑1)组成。第9位做奇偶校验位或多机通信时用来区分数据和地址。波特率是系统时钟频率的1/32 或1/64,由 SMOD位(PCON.7)来配置。图13‑3 指示串口模式2的传输时序。

向SBUF中写入数据启动TXD引脚发送,首先是开始位,然后是8位数据和TB8(SCON.3),最后是停止位,停止位发送后,TI将置位标志传输完成。
当REN=1时,串口可进行接收操作。RXD上的下降沿表示接收过程开始,数据根据所配置波特率进行采样和接收。停止位必须符合一定的条件,接收到数据才能装载到SBUF:

1. RI (SCON.0) = 0,

2. 要么SM2(SCON.5) = 0, 要么9th位 = 1同时 SM2 = 1且被寻址“Given”或符合广播地址(Broadcast address)匹配。详见 13.7 多机通讯 和 13.8 自动地址识别。
如果上述条件满足,则第9位数据进入RB8(SCON.2),8位数据进入SBUF,且RI置位。否则数据将不会装载,且RI保持为0。完成接收过程后,串口控制器等待RXD脚上的另一个1-0跳变以开始新的数据接收。
13.4 模式 3
除波特率外模式 3与模式 2相同。模式3采用定时器1的溢出率作为波特率时钟。图13‑3 模式3的传输时序,与模式2没有不同。

13.5 波特率
串口的不同模式的波特率时钟源和速度是完全不同的。详见表 13–3. 用于设定不同的波特率。
在模式1或模式3,串口0的波特率时钟源可通过BRCK (T3CON.5)选择定时器1或定时器3。对于串口1,只有采用定时器3作为唯一的时钟源。

当采用定时器1作为波特率发生器,需要关闭定时器1中断。定时器1可配置为计数器或是定时器,三种工作模式都可以。典型应用中,会配置为定时器工作在自动重装载模式(定时器模式2)。如果采用定时器3作为波特率发生器,同样也需要关闭定时器3中断。

模式1和模式3的波特率是可变的,取决于定时器1或2(003芯片)的溢出速率,就是说定时器1每溢出一次,串口发送一次数据。那么我们怎么去计算这两个模式的波特率设置时相关的寄存器的值呢?可以用公式去计算。

13.6 帧错误检测
帧错误检测用于异步模式 (模式 1, 2 和 3)。当由于总线干扰或争夺,导致没有检测到有效的停止位时,将发生帧错误。串口可以检测帧错误,并通过软件提示出错。
FE为帧错误标志,位于SCON第7位,这个位正常被用作为SM0 。当SMOD0 (PCON.6)置1时,帧错误检测功能打开,它作为FE标志。SM0和FE其实是相互独立的标志位。
当帧错误发生时,FE标志由硬件置位。如果必要,FE可在串口中断程序中检测。注意在对FE标志位进行读写时,同时SMOD0必须为1。如果FE被置位,那么下次即使接收到的正确数据帧也不会将其清除。对该位的清除必须由软件来完成。

13.7 多机通讯
N76E003串口支持多机通讯,可让一个主机(master device)向多个从机(slave device)发送多帧序列信息。在同一串行线上使用该功能过程中不需要中断其它从机设备工作。该功能只能在模式2或模式3下进行。用户设置SM2(SCON.5)为1打开这个功能,以便当一个数据帧接收后,当第9位为1时,串口中断将产生(模式2下,第9位为停止位)。当SM2为1时,如果第9位为0,不会发生中断。在该情况下,第9位能简单的把从机地址和数据分开。
当主机需要向多个从机中的一个发送数据时,首先需要发送目标从机的地址。注,地址字节与数据字节是不同的:在地址字节中,第9位为1。而数据字节中第9位为0。地址字节会触发所有从机,而每台从机检查接收到的

地址是否与自身匹配。地址匹配的从机,清除SM2,准备接收数据;未被寻址到的从机的SM2 必须保持,从而系统会持续工作,同时忽略接收数据。.
配置多机通信步骤如下:
1. 设置所有设备(主机与从机)为串口模式2或3;
2. 所有从机 SM2 位置为1;
3. 主机传输协议:
– 第一个字节:地址,目标从机地址 (第9位 = 1)
– 下一个字节:数据, (第9位 = 0)。
4. 当目标从机接收到第一个字节, 因为第9位数据为1所有从机将中断。目标从机比较自身地址并且清SM2 位等待接收后面的数据。其它从机则继续正常运行。

5. 接收到所有数据后,置 SM2 为 1 等待下一地址。
SM2 在模式 0 下无效。若 SM2 置 1,模式1可用于检测有效的停止位。同时将不会产生中断除非有效停止位已经接收。
13.8 自动地址识别
自动地址识别功能提高了多机通讯功能,允许UART通过硬件比较,来识别特别的地址信息在接收的比特流中。该功能可以节省软件识别地址而所占用的程序空间,仅当串口识别到自身地址时,接收器置位RI位并请求中断。当多机通信特征使能时(SM2置位),就使能自动地址识别。
如果需要,用户可以在模式1下使能自动地址识别功能。在这种配置下,停止位取代第九位的数据位。仅当接收命令的帧地址与器件地址匹配和有效的停止位时,RI置位。

使用自动地址识别功能,允许一个主机通过从机地址选择性与一个或几个从机通信。所有从机可以通过“广播”地址联系。有两个特殊功能寄存器用于定义从机地址 SADDR和从机地址掩码SADEN。 SADEN 用于定义SADDR的哪些位被用,哪些位不必关心. SADEN掩码可以与SADDR以“逻辑与”的方式以创建每个从机的“Given” 地址。使用 “Given”地址允许多从机被识别。

下列范例用以说明该功能的灵活应用
范例 1, 从机 0:
SADDR = 11000000b
SADEN = 11111101b
Given = 110000X0b
范例 2, 从机 1:
SADDR = 11000000b
SADEN = 11111110b
Given = 1100000Xb
在上面的例子中SADDR是相同的,SADEN的数据用于区分两个从机。从机0要求位0为” ”而忽略位1,从机1要求位1为” ”而位0被忽略。一个从机0唯一的地址11000010B,由于从机1要求位1为0。一个从机1唯一的地址将自1位11000001b将排除从机0。这两个从机可以选择在同一时间,地址位0 = 0(从机0)和第1位= 0(从机1)。因此,使用广播地址(Boadcast address) 11000000b就可以同时寻址。
更复杂应用可用于排除从机0之后,选择从机1或2:

范例 1, 从机 0:
SADDR = 11000000b
SADEN = 11111001b
Given = 11000XX0b
范例 2, 从机 1:
SADDR = 11100000b
SADEN = 11111010b
Given = 11100X0Xb
范例 3, 从机 2:
SADDR = 11000000b
SADEN = 11111100b
Given = 110000XXb
在上面的例子中,3个从机的分别是在地址的低3位。从机0要求位0 = 0,它可用11100110b解决。从机1要求位1= 0,它可用11100101b识别。从机2要求位2= 0,其独立的地址是11100011b。要选择从机0和1,去除从机2,可使用地址11100100b,因为它是必要的第2位= 1来排除从机2。
每个从机的“广播”地址的计算是通过逻辑或SADDR和SADEN。结果中的零位被视为“无关”位。例如:

SADDR = 01010110b
SADEN = 11111100b
Broadcast = 1111111Xb
使用“无关”位可在广播模式下,提供更灵活的应用。不过在大部分应用条件下,广播地址全部使用FFH。
复位后,SADDR和SADEN初始化为00H。这将对于所有“无关”地址产生一个“Given”地址,以及一个“广播”地址对应所有XXXXXXXXb地址(所有“无关”位)。这样有效地禁止了自动寻址模式,允许微控制器保持标准串口模式而不使用这个功能。

N76E003属于增强型51内核单片机,一般这种都是提供简单的串口UART使用的。
那么我们先看这个单片机一共几个串口。
手册中提到:N76E003包含两个具备增强的自动地址识别和帧错误检测功能的全双工串口。也就是2个串口。分别叫串口0和串口1.
我们也可以从手册发现每个串口具备4种模式,见下表

官方有提供的例程来操作这两个串口,全部是最常用的模式1
串口0可以使用定时器1或者定时器3产生波特率,并提供了对应的收发函数
串口1可以使用定时器3产生波特率,并提供了对应的收发函数。
基本上大家也用不上其他模式的。常规的应用足够了,我至今还没有用过串口的其他模式。
如果需要,可以参考这个库函数进行对应的寄存器修改。

关于波特率,我在定时器的博客上有描述

  1. #include "N76E003.h"
  2. #include "Common.h"
  3. #include "Delay.h"
  4. #include "SFR_Macro.h"
  5. #include "Function_define.h"
  6.  
  7. /******************************************************************************
  8. * FUNCTION_PURPOSE: Serial interrupt, echo received data.
  9. * FUNCTION_INPUTS : P0.7(RXD) serial input
  10. * FUNCTION_OUTPUTS: P0.6(TXD) serial output
  11. * Following setting in Common.c
  12. ******************************************************************************/
  13. #if 0
  14. //void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
  15. //{
  16. // P06_Quasi_Mode;
  17. // P07_Quasi_Mode;
  18. //
  19. // SCON = 0x52; //UART0 Mode1,REN=1,TI=1
  20. // TMOD |= 0x20; //Timer1 Mode1
  21. //
  22. // set_SMOD; //UART0 Double Rate Enable
  23. // set_T1M;
  24. // clr_BRCK; //Serial port 0 baud rate clock source = Timer1
  25.  
  26. //
  27. //#ifdef FOSC_160000
  28. // TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
  29. //#endif
  30. // set_TR1;
  31. //}
  32. ////---------------------------------------------------------------
  33. //void InitialUART0_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
  34. //{
  35. // P06_Quasi_Mode;
  36. // P07_Quasi_Mode;
  37. //
  38. // SCON = 0x52; //UART0 Mode1,REN=1,TI=1
  39. // set_SMOD; //UART0 Double Rate Enable
  40. // T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1)
  41. // set_BRCK; //UART0 baud rate clock source = Timer3
  42.  
  43. //#ifdef FOSC_160000
  44. // RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  45. // RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  46. //#endif
  47. // set_TR3; //Trigger Timer3
  48. //}
  49. #endif
  50.  
  51. /*******************************************************************************
  52. * FUNCTION_PURPOSE: Main function
  53. ******************************************************************************/
  54. void main (void)
  55. {
  56.  
  57. #if 0
  58. InitialUART0_Timer1(); //UART0 Baudrate initial,T1M=0,SMOD=0
  59. while()
  60. Send_Data_To_UART0(0x55);
  61. #else
  62. InitialUART0_Timer3();
  63. while()
  64. Send_Data_To_UART0(0x55);
  65. #endif
  66.  
  67. }
  1. //void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
  2. //{
  3. // P06_Quasi_Mode;
  4. // P07_Quasi_Mode;
  5. //
  6. // SCON = 0x52; //UART0 Mode1,REN=1,TI=1
  7. // TMOD |= 0x20; //Timer1 Mode1
  8. //
  9. // set_SMOD; //UART0 Double Rate Enable
  10. // set_T1M;
  11. // clr_BRCK; //Serial port 0 baud rate clock source = Timer1
  12.  
  13. //
  14. //#ifdef FOSC_160000
  15. // TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
  16. //#endif
  17. // set_TR1;
  18. //}

SCON = 0x52; //01010010 SM0=0,SM1=1即为模式一,REN=1,打开串口0在模式1,2或3模式下的接收功能。TI=1串口发送中断标志位,在发送到数据最后一位后由硬件置位。当串口0中断使能,将执行中断服务程序。该位必须由软件来清除。

  1.  
  1. TMOD |= 0x20; //Timer1 Mode2

  1. set_SMOD;

#define set_SMOD PCON |= SET_BIT7

#define SET_BIT7        0x80

#define set_T1M     CKCON   |= SET_BIT4

#define set_BRCK T3CON |= SET_BIT5

#ifdef FOSC_160000
TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
#endif
#ifdef FOSC_166000
TH1 = 256 - (1037500/u32Baudrate); /*16.6 MHz */
#endif
set_TR1;
set_TI; //For printf function must setting TI = 1
}

方式1的波特率=      即   (2^smod /32)*T1的溢出率,即  ((2^smod /32)*16000000)/(256-x)

通常都是固定的,一般都是根据所使用的波特率来求定时器初值。

  1. TH1 = 256 - (1000000/u32Baudrate+1); 
    256-TH1-1=1000000/u32Baudrate
  2.  
  3. u32Baudrate=1000000/(256-TH1-1)

set_TR1;

set_TI; //For printf function must setting TI = 1

  1. void Send_Data_To_UART0 (UINT8 c)
  2. {
  3. TI = ;
  4. SBUF = c;
  5. while(TI==);
  6. }

下面这个是一个串口零模式1的小案例

  1. #include <stdio.h>
  2. #include "N76E003.h"
  3. #include "Common.h"
  4. #include "Delay.h"
  5. #include "SFR_Macro.h"
  6. #include "Function_Define.h"
  7.  
  8. /******************************************************************************
  9. * FUNCTION_PURPOSE: Serial interrupt, echo received data.
  10. * FUNCTION_INPUTS : P0.7(RXD) serial input
  11. * FUNCTION_OUTPUTS: P0.6(TXD) serial output
  12. * Following setting in Common.c
  13. ******************************************************************************/
  14. #if 0
  15. //void InitialUART0_Timer1(UINT32 u32Baudrate) //T1M = 1, SMOD = 1
  16. //{
  17. // P06_Quasi_Mode;
  18. // P07_Quasi_Mode;
  19. //
  20. // SCON = 0x52; //UART0 Mode1,REN=1,TI=1
  21. // TMOD |= 0x20; //Timer1 Mode1
  22. //
  23. // set_SMOD; //UART0 Double Rate Enable
  24. // set_T1M;
  25. // clr_BRCK; //Serial port 0 baud rate clock source = Timer1
  26.  
  27. //
  28. //#ifdef FOSC_160000
  29. // TH1 = 256 - (1000000/u32Baudrate+1); /*16 MHz */
  30. //#endif
  31. // set_TR1;
  32. //}
  33. ////---------------------------------------------------------------
  34. //void InitialUART0_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
  35. //{
  36. // P06_Quasi_Mode;
  37. // P07_Quasi_Mode;
  38. //
  39. // SCON = 0x52; //UART0 Mode1,REN=1,TI=1
  40. // set_SMOD; //UART0 Double Rate Enable
  41. // T3CON &= 0xF8; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1)
  42. // set_BRCK; //UART0 baud rate clock source = Timer3
  43.  
  44. //#ifdef FOSC_160000
  45. // RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  46. // RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  47. //#endif
  48. // set_TR3; //Trigger Timer3
  49. //}
  50. #endif
  51.  
  52. void DelayTime(UINT32 u32CNT)
  53. {
  54. UINT32 i;
  55. i=u32CNT;
  56. while(i--);
  57.  
  58. }
  59.  
  60. /*******************************************************************************
  61. * FUNCTION_PURPOSE: Main function
  62. ******************************************************************************/
  63. void main (void)
  64. {
  65.  
  66. #if 1
  67. InitialUART0_Timer1(); //UART0 Baudrate from Timer1
  68. while()
  69. {
  70. Send_Data_To_UART0(0x33);
  71.  
  72. Timer0_Delay1ms();//ÑÓʱ500mS
  73.  
  74. }
  75. #else
  76. InitialUART0_Timer3(); //UART0 Baudrate from Timer3
  77. while()
  78. {
  79. Send_Data_To_UART0(0x55);
  80. Timer0_Delay1ms(); //ÑÓʱ500mS
  81. }
  82. #endif
  83.  
  84. }

串口0可选定时器3或定时器1,我们再看一下,串口零 模式三

模式2为全双工异步通信, 模式2是11位收发。数据由起始位(逻辑0),8位数据(最低位在前),第9位数据(TB8或RB8)和停止位(逻辑1)组成。第9位做奇偶校验位或多机通信时用来区分数据和地址。波特率是系统时钟频率的1/32 或1/64,由 SMOD位(PCON.7)来配置。图13‑3 指示串口模式2的传输时序。

串口零模式三 要采用定时器1做时钟。

  1. #include "N76E003.h"
  2. #include "SFR_Macro.h"
  3. #include "Common.h"
  4. #include "Delay.h"
  5. #include "Function_define.h"
  6.  
  7. #define BUFFER_SIZE 16
  8. UINT8 UART_BUFFER[BUFFER_SIZE],temp;
  9. UINT16 u16CNT=,u16CNT1=;
  10. bit riflag;
  11.  
  12. /**
  13. * FUNCTION_PURPOSE: serial interrupt, echo received data.
  14. * FUNCTION_INPUTS: P0.7(RXD) serial input
  15. * FUNCTION_OUTPUTS: P0.6(TXD) serial output
  16. */
  17. void SerialPort0_ISR(void) interrupt
  18. {
  19. if (RI==)
  20. { /* if reception occur */
  21. clr_RI; /* clear reception flag for next reception */
  22. UART_BUFFER[u16CNT] = SBUF;
  23. u16CNT ++;
  24. riflag =;
  25. }
  26. if(TI==)
  27. {
  28. clr_TI; /* if emission occur */
  29. }
  30. }
  31.  
  32. /************************************************************************************************************
  33. * Main function
  34. ************************************************************************************************************/
  35. void main (void)
  36. {
  37. P12_PushPull_Mode;
  38. P06_Quasi_Mode;
  39. P07_Quasi_Mode;
  40.  
  41. SCON = 0xD0; // Special setting the mode 3 and
  42. TMOD |= 0x20; //Timer1 Mode1
  43.  
  44. set_SMOD; //UART0 Double Rate Enable
  45. set_T1M; //sys clk
  46. clr_BRCK; //Serial port 0 baud rate clock source = Timer1
  47. TH1 = - (/+); /*16 MHz */
  48. set_TR1;
  49.  
  50. set_RB8; //This bit is for setting the stop bit 2 high/low status,
  51.  
  52. clr_TI;
  53. set_ES; //enable UART interrupt
  54. set_EA; //enable global interrupt
  55.  
  56. while()
  57. {
  58. if (riflag)
  59. {
  60. P12 = ~P12; //In debug mode check UART_BUFFER[u16CNT] to check receive data
  61. riflag = ;
  62. }
  63. }
  64.  
  65. }

接下来,是串口一,对于串口1,只有采用定时器3作为唯一的时钟源。

  1. #include "N76E003.h"
  2. #include "Common.h"
  3. #include "Delay.h"
  4. #include "SFR_Macro.h"
  5. #include "Function_define.h"
  6.  
  7. #define BUFFER_SIZE 16
  8. UINT8 UART_BUFFER[BUFFER_SIZE],temp;
  9. UINT16 u16CNT=,u16CNT1=;
  10. bit riflag;
  11.  
  12. /******************************************************************************
  13. * FUNCTION_PURPOSE: Serial port 1 interrupt, echo received data.
  14. * FUNCTION_INPUTS : P0.2(RXD) serial input
  15. * FUNCTION_OUTPUTS: P1.6(TXD) serial output
  16. * Following setting in Common.c
  17. ******************************************************************************/
  18. #if 0
  19. //void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
  20. //{
  21. // P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
  22. // P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
  23. //
  24. // SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1
  25. // T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1
  26. // clr_BRCK;
  27. //
  28. //#ifdef FOSC_160000
  29. // RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  30. // RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  31. //#endif
  32. //#ifdef FOSC_166000
  33. // RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
  34. // RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
  35. //#endif
  36. // set_TR3; //Trigger Timer3
  37. //}
  38. #endif
  39.  
  40. void SerialPort1_ISR(void) interrupt
  41. {
  42. if (RI_1==)
  43. { /* if reception occur */
  44. clr_RI_1; /* clear reception flag for next reception */
  45. UART_BUFFER[u16CNT] = SBUF_1;
  46. u16CNT ++;
  47. riflag =;
  48. }
  49. if(TI_1==)
  50. {
  51. clr_TI_1; /* if emission occur */
  52. }
  53. }
  54.  
  55. /****************************************************************************************************************
  56. * FUNCTION_PURPOSE: Main function
  57.  
  58. !!! N76E003 UART1 pin also occupied by debug pin,
  59. please remove Nu-link or not in debug mode to test UART1 function.
  60.  
  61. External UART1 connect also disturb debug download
  62.  
  63. ***************************************************************************************************************/
  64. void main (void)
  65. {
  66. P12_PushPull_Mode; // For I/O toggle display
  67.  
  68. #if 0
  69. //for Simple use UART1 transmit out
  70. InitialUART1_Timer3();
  71. while()
  72. Send_Data_To_UART1(0x55);
  73.  
  74. #else
  75. // For interrupt setting check receive
  76. InitialUART1_Timer3();
  77. set_ES_1; //For interrupt enable
  78. set_EA;
  79.  
  80. while()
  81. {
  82. if (riflag)
  83. {
  84. P12 = ~ P12; //Receive each byte P12 toggle, never work under debug mode
  85. riflag = ;
  86. }
  87. }
  88.  
  89. #endif
  90.  
  91. }
  1. void InitialUART1_Timer3(UINT32 u32Baudrate) //use timer3 as Baudrate generator
  2. {
  3. P02_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
  4. P16_Quasi_Mode; //Setting UART pin as Quasi mode for transmit
  5.  
  6. SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1
  7. T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1
  8. clr_BRCK;
  9.  
  10. #ifdef FOSC_160000
  11. RH3 = HIBYTE( - (/u32Baudrate)-); /*16 MHz */
  12. RL3 = LOBYTE( - (/u32Baudrate)-); /*16 MHz */
  13. #endif
  14. #ifdef FOSC_166000
  15. RH3 = HIBYTE( - (/u32Baudrate)); /*16.6 MHz */
  16. RL3 = LOBYTE( - (/u32Baudrate)); /*16.6 MHz */
  17. #endif
  18. set_TR3; //Trigger Timer3
  19. }
  1. SCON_1 = 0x50; //UART1 Mode1,REN_1=1,TI_1=1

  1.  
  1. T3CON = 0x08; //T3PS2=0,T3PS1=0,T3PS0=0(Prescale=1), UART1 in MODE 1

  1. #ifdef FOSC_160000
  2. RH3 = HIBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  3. RL3 = LOBYTE(65536 - (1000000/u32Baudrate)-1); /*16 MHz */
  4. #endif
  5. #ifdef FOSC_166000
  6. RH3 = HIBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
  7. RL3 = LOBYTE(65536 - (1037500/u32Baudrate)); /*16.6 MHz */
  8. #endif
  1. set_TR3; //Trigger Timer3

  1. set_ES_1; //For interrupt enable
  1. set_EA;

串口1只能用定时器3,串口0只能做定时器1或3,但是串口0模式三只能用定时器1,串口零其他模式正常

还有一个比较重要的问题,由于ICP烧录的时候,与串口一是重合的,由于是引脚复用的关系,所以串口功能发生作用时,就会出现烧录不进去的情况,这时只需要让串口收发不了数据就能烧录程序了。

  1.  

N76E003之串口的更多相关文章

  1. N76E003双串口无法进UART1中断问题解决办法

    最近在做有关N76E003的项目,使用到双串口.串口的配置没有特殊要求,最基本的配置 void Uart0_Init(void) { //—————————串口0引脚初始化———————— set_P ...

  2. N76E003之ISP

    Flash存储器支持硬件编程和应用编程(IAP).如果产品在研发阶段或产品需要更新软固件时,硬件编程就显得不太方便,采用在系统编程(ISP)方式,可使这一过程变得方便.执行ISP不需要将控制器从系统板 ...

  3. N76E003之定时器3

    定时器3是一个16位自动重装载,向上计数定时器.用户可以通过配置T3PS[2:0] (T3CON[2:0])选择预分频,并写入重载值到R3H 和R3L寄存器来决定它的溢出速率.用户可以设置TR3 (T ...

  4. N76E003的定时器/计数器 0和1

    定时器/计数器 0和1N76E003系列定时器/计数器 0和1是2个16位定时器/计数器.每个都是由两个8位的寄存器组成的16位计数寄存器. 对于定时器/计数器0,高8位寄存器是TH0. 低8位寄存器 ...

  5. N76E003的学习之路(ADC简单小例程篇)

    N76E003内嵌12位逐次逼近寄存器型(SAR)的模拟数字转换器(ADC).模数转换模块负责将管脚上的模拟信号转换为12位二进制数据.N76E003支持8通道单端输入模式.内部带隙电压(band-g ...

  6. 单片机成长之路(51基础篇) - 023 N76e003 系统时钟切换到外部时钟

    N76e003切换到外部时钟的资料很少(因为N76e003的片子是不支持无源晶振的,有源晶振的成本又很高,所以网上很少有对N76e003的介绍).有图有真相: 代码如下: main.c #includ ...

  7. 几款一元单片机对比:CMS8S5880、STM8S003、N76E003

    大概17年开始,STM8S003的价格被贸易商炒货,变得很不稳定,一度上涨到2~3元,因为市场需求大增,小家电.无线充和一些简单功能的产品,本人就有在空气净化器.433M触摸开关.数据收发模块.红外控 ...

  8. .NET 串口通信

    这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...

  9. [连载]《C#通讯(串口和网络)框架的设计与实现》- 0.前言

                                  目       录 前言 前言 刚参加工作,使用过VB.VC开发软件,随着C#的崛起,听说是C++++,公司决定以后开发软件使用C#,凭借在 ...

随机推荐

  1. 基础 | batchnorm原理及代码详解

    https://blog.csdn.net/qq_25737169/article/details/79048516 https://www.cnblogs.com/bonelee/p/8528722 ...

  2. Css格式化/压缩(代码)

    function $() { var elements = new Array(); for (var i = 0; i < arguments.length; i++) { var eleme ...

  3. Java数组超出范围时如何处理多个异常?

    在Java编程中,数组超出范围时如何处理多个异常? 此示例显示如何使用System类的System.err.println()方法处理多个异常方法. package com.yiibai; publi ...

  4. Bioperl 解析blast的输出结果

    用bioperl 解析blast的默认输出结果, 整理成-m8格式的输出 #!/usr/bin/perl use Bio::SearchIO; my ($blast) = @ARGV; my $sea ...

  5. Linux下设置SSH Server设置时间链接限制

    OpenSSH基于安全的理由,如果用户连线到SSH Server后闲置一段时间,SSH Server会在超过特定时间后自动终止SSH连线.本人习惯长时间连接,需要做如下修改: 1.打开ssh配置文件: ...

  6. Mongodb学习笔记(1)--入门

    文档 多个键及关联的值有序的放置在一起就是文档,如"greeting":"Hello World!" 特点 文档中键值对是有序的 除了字符串还可以是其他类型:& ...

  7. JavaScript高速掌握

    .document.write(""); 输出语句 .JS中的凝视为//或/* */ .传统的HTML文档顺序是:document->html->(head,body) ...

  8. CocoaPods 第三方库管理器

    下载地址:https://github.com/kattrali/cocoapods-xcode-plugin 跟 VVDocumenter 规范注释生成器的安装方式一样: 下载开源工程在 Xcode ...

  9. Java编程思想学习笔记——注解

    前言 在Android开发的过程中,我们为了减少重复代码的编写,会使用类似ButterKnife,AndroidAnnotations 这类依赖注解库.代码示例如下: //不使用 Button btn ...

  10. jquery获取data-xxx自定义属性的值遇到的问题

    直接用jquery的 data("name") 获取 data-name的值有问题,获取的只是最初的值,即使后边改变也不会变,所以还是要用attr("data-name& ...