[牛人杂谈] 新塘M0用定时起捕获怎么做模拟串口Rx

[复制链接]
752|10
 楼主| haunghua 发表于 2019-10-23 19:28 | 显示全部楼层 |阅读模式
谁用过新塘M0的定时器输入捕获测脉宽来搞过模拟UART的Rx,或是用过外部中断加定时器搞过模拟UART的Rx吗?
xuanhuanzi 发表于 2019-10-26 21:03 | 显示全部楼层
[M051][APP]SoftwareUART (1).zip (502.7 KB, 下载次数: 2)
xuanhuanzi 发表于 2019-10-26 21:03 | 显示全部楼层
  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. ***/

xuanhuanzi 发表于 2019-10-26 21:04 | 显示全部楼层
这是官方提供的M0系列的例子。M051系列可以直接运行。
zhuomuniao110 发表于 2019-10-26 23:59 | 显示全部楼层
楼上例子不错。
玛尼玛尼哄 发表于 2019-10-27 00:05 | 显示全部楼层
主要就是识别时序的问题。
mintspring 发表于 2019-10-27 16:44 | 显示全部楼层
是用的捕获吗,记不得了。
捉虫天师 发表于 2019-10-29 13:19 | 显示全部楼层
上面那个例子好像只是个发送的程序。
捉虫天师 发表于 2019-10-29 13:24 | 显示全部楼层
接收这个,好像一般51的单片机有用IO模拟的,可以参考一下。
捉虫天师 发表于 2019-10-29 13:26 | 显示全部楼层
  1. sbit TXD1 = P0^4;        //定义模拟输出脚
  2. sbit RXD1 = P3^2;   //定义模拟输入脚

  3. bdata unsigned char SBUF1;   //定义一个位操作变量
  4. sbit SBUF1_bit0 = SBUF1^0;
  5. sbit SBUF1_bit1 = SBUF1^1;
  6. sbit SBUF1_bit2 = SBUF1^2;
  7. sbit SBUF1_bit3 = SBUF1^3;
  8. sbit SBUF1_bit4 = SBUF1^4;
  9. sbit SBUF1_bit5 = SBUF1^5;
  10. sbit SBUF1_bit6 = SBUF1^6;
  11. sbit SBUF1_bit7 = SBUF1^7;

  12. void delay_bps() {unsigned char i; for (i = 0; i < 29; i++); _nop_();_nop_();} //波特率9600 模拟一个9600波特率

  13. unsigned char getchar2()        //模拟接收一个字节数据
  14. {
  15.         while (RXD1);
  16.     _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  17.     delay_bps();
  18.     SBUF1_bit0 = RXD1; //0      
  19.     delay_bps();
  20.     SBUF1_bit1 = RXD1; //1      
  21.     delay_bps();
  22.     SBUF1_bit2 = RXD1; //2      
  23.     delay_bps();
  24.     SBUF1_bit3 = RXD1; //3      
  25.     delay_bps();
  26.     SBUF1_bit4 = RXD1; //4      
  27.     delay_bps();
  28.     SBUF1_bit5 = RXD1; //5      
  29.     delay_bps();
  30.     SBUF1_bit6 = RXD1; //6      
  31.     delay_bps();
  32.     SBUF1_bit7 = RXD1; //7      
  33.         delay_bps();
  34.     return(SBUF1) ;      //返回读取的数据
  35. }

  36. void putchar2(unsigned char input)    //模拟发送一个字节数据
  37. {
  38.     SBUF1 = input;
  39.     TXD1 = 0;  //起始位
  40.     delay_bps();   
  41.     TXD1 = SBUF1_bit0;  //0
  42.     delay_bps();   
  43.     TXD1 = SBUF1_bit1;  //1
  44.     delay_bps();   
  45.     TXD1 = SBUF1_bit2;  //2
  46.     delay_bps();   
  47.     TXD1 = SBUF1_bit3;  //3
  48.     delay_bps();   
  49.     TXD1 = SBUF1_bit4;  //4
  50.     delay_bps();   
  51.     TXD1 = SBUF1_bit5;  //5
  52.     delay_bps();   
  53.     TXD1 = SBUF1_bit6;  //6
  54.     delay_bps();   
  55.     TXD1 = SBUF1_bit7;  //7
  56.     delay_bps();   
  57.     TXD1 = 1;       //停止位
  58.     delay_bps();   
  59. }
