搜索
bottom↓
回复: 26

CVAVR的串口通信,希望对某些朋友有所帮助!!!

[复制链接]

出0入0汤圆

发表于 2006-1-6 16:44:33 | 显示全部楼层 |阅读模式
CVAVR的串口通信,希望对某些朋友有所帮助!!!

不要象我摸索了2天才把串口搞定!以下是用CVAVR的代码!



WHILE(1)中有详细说明!

用串口调试程序向M16发个16进制的数,M16接受到后,给PORTC和1602LCD显示并返回

应答!



----------------------------------------------------------------------------

/*****************************************************

Project :  M16---PC串口通信

Version :  V1.1

Date    : 2006-1-6

Author  : whoami                          

Company :   湘灵电子工作室 http://www.mculover.net                              

Comments:  如果上位机以16进制发送则接受正确 EXMP:发0X13 则

PORTC端口显示正确,LCD显示16进制数0X13

//如果以普通模式发送,发13则视为1,LCD和PORTC同时显示1的ASC-II玛



Chip type           : ATmega16L

Program type        : Application

Clock frequency     : 8.000000 MHz

Memory model        : Small

External SRAM size  : 0

Data Stack size     : 256

*****************************************************/



#include <mega16.h>

#include<lcd.h>



char lcd_buffer[33];



#asm

        .equ __lcd_port=0x18

#endasm





#define RXB8 1

#define TXB8 0

#define UPE 2

#define OVR 3

#define FE 4

#define UDRE 5

#define RXC 7



#define FRAMING_ERROR (1<<FE)

#define PARITY_ERROR (1<<UPE)

#define DATA_OVERRUN (1<<OVR)

#define DATA_REGISTER_EMPTY (1<<UDRE)

#define RX_COMPLETE (1<<RXC)



// USART Receiver buffer

#define RX_BUFFER_SIZE 8

char rx_buffer[RX_BUFFER_SIZE];

unsigned char rx_wr_index,rx_rd_index,rx_counter;

// This flag is set on USART Receiver buffer overflow

bit rx_buffer_overflow;  

unsigned char datamy;



// USART Receiver interrupt service routine

interrupt [USART_RXC] void usart_rx_isr(void)

{

char status,data;

status=UCSRA;

data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

   {

   rx_buffer[rx_wr_index]=data;

   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;

   if (++rx_counter == RX_BUFFER_SIZE)

      {

      rx_counter=0;

      rx_buffer_overflow=1;

      };

   };

}



#ifndef _DEBUG_TERMINAL_IO_

// Get a character from the USART Receiver buffer

#define _ALTERNATE_GETCHAR_

#pragma used+

char getchar(void)

{

char data;

while (rx_counter==0);

data=rx_buffer[rx_rd_index];

if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;

#asm("cli")

--rx_counter;

#asm("sei")

return data;

}

#pragma used-

#endif



// USART Transmitter buffer

#define TX_BUFFER_SIZE 8

char tx_buffer[TX_BUFFER_SIZE];

unsigned char tx_wr_index,tx_rd_index,tx_counter;



// USART Transmitter interrupt service routine

interrupt [USART_TXC] void usart_tx_isr(void)

{

if (tx_counter)

   {

   --tx_counter;

   UDR=tx_buffer[tx_rd_index];

   if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;

   };

}



#ifndef _DEBUG_TERMINAL_IO_

// Write a character to the USART Transmitter buffer

#define _ALTERNATE_PUTCHAR_

#pragma used+

void putchar(char c)

{

while (tx_counter == TX_BUFFER_SIZE);

#asm("cli")

if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))

   {

   tx_buffer[tx_wr_index]=c;

   if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;

   ++tx_counter;

   }

else

   UDR=c;

#asm("sei")

}

#pragma used-

#endif



// Standard Input/Output functions

#include <stdio.h>



// Declare your global variables here



void main(void)

