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

📄 lcd8.c

📁 AD9850 DDS chip driver
💻 C
字号:
/*

 SWR Neter board LCD routines
 This is polling driver with 8-bit interface

 Juha Niinikoski OH2NLT 26.01.2004

 Serial I/O removed. All output functions collected here.
 Bar graph modified for SOLOMON LM1125SYLU1 display 27.01.2004
 Cross bar fwd / rev power meter 27.01.2004 
 S-meter bar display, leading zero blanc for freq display 27.04.2004
 
*/

/* 2 * 16 LCD display memory layout */

#define LINE1     0x00         /* line 1 start address */
#define LINE2     0x40         /* line 2 start address */


#define CURSET     0x80         /* set memory cursor */
#define	CLEAR	   0x01		/* clear display */
#define ADRSET	   0x40		/* set cgram address */


void	clk_lcd(unsigned char ldata)		// set data & clock both lcd controllers
	{
	LCD_DATA = ldata;
	LCD_E = 1;
	asm("nop");
	asm("nop");
	asm("nop");
	LCD_E = 0;
	}


void	wait_lcd_rdy(void)			// wait until lcd module is ready
	{
	unsigned char BF_AC;			// BF flag & address counter

	BF_AC = 0x80;				// set busy for first round
	LCD_TRIS = 0xFF;			// make data port input
	LCD_RW = 1;				// read
	LCD_RS = 0;				// command mode
	while(BF_AC & 0x80)	
		{
		asm("nop");			// 18.01.2004 for slow display
		LCD_E = 1;
		asm("nop");
		asm("nop");
		asm("nop");
		BF_AC = LCD_DATA;
		LCD_E = 0;
		}
	LCD_RW = 0;
	LCD_RS = 1;
	LCD_TRIS = 0x00;			// return to write mode
	}

void set_cur_lcd(unsigned char cur)		// set cursor position at selected display
	{
	wait_lcd_rdy( );
	LCD_RS = 0;				// switch command mode		
	clk_lcd(cur | CURSET);			// set cursor command + cursor position
	LCD_RS = 1;				// back to data mode
	}


void clear_lcd(void)				// clear selected display
	{
	wait_lcd_rdy( );
	LCD_RS = 0;				// switch command mode		
	clk_lcd(CLEAR);				// clear display. Display going to be busy 1,6 mS
	LCD_RS = 1;				// back to data mode
	}


void initlcd(void)		// init selected LCD controller
	{
	LCD_RS = 0;		// set command mode
	LCD_RW = 0;
	clk_lcd(0x38);		// write init data with delays
	delay(5);
	clk_lcd(0x38);
	delay(1);
	clk_lcd(0x38);		//8-bit, 2 rows, 5x7 matrix, display on
	delay(1);		//cursor off, no blink
	clk_lcd(0x0C);
	delay(1);
	clk_lcd(0x01);
	delay(2);	
	clk_lcd(0x06);		// increment, no display shift
	delay(1);
	LCD_RS = 1;		// set data mode
	}


void lcdoutch( unsigned char lcd_char )	// output character to selected display
	{
	wait_lcd_rdy();
	clk_lcd(lcd_char);	
	}

/* HD44780 character generator routines */
/* modified for SOLOMON LM1125SYLU1 display */

const char Blockslr[6] = {0x20, 0x00, 0x00, 0x01, 0x01, 0x02};	// blocks for L to R bar graph
const char Blocksrl[6] = {0x20, 0x03, 0x03, 0x04, 0x04, 0x02};	// R to L

void set_cgram(unsigned char adr, unsigned char dta)	// set cgram address & data
	{
	wait_lcd_rdy( );
	LCD_RS = 0;				// switch command mode		
	adr = adr & 0x3F;
	clk_lcd(adr | ADRSET);			// set cgram address command + address
	LCD_RS = 1;				// back to data mode
	wait_lcd_rdy();
	clk_lcd(dta);
	clear_lcd();				// back to normal mode (clear LCD)	
	}


void set_ch_bits(char dta, char cnt)		// set chgen bits. Data, number of sets
	{
	char x;
	for(x=0; x<cnt; x++)
		{
		wait_lcd_rdy();
		clk_lcd(dta);
		}
	}	

void set_chgen(void)				// write bar symbols to HD44780 RAM chgen
	{
	wait_lcd_rdy( );
	LCD_RS = 0;				// switch command mode		
	clk_lcd(0 | ADRSET);			// set cgram address command + address
	LCD_RS = 1;				// back to data mode

	set_ch_bits(0, 1);
	set_ch_bits(0x10, 5);			// CGRAM 00 Blocks L > R
	set_ch_bits(0, 2);

	set_ch_bits(0, 1);
	set_ch_bits(0x14, 5);			// CGRAM 01
	set_ch_bits(0, 2);

	set_ch_bits(0, 1);
	set_ch_bits(0x15, 5);			// CGRAM 02 "Full block"
	set_ch_bits(0, 2);

	set_ch_bits(0, 1);
	set_ch_bits(0x01, 5);			// CGRAM 03 Blocks R > L
	set_ch_bits(0, 2);

	set_ch_bits(0, 1);
	set_ch_bits(0x05, 5);			// CGRAM 04
	set_ch_bits(0, 2);
							
	set_ch_bits(0x08, 7);			// CGRAM 05 spare
	set_ch_bits(0, 1);

	set_ch_bits(0, 3);			// CGRAM 06 S-meter scale dot
	set_ch_bits(0x10, 1);
	set_ch_bits(0, 4);

	set_ch_bits(0, 2);			// CGRAM 07 S-meter scale bar
	set_ch_bits(0x10, 3);
	set_ch_bits(0, 3);

	clear_lcd();				// back to normal mode (clear LCD)
	}

// Meter constants

#define DISP_LEN 16					// display lemgth (char)
#define FONT_W 5					// font width
#define MAX_GRAPH (DISP_LEN * FONT_W)			// graph length in pixels (5*16 = 80)

const char scale_dots[16] = {6,32,6,32,6,32,6,32,7,32,7,32,7,32,7,32};

// draw S-meter, scale = 0...80
// buffer is used to avoid LCD flicker

void draw_s_meter(char len)
	{
	char x;
	char whole;
	char part;
	char idx;
	char bar_buffer[DISP_LEN];			// display buffer
	
	if(len > MAX_GRAPH)				// cut to max
		len = MAX_GRAPH;

	whole = len / FONT_W;				// calculate graph
	part = len % FONT_W;

	idx = 0;
	for(x=0; x<DISP_LEN; x++)			// copy scale dots to buffer
		{
		bar_buffer[idx] = scale_dots[x];
		idx++;
		}

	idx = 0;					// draw graph to buffer	
	while(whole > 0)			
		{
		bar_buffer[idx] = 0x02;			// draw full blocks
		idx++;	
		whole--;
		}

	if(part > 0)
		bar_buffer[idx] = Blockslr[part]; 	// draw partial block to buffer

	for(x=0; x<DISP_LEN; x++)			// print meter buffer to LCD
		{
		lcdoutch(bar_buffer[x]);
		}
	}


// draw graph
// 0 = left to rigth, 1 = rigth to left

void draw_bar(char len, char dir)			// draw bar graph
	{
	char x;
	char whole;
	char part;
	char l;
	char idx;
	char bar_buffer[DISP_LEN];			// display buffer

	if(len > MAX_GRAPH)				// cut to max
		len = MAX_GRAPH;

	l =  DISP_LEN;
	whole = len / FONT_W;				// calculate graph
	part = len % FONT_W;

	if(dir == 0)					// L to R
		{
		idx = 0;

		while(whole > 0)			
			{
			bar_buffer[idx] = 0x02;		// draw full blocks
			idx++;	
			whole--;
			l--;
			}
	
		if(part > 0)
			{
			bar_buffer[idx] = Blockslr[part]; // draw partial block
			idx ++;
			l--;
			}	

		for(x=0; x<l; x++)			// clear rest of the line
			{
			bar_buffer[idx] = 0x20;
			idx++;
			}

		}
	else						// draw from R to L
		{
		idx = DISP_LEN - 1;
		while(whole > 0)			
			{
			bar_buffer[idx] = 0x02;		// draw full blocks
			idx--;	
			whole--;
			l--;
			}
	
		if(part > 0)
			{
			bar_buffer[idx] = Blocksrl[part]; // draw partial block
			idx --;
			l--;
			}	

		for(x=0; x<l; x++)			// clear rest of the line
			{
			bar_buffer[idx] = 0x20;
			idx--;
			}
		}

	for(x=0; x<DISP_LEN; x++)			// print buffer
		{
		lcdoutch(bar_buffer[x]);
		}
	}


/* Set LCD back light */

void set_bl(char bl)
	{
#ifdef __A_TYPE
// Set up DAC
	if(bl == 0)
		CVREN = 0;			// ref unit off

	else
		{
		CVRCON = CVRCON_INIT | (bl - 1); // set new value
		CVREN = 1;			// ref unit on if it was off
		}
#else
	asm("nop");
#endif
	}



/* General I/O functions */


void putch(unsigned char c)			// put character
	{
	lcdoutch(c);				// to LCD panel
	}


void putchhex(unsigned char c)			// put hex character
{
	unsigned char temp;

	temp=c;

	c=(c >> 4);
	if (c<10) c+=48; else c+=55;
	putch(c);

	c=temp;

	c=(c & 0x0F);
	if (c<10) c+=48; else c+=55;
	putch(c);
}


void put1hex(unsigned char c)			// put single hex digit 
{
	c=(c & 0x0F);
	if (c<10) c+=48; else c+=55;
	putch(c);
}

// writes a character to the serial port in decimal

void putchdec(unsigned char c)
{
	unsigned char temp;

	temp=c;
	//hundreds
	putch((c/100)+'0');
	c-=(c/100)*100;

	//tens
	putch((c/10)+'0');
	c-=(c/10)*10;

	//ones
	putch((c/1)+'0');
}


// Converts to BCD and writes out. Number must be between 0 and 99

void put2dec( char c)
{
	if(c > 99)
		c = 99;

	//tens
	putch((c/10)+'0');
	c-=(c/10)*10;

	//ones
	putch((c/1)+'0');
}


// Converts to BCD and writes out. Number must be between -99 and +127

void put3dec( char c)
{
	if(c & 0x80)		// test if negative
		{
		c = 0 - c;
		if(c > 99)
			c = 99;
		putch('-');
		}
	else
		{
		if ((c/100)>0) 
			putch((c/100)+'0');
		else
			putch(' ');
		}
	c-=(c/100)*100;

	//tens
	putch((c/10)+'0');
	c-=(c/10)*10;

	//ones
	putch((c/1)+'0');
}


/*
writes int to serial port in decimal
If DP = 0 no decimal point is printed.
DP !=0 = DP place from right.
simple negative number printout added 3.7.2002
minus sign is displayed at thousands digit place
*/

void putintdec( int c, char dp)
	{
	int temp;
	unsigned char neg_sign;

	if (c > 9999)		/* clip to max reading */
		c = 9999;
	if (c < 0)		/* check if negative value */
		{
		neg_sign = 1;
		c = 0 - c;	/* invert it */
		if (c > 999)
			c = 999;	/* max negative reading */
		}
	else
		neg_sign = 0;
	temp=c;

	//thousands
	if (neg_sign == 1)
		putch('-');
	else
		{	
		if ((c/1000)>0 || (dp >= 3))
			putch((c/1000)+'0');
		else
			putch(' ');
		}
	c-=(c/1000)*1000;
	if (dp == 3)
		putch('.');

	//hundreds
	if ( ((temp/100)>0) || ((temp/1000)>0) || (dp >= 2))
		 putch((c/100)+'0');
	else
		putch(' ');	
	c-=(c/100)*100;

	if (dp == 2)
		putch('.');

	//tens
	if ( ((temp/10)>0) || ((temp/100)>0) || ((temp/1000)>0) || (dp >= 1) )
 		putch((c/10)+'0');
	else
		putch(' ');
	c-=(c/10)*10;

	if (dp == 1)
		putch('.');

	//ones
	putch((c/1)+'0');
	}

/* write long in hex format */

void putlonghex( long ww )
	{

	union
	{
	long w;
	unsigned char p[4];
	} lrek;

	lrek.w = ww;
	putchhex(lrek.p[3]);
	putchhex(lrek.p[2]);
	putchhex(lrek.p[1]);
	putchhex(lrek.p[0]);
	}


/* put long in decimal format */
/* if mode !=0 do "short" frequency display */

void putlongdec( long x, char mode )
	{
	if(mode == 0)			// full display
		{
		//giga
		putch((x/1000000000)+'0');
		x-=(x/1000000000)*1000000000;


		putch('.');

		//100_million
		putch((x/100000000)+'0');
		x-=(x/100000000)*100000000;
		}
	
	//10_million
	if(mode !=0 && x/10000000 == 0)
		putch(' ');		// leadign zero blanc for frequency display
	else
		putch((x/10000000)+'0');

	x-=(x/10000000)*10000000;

	//million
	putch((x/1000000)+'0');
	x-=(x/1000000)*1000000;


	putch('.');

	//100_thousands
	putch((x/100000)+'0');
	x-=(x/100000)*100000;

	//10_thousands
	putch((x/10000)+'0');
	x-=(x/10000)*10000;

	//thousands
	putch((x/1000)+'0');
	x-=(x/1000)*1000;


	putch('.');

	//hundreds
	putch((x/100)+'0');
	x-=(x/100)*100;

	//tens
	putch((x/10)+'0');
	x-=(x/10)*10;

	//ones
	putch((x/1)+'0');

	}


void putst(register const char *str)
{
	while((*str)!=0)
	{
		putch(*str);
    if (*str==13) putch(10);
    if (*str==10) putch(13);
		str++;
	}
}

⌨️ 快捷键说明

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