分类:
2008-05-25 22:25:58
用UART串口以中断形式实现在超级终端中输入及显示字符。
之前做过一个小程序,用轮询等待的方式不断查看接收及发送缓冲区的状态,此方法只适用于实验而已,实用性并不强,因为需要不断的查询及等待,这样会对CPU造成极大的浪费。最好的解决方案当然是用中断来实现,中断的优点及在ARM应用中的重要作用,相信不用说谁都知道,所以对于中断应该深入的理解和学习。
用了一下午时间,刚开始看DATASHEET,熟悉各寄存器的作用及用法,接着着手写程序实现,起初只是实现了接收中断,在接收中断ISR中,读敢URXBUF中的数据,然后直接输出到UTXBUF,其间发生了不少错误,通过点LED灯一一调试通过了,这样虽然可以观查到同样的实验现象,但是其本质是有区别的,当超级终端输入数据很快时,出现数据覆盖的结果,造成输出不正确,解决办法就是需要有输出中断机制。但是很长一段时间里我一直在一个问题上纠缠不清,就是在发送中断ISR中应该做些什么及如何才能触发一个发送中断,想了一些办法,但是路总是越走越窄,因为之前就没有一个整体的思考。
其实实现的逻辑很简单,画个图表示:
超 ISR 用户程序
级 ------à URXBUF ---à RECV_BUF ----à ch = getchar()
终 ß---- UTXBUF ß---- SEND_BUF ß---- putchar(ch)
端 ISR 用户程序
外设的缓冲区只能存储一个CHAR型数据,所以当发生接收中断时,ISR中要做的事情只是将URXBUF中的CH存入用户自定义的缓冲区REVE_BUF,同理发送中断的ISR只是将SEND_BUF中的CH写入UTXBUF中,而用户主程序中要做的事情就是用getchar和putchar来操纵用户自己定义的两个缓冲区。通过这样的整体布局,框架就有了,之后的工作就是具体实现了。
在具体实现中有几个细节需要注意:
1、 ISR中和用户程序中对用户自定义的BUF进行读写时应操纵不同的数组下标,具体实现时我使用了4个下标。
2、 Getchar中应判断当前RECV_BUF中是否有数据可读,可通过比较对其操作的两个下标来判断。
3、 Putchar的操作是用户自定义的SEND_BUF,所以应该由用户来人为的触发一个发送中断,我是向UTXBUF中写入0X0来实现的,对这一步的操作应该还有更好的办法,只是我没有想到。
在写程序的过程中,走了不少弯路,浪费了很多宝贵的时间,在这里我总结的教训就是:
1、 首先应该充分理解需求是什么,在需求没有分析清楚之前绝对不要开始动手。
2、 在充分进行了需求分析之后,应该对实现有一个总体的框架,即整个程序的结构如何组织,这一步至关重要。以后应加强软件工程方面的学习,让自己慢慢形成这种良好的编程思想。
3、 注重细节,今天将一个0X<<10写成了0X<<16,调试了很久才发现,实在不应该。
chinaunix网友2008-07-03 19:09:25
呵呵,我是13期的,今儿做这题不会,网上一搜,来你的博客里,我一看不是自己人么。。 用户应该不负责发送中断吧?只是putchar就完了,其他的在别的C文件里实现,用户并不知道实现细节