⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于AVR单片机 Atmel Mega128的AD采集程序。
💻 C
字号:
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <inttypes.h>
#include "adc_sram.h"
#include "macro.h"
//全局变量////////////////////////////
uint8_t global_flag_serie;//通信状态标志
uint16_t global_ad_counter;//AD转换计数器
uint8_t global_start_sample_flag;//采样开始标志
uint8_t global_sample_mode_flag;//采样方式标志:手动或自动
uint8_t global_operation_detected_flag;//检测到动作标志
uint16_t global_detect_close[5];//用于检测合闸动作开始
uint16_t global_detect_trip[5];//用于检测分闸动作开始
uint8_t global_channel_flag;//通道标志
uint16_t global_close_counter;//合闸线圈地址计数器
uint16_t global_trip_counter;//分闸线圈地址计数器
uint16_t global_motor_counter;//打压电机地址计数器
uint16_t global_voltage_counter;//操作电压地址计数器
uint8_t global_ad_finish_flag;//AD转换结束标志
//串口接收中断////////////////////////
SIGNAL(SIG_UART0_RECV)
{
//变量定义
	uint8_t temp_data;
	uint16_t i;
//关全局中断
    cli();
//等待接收到数据标志被置位
	loop_until_bit_is_set(UCSR0A,RXC0);
//对接收到的字节进行判断
	temp_data=UDR0;//读取接收的字节
	if(temp_data!=0)//如果接收到非零
	{
		if(global_flag_serie==0)//如果接收到的为第一字节
		{
			switch (temp_data)
			{
				case 2://接到本机地址
					global_flag_serie=1;//准备接收第二字节数据
					UCSR0A&=~(1<<MPCM0);//清零MPCM0,允许继续接收数据包
					break;
			//	case 0://接到复位命令
			//		global_start_sample_flag=0xff;//复位开始
			//		break;
				case 0x10://接到采集命令
					global_start_sample_flag=0;//开始采集数据
				//	sbi(PORTG,3);//测试用///////////////
					break;
			//	case 17://接到采集结束命令
				//	global_start_sample_flag=0xff;//结束采集数据
			//		break;
				case 0x22://接收到自动测试信号
					global_sample_mode_flag=0;
					break;
				default:
					break;
			}
		}
		else if((global_flag_serie==1)&&(temp_data<=32))//如果接收的是第二字节
		{
			for(i=0;i<0xfff;i++){;}//延时等待
			SEND_ONE_PACKAGE(temp_data);//发送数据包,temp_data为包序号
		//	if(temp_data==17){sbi(PORTG,3);}//测试用////////////
			global_flag_serie=0;
			UCSR0A|=(1<<MPCM0);//准备接收地址
		}
    }
	cbi(PORTE,2);//改为接收状态
	sei();
}