{

// Declare your local variables here



// Input/Output Ports initialization

// Port A initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTA=0x00;

DDRA=0x00;



// Port B initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTB=0x00;

DDRB=0xff;



// Port C initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTC=0xff;

DDRC=0xff;



// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTD=0x00;

DDRD=0x00;



// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

// Mode: Normal top=FFh

// OC0 output: Disconnected

TCCR0=0x00;

TCNT0=0x00;

OCR0=0x00;



// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;



// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

ASSR=0x00;

TCCR2=0x00;

TCNT2=0x00;

OCR2=0x00;



// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

// INT2: Off

MCUCR=0x00;

MCUCSR=0x00;



// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;



// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: On

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud rate: 9600

UCSRA=0x00;

UCSRB=0xD8;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x33;



// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

// Analog Comparator Output: Off

ACSR=0x80;

SFIOR=0x00;



// Global enable interrupts            

#asm("sei")

  

//lcd init

        lcd_init(16);   



while (1)

      {

              // Place your code here

                     datamy=getchar();//datamy可以是上位机发给的

                   //datamy=24;//也可以是软件代码生成的10进制数!比如时钟,AD等

                       PORTC= datamy;//将数值赋值给PORTC显示,注意JTAG使能去掉

                       lcd_clear( );//清屏  

                       lcd_gotoxy(0,0);//定位XY坐标

                          sprintf(lcd_buffer,"The number is:
  0x%2x",datamy);//%X以16进制输出

                          lcd_puts(lcd_buffer);//如果不是以16进制,则show ASC-II on 1602

                         

                          printf("Return:
   0x%2x
",datamy);//向上位机发送数据!%2X以16进制显示

                                                                                                          //%2d以10进制显示

      };

}

出0入0汤圆

发表于 2006-2-9 11:54:16 | 显示全部楼层
能详细解释以下你的程序吗?

interrupt [USART_RXC] void usart_rx_isr(void)



void putchar(char c)

的程序是不是,接收电脑数据-外部数据接收-电脑数据发送-外部数据发送到串口?

出0入0汤圆

发表于 2006-3-15 16:24:11 | 显示全部楼层
to; whoami



请问:没接收到数据程序是否死在



datamy=getchar();//datamy可以是上位机发给的



这句上????

出0入0汤圆

 楼主| 发表于 2006-3-15 16:50:33 | 显示全部楼层
不会的

接受和发送数据都是采用中断的方式!

出0入0汤圆

发表于 2006-3-20 10:05:20 | 显示全部楼层
to; whoami

我用CVAVR V1.24.8b Professional 的代码向导生成的代码



// USART Receiver interrupt service routine

interrupt [USART_RXC] void usart_rx_isr(void)

{

char status,data;

status=UCSRA;

data=UDR;

if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)

   {

   rx_buffer[rx_wr_index]=data;

   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;

   if (++rx_counter == RX_BUFFER_SIZE)

      {

      rx_counter=0;

      rx_buffer_overflow=1;

      };

   };

}



#ifndef _DEBUG_TERMINAL_IO_

// Get a character from the USART Receiver buffer

#define _ALTERNATE_GETCHAR_

#pragma used+

char getchar(void)

{

char data;

while (rx_counter==0);  ??????????????就死在这里

data=rx_buffer[rx_rd_index];

if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;

#asm("cli")

--rx_counter;

#asm("sei")

return data;

}

#pragma used-

#endif



已证实是死在那里,请问是怎么回事?????

出0入0汤圆

 楼主| 发表于 2006-3-20 16:27:44 | 显示全部楼层
但是我用的是1.24.1d Standard 确实可以通过的

而且

如果上位机以16进制发送则接受正确 EXMP:发0X13 则

PORTC端口显示正确,LCD显示16进制数0X13

//如果以普通模式发送,发13则视为1,LCD和PORTC同时显示1的ASC-II玛



是通过具体的实验得出的!

请你自己再看看有什么地方不对!

但是我也遇到过类似的情况:就是把1.24.1升级到1.24.4后,有些在1.24.1的代码放到1.24.4中也运行不了的情况!



由于最近其他的事情比较多,具体我也没仔细去研究!

出0入0汤圆

发表于 2006-4-3 17:57:14 | 显示全部楼层
我用AT88的芯片,外部晶振是18M,我用楼主的程序修改而成,UBRR0L=0x74;

编译和烧录都没有问题,可是发到PC上的数据确是乱码,我觉得应该是频率没有弄好,

可是又不知道怎么改才好

哪位知道的能否给我一点意见



谢谢

出0入0汤圆

发表于 2006-11-22 10:21:50 | 显示全部楼层
波特率的选择有一张表

根据你的需要 你自己选择

串口调试的时候你的波特率和程序里面的对应就OK了

出0入0汤圆

发表于 2006-12-10 23:52:39 | 显示全部楼层
正想学串口,谢谢了

出0入0汤圆

发表于 2008-4-29 09:27:03 | 显示全部楼层
mark

出0入4汤圆

发表于 2008-4-29 10:18:40 | 显示全部楼层
谢谢!

PS: whoami 恰好是 Linux 里的一个命令,哈哈。

出0入10汤圆

发表于 2008-5-30 14:43:12 | 显示全部楼层
学习

出0入0汤圆

发表于 2008-5-30 18:08:47 | 显示全部楼层
程序有点乱

出0入0汤圆

发表于 2008-5-30 18:14:16 | 显示全部楼层
谢谢。

出0入0汤圆

发表于 2008-5-30 18:23:37 | 显示全部楼层
不太喜欢用CV代码自动生成,初始化全在main()里

出0入0汤圆

发表于 2008-9-8 18:06:02 | 显示全部楼层
ddddddddddddddddd

出0入0汤圆

发表于 2009-8-5 16:25:56 | 显示全部楼层
最近做串口通信的程序,也是用CV的,每次都是刚烧玩程序后RXC位就变为1了,郁闷了好久。谢谢LZ,程序我拿去试试啦!

出0入0汤圆

发表于 2009-8-9 21:35:27 | 显示全部楼层
正在寻找,这个资料很少呀!

出0入0汤圆

发表于 2009-10-7 15:07:53 | 显示全部楼层
串口学了好多次程序都没有对,不知道是硬件还是程序出了问题

出0入0汤圆

发表于 2009-10-30 15:44:22 | 显示全部楼层
请问用CVAVR写一个简单的I2C程序怎么写啊?芯片AT24C02

出0入0汤圆

发表于 2009-11-5 17:12:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-4 18:43:02 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-9-29 19:19:36 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-23 16:08:25 | 显示全部楼层
正好需要学习,谢谢了

出0入0汤圆

发表于 2011-4-27 15:05:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-10 15:56:36 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-8 06:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表