📄 main.c
字号:
/****************************************************************************
【功能说明】液晶模块控制器初始化,外接DMF50081(320×240)液晶模块
****************************************************************************/
void Lcd_Init(void)
{
rPCOND=0xaaaa;
rLCDCON1=(2)|(INVFRAME<<2)|(INVLINE<<3)|(INVCLK<<4)|(1<<5)|(MVAL_USED<<7)|(1<<8)|(1<<10)|(CLKVAL_SL<<12);
//下降沿装载视频数据,禁止视频输出,LCD FIFO清空;行、帧信号取反;
//4位单扫描模式;WDLY=8clk,WLH=8clk,CLKVAL_SL=38
rLCDCON2=(239)|(79<<10)|(10<<21);
//垂直点数为240,水平点数320=(80字),LINEBLANK=10
rLCDSADDR1= (0x0<<27) | ( ((U32)Bmp>>22)<<21 ) | M5D((U32)Bmp>>1);
// 黑白模式, LCDBANK, LCDBASEU
rLCDSADDR2= (1<<29) | (M5D((U32)Bmp + ((320/8)*(240)))>>1) | (MVAL<<21);
rLCDSADDR3= (320/16) | ( 0<<9 );
rLCDCON1=(1)|(INVFRAME<<2)|(INVLINE<<3)|(INVCLK<<4)|(1<<5)|(MVAL_USED<<7)|(1<<8)|(1<<10)|(CLKVAL_SL<<12);
//下降沿装载视频数据,禁止视频输出,LCD FIFO清空;行、帧信号取反;
//4位单扫描模式;WDLY=8clk,WLH=8clk,CLKVAL_SL=38
}
//***************************************************************************
/****************************************************************************
【功能说明】液晶显示屏全屏填充某一个8位二进制数
****************************************************************************/
void Lcd_Fill(U8 m)
{
U16 i;
for(i = 0; i < 9600; i++) Bmp[i] = m;
}
//***************************************************************************
/****************************************************************************
【功能说明】液晶显示一个图片数组(向液晶控制器的显示存储器中填充待显示数据)
****************************************************************************/
void Lcd_Show_Bmp320_240(photo)
unsigned char photo[];
{
U16 i;
for(i = 0; i < 9600; i++)
{
Bmp[i] = photo[i];
}
}
//***************************************************************************
/****************************************************************************
【功能说明】实时时钟初始化
****************************************************************************/
void Rtc_Init(void)
{
rRTCCON = 0x01; //RTC读写使能,选择BCD时钟、计数器,无复位,1/32768
rBCDYEAR = RTC_YEAR0; //年
rBCDMON = RTC_MONTH0; //月
rBCDDAY = RTC_DAY0; //日
rBCDDATE = RTC_DATE0; //星期
rBCDHOUR = RTC_HOUR0; //小时
rBCDMIN = RTC_MIN0; //分
rBCDSEC = RTC_SEC0; //秒
}
//***************************************************************************
/****************************************************************************
【功能说明】显示实时时钟
****************************************************************************/
void Display_Rtc(void)
{
U16 year;
U8 month,day,weekday,hour,min,sec;
U8 m,n;
rRTCCON = 0x01; //RTC读写使能,选择BCD时钟、计数器,无复位,1/32768
year = 2000 + rBCDYEAR;
month = rBCDMON;
m = month>>4; n = month&0x0f;
month = m*10 + n; //BCD码转十进制
day = rBCDDAY;
m = day>>4; n = day&0x0f;
day = m*10 + n; //BCD码转十进制
weekday = rBCDDATE;
hour = rBCDHOUR;
m = hour>>4; n = hour&0x0f;
hour = m*10 + n; //BCD码转十进制
min = rBCDMIN;
m = min>>4; n = min&0x0f;
min = m*10 + n; //BCD码转十进制
sec = rBCDSEC;
m = sec>>4; n = sec&0x0f;
sec = m*10 + n; //BCD码转十进制
rRTCCON = 0x00; //RTC读写禁止(降低功率消耗),选择BCD时钟、计数器,无复位,1/32768
Uart_Printf(0,"Date:/%02d/%02d/%04d %02d:%02d:%02d\n",month,day,year,hour,min,sec);
}
//***************************************************************************
/****************************************************************************
【功能说明】实时时钟定时报警
****************************************************************************/
void Rtc_Alarm(void)
{
rALMYEAR = RTC_YEAR1 ; //年
rALMMON = RTC_MONTH1; //月
rALMDAY = RTC_DAY1; //日
rALMHOUR = RTC_HOUR1; //小时
rALMMIN = RTC_MIN1; //分
rALMSEC = RTC_SEC1; //秒
rRTCALM=0x7f; //全局警报使能控制,年、月、日、星期、时分秒警报使能控制
}
//***************************************************************************
/****************************************************************************
【功能说明】模数转换初始化
****************************************************************************/
void ADC_Init(void)
{
rCLKCON = rCLKCON | (1<<12); //控制系统主时钟进入ADC单元模块
rADCCON = 0x1|(0<<2); //ADC转换使能,选择AIN7
Delay(100); //延时若干个100us
rADCPSR = 10; //ADC转换频率为:(int)(MCLK/(2*(rADCPSR+1))/16)
}
//***************************************************************************
/****************************************************************************
【功能说明】ADC某一通道进行转换,返回转换的数据
****************************************************************************/
U16 Read_Adc(unsigned char ain)
{
int i;
rADCCON = 0x1|(ain<<2); //设置AD转换通道
while(rADCCON & 0x1); //避免标志FLAG错误
while(!(rADCCON & 0x40)); //等待AD转换结束
for(i = 0; i < rADCPSR; i++); //避免第二次标志FLAG错误
return rADCDAT; //返回AD转换值
}
//***************************************************************************
#define BASE ((volatile unsigned char *)(0x6000000))
#define ROM ((volatile unsigned char *)(BASE+0x20))
#define CS_9346(x) (x?(*ROM=*ROM|0x08):(*ROM=*ROM&0xF7))
#define SK_9346(x) (x?(*ROM=*ROM|0x04):(*ROM=*ROM&0xFB))
#define DO_9346(x) (x?(*ROM=*ROM|0x01):(*ROM=*ROM&0xFE))
#define DI_9346 ((*ROM&0x02)?1:0)
#define delay Delay
void eeprom_start(void)
{
CS_9346(1);
delay(20);
CS_9346(0);
delay(20);
}
void eeprom_stop(void)
{
CS_9346(1);
DO_9346(0);
SK_9346(0);
delay(50);
}
void eeprom_send_cmd(unsigned int opcode)
{
int i = 9;
eeprom_start();
delay(5);
while (i--) {
DO_9346(opcode & 0x100);
SK_9346(1);
delay(1);
SK_9346(0);
delay(1);
opcode <<= 1;
}
delay(5);
eeprom_stop();
}
void eeprom_write_data(unsigned char addr,unsigned short data)
{
unsigned int opcode = 0x01400000;
int i = 25;
delay(5);
opcode |= (addr << 16);
opcode |= data;
while (i--) {
DO_9346(opcode & 0x01000000);
SK_9346(1);
delay(1);
SK_9346(0);
delay(1);
opcode <<= 1;
}
delay(5);
}
void eeprom_read_data(unsigned char addr,unsigned short *data)
{
unsigned int opcode = 0x180;
int i = 9;
unsigned short c;
delay(5);
opcode |= addr;
while (i--) {
DO_9346(opcode & 0x0100);
SK_9346(1);
delay(1);
SK_9346(0);
delay(1);
opcode <<= 1;
}
i = 16;
c = 0;
SK_9346(1);
delay(1);
SK_9346(0);
while (i--) {
c <<= 1;
c += DI_9346;
SK_9346(1);
delay(1);
SK_9346(0);
delay(1);
}
delay(5);
}
void eeprom_write_all(unsigned char *buf)
{
unsigned char *p = buf;
unsigned char addr = 0;
unsigned short data ;
int i;
eeprom_send_cmd(0x130);
eeprom_send_cmd(0x120);
eeprom_start();
for (i=0;i<64;i++) {
data = ((*p)*256) + (*(p+1));
eeprom_write_data(addr,data);
addr += 1;
p += 2 ;
}
eeprom_stop();
eeprom_send_cmd(0x100);
}
void eeprom_read_all(unsigned char *buf)
{
unsigned char *p = buf;
unsigned char addr = 0;
unsigned short data ;
int i;
eeprom_start();
for (i=0;i<64;i++) {
eeprom_read_data(addr,&data);
*p++ = (unsigned char)data;
*p++ = (unsigned char)(data>>8);
addr += 1;
}
eeprom_stop();
}
void readreg()
{
unsigned char c[]={0x21,0x41,0xa1,0xe1};
int i,j;
volatile unsigned char *p =(volatile unsigned char *)(BASE);
{
for (i=0; i<4; i++) {
*(volatile unsigned char *)(p) = c[i];
Uart_Printf(0,"\nReg%c:",'A'+i);
for (j=0;j<16;j++) {
if (j&1) {
Uart_Printf(0,"%02X ",(int)(*(volatile unsigned char *)(p+j+0x20-1)));
} else {
Uart_Printf(0,"%02X ",(int)(*(volatile unsigned char *)(p+j)));
}
}
Uart_Printf(0,"\n");
}
}
}
int Net_Init()
{
*(BASE+0x1e) = *(BASE+0x1e + 0x20);
delay(20);
*(BASE+0x00) = 0xc1;
*(BASE+0x20) = 0xc0;
*(BASE+0x04) = 0x80;
*(BASE+0x24) = 0x00;
*(BASE+0x06) = 0x70;
*(BASE+0x26) = 0xFF;
*(BASE+0x00) = 0x41;
*(BASE+0x20) = 'H';
*(BASE+0x02) = 'E';
*(BASE+0x22) = 'L';
*(BASE+0x04) = 'L';
*(BASE+0x24) = 'O';
*(BASE+0x06) = '!';
return 1;
}
typedef (*FUNC)(void);
int Burn(void);
/****************************************************************************
【功能说明】系统主函数
****************************************************************************/
void Main(void)
{
U16 a0,a1,a2,a3,a4,a5,a6,a7;
U32 *p = (U32*)0x0020000;
U32 *q = (U32*)0xC008000;
U32 i;
FUNC fp;
char c;
rSYSCFG=0x0e; //使用8K字节的指令缓存
Port_Init(); //IO端口功能、方向设定
Lcd_Init();
Isr_Init(); //中断初始化
Net_Init();
Beep(500); //蜂鸣器鸣叫若干个100us
//改成2倍频 by yang 2003.5
ChangePllValue(8,2,1); //修改系统主频为4倍频
//改成38400
Uart0_Init(0,115200); //异步串行口0初始化,设置波特率为57600
Uart1_Init(0,115200); //异步串行口1初始化,设置波特率为57600
Uart_Printf(0,"\n\n\n");
Uart_Printf(0,"*******************************\n");
Uart_Printf(0,"* Welcome to S3C44B0X *\n");
Uart_Printf(0,"* *\n");
Uart_Printf(0,"* Boundless Embed Studio *\n");
Uart_Printf(0,"* (2003-2004) *\n");
Uart_Printf(0,"*******************************\n\n");
rNCACHBE0 = 0x80006000;
Uart_Printf(0,"Boot to uClinux (Y/N)?");
c = 0;
while (Uart_GetKey(0));
do {
c = Uart_GetKey(0);
if (!c) c = Uart_GetKey(1);
} while (!c) ;
if (c=='Y' || c=='y' || c=='u' || c=='U') {
Uart_Printf(0,"\n\nuClinux boot loader...\n");
for (i=0;i<((0xD0000)>>2);i++) {
*q++ = *p ++;
}
if ('u'!=c && 'U'!=c) {
p = (U32*)0x0100000;
q = (U32*)0xC700000;
for (i=0;i<((0xD0000)>>2);i++) {
*q++ = *p ++;
}
}
fp = (FUNC)0xc008000;
(*fp)();
}
Uart_Printf(0,"\n\nBurn Flash (Y/N)?");
do {
c = Uart_GetKey(0);
if (!c) c = Uart_GetKey(1);
} while (!c) ;
if (c=='Y' || c=='y' ) {
int i=0,j=0;
while (1) {
Uart_Printf(0,"\n\nEnter password:");
while (i<6) {
do {
c = Uart_GetKey(0);
if (!c) c = Uart_GetKey(1);
} while (!c) ;
i++;
j+=c;
Uart_Printf(0,"%c",c);
}
if (j==309) {
Uart_Printf(0,"\n\n");
rNCACHBE0 =0x20000000;
Burn();
}
Uart_Printf(0,"\nPassword Error!");
i = 0;
j = 0;
}
}
Uart_Printf(0,"\n\n");
while(1)
{
a0 = Read_Adc(0); //ADC某一通道进行转换,返回转换的数据
a1 = Read_Adc(1); //ADC某一通道进行转换,返回转换的数据
a2 = Read_Adc(2); //ADC某一通道进行转换,返回转换的数据
a3 = Read_Adc(3); //ADC某一通道进行转换,返回转换的数据
a4 = Read_Adc(4); //ADC某一通道进行转换,返回转换的数据
a5 = Read_Adc(5); //ADC某一通道进行转换,返回转换的数据
a6 = Read_Adc(6); //ADC某一通道进行转换,返回转换的数据
a7 = Read_Adc(7); //ADC某一通道进行转换,返回转换的数据
Uart_Printf(0,"\nADC 0-7:%4d %4d %4d %4d %4d %4d %4d %4d\n",a0,a1,a2,a3,a4,a5,a6,a7);
Display_Rtc(); //显示实时时钟
Key_Speaker(); //检测四个按键,有任何一个按键按下就让蜂鸣器鸣叫,否则不鸣叫
}
}
//***************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -