c51,单片机从串口接收字符串,放到一个数组里面,然后在通过串口发出去。急!谢谢
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar data table[10]; //暂存数组,可以将10改为你需要的数值
/***********************************************
串行口初始化波特率9600,定时器1,工作方式2 *************************************************/
void serial_init(void)
{
TMOD=0x20;//计时器1作为比特率发生器,方式2
TH1=0xfd;
TL1=0xfd; //装入初值
TR1=1;//计时中断允许
SM0=0;
SM1=1;//串行口工作于方式2
ES=1;//串行口中断允许
REN=1;//接收允许
EA=1;// 总中断允许
}
/********************* **************************
串行口传送数据
传送显示数组各字符给计算机
*************************************************/
void send(uchar *dis)
{
while(*dis!='\0')
{
SBUF=*dis;
dis++;
while(!TI);
TI=0; //软件请发送中断
}
}
void main()
{
serial_init();//初始化
while(SBUF!=0x0d);//计算机键盘按下回车键,则开始将接收到的数据回传给计算机
send(table);
}
/***********************************************
串行中断服务函数
单片机接收数据,存入table数组
*************************************************/
void serial() interrupt 4
{
int i;
ES=0; //关串口中断
table[i++]=SBUF;//命令存到命令数组
RI=0; //软件清除接收中断
ES=1;//开串口中断
}
已经通过proteus仿真如下
//芯片:mega16
#include <ioavr.h>
#define F 8000000
#define BAUD 9600
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
void usart_init(void);
char get_char(void);
void put_char(char c);
#define RX_SIZE 20
#define TX_SIZE 20
char rx[RX_SIZE];
u8 rx_head,rx_rear,rx_overflow;
char tx[TX_SIZE];
u8 tx_head,tx_rear,tx_overflow;
int main(void)
{
usart_init();
put_char( 'a' );
put_char( 'b' );
put_char( 'c' );
put_char( 'd' );
put_char( 'e' );
while(1)
put_char(get_char());
}
void usart_init(void)
{
UCSRB = (1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);//接收结束中断使能,发送结束中断使能,接收允许,发送允许
UCSRC = 0X86; //选择UCSRC,异步模式,无校验,1位停止位,8位数据位
UBRRH = (F/16/BAUD - 1)>>8; //选择UBRRH,设置波特率
UBRRL = (unsigned char)(F/16/BAUD - 1);
rx_head = 0;
rx_rear = 0;
rx_overflow = 0;
tx_head = 0;
tx_rear = 0;
tx_overflow = 0;
asm("sei");
}
char get_char(void)
{
char c;
while(rx_head == rx_rear);//如果接收缓冲区空,则一直等待
c = rx[rx_head++]; //从头取数据,头+1
if(rx_head >= RX_SIZE ) rx_head = 0;//若头超出缓冲区末端,移至缓冲区开端
return c;
}
void put_char(char c)
{
if(tx_head != tx_rear || !( UCSRA&(1<<UDRE) ) )//若 发送缓冲区非空 或 发送寄存器非空
{
tx[tx_rear++] = c;//将c移至缓冲区尾,尾+1
if(tx_rear >= TX_SIZE ) tx_rear = 0;//若尾超出缓冲区末端,移至缓冲区开端
if(tx_rear == tx_head)//若尾前进到头,说明缓冲区满
{
tx_overflow = 1;//缓冲区溢出 (事实上刚好不溢出,这里为了编程方便,牺牲一个字节并记为溢出)
tx_head++;//牺牲最早接收的那个字节
}
}
else
UDR = c;//直接发送
}
#pragma vector = USART_RXC_vect
__interrupt void receive(void)
{
rx[rx_rear++] = UDR;
if(rx_rear >= RX_SIZE ) rx_rear = 0;//若尾超出缓冲区末端,移至缓冲区开端
if(rx_rear == rx_head)//若尾前进到头,说明缓冲区满
{
rx_overflow = 1;//缓冲区溢出 (事实上刚好不溢出,这里为了编程方便,牺牲一个字节并记为溢出)
rx_head++;//牺牲最早接收的那个字节
}
}
#pragma vector = USART_TXC_vect
__interrupt void transmit(void)
{
if(tx_head != tx_rear)//如果发送缓冲区非空
{
UDR = tx[tx_head++];//发送头数据,头+1
if(tx_head >= TX_SIZE) tx_head = 0;//若头超出缓冲区末端,移至缓冲区开端
}
}
例如:
if(RI)
{
for(i=0;i<4;i++)
{
while(!RI); //查询接收标志
RI=0;
shou_shu[i]=SBUF; //创建一个4元素的数组
}
}
个数不固定,最长218个字节。最后一个为前面所有字节的异或校验和。
个数不固定,还没不知怎么处理,在此学习。