mega162串口通讯为什么有些字符接收正确,有些接收错误?
用mega162编了一段简单的异步通讯程序。在发送0x55时,接收正确为”U“,但是在发送54,56时,接收就不是正确的了。接收程序用的串口调试助手。程序如下,顺便问一下162写UCSR0C是否正确?
#include <iom162.h>
#include <stdio.h>
#define unch unsigned char
#define unit unsigned int
#define Set_Bit(val, bitn) (val |=(1<<(bitn))) //置位
#define Clr_Bit(val, bitn) (val&=~(1<<(bitn))) //位清零
#define Get_Bit(val, bitn) (val &(1<<(bitn)) ) //读位
void delay(unit i){
unit k,j;
for ( k=0;k<i;k++)
for ( j=0;j<100;j++);
}
void main(void) {
unch temp1=0x55;
unit baud=51;
DDRD=0XFF;
PORTD=0XFF;
DDRE=0X00;
PORTE=0X7; //3按键
for (;;){
if (PINE!=7){
delay (1000);
switch (PINE) //检查哪一按键动作
{
case 6: //发送一个字符
UBRR0H=(unch) baud>>8;
UBRR0L=(unch) baud;
Set_Bit(UCSR0B,3);
Set_Bit(UCSR0C,7);
UCSR0C=0XbE;
while(! Get_Bit(UCSR0A,5))
;
UDR0=temp1;
Clr_Bit(UCSR0B,3);
delay(8000);
break;
case 5://每位数字加一
temp1++;
if (temp1>0x5a)
temp1=0x55;
delay(8000);
break;
case 3://每位数字减一
temp1--;
if (temp1<0x41)
temp1=0x55;
delay(8000);
break;
}
}
}
} 使用iar编译的。奇怪用iar串口1调试,就不能用串口调试助手-串口2来接收到任何数据。 晶振x.xxxMHz?
电压?.?V?
...
问这种问题,请描述足够的条件。 主要在"临界频率"上徘徊... 电压4.95v,晶振用的是8M 1.加减baud试一下...
2.数据最好发送一个固定数...
3.将串口调试助手上的停止位暂时设为2... 我用162也发现这个问题了,不管发什么数据收到的都是0,我发现162的fuse与16有很大的不同,我以前是用16的,后来就为了用162中的两个UART所以才转到162上来的。结果就出了这个问题了,162中有个fuse是可以管外部时钟是否8分频的,我用的是7。3728M的晶振,默认是对外部时钟8分频,而且162中还有个寄存器可以对时钟进行分频,名字叫CLKPR。我现在想让UART0 以9600 N 8 1;UART1以4800 E 7 1的格式发数据,到我的计算机,但是我不知道该怎么设这些FUSE啊!我已经试了2天了!还是搞不定啊!
下面是我现在的程序关于UART的一部分,(源程序很大,就发点关键的吧)还请各位大虾指导。
void port_init(void)
{
DDRA= 0x00;
PORTA = 0xFF;
DDRB= 0b01001000;
PORTB = 0xFF;
DDRC= 0xFF;
PORTC = 0xFF;
DDRD= 0xFF;
PORTD = 0xFF;
PORTE = 0x07;
}
//UART1 initialisation
// desired baud rate: 4800
// actual: baud rate:4800 (0.0%)
// char size: 7 bit
// parity: Even
void uart1_init(void)
{
UCSR1B = 0x00; //disable while setting baud rate
UCSR1A = 0x00; //disable while setting baud rate
UCSR1C = 0b10100100;
UBRR1H = 0x00;
UBRR1L =95; //set baud rate
UCSR1B = 0b00011000; //enable
}
//UART0 initialisation
// desired baud rate:9600
// actual baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00; //disable while setting baud rate
UCSR0C = 0b10000110;
UBRR0H = 0x00;
UBRR0L =47; //set baud rate
UCSR0B = 0b00011000; //enable
}
//*******************************************uart字符输出***************************
void putchar(int upart,unsigned char charx)
//upart表示UART标号,0表示UART0,其他表示UART1;char0表示要发出的数据;
{
if(upart==0)
{
while(!UCSR0A&(1<<UDRE0));
UDR0=charx;
}
else
{
while(!UCSR1A&(1<<UDRE1));
UDR1=charx;
}
}
//******************************************uart字符输出函数结束***************
//*******************************带可选回车换行的字符串输出函数******
//upart表示发出数据使用的端口号0表示使用UART0,其他表示使用UART1;
//*s表示要发出数据的指针
//senter0表示结尾是否使用0x0d,0表示使用,其他表示不使用
//senter1表示结尾是否使用0x0a,0表示使用,其他表示不使用
//stringl表示所要输出的字符串长度,0表示无限制
void puts(unsigned char *s,int upart,int senter0,int senter1,int stringl)
{
int stringlon=0;
unsigned char outchar;
if(upart==0)
{
if(stringl==0)
{
while(*s)
{
outchar=*s;
putchar(0,outchar);
s++;
}
if(senter0==0)
putchar(0,0x0d);
if(senter1==0)
putchar(0,0x0a);
}
else
{
while(stringlon<=(stringl-1))
{
outchar=*(s+stringlon);
putchar(0,outchar);
stringlon++;
}
if(senter0==0)
putchar(0,0x0d);
if(senter1==0)
putchar(0,0x0a);
}
}
else
{
if(stringl==0)
{
while(*s)
{
outchar=*s;
putchar(1,outchar);
s++;
}
if(senter0==0)
putchar(1,0x0d);
if(senter1==0)
putchar(1,0x0a);
}
else
{
while(stringlon<=(stringl-1))
{
outchar=*(s+stringlon);
putchar(1,outchar);
stringlon++;
}
if(senter0==0)
putchar(1,0x0d);
if(senter1==0)
putchar(1,0x0a);
}
}
}
//************************************函数结束************************************
程序运行后就可以调用puts函数进行输出了但我现在不知道该如何设置MEGA162的熔丝位,也不知道该如何去写CLKPR才能使我的程序正常工作啊,我的晶振是7。3728M电源5V。还请各位大虾帮忙啊!
-----此内容被igoal于2005-03-10,21:58:43编辑过 while(!UCSR1A&(1<<UDRE1));
UDR1=charx
1.这2条语句颠倒一下,先写UDR1寄存器,在等待为空,反之死循环
2.熔丝位等,你可以循环点亮一个LED灯,很直观的就能看出来软件有没有跑起来
3.具体波特率要根据FUSE的clk8有关系,不过对错只影响发的数据对错,不影响发送的成败。{:biggrin:} 波特率问题,鉴定完毕。 igoal 发表于 2005-3-10 20:49 static/image/common/back.gif
我用162也发现这个问题了,不管发什么数据收到的都是0,我发现162的fuse与16有很大的不同,我以前是用16的 ...
用向导方式,CKDIV不要勾选,然后别的跟mega8的差不多,
页:
[1]