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

📄 44blib.c

📁 44b0控制16级灰度lcd的显示程序,有完整的启动代码
💻 C
字号:
#include "def.h"
#include "44b.h"
#include "option.h"	//defined Non_Cache_End,Non_Cache_Start,SYSCFG_0KB,SYSCFG_8KB
#include "44blib.h"


#define	ROM_SIZE	SIZE_2M
#define BIOS_ENV_ADDR		(ROM_SIZE-0x200)		//0x200000 - 0x200 = 0x1ffd00

void PortInit(void)
{
	// PORT A GROUP
	/*  BIT 9	8	7	6	5	4	3	2	1	0	*/
	/*  O	  A23	A22	A21	A20	A19	A18	A17	A16	A0	*/	      
	/*  0		1	1	1	1	1	1	1	1	1	*/
	rPCONA = 0x1ff;			//GPA9 is output for LCD_DISP
	rPDATA = rPDATA & (~(1<<9)) ;		//LCD DISPLAY and BlackLight is off

	// PORT B GROUP
	/* BIT 10   9          8       7         6        5            4          3     2     1     0    */
	/* /CS5   /CS4       /CS3    /CS2      /CS1     nWBE3        nWBE2      /SRAS /SCAS SCLS  SCKE	*/
	/* SL811 PDIUSBD12  CS8900  CF_CARD  NV_Flash   CF_POWER  D12SUBSPEND   Sdram Sdram Sdram Sdram*/
	/*     1,   1,        1,      1,        1,       0,           0,          1,    1,    1,    1    */
	rPCONB = 0x7cf;
	rPDATB = rPDATB & (~(3<<4)) ;		//CF CARD power is off, D12 SUBSPEND is Low
    
	//PORT C GROUP
	//BUSWIDTH=16													*/
	/*  PC15	14		13		12		11		10		9		8	*/
	/*	CTS0	RTS0	RXD1	TXD1	o		o		o		I	*/
	/*	CTS0	RTS0	Uart1	Uart1	CTS1	RTS1	NF_CE	NF_RB	*/
	/*  11		11		11		11		11		11		01		00	*/

	/*  PC7		6		5		4		3		2		1		0	*/
	/*   o		o		o		o		o		o		o		o	*/
	/*   VD4	VD5		VD6		VD7 	IISCLK 	IISDI 	IISDO 	IISLRCK*/
	/*   11		11		11		11		11		11		11		11	*/
	rPCONC = 0xfff4ffff;	//0->D12SUSPD, 1~3->LED, 4~7->VD7~VD4, 8->DISPON, 9->BACKLIGHT, 10~13->UART1, 14->RTS0, 15->CTS0
	rPUPC  = 0x0000;	//disable all pull-up

	//PORT D GROUP
	/*  PORT D GROUP(I/O OR LCD)										*/
	/*  BIT7		6		5		4		3		2		1		0	*/
	/*      VF		VM		VLINE	VCLK	VD3		VD2		VD1		VD0	*/
	/*	   10		10		10		10		10		10		10		10	*/
	rPCOND= 0xaaaa;	
	rPUPD = 0x00;
	//These pins must be set only after CPU's internal LCD controller is enable
	
	//PORT E GROUP 
	/*  Bit 8	7		6		5		4			3			2		1		0		*/
	/*	CODECLK	LED		BEEP	CSTPCAN	CF_IORDY	CF_DECTED	RXD0	TXD0	SM_Busy	*/ 
	/*  10		01		10		01		00			00			10		10		00		*/
	rPCONE	= 0x26428;	//0->input, 1 2->TXD0 RXD0, 3 4->input, 5->led, 6->buzzer, 7->led, 8->CODECLK
	rPDATE	= rPDATE & (~(1<<7));		//LED is ON
	rPUPE	= 0x000;	//enable all pull-up
	
	//PORT F GROUP
	/*  Bit8		7	6		5		4		3		2		1		0		*/   
	/*  output	input	L3CLOCK	output	O		O		nWAIT	O		O		*/
	/*	001		000		001		001		01		01		10		00		01		*/
	rPCONF = 0x182561;	//
	rPUPF  = 0x000;		//disable all pull-up

	//PORT G GROUP
	/*  BIT7	6		5		4			3			2			1			0	 */
	/*	INT7	INT6	INT5	INT4		INT3		INT2		INT1		INT0	*/
	/*  IDE		MCP2510	CF_IRQ	PDIUSBD12	SL811HST	CS8900_IRQ	ADS7843		KEY_IN	*/
	/*  11      11      11      11      	11     		11      	00      	00       */
	rPCONG = 0xfff0;
	rPUPG  = 0x00;		//disable all pull-up
	
	rSPUCR = 0x6;  //D15-D0 pull-up enable

	//rEXTINT = (1<<12) | (2<<8) ;	//SL811HST是高电平中断,CS8900下降沿中断
	rEXTINT = (1<<12) | (1<<8) ;	//SL811HST是高电平中断,CS8900高电平中断
}

