极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: 肥猫不吃鱼

寄存器操作的串口驱动,支持串口接收中断。

[复制链接]
发表于 2014-6-28 03:27:14 | 显示全部楼层 |阅读模式
程序设置串口为38400bps.可以串口接收中断,PC每发一个数据,13脚上的灯就会翻转一次。loop函数一直输出“test”
先对比下寄存器和库编译后的大小,谈后在上代码。
差别还是非常明显的。

  1. /*
  2. 注意:不要用arduino ide自带的串口助手打开,否则ide会崩溃//
  3. */

  4. #define BAUD 38400
  5. void RegisterInitUart()
  6. {
  7.   //bitSet(UCSR0A,U2X0);
  8.   bitSet(UCSR0B,RXCIE0);                                        //允许接收完成中断//
  9.   bitSet(UCSR0B,RXEN0);                                                //开启接收功能//
  10.   bitSet(UCSR0B,TXEN0);                                                //开启发送功能//
  11.   bitSet(UCSR0C,UCSZ01);
  12.   bitSet(UCSR0C,UCSZ00);                                        //
  13.   UBRR0=(F_CPU/16/BAUD-1);                                        //波特率小于38400
  14. }
  15. /*
  16. 函数功能:通过uart0发送一个字符
  17. */

  18. void PutChar(char c)
  19. {
  20.   loop_until_bit_is_set(UCSR0A,UDRE0);
  21.   UDR0=c;
  22. }
  23. /*
  24. 函数功能:通过uart0发送字符串
  25. */
  26. void PutString(char *str)
  27. {
  28.   while(*str)
  29.   {
  30.     PutChar(*str);
  31.     str++;
  32.   }
  33. }
  34. /*
  35. 函数功能:通过uart0发送字符串 ,并在结尾加上回车换行
  36. */
  37. void PutStringEnter(char *str)
  38. {
  39.   while(*str)
  40.   {
  41.     PutChar(*str);
  42.     str++;
  43.   }
  44.   PutChar(0x0d);
  45.   PutChar(0x0a);  
  46. }
  47. /*
  48. USART0--接收中断//
  49. */
  50. //ISR(USART_RX_vect)                                        //适合UNO
  51. ISR(USART0_RX_vect)                                        //适合MEGA 2560
  52. {
  53.   unsigned char temp;
  54.   temp=UDR0;
  55.   //bitSet(PINB,5);                                        //适合UNO                        翻转
  56.   bitSet(PINB,7);                                        //适合mega 2560                翻转
  57. }
  58. void setup()
  59. {
  60.   //bitSet(DDRB,5);                                        //适合UNO                        输出
  61.   bitSet(DDRB,7);                                        //适合mega 2560                输出
  62.   RegisterInitUart();
  63.   //PutString("test");
  64. }
  65. void loop()
  66. {
  67.   PutStringEnter("test");
  68. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2014-6-28 09:45:02 | 显示全部楼层
寄存器操作,果然是高手
回复 支持 反对

使用道具 举报

发表于 2014-6-28 23:17:49 | 显示全部楼层
很厲害, 很多看不懂的東西, 先收藏下來.

請問樓主有關的資料, 可以在那裡找到?  
例如 UDR0 是在那裡定義的, 為何 PutChar 中設定 UDRO 的值就可以發出去?  
回复 支持 反对

使用道具 举报

发表于 2014-8-13 08:26:33 | 显示全部楼层
好东西,,感谢楼主
回复 支持 反对

使用道具 举报

发表于 2014-8-13 08:34:38 | 显示全部楼层
裸奔的AVR......
回复 支持 反对

使用道具 举报

发表于 2014-10-1 14:16:22 | 显示全部楼层
寄存器操作应该会快于系统自带的函数吧?
回复 支持 反对

使用道具 举报

发表于 2014-10-1 15:54:54 | 显示全部楼层
接收中断的问题。

我有一个想法,把串口收到的数据,按照一定的协议放到1602上边显示。
比方说:
Pc端发送过来的指令为“第一行,第三个字符,显示#”,协议为“1,3,#”

那么,我在中断中该怎么做?

1、接收中断发生后,是一直在中断中直到数据接收完?还是收一个字节中断一次?
2、接收中断发生后,我如何才知道我该收的数据收完了呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-3-13 12:08:18 | 显示全部楼层
maxims 发表于 2014-10-1 15:54
接收中断的问题。

我有一个想法,把串口收到的数据,按照一定的协议放到1602上边显示。

每接收一个字节中断一次。
可以设置上位机发送的格式如:起始标志+数据+校验+结束
在中断服务函数中检测起始标志,如果检测到起始标志则将后续的数据放入缓冲区,直至结束标志。
没有检测到起始标志就退出。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-12 08:50 , Processed in 0.039378 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表