Linux GPIO模拟串口之硬件定时器

先记录下Linux GPIO模拟串口笔记。
串口协议:
起始位 + 8位数据 + 结束位  【不考虑校验位】
波特率:9600  【先实现9600】

串口发送: 按9600波特率对应的时间间隔,将10位bit数据发送出去。
0,x,x,x,x,x,x,x,x,1. x对应数据的8位。

不打算去兼容系统uart框架,太麻烦了。

网上整理的实现:
中断实现发送:实现对应9600的定时器,在定时器内发送对应Bit位。
一般高精度hrtimer实现,移植性强。
延时实现 :udelay(~~9600~~),发送对应bit位,耗cpu。

考虑cpu性能较弱,我这边用硬件定时器timer2来做定时器。

理论上:精度高于前两种,对cpu性能影响最小。

测试平台新唐N32926 主频240M ARM9, 性能太弱鸡。

对应定时器示例Code:

测试及验证精度:
查看系统时间中断的次数,
cat /proc/interrupts  | grep timer
对比系统timer中断次数的,算倍数关系。

#define DEF_BPS  9600

static irqreturn_t w55fa92_timer2_irq(int irq, void *dev_id);
static void w55fa92_clockevent_setmode(void)
{
    unsigned int val;

    val = __raw_readl(REG_TCSR2);
    val &= ~(0x03 << 27);

    __raw_writel(CLOCK_TICK_RATE / DEF_BPS/3, REG_TICR2); //采样3次
    val |= (TMR_PERIOD | TMR_COUNTEN | TMR_INTEN);
    __raw_writel(val, REG_TCSR2);
}

/*IRQ handler for the timer*/
static irqreturn_t w55fa92_timer2_irq(int irq, void *dev_id)
{
    __raw_writel(0x01, REG_TISR2);      /* clear TIF2 */
    /* 添加串口收发处理函数 */
    
	return IRQ_HANDLED;
}

static void __init w55fa92_clockevents_init(void)
{
    struct clk *clk = clk_get(NULL, "timer2");

    BUG_ON(IS_ERR(clk));
    clk_enable(clk);
    __raw_writel(0x00, REG_TCSR2);
    __raw_writel(0x01, REG_TISR2);

    if (request_irq
        (IRQ_TIMER2, w55fa92_timer2_irq, IRQF_TIMER, "timer2",
         NULL) != 0) {
        printk("register the keypad_irq failed!\n");
        return -1;
    }
}
后续添加其他部分code
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值