void Beep(U32 freq, U32 ms)
{
	rTCON  	&= ~0xf0000;			// clear manual update bit, stop Timer3
	rTCFG0 	&= ~0xff00;				// set Timer 2&3 prescaler 0
	rTCFG1 	&= ~0xf000;				// set Timer 3 MUX 1/16
	rTCFG1  |= 0x3000;
	rTCNTB3	 = GetCpuClock()/(2100*16);		//if set inverter off, when TCNT2<=TCMP2, TOUT is high, TCNT2>TCMP2, TOUT is low
	rTCMPB3  = rTCNTB3>>1;			//if set inverter on,  when TCNT2<=TCMP2, TOUT is low,  TCNT2>TCMP2, TOUT is high
	rTCON	|= 0x20000;				// manual update
	rTCON	&= ~0x20000;			// clear manal update bit
	rTCON   |= 0xd0000;				// auto reload, inverter on, start Timer 2	
	
	Delay(ms);
	
	rTCON &= ~0x10000;
}

void Beep_On( U32 freq )
{
	rTCON  	&= ~0xf0000;			// clear manual update bit, stop Timer3
	rTCFG0 	&= ~0xff00;				// set Timer 2&3 prescaler 0
	rTCFG1 	&= ~0xf000;				// set Timer 3 MUX 1/16
	rTCFG1  |= 0x3000;
	rTCNTB3	 = GetCpuClock()/(2100*16);		//if set inverter off, when TCNT2<=TCMP2, TOUT is high, TCNT2>TCMP2, TOUT is low
	rTCMPB3  = rTCNTB3>>1;			//if set inverter on,  when TCNT2<=TCMP2, TOUT is low,  TCNT2>TCMP2, TOUT is high
	rTCON	|= 0x20000;				// manual update
	rTCON	&= ~0x20000;			// clear manal update bit
	rTCON   |= 0xd0000;				// auto reload, inverter on, start Timer 2	
}
	
void Beep_Off( void )
{
	rTCON &= ~0x10000;
}

void LedSet(U32 LedStatus)
{
	if( LedStatus > 0 )
		rPDATE	= rPDATE & (~(1<<7));	//LED is ON
	else
		rPDATE	= rPDATE | (1<<7);		//LED is OFF
}

void MemCfgInit(void)
{
	rNCACHBE0 = ((unsigned int)(Non_Cache_End0>>12)<<16)|(Non_Cache_Start0>>12);
		//SDRAM最后512K禁止cache,用作LCD显示缓存
	
	rNCACHBE1 = ((unsigned int)(Non_Cache_End1>>12)<<16)|(Non_Cache_Start1>>12);
}

void CacheDisable(void)
{
	rSYSCFG = SYSCFG_0KB;
}

void CacheEnable(void)
{
	rSYSCFG = SYSCFG_8KB;
}

void CacheFlush(void)
{
	int i, saveSyscfg;
    
    saveSyscfg = rSYSCFG;
	//clear TAG & LRU
    rSYSCFG = SYSCFG_0KB;
    for(i = 0x10002000; i<0x10004800; i+=16)
		*((int *)i) = 0x0;
	
    rSYSCFG = saveSyscfg;
}

U16 GetKeyStatus(void)
{
	if( ((rPDATF&(1<<1))==0) || ((rPDATG&(1<<0))==0) )
		return 1 ;
	else	return 0 ;
}

/*************************************************************/
/*下面是时钟函数*/
/*************************************************************/
#include "def.h"
#include "44blib.h"
#include "44b.h"
#include "option.h"	//defined EXT_OSC_CLK

struct{
	U32 mclk;
	U32 pclk;
	U32 sclk;
	U32 freq;
} ClkPara;