捉虫天师 发表于 2019-10-29 13:26 | 显示全部楼层
  1. #include <reg51.h>
  2. #include "delay.h"
  3. #include "sub4094.c"
  4. #include <intrins.h>
  5. sbit spk = P2^5;    //定义蜂鸣器使用的I/O口P2.5
  6. sbit LED = P2^7;
  7. #include "subuart2.c"


  8. void main (void)
  9. {
  10. unsigned char first,zjgs,order,zhen_xh,jym,end;  //定义起始字、字节个数、命令码、帧序号、校验码、结束字
  11. unsigned char i;       //定义1个随机变量
  12. unsigned char sum;     //定义单片机计算用的校验码
  13. unsigned char LED_contrl;  //指示灯控制字
  14. unsigned contrl_1,contrl_2; //移位变量
  15. //unsigned int delay_counter;
  16. P5=0xEF;   //使能流水灯,屏蔽数码管
  17. P4=0x00;      //流水灯全部点亮       
  18. update4094(); //刷新流水灯状态
  19. delay_ms(300);
  20. P4=0xFF;      //流水灯全部熄灭
  21. update4094(); //刷新流水灯状态
  22. while(1)
  23. {
  24.         first=getchar2();   //读取6个数据进行处理。
  25.         zjgs=getchar2();
  26.         order=getchar2();
  27.         zhen_xh=getchar2();
  28.         jym=getchar2();
  29.         end=getchar2();
  30.         if(0xfa != first) goto end;
  31.         sum=zjgs+order+zhen_xh;
  32.         if(sum != jym)
  33.         {
  34.                 putchar2(0xfa);   //起始字
  35.                 putchar2(0x07);    //字节个数
  36.                 sum=0x07;
  37.                 putchar2(order);   //接收到的命令码
  38.                 sum+=order;
  39.                 putchar2(zhen_xh); //接收到的帧序号
  40.         putchar2(0x00);    //命令校验错误标志位
  41.                 sum+=zhen_xh;
  42.                 putchar2(sum);     //校验码
  43.                 putchar2(0xfb);
  44.                 //蜂鸣器发出报警声音,指示灯闪烁
  45.                 for(i=0;i<8;i++)  
  46.                 {
  47.                     LED=~LED;     //取反指示灯
  48.                         spk=~spk;     //取反蜂鸣器
  49.                         delay_ms(200);
  50.                 }
  51.                 goto end;
  52.         }
  53.         if(0xfb != end) goto end;
  54.         switch(order)
  55.         {
  56.                 case 1: //将收到的命令返回给串行口
  57.                                 LED=0;
  58.                                 putchar2(first);      //起始字  
  59.                                 putchar2(zjgs);       //字节个数
  60.                                 putchar2(order);      //命令码
  61.                                 putchar2(zhen_xh);    //帧序号
  62.                                 putchar2(jym);        //校验码
  63.                                 putchar2(end);      //结束字
  64.                                 delay_ms(50);
  65.                                 LED=1;
  66.                                 //流水灯效果 循环右移
  67.                                 P4=0xff;                       //熄灭所有指示灯
  68.                                 update4094();
  69.                                    LED_contrl=0x01;               //初始化指示灯控制字节
  70.                                 delay_ms(50);                 //延时300MS
  71.                                 for(i=0;i<8;i++)
  72.                         {
  73.                         P4=~LED_contrl;            //点亮控制字节相应指示灯
  74.                             update4094();
  75.                                         delay_ms(50);
  76.                                         LED_contrl<<=1;
  77.                         }
  78.                                 P4=0xff;                       //熄灭所有指示灯
  79.                                 update4094();
  80.                                 break;
  81.                 case 2: //将收到的命令返回给串行口
  82.                                 putchar2(first);      //起始字  
  83.                                 putchar2(zjgs);       //字节个数
  84.                                 putchar2(order);      //命令码
  85.                                 putchar2(zhen_xh);    //帧序号
  86.                                 putchar2(jym);        //校验码
  87.                                 putchar2(end);      //结束字
  88.                                 //流水灯效果 从左到右逐个点亮
  89.                                 P4=0xff;         //熄灭所有指示灯
  90.                             update4094();
  91.                                 LED_contrl=0xff;   //初始化指示灯控制字节
  92.                                 delay_ms(50);
  93.                                   for(i=0;i<8;i++)
  94.                              {
  95.                                        LED_contrl<<=1;
  96.                                     P4=LED_contrl;
  97.                                         update4094();
  98.                                         delay_ms(50);
  99.                 }
  100.                                 break;
  101.                 case 3: //将收到的命令返回给串行口
  102.                                 putchar2(first);      //起始字  
  103.                                 putchar2(zjgs);       //字节个数
  104.                                 putchar2(order);      //命令码
  105.                                 putchar2(zhen_xh);    //帧序号
  106.                                 putchar2(jym);        //校验码
  107.                                 putchar2(end);      //结束字
  108.                                 //流水灯效果  循环对撞
  109.                                 P4=0xff;          //熄灭所有指示灯
  110.                                 update4094();
  111.                                 contrl_1=0x02;   //初始化移位变量1
  112.                                 contrl_2=0x80;   //初始化移位变量2
  113.                                 delay_ms(50);
  114.                                   for(i=0;i<8;i++)
  115.                             {
  116.                             LED_contrl=contrl_1|contrl_2;
  117.                                           P4=~LED_contrl; //点亮控制字节相应指示灯
  118.                                      update4094();
  119.                                         delay_ms(50);
  120.                                           contrl_1<<=1;  //移位变量1左移1位
  121.                                            contrl_2>>=1;  //移位变量2右移1位
  122.                              }
  123.                 P4=0xff;                       //熄灭所有指示灯
  124.                                 update4094();
  125.                 break;
  126.                 default:break;
  127.         }
  128.         end:;

  129. }
  130. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

77

帖子

0

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