打印
[牛人杂谈]

新塘M0用定时起捕获怎么做模拟串口Rx

[复制链接]
418|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)

使用特权

评论回复
板凳
xuanhuanzi| | 2019-10-26 21:03 | 只看该作者
/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url]     main.c
* [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
* $Revision: 4 $
* $Date: 14/01/28 11:45a $
* [url=home.php?mod=space&uid=247401]@brief[/url]    M051 Series Timer Driver Sample Code
*
* @note
* Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
******************************************************************************/
#include <stdio.h>
#include "M051Series.h"

#define PLLCON_SETTING      CLK_PLLCON_50MHz_HXT
#define PLL_CLOCK           50000000

unsigned int data;
unsigned int count;
unsigned int p_flag;
/**
* @brief       Timer0 IRQ
*
* @param       None
*
* [url=home.php?mod=space&uid=266161]@return[/url]      None
*
* [url=home.php?mod=space&uid=1543424]@Details[/url]     The Timer0 default IRQ, declared in startup_M051Series.s.
*/
void TMR0_IRQHandler(void)
{
    /* Clear Timer0 time-out interrupt flag */
     TIMER_ClearIntFlag(TIMER0);     
           if(count!=0)
                 {
                        if(data&0x01==0x01)
             P27=1;
                         else
                         P27=0;
                  data=data>>1;
                        count--;
                 }
       
}

void UART_GPIO(unsigned char uart_data)
{
        data=0;
        data=(uart_data<<1)|(1<<9);
        count=10;
}

void SYS_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init System Clock                                                                                       */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Enable IRC22M clock */
    CLK->PWRCON |= CLK_PWRCON_IRC22M_EN_Msk;

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

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

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

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

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

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

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

    /* Enable peripheral clock */
    CLK->APBCLK = CLK_APBCLK_UART0_EN_Msk |
                  CLK_APBCLK_TMR0_EN_Msk ;

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

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

    /*---------------------------------------------------------------------------------------------------------*/
    /* Init I/O Multi-function                                                                                 */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Set P3 multi-function pins for UART0 RXD, TXD */
    SYS->P3_MFP = SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0;
}