//AD转换结束中断int7//////////////////
SIGNAL(SIG_INTERRUPT7)
{
//变量定义
	uint16_t int16_temp1;
	uint8_t temp1,temp2,i;
//关中断
	cli();
//读取ad转换结果
	int16_temp1=AD7891_READ();
//如果是需要保存到RAM的采样
	if(global_sample_mode_flag==0xFF)
	{
	//AD7891 deselect,否则数据总线与RAM冲突
		sbi(PORTD,5);
	//AD转换结果存入RAM
		temp1=int16_temp1/256;
		temp2=int16_temp1%256;
	//保存数据
		switch(global_channel_flag)
		{
			case 1://保存合闸线圈电流
				SRAM_1M_8_WRITE(global_close_counter,temp1);//高位字节
				SRAM_1M_8_WRITE(global_close_counter+1,temp2);//低位字节
				global_close_counter+=2;
				break;
			case 2://保存分闸线圈电流
				SRAM_1M_8_WRITE(global_trip_counter,temp1);//高位字节
				SRAM_1M_8_WRITE(global_trip_counter+1,temp2);//低位字节
				global_trip_counter+=2;
				break;
			case 3://保存操作电压
			//	SRAM_1M_8_WRITE(global_motor_counter,temp1);//高位字节
			//	SRAM_1M_8_WRITE(global_motor_counter+1,temp2);//低位字节
				SRAM_1M_8_WRITE(global_voltage_counter,temp1);//高位字节
				SRAM_1M_8_WRITE(global_voltage_counter+1,temp2);//低位字节
				global_voltage_counter+=2;
			//	global_motor_counter+=2;
				break;
		//	case 4://保存操作电压
			//	SRAM_1M_8_WRITE(global_voltage_counter,temp1);//高位字节
			//	SRAM_1M_8_WRITE(global_voltage_counter+1,temp2);//低位字节
			//	global_voltage_counter+=2;
			//	break;
			default:
				break;
		}
	//计数器自加
		global_ad_counter++;
	}
//如果是检测动作是否开始的采样
	if(global_sample_mode_flag==0x00)
	{
	//采样轮转赋值
		//合闸线圈采样
		if(global_ad_counter%2==0)
		{
		//	global_detect_close[0]=int16_temp1;
			global_detect_close[0]=global_detect_close[1];
			global_detect_close[1]=global_detect_close[2];
			global_detect_close[2]=int16_temp1;
	//		global_detect_close[2]=int16_temp1;
		}
		//分闸线圈采样
		if(global_ad_counter%2==1)
		{
		//	global_detect_trip[0]=int16_temp1;
			global_detect_trip[0]=global_detect_trip[1];
			global_detect_trip[1]=global_detect_trip[2];
			global_detect_trip[2]=int16_temp1;
		//	global_detect_trip[2]=int16_temp1;
		}
	//判断是否有码值变化
		//判断合闸数据
		if((global_detect_close[0]>2046)&&(global_detect_close[1]>2046)&&(global_detect_close[2]>2046))//&&(global_detect_close[3]>2045)&&(global_detect_close[4]>2045))
		{
		//检测到动作标志赋值
			global_operation_detected_flag=1;
		}
	//	if(global_detect_close[0]>2049)
	//	{
	//		if((global_detect_close[1]-global_detect_close[0]>1)&&(global_detect_close[2]-global_detect_close[1]>1))//&&(global_detect_close[3]-global_detect_close[0]>1))
	//		{
			//检测到动作标志赋值
	//			global_operation_detected_flag=1;
	//		}
	//	}
		//判断分闸数据
		if((global_detect_trip[0]>2046)&&(global_detect_trip[1]>2046)&&(global_detect_trip[2]>2046))//&&(global_detect_trip[3]>2045)&&(global_detect_trip[4]>2045))
		{
		//检测到动作标志赋值
			global_operation_detected_flag=1;
		}
	//	if(global_detect_trip[0]>2049)
	//	{
	//		if((global_detect_trip[1]-global_detect_trip[0]>1)&&(global_detect_trip[2]-global_detect_trip[1]>1))//&&(global_detect_trip[3]-global_detect_trip[0]>1))
	//		{
			//检测到动作标志赋值
	//			global_operation_detected_flag=1;
	//		}
	//	}
	//	if(int16_temp1>2049)
	//	{
		//检测到动作标志赋值
	//		global_operation_detected_flag=1;
	//	}
		global_ad_counter++;
	}
//完成一次AD转换,将AD转换结束标志赋值
	global_ad_finish_flag=0xFF;
//开中断
	sei();
}

