太奇怪了,串口发数居然不按我的意思发,它倒着发,,,,请大侠指点
//ICC-AVR application builder : 2010-10-11 14:28:07// Target : M48
// Crystal: 7.3728Mhz
/*----------------------------------
#ifndef _Uart_h_
#define _Uart_h_
#include ".\head\SD2405.h"
//晶振和波特率
#define Fosc_CPU 7372800
#define Baud 9600
void Init_Uart0();
void Uart0_SendByte(uint8 u8_Data);
uint8 Uart_getchar();
void Uart_TXD_String(char *str,uint8 Enter);
//UART初始化函数
void Init_Uart0()
{
//允许收发打开接收中断
UCSR0B=(1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
UBRR0L=((Fosc_CPU/16/Baud)-1)%256;//设置波特率寄存器
UBRR0H=((Fosc_CPU/16/Baud)-1)/256;
UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);//8位数据+1位STOP
}
//字符输出
void Uart0_SendByte(uint8 u8_Data)
{
while(!(UCSR0A&(1<<UDRE0)));//上次发送有没有完成
UDR0=u8_Data;
}
//字符输入
uint8 Uart_getchar()
{
while(!(UCSR0A&(1<<RXC0)));//有没有接收到数据
return UDR0;
}
//*****************串口发送字符串******************************
// 入口参数: *str:字符串首地址
// ENTER:(回车换行) 1:不换行0:换行
// 出口参数: 无
// 函数功能: 从串口发送一字符串
//*************************************************************
void Uart_TXD_String(char *str,uint8 Enter)
{
while( *str )
{
Uart0_SendByte(*str);
str++;
}
if(Enter==0)
{
Uart0_SendByte(0x0D);
Uart0_SendByte(0x0A);
}
}
#pragma interrupt_handler uart0_rx_isr:19
void uart0_rx_isr(void)
{
//uart has received a character in UDR0
static uint8 number;
static uint8 Recevive_Data_Flag;//串口接收数据标志
static uint8 Uart_Recevive_Data={"0"};//串口接收数据缓存
if(UDR0==0x5a)
{
number=0;//包头已经到达
Recevive_Data_Flag=1;
}
if(Recevive_Data_Flag==1)
{
Uart_Recevive_Data=UDR0;
//Uart0_SendByte(UDR0);
number++;
//Uart_TXD_String("ok",0);
}
//Uart0_SendByte(Recevive_Data_Flag);
if(number==7)
{
SD2405Time.year=Uart_Recevive_Data;
SD2405Time.month=Uart_Recevive_Data;
SD2405Time.day=Uart_Recevive_Data;
SD2405Time.hour=Uart_Recevive_Data;
SD2405Time.minute=Uart_Recevive_Data;
SD2405Time.second=Uart_Recevive_Data;
//Recevive_Data_Flag==0;
SD2405_SetTime();
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
//Uart_TXD_String(Uart_Recevive_Data,0);
//Uart_TXD_String("ok,you have succeed",0);
}
}
#endif
如我发:5a 10 12 04 12 33 45 应该回5a 10 12 04 12 33 45 但它回的是45 5a 10 12 04 12 33,,请大侠指点啊,,,谢谢
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_602213EONHMX.jpg
(原文件名:ee.jpg)
http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_602214QS2T22.jpg
(原文件名:未命名.jpg) 把程序到过来不就对上了 这还要指点什么?你肯定是有个变量用来改变一个Buf中对应的buf。一看就知道你这个i没有确保发送完后清零。所以导致每次先发最后一个,再开始正常顺序发送的 回复【2楼】honami520
-----------------------------------------------------------------------
但是我是先判断if(UDR0==0x5a),所以Uart_Recevive_Data=0x5a是没有疑问的啊 那个不一定的,UDRO是个volatile变量, 你第一次比较时已经读过一次,第二次赋值时再读不一定还是这个值,你应该使用一个中间变量用于比较赋值。 回复【4楼】tomhe666 天煞孤星
-----------------------------------------------------------------------
下面这个程序在gcc上的结果是对的,但放在icc上不知怎么就不对了
void uart0_rx_isr(void)
{
//uart has received a character in UDR0
static uint8 number;
static uint8 Recevive_Data_Flag;//串口接收数据标志
static uint8 Uart_Recevive_Data={"0"};//串口接收数据缓存
if(UDR0==0x5a)
{
number=0;//包头已经到达
Recevive_Data_Flag=1;
}
if(Recevive_Data_Flag==1)
{
Uart_Recevive_Data=UDR0;
//Uart0_SendByte(UDR0);
number++;
//Uart_TXD_String("ok",0);
}
//Uart0_SendByte(Recevive_Data_Flag);
if(number==7)
{
SD2405Time.year=Uart_Recevive_Data;
SD2405Time.month=Uart_Recevive_Data;
SD2405Time.day=Uart_Recevive_Data;
SD2405Time.hour=Uart_Recevive_Data;
SD2405Time.minute=Uart_Recevive_Data;
SD2405Time.second=Uart_Recevive_Data;
//Recevive_Data_Flag==0;
SD2405_SetTime();
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
Uart0_SendByte(Uart_Recevive_Data);
//Uart_TXD_String(Uart_Recevive_Data,0);
//Uart_TXD_String("ok,you have succeed",0);
}
} 回复【4楼】tomhe666 天煞孤星
-----------------------------------------------------------------------
你应该使用一个中间变量用于比较赋值????????????????
不懂,能说详细点吗,谢谢 中断开始unsigned char udr_tmp = UDR0; 以后都使用udr_tmp来操作, UDR0就不要再使用了
另外:你这个中断在接收最后一个数据后, 进行的耗时巨大的发送工作, 建议把发送移到中断外部 回复【7楼】tomhe666 天煞孤星
-----------------------------------------------------------------------
多谢!我试试 回复【7楼】tomhe666 天煞孤星
-----------------------------------------------------------------------
对谢大哥的指点,按您的意思改过后结果就正确了
但我还有点不太明白这是为什么 由于avr的usart有2字节的缓冲,
UDR0做为读功能时, 是串口接收值的读取寄存寄,其值只能读取一次后....你再读,应该读的是另一个缓冲中的内容-_-
这种寄存器,当然是读一次就好,是常识,不要试图多次读取的说,指望它能一直保持数据多久? 回复【10楼】snoopyzz
-----------------------------------------------------------------------
讲的很好,谢谢了
读一次,测试结果很正确 串口收发用FIFO队列是个好习惯
页:
[1]