ATmega16单片机实现串口收发数据
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、编译环境:CodeVisionAVR
2、功能:实现以5AH开头的6个字节数据帧的接收及发送
3、接收及发送方式:中断接收,查询发送
4、校验方式:所有字节相加模除256等于0则接收正确,否则不予接收程序如下所示:#include "mega16.h"
#define uchar unsigned char #define uint unsigned int #define BAUD 9600 #define F_CLK 400000 0
#define MATCH_OK 1; #define MATCH_ERROR 0; #define UDRE 5
volatile uchar i=0;
volatile uchar recc_flag=0; //命令字节接收标志(recieve command 简写成 recc) volatile uchar comm_flag=0; //命令帧接收完毕标志(command 简写成 comm) volatile uchar comm; //定义变量,用于传递UDR0中接收到的命令字
volatile uchar command[6]={0x00,0x00,0x00,0x00,0x00,0x00}; //定义长度为6的数组用于接收长度为6字节的命令帧,并将所有元素初始化为0x00
/*延时*/
void delay(uint t) {
while(t--); }
/*****/
/*******帧头校验******/ uchar check_comm(void) {
uchar i;
uint result=0;
for(i=0;i<6;i++) {
result+=command[i]; }
if((result%256)==0) {
return MATCH_OK; } else {
return MATCH_ERROR; } }
/*********************/
void uart_init(void) {
UCSRA=0x00;
UCSRB=0x98; //接收结束中断使能;数据接收使能;数据发送使能
UCSRC=0x06; //工作在异步模式;无校验;1位停止位;字符长度为8位 UBRRH=(F_CLK/BAUD/16-1)/256;
UBRRL=(F_CLK/BAUD/16-1)%256; //系统时钟为4MHz,波特率为9600bps }
void init_device(void) {
#asm("cli") //关中断
PORTA=0x04; DDRA=0x04; PORTB=0xFE; DDRB=0xFF; PORTD=0xFF; DDRD=0x02; MCUCR=0x00; TIMSK=0x00;
uart_init(); //串口初始化
#asm("sei") //重开中断 }
interrupt[USART_RXC] void usart_rec(void) {
comm=UDR; recc_flag=1; }
/*****USART0口发送命令字节程序*****/ void usart0_transcomm(uchar x) {
while(!(UCSRA&(1<<UDRE))); //数据寄存器空时才能发送数据 UDR=command[x]; }
/**********************************/
/*****命令帧的单个字节存储程序******/ void save_single_byte(uchar y) {
if(y<6)
{command[y]=comm;} recc_flag=0; }
/***********************************/
/********命令帧保存程序********/ void save_comm(void) {
uchar mount=5;
if(recc_flag==1) //接收标志置位,说明接收到命令字,则存储 {
save_single_byte(i);
i++; //指向下一个数组元素 if(command[0]!=0x5A) {
i=0;
#asm("cli")
delay(1000000); #asm("sei") }
if(i==6) //若数组存满6个字节
{
comm_flag=1; //命令帧接收完毕,将接收完毕标志置位 } } }
/*****************************/
/******USART0发送命令帧程序******/ void send_comm(void) {
uchar j;
if(comm_flag==1) //命令帧接收完毕后才允许发送,////应在发送前进行校验,在此不予考虑//// {
#asm("cli")
if(check_comm()) {
for(j=0;j<6;j++) {
usart0_transcomm(j); //调用单字节发送程序 } }
#asm("sei") i=0; }
comm_flag=0; //命令帧发送完毕后,接收完毕标志清零 }
/*******************************/
/****主程序****/ void main(void) {
init_device();
while(1) {
save_comm(); send_comm(); }
}。