美文网首页
通用io模拟串口

通用io模拟串口

作者: 嵌入式工作 | 来源:发表于2018-08-20 16:41 被阅读0次

    移植方法


    image.png

    .h文件

    #ifndef MCU_IO_H____
    #define MCU_IO_H____
    
    /*
    共10bit(bit0-->0  bit1---bit8  bit9-->1 )
    1uart通讯协议是以8个bit为 一帧,传输的时候低位在前,高位在后
    2为了区分每一个帧的开头,在每一帧之前,要有一个0作为开头,之后就是传输的8bit字节,传输8bit后跟一个1,最为结束
    3在1之后,有的通讯还发送一个校验位,目前大部分是不要校验位的,这里也不要
    
    波特率 bps  位每秒
    以9600bps来传送数据时,每一位持续的时间是 (1/9600)s
    每一位的时间 tus=1000000/baud  9600-->104.17us
    
    技巧:为了接收的不错位,接收到开始位,后等待半个周期再接收数据
    */
    
    
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    
    typedef unsigned char  uart_u8;
    typedef unsigned short  uart_u16;
    typedef unsigned long  uart_u32;
    typedef void (*tx_high_fun)(void);
    typedef void (*tx_low_fun)(void);
    typedef bool (*rx_value_fun)(void);
    
    
    void  need_timer_call(void);    //Timer time to call
    void  need_rx_hight2low_call(void);//rx irq high to low call
    void need_write_byte(uart_u8 *pdata,uart_u16 len); //uart send data
    bool need_read_byte(uint8_t *pdata);//uart read data,if read one ,return true
    
    /*
    init interface
    baud :wanted baud
    txfunhigh:tx pin hight function
    txfunlow:tx pin low function
    rxvalue:read rx pin value function
    
    return: The time, in us, required
    */
    int need_init(int baud,tx_high_fun txfunhigh,tx_low_fun txfunlow,rx_value_fun  rxvalue);
    
    
    
    
    
    
    /*example*/
    
    #if 0
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    
    #include "driver/gpio.h"
    
    #include "esp_log.h"
    #include "esp_system.h"
    
    
    #include "string.h"
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    
    #include "esp_log.h"
    
    #include "driver/gpio.h"
    #include "driver/hw_timer.h"
    
    #define MCU_IO_GPIO_RX_PIN  13
    #define MCU_IO_GPIO_TX_PIN   12  
    
    
    void tx_hight(void)
    {
     gpio_set_level(MCU_IO_GPIO_TX_PIN, 1) 
    
    }
    
    void tx_low(void)
    {
     gpio_set_level(MCU_IO_GPIO_TX_PIN, 0) 
    
    }
    
    bool rx_value(void)
    {
    return gpio_get_level(MCU_IO_GPIO_RX_PIN) ? true :false;
    }
    static void rx_gpio_isr_handler(void *arg)
    {
    need_rx_hight2low_call();
    
    }
    
    
    static void hw_timer_callback(void *arg)
    {
    need_timer_call();
    }
    void init_debug_uart(void)
    {
    
    
    
        gpio_config_t io_conf;
        //disable interrupt
        io_conf.intr_type = GPIO_INTR_DISABLE;
        //set as output mode
        io_conf.mode = GPIO_MODE_OUTPUT;
        //bit mask of the pins that you want to set,e.g.GPIO15/16
        io_conf.pin_bit_mask = 1ULL<<MCU_IO_GPIO_TX_PIN;
        //disable pull-down mode
        io_conf.pull_down_en = 0;
        //disable pull-up mode
        io_conf.pull_up_en = 0;
        //configure GPIO with the given settings
        gpio_config(&io_conf);
    
        gpio_set_level(MCU_IO_GPIO_TX_PIN, 1);
    
    
        //disable interrupt
        io_conf.intr_type = GPIO_INTR_NEGEDGE;
        //set as output mode
        io_conf.mode = GPIO_MODE_INPUT;
        //bit mask of the pins that you want to set,e.g.GPIO15/16
        io_conf.pin_bit_mask = 1ULL<<MCU_IO_GPIO_RX_PIN;
        //disable pull-down mode
        io_conf.pull_down_en = 0;
        //disable pull-up mode
        io_conf.pull_up_en = 0;
        //configure GPIO with the given settings
        gpio_config(&io_conf);
    
       gpio_install_isr_service(0);
       gpio_isr_handler_add(MCU_IO_GPIO_RX_PIN, rx_gpio_isr_handler, (void *)(MCU_IO_GPIO_RX_PIN));
    
    
        hw_timer_init(hw_timer_callback, NULL);
        hw_timer_alarm_us(need_init(4800,tx_hight,tx_low, rx_value), true);
    
    }
    
    #endif
    
    
    
    #endif
    
    
    
    
    

    .c文件

    #include "mcu_io_uart.h"
    
    #define USE_TIMER  2
    tx_high_fun need_tx_high;
    tx_low_fun need_tx_low;
    rx_value_fun need_rx_value;
    void irq_write_byte(void);
    static void irq_data_data(void);
    
    
    static uart_u8 tickr=0,wait_rev_data=0,rev_data=0,rev_err=0,r_bit=0;
    
    //定时器时间到调用
    void  need_timer_call(void)
    {
        static uart_u8 tick;
        tick++;
        tickr++;
        if(tick>=USE_TIMER)
        {
            tick=0;
            irq_write_byte();
        }
    
        irq_data_data();
    
    
    
    }
    
    
    //rx管脚低电平中断带哦用
    void  need_rx_hight2low_call(void)
    {
    
        if(wait_rev_data) return;
    //    while(NED_READ_RX()==0);
    
        tickr=0;
        rev_data=0;
        wait_rev_data=1;
        rev_err=0;
        r_bit=0;
    
    
    
    }
    
    #define DATA_LEN 256
    uart_u8 Rbuf[DATA_LEN];
    uart_u16 in=0,out=0;
    //uart read data,if read one ,return true
    bool need_read_byte(uint8_t *pdata)
    {
    
        if(in==out)
        {
            return false;
        }
        else
        {
            *pdata = Rbuf[out];
            out++;
            out%=DATA_LEN;
            return true;
        }
    }
    
    #if (USE_TIMER == 4)
    const uart_u8 bit8num[9]= {6,10,14,18,22,26,30,34,38};
    #else (USE_TIMER == 2)
    const uart_u8 bit8num[9]= {3,5,7,9,11,13,15,17,19};
    #endif
    
    static void irq_data_data(void)
    {
    #define TIME_BIT(A)  (USE_TIMER/2+USE_TIMER*(A+1))
        if(wait_rev_data == 0 || tickr == 0)return ;
    
    
    //       if(bit8num[r_bit]==tickr)
    //        {
    //            if(NED_READ_RX() && r_bit<=7)
    //            {
    //            rev_data|=0x01<<r_bit;
    //            }
    //            if(r_bit==8 && (0==NED_READ_RX()))
    //            {
    //                rev_err=1;
    //                return;
    //            }
    //            r_bit++;
    //        }else  if(tickr==(10*USE_TIMER))
    //        {
    //
    //            if(0==rev_err)
    //            {
    //            Rbuf[in]=rev_data;
    //            in++;
    //            in%=DATA_LEN;
    //            }
    //            wait_rev_data=0;
    //        }
    
        if(bit8num[r_bit]==tickr)
        {
            if(need_rx_value() && r_bit<=7)
            {
                rev_data|=0x01<<r_bit;
            }
            if(r_bit==8 )
            {
                if(need_rx_value())
                {
                    Rbuf[in]=rev_data;
                    in++;
                    in%=DATA_LEN;
                }
                wait_rev_data=0;
                return;
            }
            r_bit++;
        }
    
    
    }
    
    static volatile uart_u8 *dta;
    static volatile uart_u16 max_slen;
    static volatile uart_u8 s_bits,s_bytes;
    void irq_write_byte(void)
    {
        uart_u8 n;
    
        if(max_slen == 0 )return;
        if( 0==s_bits )
        {
            need_tx_low();
        }
        else if( 9==s_bits )
        {
            need_tx_high();
            s_bytes++;
            if(max_slen==s_bytes)
            {
                max_slen=0;
    
            }
            s_bits=0;
            return;
        }
        else
        {
            n=((dta[s_bytes]>>(s_bits-1))&0x01);
            if(n)
            {
                need_tx_high();
            }
            else
            {
                need_tx_low();
            }
        }
        s_bits++;
    
    }
    
    
    //uart send data
    void need_write_byte(uart_u8 *pdata,uart_u16 len)
    {
    
    //    while(max_slen);
        s_bits=0;
        s_bytes=0;
        dta=pdata;
        max_slen = len;
        while(max_slen);
    
    
    }
    
    /*
    init interface
    baud :wanted baud
    txfunhigh:tx pin hight function
    txfunlow:tx pin low function
    rxvalue:read rx pin value function
    
    return: The time, in us, required
    */
    int need_init(int baud,tx_high_fun txfunhigh,tx_low_fun txfunlow,rx_value_fun  rxvalue)
    {
    
     need_tx_high=txfunhigh;
     need_tx_low=txfunlow;
     need_rx_value=rxvalue;
    
     return (1000000/USE_TIMER/baud);
    }
    
    
    
    
    
    
    

    相关文章

      网友评论

          本文标题:通用io模拟串口

          本文链接:https://www.haomeiwen.com/subject/xgyliftx.html