3274|4

75

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

新手,串口输出问题,请各位大侠拔刀相助一下 [复制链接]

  1. //*************************************************************************
  2. //                               串口通信
  3. //环境:C8051F120
  4. //
  5. //说明:
  6. //
  7. //     本程序实现串口打印信息
  8. //
  9. //     使用外部晶振 22.1184MHz ,通过PLL倍频达到49.76MHz作为系统时钟
  10. //
  11. //     使用printStr(unsigned char *Str)函数输出字符串:
  12. //     使用printHex(unsigned char *Str,unsigned int length)函数输出字符串
  13. //   
  14. //**************************************************************************/




  15. #include                          // Device-specific SFR Definitions
  16. #include


  17. //-----------------------------------------------------------------------------
  18. // 16-bit SFR Definitions for 'F12x
  19. //-----------------------------------------------------------------------------

  20. sfr16  RCAP2    = 0xca;                 // Timer2 capture/reload 在51中只有T0和T1
  21.                                        // 口诀:定时晶振分溢出,T模门方两重载(51)
  22.                                                                            // 而在c51中则常用的是T2 ,使用的自动重载波特率发生方式(方式2)
  23. sfr16 TMR2      = 0xcc;                 // Timer2


  24. //------------------------------------------------------------------------------
  25. // Function Prototypes
  26. //------------------------------------------------------------------------------

  27. // Initialization Routines
  28. void PORT_Init (void);
  29. void SYSCLK_Init (void);

  30.    //用于串口通信初始化
  31. void UART0_Init (void);

  32. void printHex(unsigned char *Str,unsigned int length);//输出16进制
  33. void printStr(unsigned char *Str);//输出字符串


  34. void delay(unsigned int m)
  35. {
  36.      unsigned int n;
  37.      n=0;
  38.      while(n < m)
  39.      {n++;}
  40.      return;
  41. }


  42. //-----------------------------------------------------------------------------
  43. // Global Variables
  44. //-----------------------------------------------------------------------------
  45. unsigned int i, j;
  46. //打印信息字母必须使用大写,数字定义为unsigned char
  47. //static byte C8051F_FLASH_BUFFER[]="DEFINE AS UNSIGNED CHAR AND USE BIG LETTERS AND U CAN PRINTF CORRECTLY";
  48. unsigned char C8051F_FLASH_BUFFER[8]="";

  49. //unsigned char rebuffer[1316];
  50. unsigned char test_str1[] = "we are";
  51. // Application Functions
  52. void UDP(void);

  53. //-----------------------------------------------------------------------------
  54. // Constant Definitions
  55. //-----------------------------------------------------------------------------
  56. #define SERVER_MODE  1
  57. #define DATA_BUFF_LEN    42

  58. //-----------------------------------------------------------------------------
  59. // Global Constants
  60. //-----------------------------------------------------------------------------

  61. #define EXTCLK 22118400  // External oscillator frequency in Hz 外部晶振的频率为22118400
  62. #define SYSCLK 49760000  // Output of PLL derived from
  63. // (EXTCLK*9/4)
  64. #define BAUDRATE  115200 // Baud rate of UART in bps
  65.                                                       // Note: The minimum standard baud rate
  66.                                                  // supported by the UART0_Init routine
  67.                                                  // in this file is 19,200 bps when
  68.                                                  // SYSCLK = 49.76MHz.


  69. // SYSTEMCLOCK = System clock frequency in Hz
  70. #define SYSTEMCLOCK       22118400//L( //* 9 / 4)

  71. //-----------------------------------------------------------------------------
  72. // Main Routine
  73. //-----------------------------------------------------------------------------
  74. void main(void)
  75. {

  76.    // Disable watchdog timer
  77.    WDTCN = 0xde;
  78.    WDTCN = 0xad;//先写入0xDE再下入0xAD:禁止看门狗

  79.    // Initialize the MCU
  80.    PORT_Init();
  81.    SYSCLK_Init();

  82.         UART0_Init (); // initialize UART0
  83.         SFRPAGE = UART0_PAGE; // Direct printf output to UART0
  84.         EA=1;
  85. /*
  86.         for(i= 0; i<1316;i++)
  87.                 rebuffer[i] = 0x14;
  88.        
  89.         delay(100);

  90.         //打印16进制
  91.         for(i=0;i<1;i++)
  92.    {
  93.                 printHex(rebuffer,1316);
  94.                 delay(100);
  95.         }
  96. */
  97.         //打印字符串
  98.         for(i=0;i<1;i++)
  99.    {
  100.                 printStr(test_str1);
  101.                 delay(100);
  102.         }


  103.         while(1);

  104. }


  105. //-----------------------------------------------------------------------------
  106. // Initialization Routines
  107. //-----------------------------------------------------------------------------

  108. //-----------------------------------------------------------------------------
  109. // PORT_Init
  110. //-----------------------------------------------------------------------------
  111. //
  112. // Configure the Interrupts, Crossbar and GPIO ports
  113. //
  114. void PORT_Init (void)
  115. {

  116. char SFRPAGE_SAVE = SFRPAGE;     // 保存当前SFR页
  117.        
  118.    SFRPAGE = CONFIG_PAGE;           // 设置SFR页

  119.    P1MDOUT |= 0x40;                 // 设置 P1.6(TB_LED) 为推挽输出方式
  120.    P2MDOUT |= 0x08;                 // 设置 P2.2(AB4_LED1) 为推挽输出方式
  121.    // all pins used by the external memory interface are in push-pull mode


  122. //端口输出方式寄存器,各位设置为1时为推挽式输出,0时输出为漏极开路方式
  123.    P4MDOUT =  0xDF;
  124.    P5MDOUT =  0xFF;
  125.    P6MDOUT =  0xFF;
  126.    P7MDOUT =  0xFF;


  127.    P4 = 0xC0;   //1100 0000         //P4为控制总线  /WR(P4.7), /RD(P4.6)设置为逻辑高电平, RESET 为低电平
  128.    P5 = 0xFF;
  129.    P6 = 0xFF;                       // P5, P6 为地址总线
  130.    P7 = 0xFF;                       // P7 为数据总线

  131.    TCON &= ~0x01;                   // 设置 /INT0 位为0,使外部中断0为电平触发

  132.    // Enable UART0, CP0, and /INT0. This puts /INT0 on P0.3.
  133.    XBR0 = 0x84; // 端口I/O 交叉开关控制0  1000 0100 设置CPOE 位和 UART0EN 位 为1,

  134.    XBR1 = 0x04;        // 端口I/O 交叉开关控制1
  135.    XBR2 = 0x40;        // 端口I/O 交叉开关控制2

  136.    P0MDOUT |= 0x01;                    // Set TX pin to push-pull


  137.    SFRPAGE = SFRPAGE_SAVE;       // Restore SFR page

  138. }

  139. //-----------------------------------------------------------------------------
  140. // SYSCLK_Init
  141. //-----------------------------------------------------------------------------
  142. //
  143. // This routine initializes the system clock.
  144. //
  145. void SYSCLK_Init (void)
  146. {
  147.         int i; // delay counter
  148.         char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
  149.         SFRPAGE = CONFIG_PAGE; // set SFR page
  150.         OSCXCN = 0x67; // start external oscillator with22.1184MHz crystal

  151.         for (i=0; i < 256; i++) ; // Wait for osc. to start up
  152.         while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
  153.         CLKSEL = 0x01; // Select the external osc. as
  154.                        // the SYSCLK source


  155.         OSCICN = 0x00; // Disable the internal osc.

  156.         //Turn on the PLL and increase the system clock by a factor of M/N = 9/4
  157.         SFRPAGE = CONFIG_PAGE;
  158.         PLL0CN = 0x04; // Set PLL source as external osc.
  159.         SFRPAGE = LEGACY_PAGE;
  160.         FLSCL = 0x10; // Set FLASH read time for 50MHz clk
  161.                       // or less
  162.         SFRPAGE = CONFIG_PAGE;
  163.         PLL0CN |= 0x01; // Enable Power to PLL,之后使能PLL时就不须再使能Power to PLL了
  164.         PLL0DIV = 0x04; // Set Pre-divide value to N (N = 4)
  165.         PLL0FLT = 0x01; // Set the PLL filter register for
  166.                         // a reference clock from 19 - 30 MHz
  167.                         // and an output clock from 65-100 MHz
  168.         PLL0MUL = 0x09; // Multiply SYSCLK by M (M = 9)
  169.         for (i=0; i < 256; i++) ; // Wait at least 5us
  170.         PLL0CN |= 0x02; // Enable the PLL

  171.         while(!(PLL0CN & 0x10)); // Wait until PLL frequency is locked
  172.         CLKSEL = 0x02; // Select PLL as SYSCLK source
  173.         SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
  174. }




  175. void UART0_Init (void)
  176. {
  177.         char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
  178.         SFRPAGE = UART0_PAGE;
  179.         SCON0 = 0x50; // SCON0: URAT0 WORK mode 0, 8-bit UART, enable RX
  180.         SSTA0 = 0x10; // Timer 1 generates UART0 baud rate and
  181.                       // UART0 baud rate divide by two disabled
  182.         SFRPAGE = TIMER01_PAGE;
  183.         TMOD &= ~0xF0;
  184.         TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
  185.         TH1 = -(SYSCLK/BAUDRATE/16); //即 TH1 = 0xFF- (SYSCLK/BAUDRATE/16));
  186.                                                                  // Set the Timer1 reload value
  187.                                      // When using a low baud rate, this equation
  188.                                      // should be checked to ensure that the
  189.                                  // reload value will fit in 8-bits.
  190.         CKCON |= 0x10; // T1M = 1; SCA1:0 = xx
  191.         TL1 = TH1; // initialize Timer1
  192.         TR1 = 1; // start Timer1
  193.         SFRPAGE = UART0_PAGE;
  194.         TI0 = 1; // Indicate TX0 ready
  195.         SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
  196.         ES0=1;
  197. }

  198. /*//可软件查询,可省略中断处理
  199. void UART0_ISR (void) interrupt 4
  200. {

  201. //          if(TI0)
  202. //       {TI0=0;}
  203. }
  204. */

  205. /**********************************************************
  206. * printHex函数用法:打印16进制数据,例如:
  207. *      for(i= 0; i<1316;i++)
  208. *                rebuffer[i] = 0x14;
  209. *       
  210. *        delay(100);
  211. *
  212. *        //打印16进制
  213. *        for(i=0;i<1;i++)
  214. *   {
  215. *                printHex(rebuffer,1316);
  216. *                delay(100);
  217. *        }
  218. *                       
  219. ***********************************************************/
  220. void printHex(unsigned char *Str,unsigned int length)
  221. {
  222.         j = 0;
  223.         while(j <= length ) //判断是否到了字符串的尾部0x00
  224.         {
  225.                 SBUF0 = *Str; //输出字符
  226.                 delay(100);
  227.                 while(!TI0); //空语句判断字符是否发完
  228.                 TI0 = 0; //清TI
  229.                 Str++; //字符串指针加一
  230.                 j++;
  231.         }
  232. }

  233. /****************************************************
  234. * printStr函数用法:打印字符串或字符数组例如:
  235. *      1. unsigned char str[] = "hello my world!"
  236. *
  237. *                        printStr(str);
  238. *
  239. *          即可在串口助手中看见hello my world!打印出来,
  240. *                       
  241. ****************************************************/
  242. void printStr(unsigned char *Str)
  243. {
  244.         while(*Str != '\0' ) //判断是否到了字符串的尾部0x00
  245.         {
  246.                 SBUF0 = *Str; //输出字符
  247.                 delay(200);
  248.                 while(!TI0); //空语句判断字符是否发完
  249.                 TI0 = 0; //清TI
  250.                 Str++; //字符串指针加一
  251.         }
  252. }