static void set_pll(void)
{
	U32 i, j;
	
	if(ClkPara.mclk>255)
		ClkPara.mclk = 255;
	if(ClkPara.pclk>63)
		ClkPara.pclk = 63;
	if(ClkPara.sclk>3)
		ClkPara.sclk = 3;	
		
	j = ClkPara.sclk;
//	i = 1;
//	while(j--)
//		i *= 2;
	i = 1<<j;
	
	ClkPara.freq = (EXT_OSC_CLK*(ClkPara.mclk+8))/((ClkPara.pclk+2)*i);
	if((ClkPara.freq>=90000000)||(ClkPara.freq<EXT_OSC_CLK)) {
		ClkPara.mclk = 114;
		ClkPara.pclk = 8;
		ClkPara.sclk = 1;
		ClkPara.freq = EXT_OSC_CLK*122/20;
	}
	
	rPLLCON = (ClkPara.mclk << 12) | (ClkPara.pclk << 4) | ClkPara.sclk;
}

void SystemClockInit(void)
{
	ClkPara.mclk = PLL_M;	//	((m+8)*EXT_OSC_CLK)/((p+2)*(1<<s))
	ClkPara.pclk = PLL_P;	//
	ClkPara.sclk = PLL_S;	//
	set_pll();
}

void ChangePllValue(U16 mval, U8 pval, U8 sval)
{
	ClkPara.mclk = mval;
	ClkPara.pclk = pval;
	ClkPara.sclk = sval;
	set_pll();
}

void SetAssumeFreq(U32 freq)
{
	ClkPara.freq = freq;
}

U32 GetCpuClock(void)
{
	return ClkPara.freq;
}

U32 GetMasterClock(void)
{
	return GetCpuClock();
}

void TimerInit(U32 HZ)
{
	rTCON  	&= ~(0xf<<24);			//clear manual update bit, stop Timer5
	rTCFG0 	&= ~(0xff<<16);			//set Timer 4&5 prescaler 1/2
	rTCFG0  |= 1<<16;
	rTCFG1 	&= ~(0xf<<20);			//set Timer 5 MUX 1/16
	rTCFG1  |= 3<<20;
	rTCNTB5	 = GetCpuClock()/(HZ*2*16)-1;
	rTCON	|= 2<<24;				//manual update
	rTCON	&= ~(2<<24);			//clear manal update bit
	rTCON   |= (5<<24);				//auto reload, inverter on, start Timer 5
}

/*void ResetTimer(void)
{
	rTCON &= ~(1<<24);
	rTCON |= (1<<24);
}*/

void Delay(U32 ms)	//以ms为延时单位
{
	U16 i;
	
	i = rTCNTB5>>1;	//1000us/2
	
	rTCON &= ~(1<<24);
	rTCON |= (1<<24);	//停止再启动,重装初值,减计数
	
	while(ms--) {
		while(rTCNTO5>=i);
		while(rTCNTO5<i);
	}
}

/************************* Timer ********************************/

void Timer_Start(int divider)  //0:16us,1:32us 2:64us 3:128us
{
    rWTCON=((GetCpuClock()/1000000-1)<<8)|(divider<<3);
    rWTDAT=0xffff;
    rWTCNT=0xffff;   

    // 1/16/(65+1),nRESET & interrupt  disable
    rWTCON=((GetCpuClock()/1000000-1)<<8)|(divider<<3)|(1<<5);	
}


int Timer_Stop(void)
{
//    int i;
    rWTCON=((GetCpuClock()/1000000-1)<<8);
    return (0xffff-rWTCNT);
}

/***************************************************/
/*串口程序*/
/***************************************************/
#ifndef	SERIAL_PORTS_SWITCH
#define	SERIAL_PORTS_SWITCH		1
#endif

static U16 SerialPortSel;

U16 SerialSwitch(U16 port)
{
#ifdef	SERIAL_PORTS_SWITCH
//	U16 old_sel = SerialPortSel;

	SerialPortSel = port?1:0;
#else
	SerialPortSel = 0;
#endif
	return SerialPortSel;
}

static U32 SerialBaud;

