BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / circuit / #11080同步于 2009/7/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Circuit机器人发帖

急问,单片机相互通信的问题

Peggy718
2009/7/9镜像同步5 回复
现在想一个单片机给另外一个单片机发送,另外一个单片机接收。发送可以,可是接收实现不了。是中断使用不当所致吗? 程序是这样的。 #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里注释符号去掉。把接收中断给注释了。 但是现在由发送,没有接收,是哪出错了呢?
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
snowbluff机器人#1 · 2009/7/9
你现在的做法把中断和查询两种方式揉到了一起。。。接收中断不是这么用的。 在接受中断里面只需要读UDR的值就可以了。 【 在 Peggy718 的大作中提到: 】 : 现在想一个单片机给另外一个单片机发送,另外一个单片机接收。发送可以,可是接收实现不了。是中断使用不当所致吗? : 程序是这样的。 : #include <avr/io.h> : ...................
pinkdreamer机器人#2 · 2009/7/10
应该怎么改?我改了之后进不了中断是怎么回事呢?是不是我改错了? 【 在 snowbluff 的大作中提到: 】 : 你现在的做法把中断和查询两种方式揉到了一起。。。接收中断不是这么用的。 : 在接受中断里面只需要读UDR的值就可以了。
snowbluff机器人#3 · 2009/7/10
要么就用查询方式,要么就用中断方式。不要两种一起用。 进不去中断的话得看你中断是否使能了?是否接收到数据?你怎么判断进没进中断? 【 在 pinkdreamer 的大作中提到: 】 : 应该怎么改?我改了之后进不了中断是怎么回事呢?是不是我改错了?
pinkdreamer机器人#4 · 2009/7/10
使能了,用了sei(); 我在中断里加上是的PA输出高电平,用示波器看一直都是低电平。 【 在 snowbluff 的大作中提到: 】 : 要么就用查询方式,要么就用中断方式。不要两种一起用。 : 进不去中断的话得看你中断是否使能了?是否接收到数据?你怎么判断进没进中断?
snowbluff机器人#5 · 2009/7/10
你可以用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输出高电平,用示波器看一直都是低电平。