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

📄 logic.c

📁 2us 分辨率的逻辑分析仪器 2us 分辨率的逻辑分析仪器
💻 C
字号:
#include <avr/io.h>
#include <avr/pgmspace.h>
//#include <avr/interrupt.h>
//#include <avr/signal.h>
#include "logic.h"

#define DATAIN	PINA
#define DATADIR	DDRA
#define DATAOUT	PORTA

#define	LOCKDDR	DDRB
#define	LOCK	PORTB
#define LE		0x01

#define lock	LOCK&=(~LE)							//LE=0,锁存数据
#define unlock	LOCK|=LE							//LE=1,数据进入单片机
#define wait 	while(!(UCSRA&0x80))				//等待数据
#define waitTXC while(!(UCSRA&0x40))				//等待发送完成
#define clrTXC  UCSRA |= 0x04						//清除发送完成标志

const prog_uchar delay_lo[] = {0,  3,  8,  28,  88,  188,  132,  220,  196,148,52, 116,244};
//							   2us,5us,10us,20us,50us,100us,200us,500us,1ms,2ms,4ms,8ms,16ms
const prog_uchar delay_hi[] = {0,  1,  1,   1,   1,   1,    2,    4,    8,  16, 32, 63, 125};

int main()
{
	uint8_t ram[2048];

/****************************初始化命令************************************/
/*管脚配置*/
//DDxn 用来选择引脚的方向。DDxn 为"1“ 时, Pxn 配置为输出,否则配置为输入。
//引脚配置为输入时,若PORTxn 为"1“,上拉电阻将使能。
//如果需要关闭这个上拉电阻,可以将PORTxn 清零,或者将这个引脚配置为输出。
	DATADIR = 0x00;				//数据口设置为输入
	DATAOUT = 0x00;				//关闭上拉电阻
	LOCKDDR = (0x00|LE);		//LE设置为输出
	unlock;						//LE=0;
/*UART设置*/
	UCSRA = 0x00;				//
	UCSRB = 0x18;				//发送、接收使能
	UCSRC = 0x06;				//8位,无校验
	UBRRH = 0;
	UBRRL = 25;					//波特率为38400

	while(1)
	{
		wait;					//等待触发位数据
		trig = UDR;
		wait;					//等待触发使能数据
		trig_en = UDR;;
		wait;					//等待频率低位
		fre_lo = UDR;
		wait;					//等待频率高位
		fre_hi = UDR;
	//分辨率={lo}{hi}
	//2us=0x0402;5us=0x0a02;10us=0x1402;
	//20us=0x2802;50us=0x6402;100us=0xc802;
	//200us=0x3203;500us=0x7d03;1ms=0xfa03;
	//2ms=0x7d04;4ms=0xfa04;8ms=0x7d05;16ms=0xfa05
		wait;					//等待预触发数据
		pre_trig = UDR;
		wait;					//等待预触发数据
		pre_trig = UDR;
		wait;					//等待工作模式
		mode = UDR;
		clrTXC;
		UDR = 'D';
		waitTXC;
		for(addr=0; addr<2048; addr++)
			ram[addr] = 0;

		switch(fre_hi)
		{
			case 2:
				if(fre_lo == 0x04)
					sample_num = 0;
				if(fre_lo == 0x0a)
					sample_num = 1;
				if(fre_lo == 0x14)
					sample_num = 2;
				if(fre_lo == 0x28)
					sample_num = 3;
				if(fre_lo == 0x64)
					sample_num = 4;
				if(fre_lo == 0xc8)
					sample_num = 5;
				break;
			case 3:
				if(fre_lo == 0x32)
					sample_num = 6;
				if(fre_lo == 0x7d)
					sample_num = 7;
				if(fre_lo == 0xfa)
					sample_num = 8;
				break;
			case 4:
				if(fre_lo == 0x7d)
					sample_num = 9;
				if(fre_lo == 0xfa)
					sample_num = 10;
				break;
			case 5:
				if(fre_lo == 0x7d)
					sample_num = 11;
				if(fre_lo == 0xfa)
					sample_num = 12;
				break;
		}
		addr = 0;
		switch(mode)
		{
			case 0:				//普通模式
start:			if(sample_num > 12)
					break;
				addr = 0;
				if(sample_num==0) 						//采样频率2us
				{
					pre_trig = 8;						//采样频率为2us时不能预触发
					addr = 1;
					while(1)
					{
						lock;
						asm("nop");
						asm("nop");
						temp = DATAIN;
						asm("nop");
						asm("nop");
						unlock;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						if(trig == (temp | trig_en))
							break;
					}
					asm("nop");
					asm("nop");
					ram[0] = temp;
					asm("nop");
					asm("nop");
					while(1)
					{
						lock;
						asm("nop");
						asm("nop");
						ram[addr] = DATAIN;
						asm("nop");
						asm("nop");
						unlock;
						asm("ldi r16,1");
						asm("ldi r17,0");
						asm("add r10,r16");
						asm("adc r11,r17");
						asm("nop");
						asm("nop");
						if(addr_hi==8)
							break;
					}
				}
				else if(sample_num==1)					//采样频率为5us
				{
					while(1)
					{
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						lock;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						temp = DATAIN;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						unlock;
						if(trig == (temp | trig_en))
						{
							addr_trig_lo=addr_lo;
							addr_trig_hi=addr_hi;
							break;
						}
						else
						{
							if(addr_hi == (8 - pre_trig))			//预触发空间
							{
								addr_hi=0;
							}
							else
							{
								asm("nop");
								asm("nop");
								asm("nop");
							}
						}
						ram[addr]=DATAIN;
						asm("ldi r16,1");
						asm("ldi r17,0");
						asm("add r10,r16");
						asm("adc r11,r17");
					}
					asm("nop");
					asm("nop");
					asm("nop");
					addr_lo = 0x00;
					addr_hi = 8 - pre_trig;
					ram[addr]=temp;
					addr_lo = 0x01;
					asm("nop");
					asm("nop");
					asm("nop");
					asm("nop");
					asm("nop");
					asm("nop");
					asm("nop");
					asm("nop");
					while(1)
					{
						lock;
						asm("nop");
						asm("nop");
						asm("nop");
						ram[addr] = DATAIN;
						asm("nop");
						asm("nop");
						unlock;
						asm("ldi r16,1");
						asm("ldi r17,0");
						asm("add r10,r16");
						asm("adc r11,r17");
						asm("nop");
						asm("nop");
						if(addr_hi==8)
							break;
						time_lo=pgm_read_byte(delay_lo + 1);
						time_hi=pgm_read_byte(delay_hi + 1);
						while(1)
						{
							asm("sub r12,r16");
							asm("sbc r13,r17");
							asm("nop");
							if(!time_hi)
								break;
						}
					}
				}
				else									//大于5us
				{
					while(1)
					{
						lock;
						asm("nop");
						asm("nop");
						asm("nop");
						temp = DATAIN;
						asm("nop");
						asm("nop");
						asm("nop");
						unlock;
						if(trig == (temp | trig_en))
						{
							addr_trig_lo=addr_lo;
							addr_trig_hi=addr_hi;
							break;
						}
						else
						{
							if(addr_hi == (8 - pre_trig))			//预触发空间
							{
								addr_hi=0;
							}
							else
							{
								asm("nop");
								asm("nop");
								asm("nop");
							}
						}
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						ram[addr]=DATAIN;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("ldi r16,1");
						asm("ldi r17,0");
						asm("add r10,r16");
						asm("adc r11,r17");
						time_lo=pgm_read_byte(delay_lo + sample_num);
						time_hi=pgm_read_byte(delay_hi + sample_num);
						while(1)
						{
							asm("sub r12,r16");
							asm("sbc r13,r17");
							asm("nop");
							if(!time_hi)
								break;
						}
					}
					addr_lo = 0x00;
					addr_hi = 8 - pre_trig;
					ram[addr] = temp;
					addr_lo = 0x01;
					asm("nop");
					asm("nop");
					asm("nop");
					asm("ldi r16,1");
					asm("ldi r17,0");
					while(1)
					{
						time_lo=pgm_read_byte(delay_lo + sample_num);
						time_hi=pgm_read_byte(delay_hi + sample_num);
						asm("nop");
						asm("nop");
						while(1)
						{
							asm("sub r12,r16");
							asm("sbc r13,r17");
							asm("nop");
							if(!time_hi)
								break;
						}
						lock;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						ram[addr] = DATAIN;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						asm("nop");
						unlock;
						asm("nop");
						asm("nop");
						asm("nop");
						asm("ldi r16,1");
						asm("ldi r17,0");
						asm("add r10,r16");
						asm("adc r11,r17");
						asm("nop");
						asm("nop");
						for(temp=0;temp<1;temp++)
							asm("nop");
						if(addr_hi==8)
							break;
					}
				}
				break;
			case 1:				//外部时钟,上升延
				trig |= 0x01;
				trig_en |= 0x01;
				addr = 0;
				while(1)
				{
					do
					{
						temp = DATAIN;
					}
					while(temp & 0x01);
					do
					{
						temp = DATAIN;
					}
					while(!(temp & 0x01));
					if(trig == (temp | trig_en))
					{
						addr_trig_lo=addr_lo;
						addr_trig_hi=addr_hi;
						break;
					}
					else
					{
						if(addr_hi == (8 - pre_trig))			//预触发空间
						{
							addr_hi=0;
						}
					}
					ram[addr]=temp;
					asm("ldi r16,1");
					asm("ldi r17,0");
					asm("add r10,r16");
					asm("adc r11,r17");
				}
				addr_lo = 0x00;
				addr_hi = 8 - pre_trig;
				ram[addr] = temp;
				addr_lo = 0x01;
				while(1)
				{
					do
					{
						temp = DATAIN;
					}
					while(temp & 0x01);
					do
					{
						temp = DATAIN;
					}
					while(!(temp & 0x01));
					ram[addr]=temp;
					asm("ldi r16,1");
					asm("ldi r17,0");
					asm("add r10,r16");
					asm("adc r11,r17");
					if(addr_hi==8)
						break;
				}
				break;
			case 2:				//外部时钟,下降延
				trig |= 0x01;
				trig_en |= 0x01;
				addr = 0;
				while(1)
				{
					do
					{
						temp = DATAIN;
					}
					while(!(temp & 0x01));
					do
					{
						temp = DATAIN;
					}
					while(temp & 0x01);
					if(trig == (temp | trig_en))
					{
						addr_trig_lo=addr_lo;
						addr_trig_hi=addr_hi;
						break;
					}
					else
					{
						if(addr_hi == (8 - pre_trig))			//预触发空间
						{
							addr_hi=0;
						}
					}
					ram[addr]=temp;
					asm("ldi r16,1");
					asm("ldi r17,0");
					asm("add r10,r16");
					asm("adc r11,r17");
				}
				addr_lo = 0x00;
				addr_hi = 8 - pre_trig;
				ram[addr] = temp;
				addr_lo = 0x01;
				while(1)
				{
					do
					{
						temp = DATAIN;
					}
					while(!(temp & 0x01));
					do
					{
						temp = DATAIN;
					}
					while(temp & 0x01);
					ram[addr]=temp;
					asm("ldi r16,1");
					asm("ldi r17,0");
					asm("add r10,r16");
					asm("adc r11,r17");
					if(addr_hi==8)
						break;
				}
				break;
			case 3:				//外部触发,上升延
				trig = 0xff;
				trig_en = 0xfe;
				pre_trig = 8;
				goto start;
				break;
			case 4:				//外部触发,下降延
				trig = 0xfe;
				trig_en = 0xfe;
				pre_trig = 8;
				goto start;
				break;
			case 5:				//静态模式
				break;
			case 7:				//二进制模式
				pre_trig = 8;
				for(addr=0; addr<2048; addr++)
					ram[addr] = addr_lo;;
				break;
			case 8:				//AA、55模式
				pre_trig = 8;
				for(addr=0; addr<2048; addr++)
				{
					if(addr&0x01)
						ram[addr] = 0x55;
					else
						ram[addr] = 0xaa;
				}
				break;
			case 9:				//全为0
				pre_trig = 8;
				for(addr=0; addr<2048; addr++)
					ram[addr] = 0;
				break;
		}
		if(pre_trig != 8)		//预触发不为0%
		{
			addr = addr_trig;
			for(;addr<2048;)
			{
				clrTXC;
				UDR=ram[addr];
				waitTXC;
				addr++;
				if(addr_hi == 8 - pre_trig)
				{
					addr = 0;
				}
				if(addr == addr_trig)
				{
					break;
				}
			}
		}
		addr_lo = 0x00;
		addr_hi = 8 - pre_trig;
		for(;addr<2048;addr++)
		{
			clrTXC;
			UDR=ram[addr];
			waitTXC;
		}
	}
}

⌨️ 快捷键说明

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