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

📄 n6100.c

📁 NOKIA6100手机彩色液晶显示屏的控制驱动程序
💻 C
字号:
// Reset = PortB.4
// CS    = PortB.0   (~SS)
// GND   = GND
// SData = PortB.2   (MOSI)
// SClk  = PORTB.1   (SCK)

#include <inttypes.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/pgmspace.h>

#include "n6100.h"

/*
 * global variables
 */
uint8_t color=0;
uint8_t xCoord=0;
uint8_t yCoord=0;
uint8_t memAccessCtrl=0;
uint8_t fontOffset=0;

font f;

void delay5ms(void) {
	volatile uint16_t i;
	for(i=0; i<2200; i++);
}

void n6100SendCommand(uint8_t cmd) {
	// CS auf Low setzen
	PORTB &= ~(0x01 << CS);
	
	// 1. Bit (Command/Data) per Software erzeugen
	PORTB &= ~(0x01 << SCLK);
	PORTB &= ~(0x01 << SDATA);		// logisch 0 f黵 Command
	PORTB |= 0x01 << SCLK;
	
	// Command byte 黚ers SPI senden
	SPCR = (0x01 << SPE) | (0x01 << MSTR) | (0x01 << CPOL);
	SPDR = cmd;
	
	// Auf 躡ertragung warten und CS wieder auf High setzen
	while(!(SPSR & (0x01 << SPIF)));
	PORTB |= 0x01 << CS;			// CS wieder auf 1
	SPCR = 0x00;					// SPI wieder disablen
}

void n6100SendData(uint8_t data) {
#ifdef DEBUG
	volatile uint8_t i;
#endif

	// CS auf Low setzen
	PORTB &= ~(0x01 << CS);
	
	// 1. Bit (Command/Data) per Software erzeugen
	PORTB &= ~(0x01 << SCLK);
	PORTB |= 0x01 << SDATA;		// logisch 1 f黵 Daten
	PORTB |= 0x01 << SCLK;
	
	// Command byte 黚ers SPI senden
	SPCR = (0x01 << SPE) | (0x01 << MSTR) | (0x01 << CPOL);
	SPDR = data;
	
	// Auf 躡ertragung warten und CS wieder auf High setzen
	while(!(SPSR & (0x01 << SPIF)));
	PORTB |= 0x01 << CS;			// CS wieder auf 1
	SPCR = 0x00;					// SPI wieder disablen
	
#ifdef DEBUG
	for(i=0; i<255; i++);
#endif
}

void n6100Init(void) {
	volatile uint8_t i;
	
	// Double SPI Speed
	// gibts beim 8535 nicht
	// SPSR |= 0x01 << SPI2X;
	
	// LCD Hardware Reset
	PORTB |= 0x01 << CS;
	PORTB |= 0x01 << RESET;	
	for(int i=0; i<5; i++);
	PORTB |= ~(0x01 << RESET);	
	for(int i=0; i<10; i++);
	PORTB |= 0x01 << RESET;	
	delay5ms();
	
	PORTB |= 0x01 << SDATA;
	PORTB |= 0x01 << SCLK;
	PORTB |= 0x01 << CS;
	
	n6100SendCommand(SOFT_RESET);
	n6100SendCommand(SLEEP_OUT);
	n6100SendCommand(DISPLAY_ON);
	n6100SendCommand(BOOSTER_ON);
	// Booster Voltage stabilisieren lassen
	for(i=0; i<10; i++) {
		delay5ms();
	}
	
	n6100SendCommand(COLOR_INTERFACE);
	n6100SendData(COLOR_8_BIT);
	
	// initialize Look Up Table for 8 bit mode
	n6100SendCommand(COLOR_SET);
	// red
	n6100SendData(0x00);
	n6100SendData(0x02);
	n6100SendData(0x03);
	n6100SendData(0x04);
	n6100SendData(0x05);
	n6100SendData(0x06);
	n6100SendData(0x08);
	n6100SendData(0x0F);
	// green
	n6100SendData(0x00);
	n6100SendData(0x02);
	n6100SendData(0x03);
	n6100SendData(0x04);
	n6100SendData(0x05);
	n6100SendData(0x06);
	n6100SendData(0x08);
	n6100SendData(0x0F);
	// blue
	n6100SendData(0x00);
	n6100SendData(0x03);
	n6100SendData(0x06);
	n6100SendData(0x0F);
	
	n6100SendCommand(MEM_ACCESS_CTRL);
	memAccessCtrl = (0x01 << MIRROR_X) | (0x01 << RGB);
	n6100SendData(memAccessCtrl);
	
	n6100Clear();
}