//主程序//////////////////////////////
int main()
{
//变量定义
	uint8_t i;
//初始化和串口波特率设置
	INITIATION();
//PG3供测试用/////////////
	sbi(DDRG,3);
	cbi(PORTG,3);
//开中断
	sei();
//自动测试标志初始化
	global_sample_mode_flag=0xFF;
//采集控制标志初始化
	global_start_sample_flag=0xFF;
//串口接收控制变量初始化
	global_flag_serie=0;
//开串口接收中断
	UART_RXCINT_OPEN();
//延时
	for(i=0;i<0xFF;i++)
	{
		TIMER_BEGIN();
		//等待定时器溢出,AD结束中断处理在等待过程中完成
		while(!(TIFR&(1<<OCF1A))){;}
		TIFR|=1<<OCF1A;
		//终止定时器
		TIMER_STOP();
	}
//数据采集流程
	while(1)
	{
	//检测动作开始标志清零
		for(i=0;i<4;i++){global_detect_close[i]=0;}
		for(i=0;i<4;i++){global_detect_trip[i]=0;}
	//如果自动测试
		if(global_sample_mode_flag==0x00)
		{
		//关串口接收中断
			UART_RXCINT_CLOSE();
		//开外部中断7(AD转换结束中断)
			EXTERN_INTERRUPT_OPEN(7);
		//检测采样
			OPERATION_DETECTION();
		//如果检测到有信号变化,向COUNTER发送开始采集命令
			sbi(UCSR0B,TXB8);//将TXB8置1
			UART_DATA_BYTE_SEND(0x10);//发送数据采集命令
		//开始采样
			SAMPLE();
		//关外部中断7
			EXTERN_INTERRUPT_CLOSE(7);
		//开串口接收中断,等待数据包传输命令
			UART_RXCINT_OPEN();
		//向主机发送采集结束命令0x33
			UART_DATA_BYTE_SEND(0x33);
		//自动测试标志复原
			global_sample_mode_flag=0xFF;
		}
	//如果接收到开始采集命令
		if(global_start_sample_flag==0x00)
		{
		//关串口接收中断
			UART_RXCINT_CLOSE();
		//开外部中断7(AD转换结束中断)
			EXTERN_INTERRUPT_OPEN(7);
		//采样
			SAMPLE();
		//关外部中断7
			EXTERN_INTERRUPT_CLOSE(7);
		//开串口接收中断,等待数据包传输命令
			UART_RXCINT_OPEN();
		//开始采集标志复原
			global_start_sample_flag=0xFF;
		}
	}
	
	for(;;){;}
	return 0;
}

/*final test//////////////////////////
	//变量定义
//初始化和串口设置,不包括串口中断开启
	INITIATION();
//PG3供测试用/////////////
	sbi(DDRG,3);
	cbi(PORTG,3);
//开中断
	sei();
//数据采集流程
	while(1)
	{
	//采集控制标志初始化
		global_start_sample_flag=0xFF;
	//开串口接收中断
		UART_RXCINT_OPEN();
	//等待采集控制标志
		while(global_start_sample_flag!=0x00){;}
	//关串口接收中断
		UART_RXCINT_CLOSE();
	//开外部中断7(AD转换结束中断)
		EXTERN_INTERRUPT_OPEN(7);
	//采样
		SAMPLE();
	//关外部中断7
		EXTERN_INTERRUPT_CLOSE(7);
	//开串口接收中断,等待数据包传输命令
		UART_RXCINT_OPEN();
	}
*/
/*timer test//////////////////////////
	sbi(DDRE,6);//用示波器看PE6的输出
	sbi(PORTE,6);
	TIMER_BEGIN();
	while(1)
	{
		PORTE=~PORTE;
		while(!(TIFR&(1<<OCF1A))){;}
		TIFR|=1<<OCF1A;
	}
	TIMER_STOP();
*/
/*sun's test//////////////////////////
	DDRC=0xFF;//端口C输出
	PORTC=0xFF;
	DDRF|=0x0F;//端口F输出
	sbi(DDRB,2);//CONVST初始化,输出
	sbi(PORTB,2);
	sbi(DDRG,0);//WR初始化,输出1
	sbi(PORTG,0);
	sbi(DDRG,1);//RD初始化,输出1
	sbi(PORTG,1);
	sbi(DDRG,2);//ALE初始化,输出1
	sbi(PORTG,2);
	sbi(DDRD,5);//CS_ADC初始化,输出1
	sbi(PORTD,5);
	sbi(DDRD,6);//CS_RAM初始化,输出1
	sbi(PORTD,6);
	UART_SETTING(19200,8000000);//串口初始化
	sbi(DDRE,2);// 串口接受控制
	cbi(PORTE,2);
	EXTERN_INTERRUPT_OPEN(7);//开外部中断7,等待AD转换结束
	sei();//开中断
	sample_sign=0xff;
	global_flag_serie=0;
	
	uint32_t addd=00010;
	uint16_t i;
	for(i=0;i<0xffff;i++)
	{
		SRAM_1M_8_WRITE(addd,i);
		addd++;
	}
	
	for(;;)
	{
		;
	}
*/

