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

📄 main.c

📁 10MS/s USB-2.0 ("high speed") oscilloscope with two 8 bit sampling inputs
💻 C
📖 第 1 页 / 共 2 页
字号:
{	uint8 i;	uint8 res=0U;	// NOTE: The most significant bit is transferred first in both directions. 	for(i=0; i<8; i++)	{		res<<=1;				// SCK L->H (rising edge) latches data. 		// Wait for SCK going HIGH or PD3 going HIGH. 		for(;;)		{			if(INT1_LEVEL())  return(0x100U);			if(SCK_LEVEL())  break;		}				// Read input. 		if(RXD_LEVEL())  res|=1;		// Set new output. 		if(to_send & (0x80U>>i))  SET_TXD_HIGH();		else                      SET_TXD_LOW();				// Wait for SCK H->L or PD3 going HIGH. 		// Output data is valid at the H->L transition of the clock. 		for(;;)		{			if(INT1_LEVEL())  return(0x100U);			if(!SCK_LEVEL())  break;		}	}		return(res);}static void ReadHandleInput(){	// This means we read the input from the RxD line (PD0) respecing the 	// externally-provided serial clock SCK (PD4). 	// We can output data on the TxD line (PD1). 	// NOTE: As soon as PD3 is pulled HIGH again, we leave this routine. 	//       If there was no complete command received within this time, 	//       we just ignore it. 		// While PD3 is LOW. 	while(!INT1_LEVEL())	{		uint16 rv=SerialIOByte(0x00);		uint8 stat=rv>>8;		if(stat)  return;				uint8 cmd=rv&0xffU;		switch(cmd)		{			// In order to sent the clock speed, send 2 bytes: 			// First: CMD_CKGEN_SET_CLOCK_SPEED, then the clock speed in 			//        multiples of 50kS/s. Only certain discrete values are 			//        permissible. 			case CMD_CKGEN_SET_CLOCK_SPEED:			{				rv=SerialIOByte(CMD_CKGEN_SET_CLOCK_SPEED);				stat=rv>>8;				if(stat)  return;				clock_speed=rv&0xffU;			}  break;			default:				break;		}	}}int main(void){	Initialize();		StartSampleClock();		// ## For testing: simply pull the clock1 LOW to have all samples stored: ##	//cbi(PORTB,2);	//for(;;);		// Enable interrupts globally: 	sei();		for(;;)	{		// Run the sampler...		// We leave if PD3 is pulled low. This means that there is something 		// to read. 		ClockGeneratorLoop();				// Handle the input from the RxD and SCK lines. 		ReadHandleInput();	}		// Never reached. 	return(0);}//------------------------------------------------------------------------------	// Unused clock speeds: #if 0	// This will store every 3rd sample: (3.3 MS)	SampleClockSync();	for(;;)	{		cbi(PORTB,2);		sbi(PORTB,2);	}#elif 0	// This will store 2/3 of all samples: (6.7 MS)	SampleClockSync();	for(;;)	{		sbi(PORTB,2);		cbi(PORTB,2);	}#elif 0	// clock1 (PB2): Set up timer0 in CTC mode. Prescaler to 1: 	OCR0A=0x01;  // 0x00	TCNT0=0;	// WGM2:0=7 (fast PWM with TOP=OCR0A)	TCCR0A=0x42U;      // 01000010   <-- COM0A1:0, WGM00:1	TCCR0B=0x01U;      // 00000001	SampleClockSync();	TCNT0=1;	for(;;);#endif		// Other cruft: #if 0	// clock1 (PB2): Set up timer0 in CTC mode: 	// Prescaler to 1: 	OCR0A=0x0;  // 0x00	TCNT0=0;	TCCR0A=0x42U;      // 01000010   <-- COM0A1:0, WGM00:1	TCCR0B=0x01U;      // 00000001	TCNT0=0;	// Enable interrupt for test purpose. 	//sbi(TIMSK,TOIE0);  // overflow	//sbi(TIMSK,/*OCIE0A*/0);  // overflow ????#endif// HERE is the old version without inline assembly. // NOTE that the SampleClockSync() was not working properly (since it //      caused tiny clock gaps). #if 0#define SampleClockSync()    do { TCNT1=0xcdU; } while(0)static void ClockGeneratorLoop(){	// Main loop. This runs until PD3 is pulled LOW thereby stopping sampling. 	if(!INT1_LEVEL()) return;		switch(clock_speed)	{		case   0:  // 0kS			// This will store NO samples at all. 			SampleClockSync();			sbi(PORTB,2);			for(;;)			{				if(!INT1_LEVEL()) break;  // <-- This is 1 clock cycle!			}			break;		case   1:  // 50kS			// This will store every 200th sample: (50 kS)			SampleClockSync();			for(;;)			{				cbi(PORTB,2);				sbi(PORTB,2);				nop();				// 98 -> 200				uint8 cnt=98; while(cnt--) { nop(); }								// This is one clock cycle if placed at the end of the loop!				if(!INT1_LEVEL()) break;			}			break;		case   2:  // 100kS			// This will store every 100th sample: (100 kS)			SampleClockSync();			for(;;)			{				cbi(PORTB,2);				sbi(PORTB,2);				nop();				// 48 -> 100				uint8 cnt=48; while(cnt--) { nop(); }								// This is one clock cycle if placed at the end of the loop!				if(!INT1_LEVEL()) break;			}			break;		case   5:  // 250kS			// This will store every 40th sample: (250 kS)			SampleClockSync();			for(;;)			{				cbi(PORTB,2);				sbi(PORTB,2);				nop();				// 6 -> 16				// 7 -> 18				// 8 -> 20				// n -> 2*n+4				// 18 -> 40				uint8 cnt=18; while(cnt--) { nop(); }								// This is one clock cycle if placed at the end of the loop!				if(!INT1_LEVEL()) break;			}			break;		case  10:  // 500kS			// This will store every 20th sample: (500 kS)			SampleClockSync();			asm("sleep");			for(;;)			{				cbi(PORTB,2);				sbi(PORTB,2);				nop();				uint8 cnt=8; while(cnt--) { nop(); }								// This is one clock cycle if placed at the end of the loop!				if(!INT1_LEVEL()) break;			}			break;		case  20:  // 1MS			// This will store every 10th sample: (1 MS)			SampleClockSync();			for(;;)			{				cbi(PORTB,2);				sbi(PORTB,2);				nop();				nop();nop();				nop();nop();				nop();nop();				nop();nop();				nop();nop();				nop();nop();								// This is one clock cycle if placed at the end of the loop!				if(!INT1_LEVEL()) break;			}			break;		case  50:  // 2.5MS			// This will store every 4th sample: (2.5 MS)			SampleClockSync();			for(;;)			{				cbi(PORTB,2);				sbi(PORTB,2);				nop();				// This is one clock cycle if placed at the end of the loop!				if(!INT1_LEVEL()) break;			}			break;		case 100:  // 5MS			// This will store every 2nd sample: (5 MS)			// clock1 (PB2): Set up timer0 in CTC mode. Prescaler to 1: 			OCR0A=0x01;  // 0x00			TCNT0=0;			TCCR0A=0x42U;      // 01000010   <-- COM0A1:0, WGM00:1			TCCR0B=0x01U;      // 00000001			SampleClockSync();			TCNT0=1;			for(;;)			{				if(!INT1_LEVEL()) break;  // <-- This is 1 clock cycle!			}			break;		case 200:  // 10MS			// This will store all samples: (10 MS)			SampleClockSync();			cbi(PORTB,2);			// Sample until INT1 goes LOW. 			while(INT1_LEVEL());			break;		default:			// This is an error. 			// Don't sample: 			sbi(PORTB,2);  // Already HIGH but be sure. 			// Wait for INT1 to go LOW. 			while(INT1_LEVEL());			break;	}		// Stop recording: This works for sampling modes based on internal counter. 	TCCR0B=0x0U;	TCCR0A=0x4U;	OCR0A=0x0;	// No recording: This works for all sampling modes not using the 	// internal counter. 	sbi(PORTB,2);}#endif

⌨️ 快捷键说明

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