void UART0_Init(void)
{
    /*---------------------------------------------------------------------------------------------------------*/
    /* Init UART                                                                                               */
    /*---------------------------------------------------------------------------------------------------------*/
    /* Reset IP */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 Baudrate */
    UART_Open(UART0, 115200);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  MAIN function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
int main(void)
{
           int i;
    volatile uint32_t u32InitCount;

    /* Unlock protected registers */
    SYS_UnlockReg();

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

    /* Lock protected registers */
    SYS_LockReg();

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

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

    /* Enable Timer0 NVIC */
    NVIC_EnableIRQ(TMR0_IRQn);

    /* Start Timer0 counting */
    TIMER_Start(TIMER0);

    while(1){
                        if(count==0)
                        {
                        CLK_SysTickDelay(1000);
                        UART_GPIO(i);
                        i++;
                        }
                        }
}

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

使用特权

评论回复
地板
xuanhuanzi| | 2019-10-26 21:04 | 只看该作者
这是官方提供的M0系列的例子。M051系列可以直接运行。

使用特权

评论回复
5
zhuomuniao110| | 2019-10-26 23:59 | 只看该作者
楼上例子不错。

使用特权

评论回复
6
玛尼玛尼哄| | 2019-10-27 00:05 | 只看该作者
主要就是识别时序的问题。

使用特权

评论回复
7
mintspring| | 2019-10-27 16:44 | 只看该作者
是用的捕获吗,记不得了。

使用特权

评论回复
8
捉虫天师| | 2019-10-29 13:19 | 只看该作者
上面那个例子好像只是个发送的程序。

使用特权

评论回复
9
捉虫天师| | 2019-10-29 13:24 | 只看该作者
接收这个,好像一般51的单片机有用IO模拟的,可以参考一下。

使用特权

评论回复
10
捉虫天师| | 2019-10-29 13:26 | 只看该作者
sbit TXD1 = P0^4;        //定义模拟输出脚
sbit RXD1 = P3^2;   //定义模拟输入脚

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

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

unsigned char getchar2()        //模拟接收一个字节数据
{
        while (RXD1);
    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    delay_bps();
    SBUF1_bit0 = RXD1; //0      
    delay_bps();
    SBUF1_bit1 = RXD1; //1      
    delay_bps();
    SBUF1_bit2 = RXD1; //2      
    delay_bps();
    SBUF1_bit3 = RXD1; //3      
    delay_bps();
    SBUF1_bit4 = RXD1; //4      
    delay_bps();
    SBUF1_bit5 = RXD1; //5      
    delay_bps();
    SBUF1_bit6 = RXD1; //6      
    delay_bps();
    SBUF1_bit7 = RXD1; //7      
        delay_bps();
    return(SBUF1) ;      //返回读取的数据
}

void putchar2(unsigned char input)    //模拟发送一个字节数据
{
    SBUF1 = input;
    TXD1 = 0;  //起始位
    delay_bps();   
    TXD1 = SBUF1_bit0;  //0
    delay_bps();   
    TXD1 = SBUF1_bit1;  //1
    delay_bps();   
    TXD1 = SBUF1_bit2;  //2
    delay_bps();   
    TXD1 = SBUF1_bit3;  //3
    delay_bps();   
    TXD1 = SBUF1_bit4;  //4
    delay_bps();   
    TXD1 = SBUF1_bit5;  //5
    delay_bps();   
    TXD1 = SBUF1_bit6;  //6
    delay_bps();   
    TXD1 = SBUF1_bit7;  //7
    delay_bps();   
    TXD1 = 1;       //停止位
    delay_bps();   
}

使用特权

评论回复
11
捉虫天师| | 2019-10-29 13:26 | 只看该作者
#include <reg51.h>
#include "delay.h"
#include "sub4094.c"
#include <intrins.h>
sbit spk = P2^5;    //定义蜂鸣器使用的I/O口P2.5
sbit LED = P2^7;
#include "subuart2.c"


void main (void)
{
unsigned char first,zjgs,order,zhen_xh,jym,end;  //定义起始字、字节个数、命令码、帧序号、校验码、结束字
unsigned char i;       //定义1个随机变量
unsigned char sum;     //定义单片机计算用的校验码
unsigned char LED_contrl;  //指示灯控制字
unsigned contrl_1,contrl_2; //移位变量
//unsigned int delay_counter;
P5=0xEF;   //使能流水灯,屏蔽数码管
P4=0x00;      //流水灯全部点亮       
update4094(); //刷新流水灯状态
delay_ms(300);
P4=0xFF;      //流水灯全部熄灭
update4094(); //刷新流水灯状态
while(1)
{
        first=getchar2();   //读取6个数据进行处理。
        zjgs=getchar2();
        order=getchar2();
        zhen_xh=getchar2();
        jym=getchar2();
        end=getchar2();
        if(0xfa != first) goto end;
        sum=zjgs+order+zhen_xh;
        if(sum != jym)
        {
                putchar2(0xfa);   //起始字
                putchar2(0x07);    //字节个数
                sum=0x07;
                putchar2(order);   //接收到的命令码
                sum+=order;
                putchar2(zhen_xh); //接收到的帧序号
        putchar2(0x00);    //命令校验错误标志位
                sum+=zhen_xh;
                putchar2(sum);     //校验码
                putchar2(0xfb);
                //蜂鸣器发出报警声音,指示灯闪烁
                for(i=0;i<8;i++)  
                {
                    LED=~LED;     //取反指示灯
                        spk=~spk;     //取反蜂鸣器
                        delay_ms(200);
                }
                goto end;
        }
        if(0xfb != end) goto end;
        switch(order)
        {
                case 1: //将收到的命令返回给串行口
                                LED=0;
                                putchar2(first);      //起始字  
                                putchar2(zjgs);       //字节个数
                                putchar2(order);      //命令码
                                putchar2(zhen_xh);    //帧序号
                                putchar2(jym);        //校验码
                                putchar2(end);      //结束字
                                delay_ms(50);
                                LED=1;
                                //流水灯效果 循环右移
                                P4=0xff;                       //熄灭所有指示灯
                                update4094();
                                   LED_contrl=0x01;               //初始化指示灯控制字节
                                delay_ms(50);                 //延时300MS
                                for(i=0;i<8;i++)
                        {
                        P4=~LED_contrl;            //点亮控制字节相应指示灯
                            update4094();
                                        delay_ms(50);
                                        LED_contrl<<=1;
                        }
                                P4=0xff;                       //熄灭所有指示灯
                                update4094();
                                break;
                case 2: //将收到的命令返回给串行口
                                putchar2(first);      //起始字  
                                putchar2(zjgs);       //字节个数
                                putchar2(order);      //命令码
                                putchar2(zhen_xh);    //帧序号
                                putchar2(jym);        //校验码
                                putchar2(end);      //结束字
                                //流水灯效果 从左到右逐个点亮
                                P4=0xff;         //熄灭所有指示灯
                            update4094();
                                LED_contrl=0xff;   //初始化指示灯控制字节
                                delay_ms(50);
                                  for(i=0;i<8;i++)
                             {
                                       LED_contrl<<=1;
                                    P4=LED_contrl;
                                        update4094();
                                        delay_ms(50);
                }
                                break;
                case 3: //将收到的命令返回给串行口
                                putchar2(first);      //起始字  
                                putchar2(zjgs);       //字节个数
                                putchar2(order);      //命令码
                                putchar2(zhen_xh);    //帧序号
                                putchar2(jym);        //校验码
                                putchar2(end);      //结束字
                                //流水灯效果  循环对撞
                                P4=0xff;          //熄灭所有指示灯
                                update4094();
                                contrl_1=0x02;   //初始化移位变量1
                                contrl_2=0x80;   //初始化移位变量2
                                delay_ms(50);
                                  for(i=0;i<8;i++)
                            {
                            LED_contrl=contrl_1|contrl_2;
                                          P4=~LED_contrl; //点亮控制字节相应指示灯
                                     update4094();
                                        delay_ms(50);
                                          contrl_1<<=1;  //移位变量1左移1位
                                           contrl_2>>=1;  //移位变量2右移1位
                             }
                P4=0xff;                       //熄灭所有指示灯
                                update4094();
                break;
                default:break;
        }
        end:;

}
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

72

帖子

0

粉丝