复制代码


代码如上,我想问下,
1.以下的这些端口初始化有什么作用?之前我删除了这些口的初始化,打印出了乱码。

//端口输出方式寄存器,各位设置为1时为推挽式输出,0时输出为漏极开路方式
   P4MDOUT =  0xDF;
   P5MDOUT =  0xFF;
   P6MDOUT =  0xFF;
   P7MDOUT =  0xFF;


   P4 = 0xC0;   //1100 0000         //P4为控制总线  /WR(P4.7), /RD(P4.6)设置为逻辑高电平, RESET 为低电平
   P5 = 0xFF;
   P6 = 0xFF;                       // P5, P6 为地址总线
   P7 = 0xFF;                       // P7 为数据总线

2.我用printStr(unsigned char *Str)函数打印一字符串,第二个字符总打印不出来,比如unsigned char test_str1[] = "we are";这是我打印的字符串,在main()函数中        //打印字符串
        for(i=0;i<1;i++)
   {
                printStr(test_str1);
                delay(100);
        }


        while(1);

然后在超级终端中输出是 w are。正常应该是we are才对的,是不是哪里设置错了呢?

最新回复

众位楼主,如果想要用单片机实现真彩液晶显示的话,可以跟我索取资料的。dwin99@live.cn   详情 回复 发表于 2009-8-29 20:27
点赞 关注

回复
举报

69

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
端口初始化就是使芯片一些想用的功能初始化,不用的功能也初始化(为了稳定性)。
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
這個是端口的初始化 因為這個單片機跟一般的51不一樣 io口要交叉開關配置 建議閱讀數據手冊中相關部分

第二個問題,直接看源碼沒看出來, 可能要單步一下.
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

4
 
io口要交叉開關配置 我到明白,只是
P4 = 0xC0;  //1100 0000        //P4为控制总线  /WR(P4.7), /RD(P4.6)设置为逻辑高电平, RESET 为低电平
  P5 = 0xFF;
  P6 = 0xFF;                      // P5, P6 为地址总线
  P7 = 0xFF;                      // P7 为数据总线

这些引脚的复用原理有些不明白。

第二个问题楼上的建议挺好的,我去单步试下先
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
众位楼主,如果想要用单片机实现真彩液晶显示的话,可以跟我索取资料的。dwin99@live.cn
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表