视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
ATmega128,AVR单片机AD采样
2025-09-30 19:45:16 责编:小OO
文档
/*

芯片: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<UCSR0C|=(1<异步操作,无奇偶校验,1位停止位,8位字符长度

}

//字节发送函数

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;

}

}下载本文

显示全文
专题