void SerialChgBaud(U32 baud)
{
	U32 mclk =  GetMasterClock();
	
	rUFCON0 = 0x0;		//FIFO disable
	rUFCON1 = 0x0;
	rUMCON0 = 0x0;
	rUMCON1 = 0x0;
//UART0
//	rULCON0  = 0x7;		//Normal,No parity,2 stop,8 bit
	rULCON0  = 0x3;		//Normal,No parity,1 stop,8 bit
	rUCON0   = 0x245;	//rx=edge,tx=level,disable timeout int.,enable rx error int.,normal,interrupt or polling
	rUBRDIV0 = ((int)(mclk/16./baud + 0.5) -1);
//UART1
//	rULCON1  = 0x7;		//Normal,No parity,2 stop,8 bit
	rULCON1  = 0x3;
	rUCON1   = 0x245;
	rUBRDIV1 = ((int)(mclk/16./baud + 0.5) -1);
	
	SerialBaud = baud;
}

U32 SerialGetBaud(void)
{
	return SerialBaud;
}

void SerialTxEmpty(void)
{
//	if(SerialPortSel)
		while(!(rUTRSTAT1 & 0x4)); //wait until tx shifter is empty.
//	else
		while(!(rUTRSTAT0 & 0x4)); //wait until tx shifter is empty.

}

void SerialTxChar(char data)
{
	if(SerialPortSel) {
		if(data=='\n') {
			while(!(rUTRSTAT1 & 0x4));
	    	Delay(1);	//because the slow response of hyper_terminal 
			WrUTXH1('\r');
		}
		while(!(rUTRSTAT1 & 0x4)); //Wait until THR is empty.
		WrUTXH1(data);
    } else {
		if(data=='\n') {
			while(!(rUTRSTAT0 & 0x4));
			Delay(1);	//because the slow response of hyper_terminal 
			WrUTXH0('\r');
		}
		while(!(rUTRSTAT0 & 0x4));  //Wait until THR is empty.
		WrUTXH0(data);
    }
}

int SerialRxReady(void)
{
	if(SerialPortSel)
		return (rUTRSTAT1 & 0x1);	//Receive data ready
	else 
		return (rUTRSTAT0 & 0x1);	//Receive data ready
}

char SerialRxKey(void)
{
	if(SerialPortSel) {
		if((rUTRSTAT1 & 0x1)) //Receive data ready
			return RdURXH1();
	} else {
		if((rUTRSTAT0 & 0x1)) //Receive data ready
			return RdURXH0();
	}
	return 0;
}

char SerialRxChar(void)
{
	if(SerialPortSel) {
		while(!(rUTRSTAT1 & 0x1)); //Receive data ready
		return RdURXH1();
	} else {
		while(!(rUTRSTAT0 & 0x1)); //Receive data ready
		return RdURXH0();
	}
}

int SerialRxToBuf(char *b)
{
	if(SerialPortSel) {
		if(rUTRSTAT1 & 0x1)    //Receive data ready
			*b = RdURXH1();
		else
		    return 0;
    } else {
		if(rUTRSTAT0 & 0x1)    //Receive data ready
		    *b = RdURXH0();
		else
		    return 0;
    }
    
    return 1;
}

void SerialTxString(char *s)
{
	 while(*s)
		SerialTxChar(*s++);
}

//*****************************************************************************

/**************************************************************************/
/****其他*/
/************************************************************************/
#include <stdarg.h>

void putch(char ch)
{
	SerialTxChar(ch);
	
}

void puts(char *str)
{
	SerialTxString(str);
	
}

int kbhit(void)
{
	if(SerialRxReady())
		return 1;
	return 0;
}

int getkey(void)
{
	int c;
	
	c = SerialRxKey();
	if(c)
		return c;
	return 0;
}

char getch(void)
{
	int c;
	
	while(1) {
		c = getkey();
		if(c) {
			//printf("get key!\n");
			return c;
		}
	}
	//return SerialRxChar();
}

//If you don't use vsprintf(), the code size is reduced very much.
typedef int *__va_list[1];
int vsprintf(char * /*s*/, const char * /*format*/, __va_list /*arg*/);

void printf(char *fmt, ...)
{
	va_list ap;
	char string[1024];
	
	va_start(ap,fmt);
	vsprintf(string,fmt,ap);
	puts(string);
	va_end(ap);
}

void sprintf(char *mem, char *fmt, ...)
{
	va_list ap;
	
	va_start(ap,fmt);
	vsprintf(mem,fmt,ap);
	va_end(ap);
}


int getyorn(void)
{
	char c;
	
	puts(" [y/n] ");
	while(1) {		
		c = getch();
		if((c=='y')||(c=='Y')||(c=='n')||(c=='N'))
			break;
	}
	putch(c);
	putch('\n');
	return c&1;	//y&Y are odd, n&N are even
}



⌨️ 快捷键说明

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