肥猫不吃鱼 发表于 2014-6-28 03:27:14

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

程序设置串口为38400bps.可以串口接收中断,PC每发一个数据,13脚上的灯就会翻转一次。loop函数一直输出“test”
先对比下寄存器和库编译后的大小,谈后在上代码。
差别还是非常明显的。
/*
注意:不要用arduino ide自带的串口助手打开,否则ide会崩溃//
*/

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

void PutChar(char c)
{
loop_until_bit_is_set(UCSR0A,UDRE0);
UDR0=c;
}
/*
函数功能:通过uart0发送字符串
*/
void PutString(char *str)
{
while(*str)
{
    PutChar(*str);
    str++;
}
}
/*
函数功能:通过uart0发送字符串 ,并在结尾加上回车换行
*/
void PutStringEnter(char *str)
{
while(*str)
{
    PutChar(*str);
    str++;
}
PutChar(0x0d);
PutChar(0x0a);
}
/*
USART0--接收中断//
*/
//ISR(USART_RX_vect)                                        //适合UNO
ISR(USART0_RX_vect)                                        //适合MEGA 2560
{
unsigned char temp;
temp=UDR0;
//bitSet(PINB,5);                                        //适合UNO                        翻转
bitSet(PINB,7);                                        //适合mega 2560                翻转
}
void setup()
{
//bitSet(DDRB,5);                                        //适合UNO                        输出
bitSet(DDRB,7);                                        //适合mega 2560                输出
RegisterInitUart();
//PutString("test");
}
void loop()
{
PutStringEnter("test");
}

wing 发表于 2014-6-28 09:45:02

寄存器操作,果然是高手

Super169 发表于 2014-6-28 23:17:49

很厲害, 很多看不懂的東西, 先收藏下來.

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

zhang164534 发表于 2014-8-13 08:26:33

好东西,,感谢楼主

拾瑞 发表于 2014-8-13 08:34:38

裸奔的AVR......

maxims 发表于 2014-10-1 14:16:22

寄存器操作应该会快于系统自带的函数吧?

maxims 发表于 2014-10-1 15:54:54

接收中断的问题。

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

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

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

肥猫不吃鱼 发表于 2015-3-13 12:08:18

maxims 发表于 2014-10-1 15:54 static/image/common/back.gif
接收中断的问题。

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


每接收一个字节中断一次。
可以设置上位机发送的格式如:起始标志+数据+校验+结束
在中断服务函数中检测起始标志,如果检测到起始标志则将后续的数据放入缓冲区,直至结束标志。
没有检测到起始标志就退出。
页: [1]
查看完整版本: 寄存器操作的串口驱动,支持串口接收中断。