📄 main.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2007-06-24
** Last Version: 1.0
** Descriptions: The main() function
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**-------------------------------------------------------------------------------
** 程序进程:
** 6.24日: 完成LCD状态字的读,指令和数据的写,但没调试这部分代码
** 6.25日: 完成INI(),CLEAR(),CGRAM()和WRI_CT()等函数,没调试
** 6.26日: 把程序试跑了一下,不行,于是对前两天写的代码重新进行了修改,但调试到最后
** (只进行清屏调试),发现不能写入数据,除非在CLEAR时写入超过1365个字节数据才有数据显示
** 估计是屏的地址设置不正确
** 6.27日: 阅读了下别人在51单片机写的程序,发现PG160128F是双屏结构,清屏时应该采用图形写入单字
** 节数据方式,即从地址从0800H开始的,
** 于是把CLEAR()函数中的地址改为0800H,结果正确,哈哈,爽!
** 在晚上通过修改,可以正确写入汉字(图形写入汉字方式)
** 7.01日: 完成了开机显示页面的显示
** 7.02日: 利用ARM RTC实现万年历的显示
** 7.03日:把LCD的接口移到了P1口
** 7.04日: 写了下KEY_SCAN功能,不过好像没有用
** 7.05日: 这两天觉得中断有问题,甚至怀疑中断是不是设置有错误?写了个定时器0中断,让"好人一生平安"可以跑起来
** 7.06日:终于解决原以为RTC中断返回时没有返回到中断点处(用P0.0作为信号灯),原来是IO口设置错误,
** 不过这个"假现象"让我弄懂了函数IRQEnable()为什么弄开中断了,原来是SWI搞得鬼.
** 晚上十时三十六分按键基本上能用了,原先有问题估计是IO的选择上,换了IO口就行了,不知道为什么?
********************************************************************************************************/
#include "config.h"
#define LCD_WR 1<<18 // P1.18 is LCD的写信号
#define LCD_RD 1<<17 // P1.17 is LCD的读信号
#define LCD_CD 1<<16 // P1.16 is LCD的读数据指令通道选择
#define BEEP 1<<7 // BUZZER is connected P0.7,低电平蜂鸣
#define KEY_A 1<<20
#define KEY_B 1<<21
#define KEY_C 1<<22
#define KEY_D 1<<23
#define KEY_E 1<<26
#define KEY_F 1<<31
uint8 DAT1; // LCD的第一参数单元
uint8 DAT2; // LCD的第二参数单元
uint8 COM; // LCD的指令代码单元
uint8 CODE; // LCD的汉字 字符代码 单元
uint8 LCD_X; // LCD的X座标
uint8 LCD_Y; // LCD的Y座标
uint8 COUNT; // LCD显示的字符个数,若是汉字,则需要四个字节字符
uint8 cursor_Flag; // LCD的光标标志,1显示光
uint8 Dis_Page; // LCD的显示页码
typedef struct My_calendar
{
uint16 year;
uint8 month;
uint8 date;
uint8 week;
uint8 hour;
uint8 minute;
uint8 second;
uint8 temp;
}Calendar;
/*******函数声明*******/
void WRI_CC (uint8 x,uint8 y,uint8 cod,uint8 dat8_16);
void PR1(uint8 dat_1,uint8 dat_2,uint8 cmd);
void PR12(uint8 cmd);
void PR13(uint8 dat);
/*
********************************************************************************************************
** 函数名称 : RTC_Int()
** 功能描述 : RTC中断服务函数。
** 入口参数 :无
** 出口参数 :无
*******************************************************************************************************
*/
void __irq RTC_Int(void)
{
uint32 datas;
uint32 times;
uint32 bak;
if ((IO0SET & BEEP) == 0)
IO0SET = BEEP; /* 关闭BEEP */
else
IO0CLR = BEEP;
times = CTIME0;
datas = CTIME1;
bak = (datas >> 16) & 0xfff;// 获取 年
WRI_CC(4,18,(bak / 1000),1);//2
bak = bak % 1000;
WRI_CC(5,18,(bak / 100),1);//0
bak = bak % 100;
WRI_CC(6,18,(bak / 10),1);//0
WRI_CC(7,18,(bak % 10),1);//7
//WRI_CC(8,18,5,2);//年
bak = (datas >> 8) & 0x0f; // 获取 月
if(bak > 9)
{
WRI_CC(10,18,(bak / 10),1);
WRI_CC(11,18,(bak % 10),1);
WRI_CC(12,18,6,2);// 重新写"月"
bak = datas & 0x1f; // 获取 日
if(bak > 9)
{
WRI_CC(14,18,(bak / 10),1);
WRI_CC(15,18,(bak % 10),1);
WRI_CC(16,18,7,2);// 重新写"日"
}
else
{
WRI_CC(14,18,bak,1);
WRI_CC(15,18,7,2);// 重新写"日"
}
}
else if (( (datas >> 8) & 0x0f ) < 10 )
{
WRI_CC(10,18,bak,1);
//WRI_CC(11,18,6,2);//月
bak = datas & 0x1f; // 获取 日
if(bak > 9)
{
WRI_CC(13,18,(bak / 10),1);
WRI_CC(14,18,(bak % 10),1);
WRI_CC(15,18,7,2);// 重新写"日"
}
else
{
WRI_CC(13,18,bak,1);
//WRI_CC(15,18,7,2);// 重新写"日"
}
}
bak = (times >> 16) & 0x1f; // 获取 小时
WRI_CC(6,43,(bak / 10),1);
WRI_CC(7,43,(bak % 10),1);
bak = (times >> 8) & 0x3f; // 获取 分钟
WRI_CC(9,43,(bak / 10),1);
WRI_CC(10,43,(bak % 10),1);
bak = times & 0x3f; // 获取 秒钟
WRI_CC(12,43,(bak / 10),1);
WRI_CC(13,43,(bak % 10),1);
bak = (times >> 24) & 0x07; // 获取 星期
if(bak == 0 )
{
WRI_CC(8,73,7,2);
}
else
{
WRI_CC(8,73,(bak +10),2);//一
}
//WRI_CC(11,73,2,1);//2
//WRI_CC(12,73,5,1);//5
//WRI_CC(13,73,10,2);//℃
ILR = 0x01; // 清除RTC增量中断标志
VICVectAddr = 0; // 向量中断结束
}
/*
*********************************************************************************************************
** 函数名称 :IRQ_Timer0()
** 函数功能 :定时器0中断服务程序,取反LED9控制口。
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void __irq IRQ_Timer0 (void)
{
uint8 i;
Dis_Page--;
WRI_CC((Dis_Page-5),0,12,1);//好 从第0行开始
WRI_CC((Dis_Page-4),0,13,1);//人
WRI_CC((Dis_Page-3),0,14,1);//一
WRI_CC((Dis_Page-2),0,15,1);//生
WRI_CC((Dis_Page-1),0,16,1);//平
WRI_CC(Dis_Page,0,17,1);//安 第15行结束
if(Dis_Page < 19)
{
for(i = (Dis_Page+1);i<20;i++)
WRI_CC(i,0,18,1);
}
if(Dis_Page == 25) WRI_CC(0,0,18,1);
if(Dis_Page == 0) Dis_Page = 26;
T0IR = 0x01; /* 清除中断标志 */
VICVectAddr = 0x00; /* 通知VIC中断处理结束 */
}
/*
*******************************************************************************************************
** 函数名称 :VIC_Init()
** 函数功能 :初始化VIC
** 入口参数 :无
** 出口参数 :无
*******************************************************************************************************
*/
void VIC_Init(void)
{
VICIntSelect = 0x00; // 设置所有中断连接IRQ中断
/* 设置RTC中断IRQ */
VICVectCntl1 = 0x20 | 13; // 分配通道0
VICVectAddr1 = (int)RTC_Int;// 设置中断服务程序地址
//VICDefVectAddr = (uint32)RTC_Int;
//VICIntEnable = (1 << 13); // 使能RTC中断
/* 设置定时器0中断IRQ */
VICVectCntl0 = 0x20 | 0x04; /* 设置定时器0中断通道分配次优先级 */
VICVectAddr0 = (uint32)IRQ_Timer0; /* 设置中断服务程序地址 */
VICIntEnable = (1 << 0x04) | (1 << 13);/* 使能定时器0中断,RTC中断 */
}
/*
*******************************************************************************************************
** 函数名称 :RTCInit()
** 函数功能 :初始化实时时钟
** 入口参数 :无
** 出口参数 :无
*******************************************************************************************************
*/
void RTCInit (void)
{
//PREINT = Fpclk / 32768 - 1; // 设置基准时钟分频器
//PREFRAC = Fpclk - (Fpclk / 32768) * 32768;
//CCR = 0x00; // 禁止时间计数器,RTC对连接在RTCX1 和RTCX2 两端的32kHz 振荡器信号进行计数
YEAR = 2008;
MONTH = 11;
DOM = 12;
DOW = 2;
HOUR = 12;
MIN = 58;
SEC = 58;
CIIR = 0x01; // 设置秒值的增量产生1次中断
//AMR = 0xFF; // 所有报警都被屏蔽
ILR = 0x03; // 清除RTC增量和报警中断标志
CCR = 0x11; // 启动RTC
}
/*
*********************************************************************************************************
** 函数名称 :DelayNS()
** 函数功能 :长软件延时
** 入口参数 :dly 延时参数,值越大,延时越久
** 出口参数 :无
*********************************************************************************************************
*/
void DelayNS (uint32 dly)
{
uint32 i;
for ( ; dly>0; dly--)
for (i=0; i<10000; i++);
}
/*
*********************************************************************************************************
** 函数名称 :R_ST()
** 函数功能 :读状态子程序。
** 入口参数 :无
** 出口参数 :LCD_State
*********************************************************************************************************
*/
uint8 R_ST(void)
{
uint8 LCD_State;
IO1DIR = 0x00070000; //P1.24~P1.31(D0~D7)is set INPUT,and P1.16 P1.17 P1.18 are set OUTPUT
IO1SET = LCD_CD; //指令通道 CD=1
IO1CLR = LCD_RD;
LCD_State = (IO1PIN >> 24) & 0x0ff ;
IO1SET = LCD_RD;
return (LCD_State);
}
/*
*********************************************************************************************************
** 函数名称 :ST01()
** 函数功能 :判状态位S1,SO子程序(读写指令和读写数据状态)
** 入口参数 :LCD_State
** 出口参数 :无
*********************************************************************************************************
*/
void ST01(void)
{
uint8 LCD_State;
LCD_State = R_ST();
while((LCD_State & 0x03) != 0x03)
{
LCD_State = R_ST();
}
}
/*
*********************************************************************************************************
** 函数名称 :ST2()
** 函数功能 :判状态位S2子程序(数据自动读状态)
** 入口参数 :LCD_State
** 出口参数 :无
*********************************************************************************************************
*/
void ST2(void)
{
uint8 LCD_State;
LCD_State = R_ST();
while((LCD_State & 0x04) != 0x04)
{
LCD_State = R_ST();
}
}
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -