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

📄 pcd8544.c

📁 Nokia 6110 LCD 驱动 Atmega8
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    /* Recalculating index and offset */
    index = ( ( y / 8 ) * 84 ) + x;
    offset  = y - ( ( y / 8 ) * 8 );

    data = LcdCache[ index ];

    /* Bit processing */
    
	/* Clear mode */
    if ( mode == PIXEL_OFF )
    {
        data &= ( ~( 0x01 << offset ) );
    }

    /* On mode */
    else if ( mode == PIXEL_ON )
    {
        data |= ( 0x01 << offset );
    }

    /* Xor mode */
    else if ( mode  == PIXEL_XOR )
    {
        data ^= ( 0x01 << offset );
    }
	
    /* Final result copied to cache */
    LcdCache[ index ] = data;

    if ( index < LoWaterMark )
    {
        /*  Update low marker. */
        LoWaterMark = index;
    }

    if ( index > HiWaterMark )
    {
        /*  Update high marker. */
        HiWaterMark = index;
    }
    return OK;
}

/*
 * Name         :  LcdLine
 * Description  :  Draws a line between two points on the display.
 * Argument(s)  :  x1, y1 -> Absolute pixel coordinates for line origin.
 *                 x2, y2 -> Absolute pixel coordinates for line end.
 *                 mode   -> Off, On or Xor. See enum in pcd8544.h.
 * Return value :  see return value on pcd8544.h
 */
byte LcdLine ( byte x1, byte x2, byte y1, byte y2, LcdPixelMode mode )
{
    int dx, dy, stepx, stepy, fraction;
    byte response;

    /* Calculate differential form */
    /* dy   y2 - y1 */
    /* -- = ------- */
    /* dx   x2 - x1 */

    /* Take differences */
    dy = y2 - y1;
    dx = x2 - x1;
	
    /* dy is negative */
    if ( dy < 0 )
    {
        dy    = -dy;
        stepy = -1;
    }
    else
    {
        stepy = 1;
    }
	
    /* dx is negative */
    if ( dx < 0 )
    {
        dx    = -dx;
        stepx = -1;
    }
    else
    {
        stepx = 1;
    }

    dx <<= 1;
    dy <<= 1;
	
    /* Draw initial position */
    response = LcdPixel( x1, y1, mode );
    if(response)
        return response;
	
    /* Draw next positions until end */
    if ( dx > dy )
    {	
        /* Take fraction */
        fraction = dy - ( dx >> 1);
        while ( x1 != x2 )
        {
            if ( fraction >= 0 )
            {
                y1 += stepy;
                fraction -= dx;
            }
            x1 += stepx;
            fraction += dy;
			
            /* Draw calculated point */
            response = LcdPixel( x1, y1, mode );
            if(response)
                return response;

        }
    }
    else
    {
        /* Take fraction */
        fraction = dx - ( dy >> 1);
        while ( y1 != y2 )
        {
            if ( fraction >= 0 )
            {
                x1 += stepx;
                fraction -= dy;
            }
            y1 += stepy;
            fraction += dx;
			
            /* Draw calculated point */
            response = LcdPixel( x1, y1, mode );
            if(response)
                return response;
        }
    }
	
    /* Set update flag to be true */
    UpdateLcd = TRUE;
    return OK;
}

/*
 * Name         :  LcdSingleBar
 * Description  :  Display single bar.
 * Argument(s)  :  baseX  -> absolute x axis coordinate
 *                 baseY  -> absolute y axis coordinate
 *				   height -> height of bar (in pixel)
 *				   width  -> width of bar (in pixel)
 *				   mode   -> Off, On or Xor. See enum in pcd8544.h.
 * Return value :  see return value on pcd8544.h
 */
byte LcdSingleBar ( byte baseX, byte baseY, byte height, byte width, LcdPixelMode mode )
{
	byte tmpIdxX,tmpIdxY,tmp;

    byte response;

    /* Checking border */
	if ( ( baseX > LCD_X_RES ) || ( baseY > LCD_Y_RES ) ) return OUT_OF_BORDER;
	
	if ( height > baseY )
		tmp = 0;
	else
		tmp = baseY - height;

    /* Draw lines */
	for ( tmpIdxY = tmp; tmpIdxY < baseY; tmpIdxY++ )
	{
		for ( tmpIdxX = baseX; tmpIdxX < (baseX + width); tmpIdxX++ )
        {
			response = LcdPixel( tmpIdxX, tmpIdxY, mode ); 
            if(response)
                return response;

        }
	}

    /* Set update flag to be true */
	UpdateLcd = TRUE;
    return OK;
}

/*
 * Name         :  LcdBars
 * Description  :  Display multiple bars.
 * Argument(s)  :  data[] -> data which want to be plotted
 *                 numbBars  -> number of bars want to be plotted
 *				   width  -> width of bar (in pixel)
 * Return value :  None.
 * Note         :  Please check EMPTY_SPACE_BARS, BAR_X, BAR_Y in pcd8544.h 
 */  
byte LcdBars ( byte data[], byte numbBars, byte width, byte multiplier )
{
	byte b;
	byte tmpIdx = 0;
    byte response;

	for ( b = 0;  b < numbBars ; b++ )
	{
        /* Preventing from out of border (LCD_X_RES) */
		if ( tmpIdx > LCD_X_RES ) return OUT_OF_BORDER;
		
		/* Calculate x axis */
		tmpIdx = ((width + EMPTY_SPACE_BARS) * b) + BAR_X;

		/* Draw single bar */
		response = LcdSingleBar( tmpIdx, BAR_Y, data[ b ] * multiplier, width, PIXEL_ON);  
        if(response == OUT_OF_BORDER)
            return response;
	}

	/* Set update flag to be true */
	UpdateLcd = TRUE;
    return OK;

}
/*
 * Name         :  LcdRect
 * Description  :  Display a rectangle.
 * Argument(s)  :  x1   -> absolute first x axis coordinate
 *                 y1   -> absolute first y axis coordinate
 *				   x2   -> absolute second x axis coordinate
 *				   y2   -> absolute second y axis coordinate
 *				   mode -> Off, On or Xor. See enum in pcd8544.h.
 * Return value :  see return value on pcd8544.h.
 */
byte LcdRect ( byte x1, byte x2, byte y1, byte y2, LcdPixelMode mode )
{
	byte tmpIdxX,tmpIdxY;
    byte response;

	/* Checking border */
	if ( ( x1 > LCD_X_RES ) ||  ( x2 > LCD_X_RES ) || ( y1 > LCD_Y_RES ) || ( y2 > LCD_Y_RES ) )
		/* If out of border then return */
		return OUT_OF_BORDER;

	if ( ( x2 > x1 ) && ( y2 > y1 ) )
	{ 
		for ( tmpIdxY = y1; tmpIdxY < y2; tmpIdxY++ )
		{		
			/* Draw line horizontally */
			for ( tmpIdxX = x1; tmpIdxX < x2; tmpIdxX++ )
            {
				/* Draw a pixel */
				response = LcdPixel( tmpIdxX, tmpIdxY, mode ); 
                if(response)
                    return response;
            }
		}

		/* Set update flag to be true */
		UpdateLcd = TRUE;
	}
    return OK;	
}
/*
 * Name         :  LcdImage
 * Description  :  Image mode display routine.
 * Argument(s)  :  Address of image in hexes
 * Return value :  None.
 * Example      :  LcdImage(&sample_image_declared_as_array);
 */
void LcdImage ( const byte *imageData )
{
	/* Initialize cache index to 0 */
	LcdCacheIdx = 0;
	/* While within cache range */
    for ( LcdCacheIdx = 0; LcdCacheIdx < LCD_CACHE_SIZE; LcdCacheIdx++ )
    {
		/* Copy data from pointer to cache buffer */
        LcdCache[LcdCacheIdx] = pgm_read_byte( imageData++ );
    }
	/* Reset watermark pointers to be full */
    LoWaterMark = 0;
    HiWaterMark = LCD_CACHE_SIZE - 1;

	/* Set update flag to be true */
    UpdateLcd = TRUE;
}

/*
 * Name         :  LcdUpdate
 * Description  :  Copies the LCD cache into the device RAM.
 * Argument(s)  :  None.
 * Return value :  None.
 */
void LcdUpdate ( void )
{
    int i;

    if ( LoWaterMark < 0 )
        LoWaterMark = 0;
    else if ( LoWaterMark >= LCD_CACHE_SIZE )
        LoWaterMark = LCD_CACHE_SIZE - 1;

    if ( HiWaterMark < 0 )
        HiWaterMark = 0;
    else if ( HiWaterMark >= LCD_CACHE_SIZE )
        HiWaterMark = LCD_CACHE_SIZE - 1;

    /*  Set base address according to LoWaterMark. */
    LcdSend( 0x80 | ( LoWaterMark % LCD_X_RES ), LCD_CMD );
    LcdSend( 0x40 | ( LoWaterMark / LCD_X_RES ), LCD_CMD );

    /*  Serialize the display buffer. */
    for ( i = LoWaterMark; i <= HiWaterMark; i++ )
    {
        LcdSend( LcdCache[ i ], LCD_DATA );
    }

    /*  Reset watermark pointers. */
    LoWaterMark = LCD_CACHE_SIZE - 1;
    HiWaterMark = 0;

    /* Set update flag to be true */
	UpdateLcd = FALSE;
}

/*
 * Name         :  LcdSend
 * Description  :  Sends data to display controller.
 * Argument(s)  :  data -> Data to be sent
 *                 cd   -> Command or data (see enum in pcd8544.h)
 * Return value :  None.
 */
static void LcdSend ( byte data, LcdCmdData cd )
{
    /*  Enable display controller (active low). */
    LCD_PORT &= ~( _BV( LCD_CE_PIN ) );

    if ( cd == LCD_DATA )
    {
        LCD_PORT |= _BV( LCD_DC_PIN );
    }
    else
    {
        LCD_PORT &= ~( _BV( LCD_DC_PIN ) );
    }
	
    /*  Send data to display controller. */
    SPDR = data;

    /*  Wait until Tx register empty. */
    while ( (SPSR & 0x80) != 0x80 );
	

    /* Disable display controller. */
    LCD_PORT |= _BV( LCD_CE_PIN );
}

/*
 * Name         :  Delay
 * Description  :  Uncalibrated delay for LCD init routine.
 * Argument(s)  :  None.
 * Return value :  None.
 */
static void Delay ( void )
{
    int i;

    for ( i = -32000; i < 32000; i++ );
}

⌨️ 快捷键说明

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