返回信息流现在想一个单片机给另外一个单片机发送,另外一个单片机接收。发送可以,可是接收实现不了。是中断使用不当所致吗?
程序是这样的。
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "usart.h"
#include <avr/delay.h>
#include <inttypes.h>
#include "lcd_1.h"
//常量定义
#define BAUDRATE 2400 //波特率
#define F_CPU 1000000 //这个已经在makefile里面定义了
unsigned char rev = 0;
void init_USART(void)//USART 初始化
{
//USART 9600 8, n,1 PC上位机软件(超级终端等)也要设成同样的设置才能通讯
UCSRC = (1<<URSEL) | 0x06;
//异步,8位数据,无奇偶校验,一个停止位,无倍速
//U2X=0时的公式计算
UBRRL= (F_CPU/BAUDRATE/16-1)%256;
UBRRH= (F_CPU/BAUDRATE/16-1)/256;
UCSRA = 0x00;
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
//使能接收中断,使能接收,使能发送
}
void put_c(unsigned char c) //发送采用查询方式 发送字符
{
while( !(UCSRA & (1<<UDRE)) );
UDR=c;
}
void put_s(unsigned char *ptr)//发送采用查询方式 发送字符窜
{
while (*ptr)
{
put_c(*ptr++);
}
put_c(0x0D);
put_c(0x0A); //结尾发送回车换行
}
// 数据接收【以5 到8 个数据位的方式接收数 据帧】
unsigned char USART_Receive( void )
{
/* 等待接收数据*/
while ( !(UCSRA & (1<<RXC)) );
/* 从缓冲器中获取并返回数据*/
return UDR;
}
int main(void)
{
//DDRD=0xfe;//11111110
DDRD = 0XFF;
PORTD = 0Xff;
DDRB = 0XFF;
PORTB = 0X00;
init_USART();//USART初始化
sei();
while(1)
{
//put_c("a");
//_delay_ms(100);
Initialize_LCD();
Write_Position(1,1);
Write_String(rev);
//Write_Position(2,2);
//Write_String("gg");
//cli();
}
}
volatile char rev_data;
SIGNAL(SIG_UART_RECV)
{
rev_data = USART_Receive();
rev=rev_data;
}
这是接收部分,给一个单片机下载了。
另外一个则是把WHILE里注释符号去掉。把接收中断给注释了。
但是现在由发送,没有接收,是哪出错了呢?
这是一条镜像帖。来源:北邮人论坛 / circuit / #11080同步于 2009/7/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Circuit机器人发帖
急问,单片机相互通信的问题
Peggy718
2009/7/9镜像同步5 回复
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
你现在的做法把中断和查询两种方式揉到了一起。。。接收中断不是这么用的。
在接受中断里面只需要读UDR的值就可以了。
【 在 Peggy718 的大作中提到: 】
: 现在想一个单片机给另外一个单片机发送,另外一个单片机接收。发送可以,可是接收实现不了。是中断使用不当所致吗?
: 程序是这样的。
: #include <avr/io.h>
: ...................
应该怎么改?我改了之后进不了中断是怎么回事呢?是不是我改错了?
【 在 snowbluff 的大作中提到: 】
: 你现在的做法把中断和查询两种方式揉到了一起。。。接收中断不是这么用的。
: 在接受中断里面只需要读UDR的值就可以了。
要么就用查询方式,要么就用中断方式。不要两种一起用。
进不去中断的话得看你中断是否使能了?是否接收到数据?你怎么判断进没进中断?
【 在 pinkdreamer 的大作中提到: 】
: 应该怎么改?我改了之后进不了中断是怎么回事呢?是不是我改错了?
使能了,用了sei();
我在中断里加上是的PA输出高电平,用示波器看一直都是低电平。
【 在 snowbluff 的大作中提到: 】
: 要么就用查询方式,要么就用中断方式。不要两种一起用。
: 进不去中断的话得看你中断是否使能了?是否接收到数据?你怎么判断进没进中断?
你可以用PC的串口和单片机通信试一下。如果没接收到数据的话肯定是不会触发接收中断的。
我给你贴一个前一阵子写的mega8测试UART的实例吧。使用PC和mega8通信,PC发数据,单片机收到数据之后回传给PC。使用ICCAVR写的。
//ICC-AVR application builder : 2009-5-9 19:16:15
// Target : M8
// Crystal: 8.0000Mhz
#include <iom8v.h>
#include <macros.h>
int value;
void port_init(void)
{
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x0F; //m103 output only
DDRC = 0x0F;
PORTD = 0x00;
DDRD = 0x00;
}
//UART0 initialize
// desired baud rate: 38400
// actual: baud rate:38462 (0.2%)
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x0C; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0xD8;
}
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
//uart has received a character in UDR
value= UDR;
PORTC=value&0x0F;
//UDR=value;
while(!(UCSRA&(1<<UDRE)));//等待串口空闲。
UDR=value;
}
#pragma interrupt_handler uart0_tx_isr:iv_USART0_TXC
void uart0_tx_isr(void)
{
//character has been transmitted
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
uart0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main()
{
init_devices();
while(1);
}
【 在 pinkdreamer 的大作中提到: 】
: 使能了,用了sei();
: 我在中断里加上是的PA输出高电平,用示波器看一直都是低电平。