void n6100Clear(void) {
	uint16_t i;
	
	n6100SetDrawRect(DISP_X_START, DISP_X_END, DISP_Y_START, DISP_Y_END);
	n6100SendCommand(MEM_WRITE);
	for(i=0; i<17030; i++) {
		n6100SendData(WHITE);
	}
}

int n6100DrawChar(char c) {
	uint16_t index;
	uint8_t i, j, w, data, skipped=1, startY=yCoord;
	
	n6100SendCommand(MEM_ACCESS_CTRL);
	memAccessCtrl |= (0x01 << VERT_WRITE);
	n6100SendData(memAccessCtrl);
	
	if(c == '\n')
		n6100NewLine();
	if(c < 32)
		return 0;
	
	c -= 32;
	index = c*f.width*(f.height/8);
	
	for(w=0; w<f.width; w++) {
		for(i=0; i<f.height/8; i++) {
			data = pgm_read_byte(f.charData + index++);
			for(j=0; j<8; j++) {
				if(data & 0x01) {
					if(skipped) {
						n6100GotoXY(xCoord, yCoord);
						n6100SendCommand(MEM_WRITE);
						skipped=0;
					}
					n6100DrawPixel();
					yCoord++;
				} else {
					skipped=1;
					n6100GotoXY(xCoord, ++yCoord);
				}
				data >>= 1;
			}
		}
		n6100GotoXY(++xCoord, startY);
	}
	
	n6100SendCommand(MEM_ACCESS_CTRL);
	memAccessCtrl &= ~(0x01 << VERT_WRITE);
	n6100SendData(memAccessCtrl);
	
	return 0;
}

void n6100NewLine(void) {
	if(yCoord+f.height < 128)
		n6100GotoXY(fontOffset, yCoord+f.height);
	else
		n6100GotoXY(fontOffset, 0);
}

void n6100DrawCircle(uint8_t xCenter, uint8_t yCenter, uint8_t radius) {
  	int16_t tSwitch, y, x = 0;
  	uint8_t d;

  	d = yCenter - xCenter;
  	y = radius;
  	tSwitch = 3 - 2 * radius;
  	
  	while (x <= y) {
    	n6100DrawPixelXY(xCenter + x, yCenter + y);
    	n6100DrawPixelXY(xCenter + x, yCenter - y);
    	
    	n6100DrawPixelXY(xCenter - x, yCenter + y);
    	n6100DrawPixelXY(xCenter - x, yCenter - y);
    	
    	n6100DrawPixelXY(yCenter + y - d, yCenter + x);
    	n6100DrawPixelXY(yCenter + y - d, yCenter - x);
    	
    	n6100DrawPixelXY(yCenter - y - d, yCenter + x);
    	n6100DrawPixelXY(yCenter - y - d, yCenter - x);

    	if (tSwitch < 0) {
    		tSwitch += (4 * x + 6);
    	} else {
      		tSwitch += (4 * (x - y) + 10);
      		y--;
    	}
    	x++;
  	}
}

void n6100DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
	uint8_t length, xTmp, yTmp, i, y, yAlt;
	int16_t m;
	
	if(x1 == x2) {									// vertical line
		// x1|y1 must be the upper point
		if(y1 > y2) {
			xTmp = x1;
			yTmp = y1;
			x1 = x2;
			y1 = y2;
			x2 = xTmp;
			y2 = yTmp;
		}
		
		length = y2-y1;
		for(i=0; i<=length; i++) {
			n6100DrawPixelXY(x1, y1+i);
		}
	} else if(y1 == y2) {							// horizontal line
		// x1|y1 must be the left point
		if(x1 > x2) {
			xTmp = x1;
			yTmp = y1;
			x1 = x2;
			y1 = y2;
			x2 = xTmp;
			y2 = yTmp;
		}
		
		length = x2-x1;
		for(i=0; i<=length; i++) {
			n6100DrawPixelXY(x1+i, y1);
		}
	} else {
		// x1 must be smaller than x2
		if(x1 > x2) {
			xTmp = x1;
			yTmp = y1;
			x1 = x2;
			y1 = y2;
			x2 = xTmp;
			y2 = yTmp;
		}
		
		if((y2-y1) >= (x2-x1) || (y1-y2) >= (x2-x1)) {	// angle larger or equal 45

⌨️ 快捷键说明

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