/*extern interrupt test///////////////
	uint16_t j;
	
	INITIATION();//初始化和串口设置,不包括串口中断开启
	sei();//开中断
	EXTERN_INTERRUPT_OPEN(7);//开外部中断7(AD转换结束中断)
	AD7891_CHANNEL_SELECT(2);
	for(;;)
	{
		AD7891_CONVERSION_START();
		for(j=0;j<0xFF;j++)
		{
			j|=0x00;
		}
	}
*/

/*AD7891 test/////////////////////////
	INITIATION();//初始化和串口设置,不包括串口中断开启
	sei();//开中断
	while(1)
	{
		EXTERN_INTERRUPT_OPEN(7);//开外部中断7(AD转换结束中断)
		AD7891_CHANNEL_SELECT(1);//选择通道1
		AD7891_CONVERSION_START();//转换开始
	}
*/
/*SRAM test///////////////////////////
	uint8_t temp1,temp2;
	SRAM_1M_8_WRITE(0x10,0x88);//高位字节
	SRAM_1M_8_WRITE(0x11,0x89);//低位字节

	temp1=SRAM_1M_8_READ(0x10);//高位字节
	temp2=SRAM_1M_8_READ(0x11);//低位字节
	
	temp1=0x88;
	temp2=0xFF;
*/
/*SIGNAL(SIG_INTERRUPT7)//////////////
SIGNAL(SIG_INTERRUPT7)
{
//变量定义
	uint16_t int16_temp1,int16_temp2,int16_temp3;
	uint8_t temp1,temp2,i;
//关中断
	cli();
//读取ad转换结果
	int16_temp1=AD7891_READ();
//AD7891 deselect,否则数据总线与RAM冲突
	sbi(PORTD,5);
//AD转换结果存入RAM
	temp1=int16_temp1/256;
	temp2=int16_temp1%256;
	int16_temp2=global_ad_counter%4;
	int16_temp3=global_ad_counter/4;
	//保存合闸线圈电流
	if(int16_temp2==0)
	{
		SRAM_1M_8_WRITE(0+int16_temp3*2,temp1);//高位字节
		SRAM_1M_8_WRITE(0+int16_temp3*2+1,temp2);//低位字节
	}
	//保存分闸线圈电流
	if(int16_temp2==1)
	{
		SRAM_1M_8_WRITE(10000+int16_temp3*2,temp1);//高位字节
		SRAM_1M_8_WRITE(10000+int16_temp3*2+1,temp2);//低位字节
	}
	//保存电机电流
	if(int16_temp2==2)
	{
		SRAM_1M_8_WRITE(20000+int16_temp3*2,temp1);//高位字节
		SRAM_1M_8_WRITE(20000+int16_temp3*2+1,temp2);//低位字节
	}
	//保存操作电压
	if(int16_temp2==3)
	{
		SRAM_1M_8_WRITE(30000+int16_temp3*2,temp1);//高位字节
		SRAM_1M_8_WRITE(30000+int16_temp3*2+1,temp2);//低位字节
	}
//计数器自加
	global_ad_counter++;
//开中断
	sei();
}
*/
/*传感器测试用////////////////////////
SIGNAL(SIG_INTERRUPT7)
{
//变量定义
	uint16_t int16_temp1;
	float float_temp1,float_temp2;
//关中断
	cli();
//读取ad转换结果
	int16_temp1=AD7891_READ();
	float_temp1=int16_temp1;
	float_temp2=float_temp1/20.48;
	float_temp2-=100;
	float_temp2*=1000;
//开中断
	sei();
}
*/
/*测试SRAM中数据是否正确//////////////
//变量定义
	uint16_t i;
	uint8_t temp_array[512];
//初始化和串口设置,不包括串口中断开启
	INITIATION();
//PG3供测试用/////////////
	sbi(DDRG,3);
	cbi(PORTG,3);
//开中断
	sei();
//数据采集流程
	while(1)
	{
	//开外部中断7(AD转换结束中断)
		EXTERN_INTERRUPT_OPEN(7);
	//采样
		SAMPLE();
	//关外部中断7
		EXTERN_INTERRUPT_CLOSE(7);

		for(i=0;i<512;i++)
		{
			temp_array[i]=SRAM_1M_8_READ(i);//读取数据
		}
	}
*/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -