linux系统硬件定时器中断,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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值