[牛人杂谈] M051利用IO模拟串口技术

[复制链接]
 楼主| 幸福小强 发表于 2018-3-6 11:38 | 显示全部楼层 |阅读模式
当应用时有时难免会到硬件UART组数不够用,此时便可以用GPIO的方式来产生软件的UART。范例便是用Time中断配合GPIO产生UART的协定。因为是软件处理,用户需要小心,在UART丢出去前,把其它中断关闭以免被打断传输。
 楼主| 幸福小强 发表于 2018-3-6 11:38 | 显示全部楼层
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * $Revision: 4 $
  5. * $Date: 14/01/28 11:45a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    M051 Series Timer Driver Sample Code
  7. *
  8. * @note
  9. * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
  10. ******************************************************************************/
  11. #include <stdio.h>
  12. #include "M051Series.h"

  13. #define PLLCON_SETTING      CLK_PLLCON_50MHz_HXT
  14. #define PLL_CLOCK           50000000

  15. unsigned int data;
  16. unsigned int count;
  17. unsigned int p_flag;
  18. /**
  19. * @brief       Timer0 IRQ
  20. *
  21. * @param       None
  22. *
  23. * [url=home.php?mod=space&uid=266161]@return[/url]      None
  24. *
  25. * [url=home.php?mod=space&uid=1543424]@Details[/url]     The Timer0 default IRQ, declared in startup_M051Series.s.
  26. */
  27. void TMR0_IRQHandler(void)
  28. {
  29.     /* Clear Timer0 time-out interrupt flag */
  30.      TIMER_ClearIntFlag(TIMER0);     
  31.            if(count!=0)
  32.                  {
  33.                         if(data&0x01==0x01)
  34.              P27=1;
  35.                          else
  36.                          P27=0;
  37.                   data=data>>1;
  38.                         count--;
  39.                  }
  40.        
  41. }

  42. void UART_GPIO(unsigned char uart_data)
  43. {
  44.         data=0;
  45.         data=(uart_data<<1)|(1<<9);
  46.         count=10;
  47. }

  48. void SYS_Init(void)
  49. {
  50.     /*---------------------------------------------------------------------------------------------------------*/
  51.     /* Init System Clock                                                                                       */
  52.     /*---------------------------------------------------------------------------------------------------------*/
  53.     /* Enable IRC22M clock */
  54.     CLK->PWRCON |= CLK_PWRCON_IRC22M_EN_Msk;

  55.     /* Waiting for IRC22M clock ready */
  56.     CLK_WaitClockReady(CLK_CLKSTATUS_IRC22M_STB_Msk);

  57.     /* Switch HCLK clock source to HIRC */
  58.     CLK->CLKSEL0 = CLK_CLKSEL0_HCLK_S_HIRC;

  59.     /* Set PLL to Power-down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
  60.     CLK->PLLCON |= CLK_PLLCON_PD_Msk;

  61.     /* Enable external 12 MHz XTAL, IRC10K */
  62.     CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk | CLK_PWRCON_OSC10K_EN_Msk;

  63.     /* Enable PLL and Set PLL frequency */
  64.     CLK->PLLCON = PLLCON_SETTING;

  65.     /* Waiting for clock ready */
  66.     CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk | CLK_CLKSTATUS_XTL12M_STB_Msk | CLK_CLKSTATUS_IRC10K_STB_Msk);

  67.     /* Switch HCLK clock source to PLL, STCLK to HCLK/2 */
  68.     CLK->CLKSEL0 = CLK_CLKSEL0_STCLK_S_HCLK_DIV2 | CLK_CLKSEL0_HCLK_S_PLL;

  69.     /* Enable peripheral clock */
  70.     CLK->APBCLK = CLK_APBCLK_UART0_EN_Msk |
  71.                   CLK_APBCLK_TMR0_EN_Msk ;

  72.     /* Peripheral clock source */
  73.     CLK->CLKSEL1 = CLK_CLKSEL1_UART_S_PLL |CLK_CLKSEL1_TMR0_S_HIRC;

  74.     /* Update System Core Clock */
  75.     /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  76.     SystemCoreClockUpdate();

  77.     /*---------------------------------------------------------------------------------------------------------*/
  78.     /* Init I/O Multi-function                                                                                 */
  79.     /*---------------------------------------------------------------------------------------------------------*/
  80.     /* Set P3 multi-function pins for UART0 RXD, TXD */
  81.     SYS->P3_MFP = SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0;
  82. }

  83. void UART0_Init(void)
  84. {
  85.     /*---------------------------------------------------------------------------------------------------------*/
  86.     /* Init UART                                                                                               */
  87.     /*---------------------------------------------------------------------------------------------------------*/
  88.     /* Reset IP */
  89.     SYS_ResetModule(UART0_RST);

  90.     /* Configure UART0 and set UART0 Baudrate */
  91.     UART_Open(UART0, 115200);
  92. }

  93. /*---------------------------------------------------------------------------------------------------------*/
  94. /*  MAIN function                                                                                          */
  95. /*---------------------------------------------------------------------------------------------------------*/
  96. int main(void)
  97. {
  98.            int i;
  99.     volatile uint32_t u32InitCount;

  100.     /* Unlock protected registers */
  101.     SYS_UnlockReg();

  102.     /* Init System, peripheral clock and multi-function I/O */
  103.     SYS_Init();

  104.     /* Lock protected registers */
  105.     SYS_LockReg();

  106.     /* Init UART0 for printf */
  107.     UART0_Init();
  108.     /* Configure P1.5 as Output mode*/
  109.     GPIO_SetMode(P2, BIT7, GPIO_PMD_OUTPUT);

  110.     /* Open Timer0 frequency 38400 in periodic mode, and enable interrupt */
  111.     TIMER0->TCMPR = (22118400/38400);
  112.     TIMER0->TCSR = TIMER_TCSR_IE_Msk | TIMER_PERIODIC_MODE;
  113.     TIMER_SET_PRESCALE_VALUE(TIMER0, 0);       

  114.     /* Enable Timer0 NVIC */
  115.     NVIC_EnableIRQ(TMR0_IRQn);

  116.     /* Start Timer0 counting */
  117.     TIMER_Start(TIMER0);

  118.     while(1){
  119.                         if(count==0)
  120.                         {
  121.                         CLK_SysTickDelay(1000);
  122.                         UART_GPIO(i);
  123.                         i++;
  124.                         }
  125.                         }
  126. }

  127. /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/

 楼主| 幸福小强 发表于 2018-3-6 11:39 | 显示全部楼层
当然了,这其实就是定时器应用,因为串口是时间上的时序。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

143

主题

1720

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部