芯片:ATmega128,AVR单片机
晶振:片内标定的RC 振荡器工作模式 7.3728MHz
程序功能:
最后调试时间:2012.7.3
备注:嵌入式作业,通过串口小助手发送并接受数据;
设计者:
*/
#include #include #include #include #include //常量声明 #define F_CPU7372800 #define BAUD115200 #define RX_BUFFER_SIZE256 struct ring_buffer//环形缓冲区 { unsigned char buffer[RX_BUFFER_SIZE]; unsigned int head; unsigned int tail; }; struct ring_buffer rx_bufferB={{0},0,0}; unsigned char RX_data1[256]={0}; unsigned char RX_data2[768]={0}; unsigned int num=0; unsigned char rev_dat[2]={0}; unsigned int i=0; //全局变量声明 unsigned char RX_data_OK=0; //函数声明 void Port_Init(void); //端口初始化配置 void Usart_Init(void); //USART寄存器设置 void AD_Init(void); //AD初始化 void Usart_PutChar(unsigned char cTXData); //字节发送函数 void Usart_PutString(unsigned char *pcString); // 字符串发送数据 void store_char(unsigned char ch, struct ring_buffer * rx_buffer);//向环形缓冲区存储一个字节 unsigned int available(struct ring_buffer * p);//缓冲区内有无数据判断函数 unsigned char read(struct ring_buffer * p);//从环形缓冲区中取一个元素 unsigned char get_data(struct ring_buffer * rx_data);//判断环形缓冲区中的数据是否大于0.5V,若大于返回值1 unsigned char panduan();//判断是否开始ADC,或者是否回传数据 int main(void) { Port_Init(); Usart_Init(); AD_Init(); sei(); //使能全局中断 while(1) { if(panduan()==1)//如果接收到0x68 0xc0 开始ADC转换 { if(RX_data_OK==1)//判断电压是否大于0.5V { eeprom_write_block (RX_data1,0x00,256);//将前256个数据存入单片机eeprom中256字节 eeprom_write_block (RX_data2,0x255,768);//将后768个数据存入单片机eeprom中768字节 } else while(1); } else if(panduan()==2)//如果接收到0x68 0xc1 回传数据 { eeprom_read_block(RX_data1,0x00,256); eeprom_read_block(RX_data2,0x255,768); for(i=0;i<256;i++) { Usart_PutChar(RX_data1[i]); } for(i=0;i<768;i++) { Usart_PutChar(RX_data2[i]); } } } } //端口状态初始化设置函数 void Port_Init() { PORTA = 0X00; DDRA = 0x00; //ADC通道设置为输入口,高阻态 } //USART寄存器配置函数 void Usart_Init() { //异步正常模式BAUD=(Fosc(16*(UBRR+1)))则,UBRR=(Fsoc/BAUD/16-1) UCSR0A=0x00; UBRR0H=(F_CPU/BAUD/16-1)/256; UBRR0L=(F_CPU/BAUD/16-1)%256;//%为取余运算符 UCSR0B|=(1< } //字节发送函数 void Usart_PutChar(unsigned char cTXData) { while( !(UCSR0A & (1 << UDRE0)) ); //只有数据寄存器为空时才能发送数据 UDR0 = cTXData; //发送数据送USART I/O数据寄存器-UDR } //接收中断函数 SIGNAL(SIG_UART0_RECV) { rev_dat[i++]= UDR0; //从USART I/O数据寄存器-UDR中读出数据 } unsigned char panduan()//判断是否开始ADC,或者是否回传数据 { unsigned char start_ADC_OK=0; if(rev_dat[0]==0x68 && rev_dat[1]==0xc0)//如果接收到0x68 0xc0 开始ADC转换 { start_ADC_OK=1; i=0; } else if(rev_dat[0]==0x68 && rev_dat[1]==0xc1)//如果接收到0x68 0xc1 回传数据 { start_ADC_OK=2; i=0; } return start_ADC_OK; } void Usart_PutString(unsigned char *pcString) { while (*pcString) { Usart_PutChar(*pcString++); } Usart_PutChar(0x0D); Usart_PutChar(0x0A); //结尾发送回车换行 } //AD转换初始化函数 void AD_Init() { ADMUX |= (1 << REFS0) | (1 << ADLAR); //ADC参考电压为AVcc,ADC结果左对齐,选择通道ADC0 ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1)| (1 << ADIE); //使能AD转换,ADC时钟分频,开中断 } unsigned char get_data(struct ring_buffer * rx_data)//判断环形缓冲区中的数据是否大于0.5V,若大于返回值1 { unsigned int length=0; unsigned char i=0; unsigned char data=0; length=available(rx_data);//缓冲区中字符个数 if(length>0) { for(i=0;i data=read(rx_data); if( data* 5010 / 1024 >= 0.5)//判断电压是否大于0.5V { RX_data1[i]=data; //并将256数据存到RX_data1[256]数组中; RX_data_OK=1; } else RX_data_OK=0; } } return RX_data_OK; } //从环形缓冲区中取一个元素 unsigned char read(struct ring_buffer * p) { // if the head isn't ahead of the tail, we don't have any characters if (p->head == p->tail) { return '#'; } else { unsigned char c = p->buffer[p->tail]; p->tail = (unsigned int)(p->tail + 1) % RX_BUFFER_SIZE; return c; } } //缓冲区内有无数据判断函数 unsigned int available(struct ring_buffer * p) { return (unsigned int)(RX_BUFFER_SIZE + p->head - p->tail) % RX_BUFFER_SIZE; } //向环形缓冲区存储一个字节 void store_char(unsigned char ch, struct ring_buffer * rx_buffer) { int i = (unsigned int)(rx_buffer->head + 1) % RX_BUFFER_SIZE; if (i != rx_buffer->tail) { rx_buffer->buffer[rx_buffer->head] = ch; rx_buffer->head = i; } } //AD转换中断并将接受的字符存入环形缓冲区 SIGNAL(SIG_ADC) { unsigned char rev_data0; if(RX_data_OK=0) { rev_data0=ADCH; store_char(rev_data0, &rx_bufferB);//应该可直接用rx_bufferB } else if(RX_data_OK=1) { RX_data2[num++] = ADCH; } }下载本文