通用io模拟串口

2018-08-20  本文已影响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);
}






上一篇下一篇

猜你喜欢

热点阅读